.PP
Time changes of more than 3 hours are considered to be corrections to
the clock or timezone, and the new time is used immediately.
+.SS PAM Access Control
+On Red Hat systems, crond now supports access control with PAM - see
+.IR pam (8) .
+A PAM configuration file for crond is installed in /etc/pam.d/crond .
+crond loads the PAM environment from the pam_env module, but these
+can be overriden by settings in the crontab file.
.SH SIGNALS
On receipt of a \s-2SIGHUP\s+2, the cron daemon will close and reopen its
log file. This is useful in scripts which rotate and age log files.
In other words, it should be mode 0600.
.SH "SEE ALSO"
.IR crontab (1),
-.IR crontab (5)
+.IR crontab (5),
+.IR pam (8)
.SH AUTHOR
.nf
Paul Vixie <vixie@isc.org>
#include "cron.h"
+#ifdef WITH_PAM
+static pam_handle_t *pamh = NULL;
+static const struct pam_conv conv = {
+ NULL
+};
+#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
+ fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \
+ syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
+ pam_end(pamh, retcode); exit(1); \
+ }
+#endif
+
static void child_process(entry *, user *);
static int safe_p(const char *, const char *);
+/* Build up the job environment from the PAM environment plus the
+ crontab environment */
+static char ** build_env(char **cronenv)
+{
+ char **jobenv = cronenv;
+#if defined(WITH_PAM)
+ char **pamenv = pam_getenvlist(pamh);
+ char *cronvar;
+ int count = 0;
+
+ jobenv = env_copy(pamenv);
+
+ /* Now add the cron environment variables. Since env_set()
+ overwrites existing variables, this will let cron's
+ environment settings override pam's */
+
+ while ((cronvar = cronenv[count++])) {
+ if (!(jobenv = env_set(jobenv, cronvar))) {
+ syslog(LOG_ERR, "Setting Cron environment variable %s failed", cronvar);
+ return NULL;
+ }
+ }
+#endif
+ return jobenv;
+}
+
void
do_command(entry *e, user *u) {
Debug(DPROC, ("[%ld] do_command(%s, (%s,%ld,%ld))\n",
child_process(entry *e, user *u) {
int stdin_pipe[2], stdout_pipe[2];
char *input_data, *usernm, *mailto;
- int children = 0;
+ int children = 0;
+#if defined(WITH_PAM)
+ int retcode = 0;
+#endif
+
Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd))
*p = '\0';
}
+#if defined(WITH_PAM)
+ retcode = pam_start("crond", usernm, &conv, &pamh);
+ PAM_FAIL_CHECK;
+ retcode = pam_acct_mgmt(pamh, PAM_SILENT);
+ PAM_FAIL_CHECK;
+ retcode = pam_open_session(pamh, PAM_SILENT);
+ PAM_FAIL_CHECK;
+ retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
+ PAM_FAIL_CHECK;
+#endif
+
/* fork again, this time so we can exec the user's command.
*/
switch (fork()) {
Debug(DPROC, (", dumped core"))
Debug(DPROC, ("\n"))
}
+
+#if defined(WITH_PAM)
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
+ retcode = pam_close_session(pamh, PAM_SILENT);
+ pam_end(pamh, retcode);
+#endif
}
static int