]> granicus.if.org Git - cronie/commitdiff
Cache the security class and bit values and translate the remaining hardcoded values.
authorTomas Mraz <tmraz@fedoraproject.org>
Wed, 15 Dec 2010 21:51:38 +0000 (22:51 +0100)
committerTomas Mraz <tmraz@fedoraproject.org>
Wed, 15 Dec 2010 21:51:38 +0000 (22:51 +0100)
src/cron.c
src/funcs.h
src/security.c

index 9159164df7b7f226fe3c963017dffc0ded004066..ac9bba7dd2f9e7d3194b641025463f2ba82c953c 100644 (file)
@@ -198,6 +198,10 @@ int main(int argc, char *argv[]) {
                exit(1);
        }
 
+       if (cron_init_security() < 0) {
+               log_it("CRON", pid, "DEATH", "Critical security parameters not initialized", 0);
+       }
+
        /* Get the default locale character set for the mail 
         * "Content-Type: ...; charset=" header
         */
index fabd0b27a28f49bcb9f413d549ab9facc1b67362..a1645e90c6bc6d6f1c923f4c99291c0547ba8b7a 100644 (file)
@@ -85,6 +85,8 @@ long          get_gmtoff(time_t *, struct tm *);
 
 /* Red Hat security stuff (security.c): 
  */
+int cron_init_security( void );
+
 void cron_restore_default_security_context( void );
 
 int cron_set_job_security_context( entry *e, user *u, char ***jobenvp );
index 3ea7a1f0d7a6f9d5676765dc17be0d26544293e7..65cea73dbc7c3f7837fcc1ace7890d47d74ccc63 100644 (file)
@@ -80,6 +80,11 @@ static char **build_env(char **cronenv);
 static int cron_change_selinux_range(user * u, security_context_t ucontext);
 static int cron_get_job_range(user * u, security_context_t * ucontextp,
        char **jobenv);
+
+static security_class_t file_class;
+static security_class_t context_class;
+static access_vector_t entrypoint_bit;
+static access_vector_t contains_bit;
 #endif
 
 void cron_restore_default_security_context() {
@@ -88,6 +93,40 @@ void cron_restore_default_security_context() {
 #endif
 }
 
+int cron_init_security() {
+#ifdef WITH_SELINUX
+       int rv = -1;
+
+       if (is_selinux_enabled() <= 0)
+               return 0;
+
+       if (security_getenforce() <= 0)
+               rv = 0;
+
+       file_class = string_to_security_class("file");
+       if (!file_class) {
+               log_it("CRON", getpid(), "ERROR", "Failed to translate security class file", errno);
+               return rv;
+       }
+       context_class = string_to_security_class("context");
+       if (!context_class) {
+               log_it("CRON", getpid(), "ERROR", "Failed to translate security class context", errno);
+               return rv;
+       }
+       entrypoint_bit = string_to_av_perm(file_class, "entrypoint");
+       if (!entrypoint_bit) {
+               log_it("CRON", getpid(), "ERROR", "Failed to translate av perm entrypoint", errno);
+               return rv;
+       }
+       contains_bit = string_to_av_perm(context_class, "contains");
+       if (!contains_bit) {
+               log_it("CRON", getpid(), "ERROR", "Failed to translate av perm contains", errno);
+               return rv;
+       }
+#endif
+       return 0;
+}
+
 int cron_set_job_security_context(entry * e, user * u, char ***jobenv) {
        time_t minutely_time = 0;
 #ifdef WITH_PAM
@@ -254,12 +293,6 @@ static int cron_authorize_context(security_context_t scontext,
        struct av_decision avd;
        int retval;
 
-       security_class_t tclass = string_to_security_class("file");
-       if (!tclass)
-               return 0;
-       access_vector_t bit = string_to_av_perm(tclass, "entrypoint");
-       if (!bit)
-               return 0;
        /*
         * Since crontab files are not directly executed,
         * crond must ensure that the crontab file has
@@ -267,9 +300,11 @@ static int cron_authorize_context(security_context_t scontext,
         * the user cron job.  It performs an entrypoint
         * permission check for this purpose.
         */
+       if (!file_class || !entrypoint_bit)
+               return 0;
        retval = security_compute_av(scontext, file_context,
-               tclass, bit, &avd);
-       if (retval || ((bit & avd.allowed) != bit))
+               file_class, entrypoint_bit, &avd);
+       if (retval || ((entrypoint_bit & avd.allowed) != entrypoint_bit))
                return 0;
 #endif
        return 1;
@@ -280,16 +315,17 @@ static int cron_authorize_range(security_context_t scontext,
 #ifdef WITH_SELINUX
        struct av_decision avd;
        int retval;
-       unsigned int bit = CONTEXT__CONTAINS;
        /*
         * Since crontab files are not directly executed,
         * so crond must ensure that any user specified range
         * falls within the seusers-specified range for that Linux user.
         */
+       if (!context_class || !contains_bit)
+               return 0;
        retval = security_compute_av(scontext, ucontext,
-               SECCLASS_CONTEXT, bit, &avd);
+               context_class, contains_bit, &avd);
 
-       if (retval || ((bit & avd.allowed) != bit))
+       if (retval || ((contains_bit & avd.allowed) != contains_bit))
                return 0;
 #endif
        return 1;
@@ -527,22 +563,30 @@ int crontab_security_access(void) {
                security_context_t user_context;
                if (getprevcon_raw(&user_context) == 0) {
                        security_class_t passwd_class;
+                       access_vector_t crontab_bit;
                        struct av_decision avd;
-                       int retval;
+                       int retval = 0;
 
                        passwd_class = string_to_security_class("passwd");
                        if (passwd_class == 0) {
-                               selinux_check_passwd_access = -1;
                                fprintf(stderr, "Security class \"passwd\" is not defined in the SELinux policy.\n");
+                               retval = -1;
+                       }
+
+                       if (retval == 0) {
+                               crontab_bit = string_to_av_perm(passwd_class, "crontab");
+                               if (crontab_bit == 0) {
+                                       fprintf(stderr, "Security av permission \"crontab\" is not defined in the SELinux policy.\n");
+                                       retval = -1;
+                               }
                        }
 
-                       retval = security_compute_av_raw(user_context,
-                                                       user_context,
-                                                       passwd_class,
-                                                       PASSWD__CRONTAB,
-                                                       &avd);
+                       if (retval == 0)
+                               retval = security_compute_av_raw(user_context,
+                                       user_context, passwd_class,
+                                       crontab_bit, &avd);
 
-                       if ((retval == 0) && ((PASSWD__CRONTAB & avd.allowed) == PASSWD__CRONTAB)) {
+                       if ((retval == 0) && ((crontab_bit & avd.allowed) == crontab_bit)) {
                                selinux_check_passwd_access = 0;
                        }
                        freecon(user_context);