From 15606317ac2582858a14565d3c8ce2a4bef86dd5 Mon Sep 17 00:00:00 2001 From: mmaslano Date: Fri, 17 Aug 2007 14:58:01 +0200 Subject: [PATCH] PAM support was added: open sessions and set credentials for users. --- cron.8 | 9 +++++++- cron.h | 9 ++++++-- do_command.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/cron.8 b/cron.8 index 18f1107..727f128 100644 --- a/cron.8 +++ b/cron.8 @@ -76,6 +76,12 @@ jobs twice. .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. @@ -88,7 +94,8 @@ In this version of 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 diff --git a/cron.h b/cron.h index f1b3671..4e78ed8 100644 --- a/cron.h +++ b/cron.h @@ -30,12 +30,17 @@ #define CRON_VERSION "V5.0" +#include "config.h" +#include "externs.h" + #ifdef WITH_SELINUX #include #endif -#include "config.h" -#include "externs.h" +#ifdef WITH_PAM +#include +#endif + #include "pathnames.h" #include "macros.h" #include "structs.h" diff --git a/do_command.c b/do_command.c index 3449916..f9192c3 100644 --- a/do_command.c +++ b/do_command.c @@ -25,9 +25,47 @@ static char rcsid[] = "$Id: do_command.c,v 1.9 2004/01/23 18:56:42 vixie Exp $"; #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", @@ -64,7 +102,11 @@ static void 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)) @@ -134,6 +176,17 @@ child_process(entry *e, user *u) { *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()) { @@ -528,6 +581,12 @@ child_process(entry *e, user *u) { 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 -- 2.40.0