Blob Blame History Raw
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) {