diff -upk.orig vixie-cron-4.1.20060426.orig/lib/libc/gen/pw_dup.c vixie-cron-4.1.20060426/lib/libc/gen/pw_dup.c --- vixie-cron-4.1.20060426.orig/lib/libc/gen/pw_dup.c 2005-08-08 08:05:34 +0000 +++ vixie-cron-4.1.20060426/lib/libc/gen/pw_dup.c 2006-04-30 22:19:32 +0000 @@ -48,14 +48,19 @@ struct passwd * pw_dup(const struct passwd *pw) { char *cp; - size_t nsize, psize, csize, gsize, dsize, ssize, total; + size_t nsize = 0, psize = 0, gsize = 0, dsize = 0, ssize = 0, total; +#ifdef LOGIN_CAP + size_t csize = 0; +#endif struct passwd *newpw; /* Allocate in one big chunk for easy freeing */ total = sizeof(struct passwd); PW_SIZE(pw_name, nsize); PW_SIZE(pw_passwd, psize); +#ifdef LOGIN_CAP PW_SIZE(pw_class, csize); +#endif PW_SIZE(pw_gecos, gsize); PW_SIZE(pw_dir, dsize); PW_SIZE(pw_shell, ssize); @@ -73,7 +78,9 @@ pw_dup(const struct passwd *pw) PW_COPY(pw_name, nsize); PW_COPY(pw_passwd, psize); +#ifdef LOGIN_CAP PW_COPY(pw_class, csize); +#endif PW_COPY(pw_gecos, gsize); PW_COPY(pw_dir, dsize); PW_COPY(pw_shell, ssize); diff -upk.orig vixie-cron-4.1.20060426.orig/usr.bin/at/at.1 vixie-cron-4.1.20060426/usr.bin/at/at.1 --- vixie-cron-4.1.20060426.orig/usr.bin/at/at.1 2005-09-30 20:34:25 +0000 +++ vixie-cron-4.1.20060426/usr.bin/at/at.1 2006-04-30 22:16:46 +0000 @@ -273,20 +273,20 @@ shell, the owner of the login shell will For non-root users, permission to run .Nm is determined by the files -.Pa /var/cron/at.allow +.Pa /etc/at.allow and -.Pa /var/cron/at.deny . +.Pa /etc/at.deny . .Em Note : these files must be readable by group crontab (if they exist). .Pp If the file -.Pa /var/cron/at.allow +.Pa /etc/at.allow exists, only usernames mentioned in it are allowed to use .Nm at . If -.Pa /var/cron/at.allow +.Pa /etc/at.allow does not exist, -.Pa /var/cron/at.deny +.Pa /etc/at.deny is checked. Every username not mentioned in it is then allowed to use .Nm at . @@ -294,16 +294,16 @@ If neither exists, only the superuser is .Nm at . .Pp An empty -.Pa /var/cron/at.deny +.Pa /etc/at.deny means that every user is allowed use these commands. This is the default configuration. .Sh FILES -.Bl -tag -width /var/cron/at.allow -compact -.It Pa /var/cron/atjobs +.Bl -tag -width /etc/at.allow -compact +.It Pa /var/spool/at directory containing job files -.It Pa /var/cron/at.allow +.It Pa /etc/at.allow allow permission control -.It Pa /var/cron/at.deny +.It Pa /etc/at.deny deny permission control .El .Sh SEE ALSO diff -upk.orig vixie-cron-4.1.20060426.orig/usr.bin/at/at.c vixie-cron-4.1.20060426/usr.bin/at/at.c --- vixie-cron-4.1.20060426.orig/usr.bin/at/at.c 2006-04-26 03:01:48 +0000 +++ vixie-cron-4.1.20060426/usr.bin/at/at.c 2006-04-30 22:22:37 +0000 @@ -38,6 +38,8 @@ #include "privs.h" #include +#define __dead __attribute__ ((noreturn)) + #define ALARMC 10 /* Number of seconds to wait for timeout */ #define TIMESIZE 50 /* Size of buffer passed to strftime() */ @@ -62,15 +64,15 @@ char force = 0; /* suppress errors (at char interactive = 0; /* interactive mode (atrm) */ static int send_mail = 0; /* whether we are sending mail */ -static void sigc(int); +static __dead void sigc(int); static void alarmc(int); static void writefile(const char *, time_t, char); static void list_jobs(int, char **, int, int); static time_t ttime(const char *); static int check_permission(void); static __dead void panic(const char *); -static void perr(const char *); -static void perr2(const char *, const char *); +static __dead void perr(const char *); +static __dead void perr2(const char *, const char *); static __dead void usage(void); time_t parsetime(int, char **); @@ -135,7 +137,7 @@ perr2(const char *a, const char *b) } /* ARGSUSED */ -static void +static __dead void sigc(int signo) { /* If the user presses ^C, remove the spool file and exit. */ @@ -514,7 +516,7 @@ list_jobs(int argc, char **argv, int cou PRIV_END; - if (fstat(spool->dd_fd, &stbuf) != 0) + if (fstat(dirfd(spool), &stbuf) != 0) perr2("Cannot stat ", AT_DIR); /* diff -upk.orig vixie-cron-4.1.20060426.orig/usr.bin/at/atq.1 vixie-cron-4.1.20060426/usr.bin/at/atq.1 --- vixie-cron-4.1.20060426.orig/usr.bin/at/atq.1 2003-06-10 09:12:09 +0000 +++ vixie-cron-4.1.20060426/usr.bin/at/atq.1 2006-04-30 22:16:46 +0000 @@ -88,8 +88,8 @@ Jobs that have completed but have not ye If a name(s) is provided, only those files belonging to that user(s) are displayed. .Sh FILES -.Bl -tag -width /var/cron/atjobs -compact -.It Pa /var/cron/atjobs +.Bl -tag -width /var/spool/at -compact +.It Pa /var/spool/at directory containing job files .El .Sh SEE ALSO diff -upk.orig vixie-cron-4.1.20060426.orig/usr.bin/at/atrm.1 vixie-cron-4.1.20060426/usr.bin/at/atrm.1 --- vixie-cron-4.1.20060426.orig/usr.bin/at/atrm.1 2005-06-23 14:39:35 +0000 +++ vixie-cron-4.1.20060426/usr.bin/at/atrm.1 2006-04-30 22:16:46 +0000 @@ -77,8 +77,8 @@ If one or more user names are specified, are removed. Only the superuser may remove other users' jobs. .Sh FILES -.Bl -tag -width /var/cron/atjobs -compact -.It Pa /var/cron/atjobs +.Bl -tag -width /var/spool/at -compact +.It Pa /var/spool/at directory containing job files .El .Sh SEE ALSO diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/atrun.c vixie-cron-4.1.20060426/usr.sbin/cron/atrun.c --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/atrun.c 2005-01-30 20:45:58 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/atrun.c 2006-04-30 22:16:46 +0000 @@ -386,7 +386,9 @@ run_job(atjob *job, char *atfile) } /* mark ourselves as different to PS command watchers */ +#ifdef HAVE_SETPROCTITLE setproctitle("atrun %s", atfile); +#endif pipe(output_pipe); /* child's stdout/stderr */ diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/closeall.c vixie-cron-4.1.20060426/usr.sbin/cron/closeall.c --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/closeall.c 1970-01-01 00:00:00 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/closeall.c 2006-04-30 22:16:46 +0000 @@ -0,0 +1,27 @@ +#include +#include + +#ifdef __linux__ +#include +#endif + +int close_all(void) +{ + int fd, max; + + max = sysconf(_SC_OPEN_MAX); + if (max <= 0) + return -1; + +#ifdef __linux__ + if (max < NR_OPEN) + max = NR_OPEN; +#endif + + for (fd = 3; fd < max; fd++) { + if (close(fd) && errno != EBADF) + return -1; + } + + return 0; +} diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/config.h vixie-cron-4.1.20060426/usr.sbin/cron/config.h --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/config.h 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/config.h 2006-04-30 22:16:46 +0000 @@ -29,7 +29,7 @@ */ #ifndef DEBUGGING -#define DEBUGGING 1 /* 1 or 0 -- do you want debugging code built in? */ +#define DEBUGGING 0 /* 1 or 0 -- do you want debugging code built in? */ #endif /* @@ -78,18 +78,20 @@ * are both defined, then logging will go to both * places. */ -#define SYSLOG /*-*/ +#define SYSLOG 1 /*-*/ /* if you have a tm_gmtoff member in struct tm. * If not, we will have to compute the value ourselves. */ -#define HAVE_TM_GMTOFF /*-*/ +#define HAVE_TM_GMTOFF 1 /*-*/ /* if your OS supports a BSD-style login.conf file */ -#define LOGIN_CAP /*-*/ +#undef LOGIN_CAP +/* #define LOGIN_CAP */ /*-*/ /* if your OS supports BSD authentication */ -#define BSD_AUTH /*-*/ +#undef BSD_AUTH +/*#define BSD_AUTH*/ /*-*/ /* if your OS has a getloadavg() function */ #define HAVE_GETLOADAVG /*-*/ diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/cron.8 vixie-cron-4.1.20060426/usr.sbin/cron/cron.8 --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/cron.8 2005-11-30 11:18:28 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/cron.8 2006-04-30 22:16:46 +0000 @@ -29,7 +29,7 @@ .Nm cron .Op Fl l Ar load_avg .Op Fl n -.Op Fl x Ar [ext,sch,proc,pars,load,misc,test] +.Op Fl x Ar [ext,sch,proc,pars,load,misc,test,bit] .Sh DESCRIPTION The .Nm @@ -45,7 +45,7 @@ commands. Normally, the .Nm daemon is started from the -.Pa /etc/rc +.Pa /etc/init.d/crond command script. Because it can execute commands on a user's behalf, .Nm @@ -67,9 +67,9 @@ Additionally, checks the modification time on the system crontab file .Pq Pa /etc/crontab , the crontab spool -.Pq Pa /var/cron/tabs , +.Pq Pa /var/spool/cron , and the at spool -.Pq Pa /var/cron/atjobs +.Pq Pa /var/spool/at once a minute. If the modification time has changed, the affected files are reloaded. .Pp @@ -171,28 +171,27 @@ causes .Nm to close and reopen its log file. This is useful in scripts which rotate and age log files. -On -.Ox +On Linux this has no effect because .Nm cron logs via .Xr syslog 3 . .El .Sh FILES -.Bl -tag -width "/var/cron/tabs/.sock" -compact +.Bl -tag -width "/var/spool/cron/.sock" -compact .It Pa /etc/crontab system crontab file -.It Pa /var/cron/atjobs +.It Pa /var/spool/at directory containing .Xr at 1 jobs -.It Pa /var/cron/log -cron's log file -.It Pa /var/cron/tabs +.It Pa /var/spool/cron directory containing individual crontab files -.It Pa /var/cron/tabs/.sock +.It Pa /var/spool/cron/.sock used by .Xr crontab 1 +and +.Xr at 1 to tell .Nm to check for crontab changes immediately @@ -207,12 +206,7 @@ to check for crontab changes immediately .Sh CAVEATS All .Xr crontab 5 -files must not be readable or writable by any user other than their owner, -including -.Pa /etc/crontab . +files must not be readable or writable by any user other than their owner. In practice this means they should be mode 0600. This restriction is enforced automatically by -.Xr crontab 1 -but if -.Pa /etc/crontab -is used, the mode must be set manually on that file. +.Xr crontab 1 . diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/cron.c vixie-cron-4.1.20060426/usr.sbin/cron/cron.c --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/cron.c 2005-11-15 07:02:37 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/cron.c 2006-04-30 22:16:46 +0000 @@ -49,6 +49,8 @@ static cron_db database; static at_db at_database; static double batch_maxload = BATCH_MAXLOAD; +extern int close_all(void); + static void usage(void) { #if DEBUGGING @@ -72,6 +74,7 @@ main(int argc, char *argv[]) { int fd; ProgramName = argv[0]; + FixedName = "crond"; setlocale(LC_ALL, ""); @@ -82,6 +85,10 @@ main(int argc, char *argv[]) { NoFork = 0; parse_args(argc, argv); + if (close_all()) { + perror("close"); + exit(ERROR_EXIT); + } bzero((char *)&sact, sizeof sact); sigemptyset(&sact.sa_mask); diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/crontab.1 vixie-cron-4.1.20060426/usr.sbin/cron/crontab.1 --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/crontab.1 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/crontab.1 2006-04-30 22:16:46 +0000 @@ -45,7 +45,7 @@ daemon. Each user can have their own .Xr crontab 5 , and though these are files in -.Pa /var/cron/tabs , +.Pa /var/spool/cron , they are not intended to be edited directly. .Pp The first form of this command is used to install a new crontab from some @@ -54,17 +54,17 @@ named file, or standard input if the pse is given. .Pp If the -.Pa /var/cron/cron.allow +.Pa /etc/cron.allow file exists, then you must be listed therein in order to use .Nm crontab . If the -.Pa /var/cron/cron.allow +.Pa /etc/cron.allow file does not exist but the -.Pa /var/cron/cron.deny +.Pa /etc/cron.deny file does exist, then you must .Em not be listed in the -.Pa /var/cron/cron.deny +.Pa /etc/cron.deny file in order to use .Nm crontab . If neither of these files exists then only the super user @@ -72,9 +72,9 @@ will be allowed to use .Nm crontab . .Em NOTE : if they exist, -.Pa /var/cron/cron.allow +.Pa /etc/cron.allow and -.Pa /var/cron/cron.deny +.Pa /etc/cron.deny must be readable by group crontab. If .Nm @@ -119,12 +119,12 @@ After you exit from the editor, the modi will be installed automatically. .El .Sh FILES -.Bl -tag -width "/var/cron/cron.allow" -compact -.It Pa /var/cron/cron.allow +.Bl -tag -width "/etc/cron.allow" -compact +.It Pa /etc/cron.allow list of users allowed to use crontab -.It Pa /var/cron/cron.deny +.It Pa /etc/cron.deny list of users prohibited from using crontab -.It Pa /var/cron/tabs +.It Pa /var/spool/cron directory of individual crontabs .El .Sh DIAGNOSTICS diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/crontab.5 vixie-cron-4.1.20060426/usr.sbin/cron/crontab.5 --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/crontab.5 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/crontab.5 2006-04-30 22:16:46 +0000 @@ -39,7 +39,7 @@ There may be a system .Pf ( Pa /etc/crontab ) and each user may have their own .Nm -.Pf ( Pa /var/cron/tabs/ ) . +.Pf ( Pa /var/spool/cron/ ) . Commands in any given .Nm will be diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/crontab.c vixie-cron-4.1.20060426/usr.sbin/cron/crontab.c --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/crontab.c 2005-11-29 20:43:31 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/crontab.c 2006-04-30 22:28:05 +0000 @@ -58,6 +58,8 @@ static void list_cmd(void), die(int); static int replace_cmd(void); +extern int close_all(void); + static void usage(const char *msg) { fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg); @@ -76,6 +78,7 @@ main(int argc, char *argv[]) { Pid = getpid(); ProgramName = argv[0]; + FixedName = "crontab"; setlocale(LC_ALL, ""); @@ -283,8 +286,12 @@ edit_cmd(void) { FILE *f; int ch, t, x; struct stat statbuf, xstatbuf; +#ifndef HAVE_FUTIMES + struct utimbuf utimebuf; +#else struct timespec mtimespec; struct timeval tv[2]; +#endif WAIT_T waiter; PID_T pid, xpid; @@ -310,16 +317,21 @@ edit_cmd(void) { perror("fstat"); goto fatal; } +#ifndef HAVE_FUTIMES + utimebuf.actime = statbuf.st_atime; + utimebuf.modtime = statbuf.st_mtime; +#else memcpy(&mtimespec, &statbuf.st_mtimespec, sizeof(mtimespec)); TIMESPEC_TO_TIMEVAL(&tv[0], &statbuf.st_atimespec); TIMESPEC_TO_TIMEVAL(&tv[1], &statbuf.st_mtimespec); +#endif /* Turn off signals. */ (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); - if (snprintf(Filename, sizeof Filename, "%s/crontab.XXXXXXXXXX", + if (snprintf(Filename, sizeof Filename, "%s/crontab.XXXXXX", _PATH_TMP) >= sizeof(Filename)) { fprintf(stderr, "path too long\n"); goto fatal; @@ -360,7 +372,11 @@ edit_cmd(void) { perror(Filename); exit(ERROR_EXIT); } +#ifndef HAVE_FUTIMES + utime(Filename, &utimebuf); +#else (void)futimes(t, tv); +#endif again: rewind(NewCrontab); if (ferror(NewCrontab)) { @@ -390,12 +406,16 @@ edit_cmd(void) { goto fatal; case 0: /* child */ - if (setgid(MY_GID(pw)) < 0) { + if (setgid(getgid()) < 0) { perror("setgid(getgid())"); exit(ERROR_EXIT); } - if (chdir(_PATH_TMP) < 0) { - perror(_PATH_TMP); + if (chdir("/") < 0) { + perror("/"); + exit(ERROR_EXIT); + } + if (close_all()) { + perror("close"); exit(ERROR_EXIT); } if (snprintf(q, sizeof q, "%s %s", editor, Filename) >= sizeof(q)) { @@ -445,7 +465,11 @@ edit_cmd(void) { perror("fstat"); goto fatal; } +#ifndef HAVE_FUTIMES + if (utimebuf.modtime == statbuf.st_mtime) { +#else if (timespeccmp(&mtimespec, &statbuf.st_mtimespec, -) == 0) { +#endif if (lstat(Filename, &xstatbuf) == 0 && statbuf.st_ino != xstatbuf.st_ino) { fprintf(stderr, "%s: crontab temp file moved, editor " @@ -514,7 +538,7 @@ replace_cmd(void) { fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName); return (-2); } - if (snprintf(TempFilename, sizeof TempFilename, "%s/tmp.XXXXXXXXX", + if (snprintf(TempFilename, sizeof TempFilename, "%s/tmp.XXXXXX", SPOOL_DIR) >= sizeof(TempFilename)) { TempFilename[0] = '\0'; fprintf(stderr, "path too long\n"); diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/do_command.c vixie-cron-4.1.20060426/usr.sbin/cron/do_command.c --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/do_command.c 2004-11-02 21:46:16 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/do_command.c 2006-04-30 22:16:46 +0000 @@ -70,7 +70,9 @@ child_process(entry *e, user *u) { Debug(DPROC, ("[%ld] child_process('%s')\n", (long)getpid(), e->cmd)) /* mark ourselves as different to PS command watchers */ +#ifdef HAVE_SETPROCTITLE setproctitle("running job"); +#endif /* discover some useful and important environment settings */ diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/externs.h vixie-cron-4.1.20060426/usr.sbin/cron/externs.h --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/externs.h 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/externs.h 2006-04-30 22:16:46 +0000 @@ -22,6 +22,9 @@ */ /* reorder these #include's at your peril */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif #include #include diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/funcs.h vixie-cron-4.1.20060426/usr.sbin/cron/funcs.h --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/funcs.h 2005-01-30 20:44:50 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/funcs.h 2006-04-30 22:16:46 +0000 @@ -66,6 +66,7 @@ char *env_get(char *, char **), **env_copy(char **), **env_set(char **, char *); +struct passwd *pw_dup(const struct passwd *); void mkprint(char *, unsigned char *, int); user *load_user(int, struct passwd *, const char *), diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/globals.h vixie-cron-4.1.20060426/usr.sbin/cron/globals.h --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/globals.h 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/globals.h 2006-04-30 22:16:46 +0000 @@ -57,7 +57,8 @@ XTRN const char *DowNames[] #endif ; -XTRN char *ProgramName INIT("amnesia"); +XTRN char *ProgramName INIT("crond"); +XTRN char *FixedName INIT("crond"); XTRN int LineNumber INIT(0); XTRN time_t StartTime INIT(0); XTRN int NoFork INIT(0); diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/macros.h vixie-cron-4.1.20060426/usr.sbin/cron/macros.h --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/macros.h 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/macros.h 2006-04-30 22:16:46 +0000 @@ -46,6 +46,9 @@ #define MAX_COMMAND 1000 /* max length of internally generated cmd */ #define MAX_ENVSTR 1000 /* max length of envvar=value\0 strings */ #define MAX_TEMPSTR 100 /* obvious */ +#ifndef _PW_NAME_LEN +#define _PW_NAME_LEN 256 +#endif #define MAX_UNAME (_PW_NAME_LEN+1) /* 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 */ diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/misc.c vixie-cron-4.1.20060426/usr.sbin/cron/misc.c --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/misc.c 2005-06-08 18:34:00 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/misc.c 2006-04-30 22:37:44 +0000 @@ -173,13 +173,15 @@ set_cron_uid(void) { void set_cron_cwd(void) { struct stat sb; - struct group *grp = NULL; +#ifdef ENABLE_FIX_DIRECTORIES #ifdef CRON_GROUP - grp = getgrnam(CRON_GROUP); + struct group *grp = getgrnam(CRON_GROUP); +#endif #endif /* first check for CRONDIR ("/var/cron" or some such) */ +#ifdef ENABLE_FIX_DIRECTORIES if (stat(CRONDIR, &sb) < OK && errno == ENOENT) { perror(CRONDIR); if (OK == mkdir(CRONDIR, 0710)) { @@ -196,6 +198,7 @@ set_cron_cwd(void) { CRONDIR); exit(ERROR_EXIT); } +#endif /* ENABLE_FIX_DIRECTORIES */ if (chdir(CRONDIR) < OK) { fprintf(stderr, "cannot chdir(%s), bailing out.\n", CRONDIR); perror(CRONDIR); @@ -204,6 +207,7 @@ set_cron_cwd(void) { /* CRONDIR okay (now==CWD), now look at SPOOL_DIR ("tabs" or some such) */ +#ifdef ENABLE_FIX_DIRECTORIES if (stat(SPOOL_DIR, &sb) < OK && errno == ENOENT) { perror(SPOOL_DIR); if (OK == mkdir(SPOOL_DIR, 0700)) { @@ -215,20 +219,29 @@ set_cron_cwd(void) { exit(ERROR_EXIT); } } +#else + if (stat(SPOOL_DIR, &sb)) { + perror(SPOOL_DIR); + exit(ERROR_EXIT); + } +#endif /* ENABLE_FIX_DIRECTORIES */ if (!S_ISDIR(sb.st_mode)) { fprintf(stderr, "'%s' is not a directory, bailing out.\n", SPOOL_DIR); exit(ERROR_EXIT); } +#ifdef ENABLE_FIX_DIRECTORIES if (grp != NULL) { if (sb.st_gid != grp->gr_gid) chown(SPOOL_DIR, -1, grp->gr_gid); if (sb.st_mode != 01730) chmod(SPOOL_DIR, 01730); } +#endif /* ENABLE_FIX_DIRECTORIES */ /* finally, look at AT_DIR ("atjobs" or some such) */ +#ifdef ENABLE_FIX_DIRECTORIES if (stat(AT_DIR, &sb) < OK && errno == ENOENT) { perror(AT_DIR); if (OK == mkdir(AT_DIR, 0700)) { @@ -240,17 +253,25 @@ set_cron_cwd(void) { exit(ERROR_EXIT); } } +#else + if (stat(AT_DIR, &sb)) { + perror(AT_DIR); + exit(ERROR_EXIT); + } +#endif /* ENABLE_FIX_DIRECTORIES */ if (!S_ISDIR(sb.st_mode)) { fprintf(stderr, "'%s' is not a directory, bailing out.\n", AT_DIR); exit(ERROR_EXIT); } +#ifdef ENABLE_FIX_DIRECTORIES if (grp != NULL) { if (sb.st_gid != grp->gr_gid) chown(AT_DIR, -1, grp->gr_gid); if (sb.st_mode != 01770) chmod(AT_DIR, 01770); } +#endif /* ENABLE_FIX_DIRECTORIES */ } /* acquire_daemonlock() - write our PID into /etc/cron.pid, unless @@ -280,23 +301,31 @@ acquire_daemonlock(int closeflag) { if (fd == -1) { pidfile = _PATH_CRON_PID; - if ((fd = open(pidfile, O_RDWR|O_CREAT|O_EXLOCK|O_NONBLOCK, - 0644)) == -1) { - int save_errno = errno; - - if (errno != EWOULDBLOCK) { + /* Initial mode is 0600 to prevent flock() race/DoS. */ + if ((fd = open(pidfile, O_RDWR|O_CREAT, 0600)) == -1) { + snprintf(buf, sizeof buf, "can't open or create %s: %s", + pidfile, strerror(errno)); + fprintf(stderr, "%s: %s\n", ProgramName, buf); + log_it("CRON", getpid(), "DEATH", buf); + exit(ERROR_EXIT); + } + /* fd must be > STDERR since we dup fd 0-2 to /dev/null */ + if (fd <= STDERR) { + if (dup2(fd, STDERR + 1) < 0) { snprintf(buf, sizeof buf, - "can't open or create %s: %s", pidfile, - strerror(save_errno)); + "can't dup pid fd: %s", strerror(errno)); fprintf(stderr, "%s: %s\n", ProgramName, buf); log_it("CRON", getpid(), "DEATH", buf); exit(ERROR_EXIT); } + close(fd); + fd = STDERR + 1; + } + if (flock(fd, LOCK_EX|LOCK_NB) < OK) { + int save_errno = errno; - /* couldn't lock the pid file, try to read existing. */ bzero(buf, sizeof(buf)); - if ((fd = open(pidfile, O_RDONLY, 0)) >= 0 && - (num = read(fd, buf, sizeof(buf) - 1)) > 0 && + if ((num = read(fd, buf, sizeof(buf) - 1)) > 0 && (otherpid = strtol(buf, &ep, 10)) > 0 && ep != buf && *ep == '\n' && otherpid != LONG_MAX) { snprintf(buf, sizeof buf, @@ -311,18 +340,7 @@ acquire_daemonlock(int closeflag) { log_it("CRON", getpid(), "DEATH", buf); exit(ERROR_EXIT); } - /* fd must be > STDERR since we dup fd 0-2 to /dev/null */ - if (fd <= STDERR) { - if (dup2(fd, STDERR + 1) < 0) { - snprintf(buf, sizeof buf, - "can't dup pid fd: %s", strerror(errno)); - fprintf(stderr, "%s: %s\n", ProgramName, buf); - log_it("CRON", getpid(), "DEATH", buf); - exit(ERROR_EXIT); - } - close(fd); - fd = STDERR + 1; - } + (void) fchmod(fd, 0644); (void) fcntl(fd, F_SETFD, 1); } @@ -519,11 +537,7 @@ log_it(const char *username, PID_T xpid, #if defined(SYSLOG) if (!syslog_open) { -# ifdef LOG_DAEMON - openlog(ProgramName, LOG_PID, FACILITY); -# else - openlog(ProgramName, LOG_PID); -# endif + openlog(FixedName, LOG_PID, LOG_CRON); syslog_open = TRUE; /* assume openlog success */ } @@ -724,6 +738,10 @@ open_socket(void) int sock; mode_t omask; struct sockaddr_un s_un; +#ifdef CRON_GROUP + struct group *grp = NULL; +#endif + int rc, saved_errno; sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock == -1) { @@ -755,26 +773,32 @@ open_socket(void) } unlink(s_un.sun_path); s_un.sun_family = AF_UNIX; -#ifdef SUN_LEN +#ifdef HAVE_SUN_LEN_MEMBER s_un.sun_len = SUN_LEN(&s_un); #endif - - omask = umask(007); - if (bind(sock, (struct sockaddr *)&s_un, sizeof(s_un))) { + omask = umask(0157); + rc = bind(sock, (struct sockaddr *)&s_un, SUN_LEN(&s_un)); + saved_errno = errno; + umask(omask); + if (rc) { + errno = saved_errno; fprintf(stderr, "%s: can't bind socket: %s\n", ProgramName, strerror(errno)); log_it("CRON", getpid(), "DEATH", "can't bind socket"); - umask(omask); exit(ERROR_EXIT); } - umask(omask); if (listen(sock, SOMAXCONN)) { fprintf(stderr, "%s: can't listen on socket: %s\n", ProgramName, strerror(errno)); log_it("CRON", getpid(), "DEATH", "can't listen on socket"); exit(ERROR_EXIT); } - chmod(s_un.sun_path, 0660); +#ifdef CRON_GROUP + if ((grp = getgrnam(CRON_GROUP)) == NULL) { + log_it("CRON", getpid(), "DEATH", "can't find crontab group"); + exit(ERROR_EXIT); + } +#endif return(sock); } @@ -794,12 +818,12 @@ poke_daemon(const char *spool_dir, unsig return; } s_un.sun_family = AF_UNIX; -#ifdef SUN_LEN +#ifdef HAVE_SUN_LEN_MEMBER s_un.sun_len = SUN_LEN(&s_un); #endif (void) signal(SIGPIPE, SIG_IGN); if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0 && - connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == 0) + connect(sock, (struct sockaddr *)&s_un, SUN_LEN(&s_un)) == 0) write(sock, &cookie, 1); else fprintf(stderr, "%s: warning, cron does not appear to be " diff -upk.orig vixie-cron-4.1.20060426.orig/usr.sbin/cron/pathnames.h vixie-cron-4.1.20060426/usr.sbin/cron/pathnames.h --- vixie-cron-4.1.20060426.orig/usr.sbin/cron/pathnames.h 2004-06-17 22:11:55 +0000 +++ vixie-cron-4.1.20060426/usr.sbin/cron/pathnames.h 2006-04-30 22:16:46 +0000 @@ -33,7 +33,7 @@ * to; SPOOL_DIR, CRON_ALLOW, CRON_DENY, and LOG_FILE * are all relative to this directory. */ -#define CRONDIR "/var/cron" +#define CRONDIR "/var/spool" #endif /* SPOOLDIR is where the crontabs live. @@ -44,7 +44,7 @@ * newer than they were last time around (or which * didn't exist last time around...) */ -#define SPOOL_DIR "tabs" +#define SPOOL_DIR "cron" /* ATDIR is where the at jobs live (relative to CRONDIR) * This directory will have its modtime updated @@ -52,7 +52,7 @@ * the signal for cron(8) to look for changes in the * jobs directory (new, changed or jobs). */ -#define AT_DIR "atjobs" +#define AT_DIR "at" /* CRONSOCK is the name of the socket used by at and * crontab to poke cron to re-read the at and cron @@ -64,14 +64,14 @@ /* cron allow/deny file. At least cron.deny must * exist for ordinary users to run crontab. */ -#define CRON_ALLOW "cron.allow" -#define CRON_DENY "cron.deny" +#define CRON_ALLOW "/etc/cron.allow" +#define CRON_DENY "/etc/cron.deny" /* at allow/deny file. At least at.deny must * exist for ordinary users to run at. */ -#define AT_ALLOW "at.allow" -#define AT_DENY "at.deny" +#define AT_ALLOW "/etc/at.allow" +#define AT_DENY "/etc/at.deny" /* undefining this turns off logging to a file. If * neither LOG_FILE or SYSLOG is defined, we don't log. @@ -79,7 +79,7 @@ * LOG_CRON is defined by , LOG_FILE will not * be used. */ -#define LOG_FILE "log" +/*#define LOG_FILE "log"*/ /* where should the daemon stick its PID? * PIDDIR must end in '/'. @@ -87,9 +87,9 @@ #ifdef _PATH_VARRUN # define PIDDIR _PATH_VARRUN #else -# define PIDDIR "/etc/" +# define PIDDIR "/var/run/" #endif -#define PIDFILE "cron.pid" +#define PIDFILE "crond.pid" #define _PATH_CRON_PID PIDDIR PIDFILE /* 4.3BSD-style crontab */