PAM support for cron(8)
Matthias Schmidt
schmidtm at mathematik.uni-marburg.de
Wed Dec 12 03:45:56 PST 2007
Hi,
as stated in my last message, I ported PAM support for cron(8) from
FreeBSD (have a look at [1]). The commit message is really clear about
the vantages so I don't want to elaborate on that :)
A patch is attached. I'm not really sure how to handle $FreeBSD$ IDs.
I just added the IDs from the FreeBSD files I used. The patch applies
clean (against HEAD) and works flawlessly.
Regards,
Matthias
[1] http://lists.freebsd.org/pipermail/cvs-src/2007-June/080023.html
--
Dipl.-Inf. Matthias Schmidt <schmidtm at mathematik.uni-marburg.de>
Dept. of Mathematics and Computer Science, Distributed Systems Group
University of Marburg, Hans-Meerwein-Strasse, 35032 Marburg, Germany
Tel: +49.6421.28 21 591, Fax: +49.6421.28 21 573, Office C4347
Index: Makefile
===================================================================
RCS file: /usr/dcvs/src/usr.sbin/cron/cron/Makefile,v
retrieving revision 1.2
diff -u -r1.2 Makefile
--- Makefile 17 Jun 2003 04:29:53 -0000 1.2
+++ Makefile 12 Dec 2007 11:39:16 -0000
@@ -1,11 +1,11 @@
-# $FreeBSD: src/usr.sbin/cron/cron/Makefile,v 1.12.2.1 2001/04/25 12:09:23 ru Exp $
+# $FreeBSD: src/usr.sbin/cron/cron/Makefile,v 1.16 2007/06/17 17:25:53 yar Exp $
# $DragonFly: src/usr.sbin/cron/cron/Makefile,v 1.2 2003/06/17 04:29:53 dillon Exp $
PROG= cron
SRCS= cron.c database.c do_command.c job.c user.c popen.c
-CFLAGS+=-DLOGIN_CAP
-DPADD= ${LIBCRON} ${LIBUTIL}
-LDADD= ${LIBCRON} -lutil
+CFLAGS+=-DLOGIN_CAP -DPAM
+DPADD= ${LIBCRON} ${LIBPAM} ${LIBUTIL}
+LDADD= ${LIBCRON} -lpam -lutil
MAN= cron.8
.include <bsd.prog.mk>
Index: cron.8
===================================================================
RCS file: /usr/dcvs/src/usr.sbin/cron/cron/cron.8,v
retrieving revision 1.3
diff -u -r1.3 cron.8
--- cron.8 18 Mar 2006 20:29:50 -0000 1.3
+++ cron.8 12 Dec 2007 11:39:16 -0000
@@ -15,10 +15,10 @@
.\" * Paul Vixie <paul at vix.com> uunet!decwrl!vixie!paul
.\" */
.\"
-.\" $FreeBSD: src/usr.sbin/cron/cron/cron.8,v 1.7.2.9 2003/03/11 21:13:48 trhodes Exp $
+.\" $FreeBSD: src/usr.sbin/cron/cron/cron.8,v 1.25 2007/06/17 17:25:53 yar Exp $
.\" $DragonFly: src/usr.sbin/cron/cron/cron.8,v 1.3 2006/03/18 20:29:50 dillon Exp $
.\"
-.Dd December 20, 1993
+.Dd June 17, 2007
.Dt CRON 8
.Os
.Sh NAME
@@ -54,11 +54,22 @@
.Pa /etc/crontab
which is in a different format (see
.Xr crontab 5 ) .
+.Pp
The
.Nm
utility
then wakes up every minute, examining all stored crontabs, checking each
-command to see if it should be run in the current minute. When executing
+command to see if it should be run in the current minute.
+Before running a command from a per-account crontab file,
+.Nm
+checks the status of the account with
+.Xr pam 3
+and skips the command if the account is unavailable,
+e.g., locked out or expired.
+Commands from
+.Pa /etc/crontab
+bypass this check.
+When executing
commands, any output is mailed to the owner of the crontab (or to the user
named in the
.Ev MAILTO
@@ -171,8 +182,21 @@
trace through the execution, but do not perform any actions
.El
.El
+.Sh FILES
+.Bl -tag -width /etc/pam.d/cron -compact
+.It Pa /etc/crontab
+System crontab file
+.It Pa /etc/pam.d/cron
+.Xr pam.conf 5
+configuration file for
+.Nm
+.It Pa /var/cron/tabs
+Directory for personal crontab files
+.El
.Sh SEE ALSO
.Xr crontab 1 ,
-.Xr crontab 5
+.Xr pam 3 ,
+.Xr crontab 5 ,
+.Xr pam.conf 5
.Sh AUTHORS
.An Paul Vixie Aq paul at vix.com
Index: cron.h
===================================================================
RCS file: /usr/dcvs/src/usr.sbin/cron/cron/cron.h,v
retrieving revision 1.5
diff -u -r1.5 cron.h
--- cron.h 18 Mar 2006 20:29:50 -0000 1.5
+++ cron.h 12 Dec 2007 11:39:16 -0000
@@ -17,7 +17,7 @@
/* cron.h - header for vixie's cron
*
- * $FreeBSD: src/usr.sbin/cron/cron/cron.h,v 1.9.2.3 2001/05/28 23:37:26 babkin Exp $
+ * $FreeBSD: src/usr.sbin/cron/cron/cron.h,v 1.17 2007/06/17 17:25:53 yar Exp $
* $DragonFly: src/usr.sbin/cron/cron/cron.h,v 1.5 2006/03/18 20:29:50 dillon Exp $
*
* vix 14nov88 [rest of log is in RCS]
@@ -76,6 +76,7 @@
#define MAX_UNAME 20 /* max length of username, should be overkill */
#define ROOT_UID 0 /* don't change this, it really must be root */
#define ROOT_USER "root" /* ditto */
+#define SYS_NAME "*system*" /* magic owner name for system crontab */
/* NOTE: these correspond to DebugFlagNames,
* defined below.
Index: database.c
===================================================================
RCS file: /usr/dcvs/src/usr.sbin/cron/cron/database.c,v
retrieving revision 1.6
diff -u -r1.6 database.c
--- database.c 8 Aug 2005 18:36:28 -0000 1.6
+++ database.c 12 Dec 2007 11:39:16 -0000
@@ -84,7 +84,7 @@
new_db.head = new_db.tail = NULL;
if (syscron_stat.st_mtime) {
- process_crontab("root", "*system*",
+ process_crontab("root", SYS_NAME,
SYSCRONTAB, &syscron_stat,
&new_db, old_db);
}
@@ -189,7 +189,7 @@
int crontab_fd = OK - 1;
user *u;
- if (strcmp(fname, "*system*") && !(pw = getpwnam(uname))) {
+ if (strcmp(fname, SYS_NAME) && !(pw = getpwnam(uname))) {
/* file doesn't have a user in passwd file.
*/
log_it(fname, getpid(), "ORPHAN", "no passwd entry");
Index: do_command.c
===================================================================
RCS file: /usr/dcvs/src/usr.sbin/cron/cron/do_command.c,v
retrieving revision 1.7
diff -u -r1.7 do_command.c
--- do_command.c 18 Mar 2006 20:29:50 -0000 1.7
+++ do_command.c 12 Dec 2007 11:54:06 -0000
@@ -14,7 +14,7 @@
* I'll try to keep a version up to date. I can be reached as follows:
* Paul Vixie <paul at vix.com> uunet!decwrl!vixie!paul
*
- * $FreeBSD: src/usr.sbin/cron/cron/do_command.c,v 1.15.2.5 2001/05/04 00:59:40 peter Exp $
+ * $FreeBSD: src/usr.sbin/cron/cron/do_command.c,v 1.27 2007/06/17 17:25:53 yar Exp $
* $DragonFly: src/usr.sbin/cron/cron/do_command.c,v 1.7 2006/03/18 20:29:50 dillon Exp $
*/
@@ -29,7 +29,10 @@
#if defined(LOGIN_CAP)
# include <login_cap.h>
#endif
-
+#ifdef PAM
+# include <security/pam_appl.h>
+# include <security/openpam.h>
+#endif
static void child_process(entry *, user *),
do_univ(user *);
@@ -92,6 +95,48 @@
usernm = env_get("LOGNAME", e->envp);
mailto = env_get("MAILTO", e->envp);
+#ifdef PAM
+ /* use PAM to see if the user's account is available,
+ * i.e., not locked or expired or whatever. skip this
+ * for system tasks from /etc/crontab -- they can run
+ * as any user.
+ */
+ if (strcmp(u->name, SYS_NAME)) { /* not equal */
+ pam_handle_t *pamh = NULL;
+ int pam_err;
+ struct pam_conv pamc = {
+ .conv = openpam_nullconv,
+ .appdata_ptr = NULL
+ };
+
+ Debug(DPROC, ("[%d] checking account with PAM\n", getpid()))
+
+ /* u->name keeps crontab owner name while LOGNAME is the name
+ * of user to run command on behalf of. they should be the
+ * same for a task from a per-user crontab.
+ */
+ if (strcmp(u->name, usernm)) {
+ log_it(usernm, getpid(), "username ambiguity", u->name);
+ exit(ERROR_EXIT);
+ }
+
+ pam_err = pam_start("cron", usernm, &pamc, &pamh);
+ if (pam_err != PAM_SUCCESS) {
+ log_it("CRON", getpid(), "error", "can't start PAM");
+ exit(ERROR_EXIT);
+ }
+
+ pam_err = pam_acct_mgmt(pamh, PAM_SILENT);
+ /* Expired password shouldn't prevent the job from running. */
+ if (pam_err != PAM_SUCCESS && pam_err != PAM_NEW_AUTHTOK_REQD) {
+ log_it(usernm, getpid(), "USER", "account unavailable");
+ exit(ERROR_EXIT);
+ }
+
+ pam_end(pamh, pam_err);
+ }
+#endif
+
#ifdef USE_SIGCHLD
/* our parent is watching for our death by catching SIGCHLD. we
* do not care to watch for our children's deaths this way -- we
More information about the Submit
mailing list