diff --git a/src/crontab.c b/src/crontab.c index 22571ff..d165a06 100644 --- a/src/crontab.c +++ b/src/crontab.c @@ -170,7 +170,7 @@ int main(int argc, char *argv[]) { } #if defined(WITH_PAM) - if (cron_start_pam(pw) != PAM_SUCCESS) { + if (getuid() != 0 && cron_start_pam(pw) != PAM_SUCCESS) { fprintf(stderr, "You (%s) are not allowed to access to (%s) because of pam configuration.\n", User, ProgramName); diff --git a/src/security.c b/src/security.c index 4eee004..1668890 100644 --- a/src/security.c +++ b/src/security.c @@ -88,6 +88,7 @@ static int cron_open_pam_session(struct passwd *pw); if (pam_session_opened != 0) \ pam_close_session(pamh, PAM_SILENT); \ pam_end(pamh, retcode); \ + pamh = NULL; \ } \ return(retcode); } #endif @@ -122,7 +123,8 @@ int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED, } #ifdef WITH_PAM - if ((ret = cron_start_pam(e->pwd)) != 0) { + /* PAM is called only for non-root users or non-system crontab */ + if ((!u->system || e->pwd->pw_uid != 0) && (ret = cron_start_pam(e->pwd)) != 0) { log_it(e->pwd->pw_name, getpid(), "FAILED to authorize user with PAM", pam_strerror(pamh, ret), 0); return -1; @@ -152,7 +154,7 @@ int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED, freecon(ucontext); #endif #ifdef WITH_PAM - if ((ret = cron_open_pam_session(e->pwd)) != 0) { + if (pamh != NULL && (ret = cron_open_pam_session(e->pwd)) != 0) { log_it(e->pwd->pw_name, getpid(), "FAILED to open PAM security session", pam_strerror(pamh, ret), 0); return -1; @@ -223,7 +225,10 @@ void cron_close_pam(void) { pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); pam_close_session(pamh, PAM_SILENT); } - pam_end(pamh, PAM_SUCCESS); + if (pamh != NULL) { + pam_end(pamh, PAM_SUCCESS); + pamh = NULL; + } #endif } @@ -243,7 +248,9 @@ int cron_change_groups(struct passwd *pw) { #if defined(WITH_PAM) /* credentials may take form of supplementary groups so reinitialize * them here */ - pam_setcred(pamh, PAM_REINITIALIZE_CRED | PAM_SILENT); + if (pamh != NULL) { + pam_setcred(pamh, PAM_REINITIALIZE_CRED | PAM_SILENT); + } #endif return 0; @@ -614,18 +621,19 @@ int crontab_security_access(void) { * crontab environment */ static char **build_env(char **cronenv) { + char **jobenv; #ifdef WITH_PAM - char **jobenv = pam_getenvlist(pamh); char *cronvar; int count = 0; - if (jobenv == NULL) { - jobenv = env_init(); - if (jobenv == NULL) { + if (pamh == NULL || (jobenv=pam_getenvlist(pamh)) == NULL) { +#endif + jobenv = env_copy(cronenv); + if (jobenv == NULL) log_it("CRON", getpid(), "ERROR", "Initialization of cron environment variables failed", 0); - return NULL; - } + return jobenv; +#ifdef WITH_PAM } /* Now add the cron environment variables. Since env_set() @@ -640,7 +648,5 @@ static char **build_env(char **cronenv) { } } return jobenv; -#else - return env_copy(cronenv); #endif } diff --git a/src/structs.h b/src/structs.h index 272777a..6d3c15b 100644 --- a/src/structs.h +++ b/src/structs.h @@ -67,6 +67,7 @@ typedef struct _user { time_t mtime; /* last modtime of crontab */ entry *crontab; /* this person's crontab */ security_context_t scontext; /* SELinux security context */ + int system; /* is it a system crontab */ } user; typedef struct _orphan { diff --git a/src/user.c b/src/user.c index 20c0d96..e950db7 100644 --- a/src/user.c +++ b/src/user.c @@ -89,6 +89,8 @@ load_user (int crontab_fd, struct passwd *pw, const char *uname, goto done; } + u->system = pw == NULL; + /* init environment. this will be copied/augmented for each entry. */ if ((envp = env_init()) == NULL) {