]> granicus.if.org Git - cronie/commitdiff
PAM support was added: open sessions and set credentials for users.
authormmaslano <mmaslano@redhat.com>
Fri, 17 Aug 2007 12:58:01 +0000 (14:58 +0200)
committermmaslano <mmaslano@redhat.com>
Fri, 17 Aug 2007 12:58:01 +0000 (14:58 +0200)
cron.8
cron.h
do_command.c

diff --git a/cron.8 b/cron.8
index 18f11077694d5f67d65f0d1265c9318a20d17931..727f1284104bb8252b89d2f2f29a31ee017b6e0d 100644 (file)
--- 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 <vixie@isc.org>
diff --git a/cron.h b/cron.h
index f1b3671abed54c07827a19d6aaf51eae1a52aaf7..4e78ed8c35d732019901932ba30f55904b92655d 100644 (file)
--- a/cron.h
+++ b/cron.h
 
 #define CRON_VERSION "V5.0"
 
+#include "config.h"
+#include "externs.h"
+
 #ifdef WITH_SELINUX
 #include <selinux/selinux.h>
 #endif
 
-#include "config.h"
-#include "externs.h"
+#ifdef WITH_PAM
+#include <security/pam_appl.h>
+#endif
+
 #include "pathnames.h"
 #include "macros.h"
 #include "structs.h"
index 344991645aecc82072c90a6a744dcd8c58d2d857..f9192c300002d7270dce53144a8d762efbfb1ed5 100644 (file)
@@ -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