1 --- cron-3.0pl1.orig/Makefile
2 +++ cron-3.0pl1/Makefile
9 #<<optimize or debug?>>
14 #<<ATT or BSD or POSIX?>>
17 #(BSD is only needed if <sys/params.h> does not define it, as on ULTRIX)
22 #<<lint flags of choice?>>
23 LINTFLAGS = -hbxa $(INCLUDE) $(COMPAT) $(DEBUGGING)
24 #<<want to use a nonstandard CC?>>
28 +# Allow override from command line
29 +DEBUG_DEFS = -DDEBUGGING=0
30 +# The -DUSE_SIGCHLD is needed for the Alpha port
31 +DEFS = -DDEBIAN -DUSE_SIGCHLD $(DEBUG_DEFS) $(PAM_DEFS)
32 #(SGI IRIX systems need this)
33 #DEFS = -D_BSD_SIGNALS -Dconst=
34 #<<the name of the BSD-like install program>>
37 #<<any special load flags>>
40 +# Let install do the strip
42 #################################### end configurable stuff
46 $(CC) $(LDFLAGS) -o crontab $(CRONTAB_OBJ) $(LIBS)
49 - $(INSTALL) -c -m 111 -o root -s cron $(DESTSBIN)/
50 - $(INSTALL) -c -m 4111 -o root -s crontab $(DESTBIN)/
51 + $(INSTALL) -c -m 755 -o root -s cron $(DESTSBIN)/
52 + $(INSTALL) -c -m 4755 -o root -s crontab $(DESTBIN)/
53 sh putman.sh crontab.1 $(DESTMAN)
54 sh putman.sh cron.8 $(DESTMAN)
55 sh putman.sh crontab.5 $(DESTMAN)
57 -clean :; rm -f *.o cron crontab a.out core tags *~ #*
59 + rm -f *.o cron crontab a.out core tags *~ #*
62 makekit -m -s99k $(SHAR_SOURCE)
63 --- cron-3.0pl1.orig/README
64 +++ cron-3.0pl1/README
66 [V1.0 was May 6, 1987]
69 +[Note from Debian cron maintainer: This is the original README from
70 +the the vixie-cron package. The location of many cron files has been
71 +changed in order to comply with Debian policy and common sense -- look
72 +in the cron(8), crontab(1) and crontab(5) man pages for more info, as
73 +well as the README.Debian file in this directory.]
75 This is a version of 'cron' that is known to run on BSD 4.[23] systems. It
76 is functionally based on the SysV cron, which means that each user can have
77 their own crontab file (all crontab files are stored in a read-protected
78 --- cron-3.0pl1.orig/compat.c
79 +++ cron-3.0pl1/compat.c
84 - temp = malloc(strlen(str) + 1);
85 + if ((temp = malloc(strlen(str) + 1)) == NULL) {
89 (void) strcpy(temp, str);
93 return sys_errlist[error];
96 - sprintf(buf, "Unknown error: %d", error);
97 + snprintf(buf, 32, "Unknown error: %d", error);
101 @@ -218,16 +221,18 @@
107 if (overwrite && getenv(name))
110 - if (!(tmp = malloc(strlen(name) + strlen(value) + 2))) {
111 + tmp_size = strlen(name) + strlen(value) + 2;
112 + if (!(tmp = malloc(tmp_size))) {
117 - sprintf("%s=%s", name, value);
118 + snprintf(tmp, tmp_size, "%s=%s", name, value);
119 return putenv(tmp); /* intentionally orphan 'tmp' storage */
122 --- cron-3.0pl1.orig/compat.h
123 +++ cron-3.0pl1/compat.h
128 -# if (BSD >= 199103) || defined(__linux) || defined(ultrix) || defined(AIX) ||\
129 - defined(HPUX) || defined(CONVEX) || defined(IRIX)
130 +# if (BSD >= 199103) || defined(__linux__) || defined(__GNU__) || defined(ultrix) ||\
131 + defined(AIX) ||\ defined(HPUX) || defined(CONVEX) || defined(IRIX)
137 /*****************************************************************/
139 -#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux)
140 +#if !defined(BSD) && !defined(HPUX) && !defined(CONVEX) && !defined(__linux__) && !defined(__GNU__)
144 -#if (!defined(BSD) || (BSD < 198902)) && !defined(__linux) && \
145 - !defined(IRIX) && !defined(NeXT) && !defined(HPUX)
146 +#if (!defined(BSD) || (BSD < 198902)) && !defined(__linux__) && \
147 + !defined(IRIX) && !defined(NeXT) && !defined(HPUX) && !defined(__GNU__)
148 # define NEED_STRCASECMP
151 -#if (!defined(BSD) || (BSD < 198911)) && !defined(__linux) &&\
152 - !defined(IRIX) && !defined(UNICOS) && !defined(HPUX)
153 +#if (!defined(BSD) || (BSD < 198911)) && !defined(__linux__) &&\
154 + !defined(IRIX) && !defined(UNICOS) && !defined(HPUX) && !defined(__GNU__)
162 -#if (defined(POSIX) && !defined(BSD)) && !defined(__linux)
163 +#if (defined(POSIX) && !defined(BSD)) && !defined(__linux__) && !defined(__GNU__)
164 # define NEED_GETDTABLESIZE
167 @@ -110,11 +110,11 @@
168 # define HAVE_SAVED_UIDS
171 -#if !defined(ATT) && !defined(__linux) && !defined(IRIX) && !defined(UNICOS)
172 +#if !defined(ATT) && !defined(__linux__) && !defined(__GNU__) && !defined(IRIX) && !defined(UNICOS)
176 -#if !defined(AIX) && !defined(UNICOS)
177 +#if !defined(AIX) && !defined(UNICOS) && !defined(DEBIAN)
178 # define SYS_TIME_H 1
180 # define SYS_TIME_H 0
181 --- cron-3.0pl1.orig/config.h
182 +++ cron-3.0pl1/config.h
187 +#error DEBUGGING not defined
188 #define DEBUGGING 1 /* 1 or 0 -- do you want debugging code built in? */
194 #define MAILCMD _PATH_SENDMAIL /*-*/
195 -#define MAILARGS "%s -FCronDaemon -odi -oem -or0s %s" /*-*/
196 - /* -Fx = set full-name of sender
197 +#define MAILARGS "%s -i -FCronDaemon -odi -oem %s" /*-*/
198 + /* -i = don't terminate on "." by itself
199 + * -Fx = set full-name of sender
200 * -odi = Option Deliverymode Interactive
201 * -oem = Option Errors Mailedtosender
202 + * -t = read recipient from header of message
203 * -or0s = Option Readtimeout -- don't time out
204 + * XXX: sendmail doesn't allow -or0s when invoked
205 + * by joe user. --okir
208 -/* #define MAILCMD "/bin/mail" /*-*/
209 -/* #define MAILARGS "%s -d %s" /*-*/
210 +/* #define MAILCMD "/bin/mail" -*/
211 +/* #define MAILARGS "%s -d %s" -*/
212 /* -d = undocumented but common flag: deliver locally?
215 -/* #define MAILCMD "/usr/mmdf/bin/submit" /*-*/
216 -/* #define MAILARGS "%s -mlrxto %s" /*-*/
217 +/* #define MAILCMD "/usr/mmdf/bin/submit" -*/
218 +/* #define MAILARGS "%s -mlrxto %s" -*/
220 -/* #define MAIL_DATE /*-*/
221 +/* #define MAIL_DATE -*/
222 /* should we include an ersatz Date: header in
223 * generated mail? if you are using sendmail
224 * for MAILCMD, it is better to let sendmail
226 * defined but neither exists, should crontab(1) be
227 * usable only by root?
229 -/*#define ALLOW_ONLY_ROOT /*-*/
230 +/*#define ALLOW_ONLY_ROOT -*/
232 /* if you want to use syslog(3) instead of appending
233 * to CRONDIR/LOG_FILE (/var/cron/log, e.g.), define
234 --- cron-3.0pl1.orig/cron.8
235 +++ cron-3.0pl1/cron.8
241 -should be started from /etc/rc or /etc/rc.local. It will return immediately,
242 -so you don't need to start it with '&'.
244 +is started automatically from /etc/init.d on entering multi-user
248 -searches /var/cron/tabs for crontab files which are named after accounts in
249 -/etc/passwd; crontabs found are loaded into memory.
251 -also searches for /etc/crontab which is in a different format (see
254 -then wakes up every minute, examining all stored crontabs, checking each
255 -command to see if it should be run in the current minute. When executing
256 -commands, any output is mailed to the owner of the crontab (or to the user
257 -named in the MAILTO environment variable in the crontab, if such exists).
259 +searches its spool area (/var/spool/cron/crontabs) for crontab
260 +files (which are named after accounts in
261 +/etc/passwd); crontabs found are loaded into memory. Note that
262 +crontabs in this directory should not be accessed directly -
265 +command should be used to access and update them.
268 +also reads /etc/crontab, which is in a slightly different format (see
270 +Additionally, cron reads the files in /etc/cron.d; see
273 +section below for more details.
276 +then wakes up every minute, examining all stored crontabs, checking
277 +each command to see if it should be run in the current minute. When
278 +executing commands, any output is mailed to the owner of the crontab
279 +(or to the user named in the MAILTO environment variable in the
280 +crontab, if such exists). The children copies of cron running these
281 +processes has its name coerced to uppercase, as will be seen in the
282 +syslog and ps output.
289 need not be restarted whenever a crontab file is modified. Note that the
292 command updates the modtime of the spool directory whenever it changes a
295 +Special considerations exist when the clock is changed by less than 3
296 +hours, for example at the beginning and end of daylight savings
297 +time. If the time has moved forwards, those jobs which would have
298 +run in the time that was skipped will be run soon after the change.
299 +Conversely, if the time has moved backwards by less than 3 hours,
300 +those jobs that fall into the repeated time will not be re-run.
302 +Only jobs that run at a particular time (not specified as
303 +@hourly, nor with '*' in the hour or minute specifier) are
304 +affected. Jobs which are specified with wildcards are run based on the
305 +new time immediately.
307 +Clock changes of more than 3 hours are considered to be corrections to
308 +the clock, and the new time is used immediately.
311 +treats the files in /etc/cron.d as extensions to the /etc/crontab file (they
312 +follow the special format of that file, i.e. they include the
314 +field). The intended purpose of this feature is to allow packages that require
315 +finer control of their scheduling than the /etc/cron.{daily,weekly,monthly}
316 +directories allow to add a crontab file to /etc/cron.d. Such files
317 +should be named after the package that supplies them. Files must
318 +conform to the same naming convention as used by run-parts(8): they
319 +must consist solely of upper- and lower-case letters, digits, underscores,
320 +and hyphens. Like /etc/crontab, the files in the /etc/cron.d directory are
321 +monitored for changes.
323 crontab(1), crontab(5)
325 --- cron-3.0pl1.orig/cron.c
326 +++ cron-3.0pl1/cron.c
331 -#include <sys/signal.h>
334 # include <sys/time.h>
338 static void usage __P((void)),
339 run_reboot_jobs __P((cron_db *)),
340 - cron_tick __P((cron_db *)),
341 - cron_sync __P((void)),
342 - cron_sleep __P((void)),
343 + find_jobs __P((time_min, cron_db *, int, int)),
344 + set_time __P((void)),
345 + cron_sleep __P((time_min)),
347 sigchld_handler __P((int)),
353 - fprintf(stderr, "usage: %s [-x debugflag[,...]]\n", ProgramName);
357 + fprintf(stderr, "usage: %s [-x [", ProgramName);
358 + for(dflags = DebugFlagNames; *dflags; dflags++)
359 + fprintf(stderr, "%s%s", *dflags, dflags[1] ? "," : "]");
360 + fprintf(stderr, "]\n");
362 + fprintf(stderr, "usage: %s\n", ProgramName);
369 log_it("CRON",getpid(),"STARTUP","fork ok");
371 + freopen("/dev/null", "r", stdin);
372 + freopen("/dev/null", "w", stdout);
373 + freopen("/dev/null", "w", stderr);
376 /* parent process should just die */
377 @@ -110,28 +122,136 @@
378 acquire_daemonlock(0);
379 database.head = NULL;
380 database.tail = NULL;
381 - database.mtime = (time_t) 0;
382 + database.sys_mtime = (time_t) 0;
383 + database.user_mtime = (time_t) 0;
385 + database.sysd_mtime = (time_t) 0;
387 load_database(&database);
390 run_reboot_jobs(&database);
392 + timeRunning = virtualTime = clockTime;
395 + * too many clocks, not enough time (Al. Einstein)
396 + * These clocks are in minutes since the epoch (time()/60).
397 + * virtualTime: is the time it *would* be if we woke up
398 + * promptly and nobody ever changed the clock. It is
399 + * monotonically increasing... unless a timejump happens.
400 + * At the top of the loop, all jobs for 'virtualTime' have run.
401 + * timeRunning: is the time we last awakened.
402 + * clockTime: is the time when set_time was last called.
406 - if (!(DebugFlags & DTEST))
407 -# endif /*DEBUGGING*/
412 load_database(&database);
414 - /* do this iteration
415 + /* ... wait for the time (in minutes) to change ... */
417 + cron_sleep(timeRunning + 1);
419 + } while (clockTime == timeRunning);
420 + timeRunning = clockTime;
423 + * ... calculate how the current time differs from
424 + * our virtual clock. Classify the change into one
427 - cron_tick(&database);
428 + timeDiff = timeRunning - virtualTime;
433 + /* shortcut for the most common case */
434 + if (timeDiff == 1) {
435 + virtualTime = timeRunning;
436 + find_jobs(virtualTime, &database, TRUE, TRUE);
439 + if (timeDiff > -(3*MINUTE_COUNT))
445 + if (timeDiff > (3*MINUTE_COUNT))
448 + switch (wakeupKind) {
451 + * case 1: timeDiff is a small positive number
452 + * (wokeup late) run jobs for each virtual minute
455 + Debug(DSCH, ("[%d], normal case %d minutes to go\n",
456 + getpid(), timeRunning - virtualTime))
458 + if (job_runqueue())
461 + find_jobs(virtualTime, &database, TRUE, TRUE);
462 + } while (virtualTime< timeRunning);
467 + * case 2: timeDiff is a medium-sized positive number,
468 + * for example because we went to DST run wildcard
469 + * jobs once, then run any fixed-time jobs that would
470 + * otherwise be skipped if we use up our minute
471 + * (possible, if there are a lot of jobs to run) go
472 + * around the loop again so that wildcard jobs have
473 + * a chance to run, and we do our housekeeping
475 + Debug(DSCH, ("[%d], DST begins %d minutes to go\n",
476 + getpid(), timeRunning - virtualTime))
477 + /* run wildcard jobs for current minute */
478 + find_jobs(timeRunning, &database, TRUE, FALSE);
480 + /* run fixed-time jobs for each minute missed */
482 + if (job_runqueue())
485 + find_jobs(virtualTime, &database, FALSE, TRUE);
487 + } while (virtualTime< timeRunning &&
488 + clockTime == timeRunning);
493 + * case 3: timeDiff is a small or medium-sized
494 + * negative num, eg. because of DST ending just run
495 + * the wildcard jobs. The fixed-time jobs probably
496 + * have already run, and should not be repeated
497 + * virtual time does not change until we are caught up
499 + Debug(DSCH, ("[%d], DST ends %d minutes to go\n",
500 + getpid(), virtualTime - timeRunning))
501 + find_jobs(timeRunning, &database, TRUE, FALSE);
505 + * other: time has changed a *lot*,
506 + * jump virtual time, and run everything
508 + Debug(DSCH, ("[%d], clock jumped\n", getpid()))
509 + virtualTime = timeRunning;
510 + find_jobs(timeRunning, &database, TRUE, TRUE);
513 + /* jobs to be run (if any) are loaded. clear the queue */
519 +#include <sys/stat.h>
531 +#define REBOOT_FILE "/var/run/crond.reboot"
532 + /* Run on actual reboot, rather than cron restart */
533 + if (access(REBOOT_FILE, F_OK) == 0) {
534 + /* File exists, return */
535 + log_it("CRON", getpid(),"INFO",
536 + "Skipping @reboot jobs -- not system startup");
539 + /* Create the file */
540 + if ((rbfd = creat(REBOOT_FILE, S_IRUSR&S_IWUSR)) < 0) {
541 + /* Bad news, bail out */
542 + log_it("CRON",getpid(),"DEATH","Can't create reboot check file");
546 + log_it("CRON", getpid(),"INFO", "Running @reboot jobs");
550 + Debug(DMISC, ("[%d], Debian running reboot jobs\n",getpid()));
553 + Debug(DMISC, ("[%d], vixie running reboot jobs\n", getpid()));
554 for (u = db->head; u != NULL; u = u->next) {
555 for (e = u->crontab; e != NULL; e = e->next) {
556 if (e->flags & WHEN_REBOOT) {
557 @@ -152,10 +296,14 @@
562 +find_jobs(vtime, db, doWild, doNonWild)
568 - register struct tm *tm = localtime(&TargetTime);
569 + time_t virtualSecond = vtime * SECONDS_PER_MINUTE;
570 + register struct tm *tm = localtime(&virtualSecond);
571 register int minute, hour, dom, month, dow;
575 month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
576 dow = tm->tm_wday -FIRST_DOW;
578 - Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n",
579 - getpid(), minute, hour, dom, month, dow))
580 + Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d) %s %s\n",
581 + getpid(), minute, hour, dom, month, dow,
582 + doWild?" ":"No wildcard",doNonWild?" ":"Wildcard only"))
584 /* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
585 * first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
586 @@ -180,73 +329,57 @@
587 for (u = db->head; u != NULL; u = u->next) {
588 for (e = u->crontab; e != NULL; e = e->next) {
589 Debug(DSCH|DEXT, ("user [%s:%d:%d:...] cmd=\"%s\"\n",
590 - env_get("LOGNAME", e->envp),
591 - e->uid, e->gid, e->cmd))
592 - if (bit_test(e->minute, minute)
593 - && bit_test(e->hour, hour)
594 - && bit_test(e->month, month)
595 - && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
596 + env_get("LOGNAME", e->envp),
597 + e->uid, e->gid, e->cmd))
598 + if (bit_test(e->minute, minute) &&
599 + bit_test(e->hour, hour) &&
600 + bit_test(e->month, month) &&
601 + ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
602 ? (bit_test(e->dow,dow) && bit_test(e->dom,dom))
603 - : (bit_test(e->dow,dow) || bit_test(e->dom,dom))
607 + : (bit_test(e->dow,dow) || bit_test(e->dom,dom)))) {
608 + if ((doNonWild && !(e->flags & (MIN_STAR|HR_STAR)))
609 + || (doWild && (e->flags & (MIN_STAR|HR_STAR))))
617 -/* the task here is to figure out how long it's going to be until :00 of the
618 - * following minute and initialize TargetTime to this value. TargetTime
619 - * will subsequently slide 60 seconds at a time, with correction applied
620 - * implicitly in cron_sleep(). it would be nice to let cron execute in
621 - * the "current minute" before going to sleep, but by restarting cron you
622 - * could then get it to execute a given minute's jobs more than once.
623 - * instead we have the chance of missing a minute's jobs completely, but
624 - * that's something sysadmin's know to expect what with crashing computers..
626 + * set StartTime and clockTime to the current time.
627 + * these are used for computing what time it really is right now.
628 + * note that clockTime is a unix wallclock time converted to minutes
632 - register struct tm *tm;
634 - TargetTime = time((time_t*)0);
635 - tm = localtime(&TargetTime);
636 - TargetTime += (60 - tm->tm_sec);
639 + StartTime = time((time_t *)0);
640 + clockTime = StartTime / (unsigned long)SECONDS_PER_MINUTE;
645 + * try to just hit the next minute
652 register int seconds_to_wait;
655 - seconds_to_wait = (int) (TargetTime - time((time_t*)0));
656 - Debug(DSCH, ("[%d] TargetTime=%ld, sec-to-wait=%d\n",
657 - getpid(), TargetTime, seconds_to_wait))
659 - /* if we intend to sleep, this means that it's finally
660 - * time to empty the job queue (execute it).
662 - * if we run any jobs, we'll probably screw up our timing,
665 - * note that we depend here on the left-to-right nature
666 - * of &&, and the short-circuiting.
668 - } while (seconds_to_wait > 0 && job_runqueue());
669 + seconds_to_wait = (int)(target*SECONDS_PER_MINUTE - time((time_t*)0)) + 1;
670 + Debug(DSCH, ("[%d] TargetTime=%ld, sec-to-wait=%d\n",
671 + getpid(), (long)target*SECONDS_PER_MINUTE, seconds_to_wait))
673 - while (seconds_to_wait > 0) {
674 - Debug(DSCH, ("[%d] sleeping for %d seconds\n",
675 - getpid(), seconds_to_wait))
676 - seconds_to_wait = (int) sleep((unsigned int) seconds_to_wait);
678 + if (seconds_to_wait > 0 && seconds_to_wait< 65)
679 + sleep((unsigned int) seconds_to_wait);
686 + int save_errno = errno;
690 @@ -260,10 +393,12 @@
693 ("[%d] sigchld...no children\n", getpid()))
694 + errno = save_errno;
698 ("[%d] sigchld...no dead kids\n", getpid()))
699 + errno = save_errno;
704 getpid(), pid, WEXITSTATUS(waiter)))
707 + errno = save_errno;
709 #endif /*USE_SIGCHLD*/
716 + /* we should use sigaction for proper signal blocking as this
717 + has a race, but... */
718 + signal(SIGHUP, sighup_handler);
722 --- cron-3.0pl1.orig/cron.h
723 +++ cron-3.0pl1/cron.h
725 #define OK_EXIT 0 /* exit() with this is considered 'normal' */
726 #define MAX_FNAME 100 /* max length of internally generated fn */
727 #define MAX_COMMAND 1000 /* max length of internally generated cmd */
728 -#define MAX_ENVSTR 1000 /* max length of envvar=value\0 strings */
729 -#define MAX_TEMPSTR 100 /* obvious */
730 +#define MAX_TEMPSTR 1000 /* max length of envvar=value\0 strings */
731 +#define MAX_ENVSTR MAX_TEMPSTR /* DO NOT change - buffer overruns otherwise */
732 #define MAX_UNAME 20 /* max length of username, should be overkill */
733 #define ROOT_UID 0 /* don't change this, it really must be root */
734 #define ROOT_USER "root" /* ditto */
739 +typedef int time_min;
741 +#define SECONDS_PER_MINUTE 60
743 #define FIRST_MINUTE 0
744 #define LAST_MINUTE 59
745 #define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1)
747 #define DOM_STAR 0x01
748 #define DOW_STAR 0x02
749 #define WHEN_REBOOT 0x04
750 +#define MIN_STAR 0x08
751 +#define HR_STAR 0x10
754 /* the crontab database will be a list of the
757 typedef struct _cron_db {
758 user *head, *tail; /* links */
759 - time_t mtime; /* last modtime on spooldir */
760 + time_t user_mtime; /* last modtime on spooldir */
761 + time_t sys_mtime; /* last modtime on system crontab */
763 + time_t sysd_mtime; /* last modtime on system crondir */
769 get_char __P((FILE *)),
770 get_string __P((char *, int, FILE *, char *)),
771 swap_uids __P((void)),
772 + swap_uids_back __P((void)),
773 load_env __P((char *, FILE *)),
774 cron_pclose __P((FILE *)),
775 strcmp_until __P((char *, char *, int)),
777 entry *load_entry __P((FILE *, void (*)(),
778 struct passwd *, char **));
780 -FILE *cron_popen __P((char *, char *));
781 +FILE *cron_popen __P((char *, char *, entry *));
784 /* in the C tradition, we only create
791 +time_min timeRunning;
792 +time_min virtualTime;
800 extern int LineNumber;
801 -extern time_t TargetTime;
802 +extern time_t StartTime;
803 +extern time_min timeRunning;
804 +extern time_min virtualTime;
805 +extern time_min clockTime;
807 extern int DebugFlags;
808 extern char *DebugFlagNames[];
809 --- cron-3.0pl1.orig/crontab.1
810 +++ cron-3.0pl1/crontab.1
813 crontab [ -u user ] { -l | -r | -e }
817 is the program used to install, deinstall or list the tables
820 daemon in Vixie Cron. Each user can have their own crontab, and though
821 -these are files in /var, they are not intended to be edited directly.
822 +these are files in /var/spool/cron/crontabs,
823 +they are not intended to be edited directly.
828 file exists, then you must be listed therein in order to be allowed to use
832 file does not exist but the
835 file does exist, then you must \fBnot\fR be listed in the
838 file in order to use this command. If neither of these files exists, then
839 depending on site-dependent configuration parameters, only the super user
840 will be allowed to use this command, or all users will be able to use this
842 +command. For standard Debian systems, all users may use this command.
849 and that if you are running inside of
852 you should always use the
854 option for safety's sake.
859 -option causes the current crontab to be displayed on standard output.
860 +option causes the current crontab to be displayed on standard output. See
870 option is used to edit the current crontab using the editor specified by
871 -the \s-1VISUAL\s+1 or \s-1EDITOR\s+1 environment variables. After you exit
872 +the \s-1VISUAL\s+1 or \s-1EDITOR\s+1 environment variables.
873 +The specified editor
875 +edit the file in place;
876 +any editor that unlinks the file and recreates it cannot be used.
878 from the editor, the modified crontab will be installed automatically.
880 +The "out-of-the-box" behaviour for
882 +is to display the three line "DO NOT EDIT THIS FILE" header
883 +that is placed at the
884 +beginning of the crontab when it is installed. The problem is that
885 +it makes the sequence
887 +crontab -l | crontab -
889 +non-idempotent -- you keep adding copies of the header. This causes
890 +pain to scripts that use sed to edit a crontab. Therefore, the default
893 +option has been changed to not output such header. You may obtain the
894 +original behaviour by setting the environment variable
896 +to 'N', which will cause the
898 +command to emit the extraneous header.
911 command conforms to IEEE Std1003.2-1992 (``POSIX''). This new command syntax
912 differs from previous versions of Vixie Cron, as well as from the classic
916 A fairly informative usage message appears if you run it with a bad command
920 +Although cron requires that each entry in a crontab end in a newline
921 +character, the neither the crontab command nor the cron daemon will
922 +detect this error. Instead, the crontab will appear load
923 +normally. However, the command will never run. The best choice is to
924 +ensure that your crontab has a blank line at the end.
928 Paul Vixie <paul@vix.com>
929 --- cron-3.0pl1.orig/crontab.5
930 +++ cron-3.0pl1/crontab.5
932 as part of a cron command.
934 Blank lines and leading spaces and tabs are ignored. Lines whose first
935 -non-space character is a pound-sign (#) are comments, and are ignored.
936 +non-space character is a hash-sign (#) are comments, and are ignored.
937 Note that comments are not allowed on the same line as cron commands, since
938 they will be taken to be part of the command. Similarly, comments are not
939 allowed on the same line as environment variable settings.
943 SHELL is set to /bin/sh, and LOGNAME and HOME are set from the /etc/passwd
944 -line of the crontab's owner.
945 -HOME and SHELL may be overridden by settings in the crontab; LOGNAME may not.
946 +line of the crontab's owner. PATH is set to "/usr/bin:/bin".
947 +HOME, SHELL, and PATH may be overridden by settings in the crontab;
950 (Another note: the LOGNAME variable is sometimes called USER on BSD systems...
951 on these systems, USER will be set also.)
953 will look at MAILTO if it has any reason to send mail as a result of running
954 commands in ``this'' crontab. If MAILTO is defined (and non-empty), mail is
955 sent to the user so named. If MAILTO is defined but empty (MAILTO=""), no
956 -mail will be sent. Otherwise mail is sent to the owner of the crontab. This
957 -option is useful if you decide on /bin/mail instead of /usr/lib/sendmail as
958 -your mailer when you install cron -- /bin/mail doesn't do aliasing, and UUCP
959 -usually doesn't read its mail.
960 +mail will be sent. Otherwise mail is sent to the owner of the crontab.
962 The format of a cron command is very much the V7 standard, with a number of
963 upward-compatible extensions. Each line has five time and date fields,
964 -followed by a user name if this is the system crontab file,
965 -followed by a command. Commands are executed by
966 +followed by a command, followed by a newline character ('\n').
967 +The system crontab (/etc/crontab) uses the same format, except that
968 +the username for the command is specified after the time and
969 +date fields and before the command.
970 +Note that if the line does not have a trailing newline character, the
971 +entire line will be silently ignored by both crontab and cron; the command
972 +will never be executed.
974 +Commands are executed by
976 when the minute, hour, and month of year fields match the current time,
985 -month 0-12 (or names, see below)
986 +month 1-12 (or names, see below)
988 day of week 0-7 (0 or 7 is Sun, or use names)
992 would cause a command to be run at 4:30 am on the 1st and 15th of each
993 month, plus every Friday.
995 +Instead of the first five fields, one of eight special strings may appear:
1002 +@reboot Run once, at startup.
1004 +@yearly Run once a year, "0 0 1 1 *".
1006 +@annually (same as @yearly)
1008 +@monthly Run once a month, "0 0 1 * *".
1010 +@weekly Run once a week, "0 0 * * 0".
1012 +@daily Run once a day, "0 0 * * *".
1014 +@midnight (same as @daily)
1016 +@hourly Run once an hour, "0 * * * *".
1018 .SH EXAMPLE CRON FILE
1021 @@ -163,6 +192,25 @@
1022 23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
1023 5 4 * * sun echo "run at 5 after 4 every sunday"
1025 +.SH EXAMPLE SYSTEM CRON FILE
1026 +This has the username field, as used by /etc/crontab.
1028 +# /etc/crontab: system-wide crontab
1029 +# Unlike any other crontab you don't have to run the `crontab'
1030 +# command to install the new version when you edit this file.
1031 +# This file also has a username field, that none of the other crontabs do.
1034 +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
1036 +# m h dom mon dow user command
1037 +42 6 * * * root run-parts --report /etc/cron.daily
1038 +47 6 * * 7 root run-parts --report /etc/cron.weekly
1039 +52 6 1 * * root run-parts --report /etc/cron.monthly
1041 +# Removed invocation of anacron, as this is now handled by a
1048 mailed to a person other than the crontab owner (SysV can't do this), or the
1049 feature can be turned off and no mail will be sent at all (SysV can't do this
1052 +All of the `@' commands that can appear in place of the first five fields
1056 Paul Vixie <paul@vix.com>
1057 --- cron-3.0pl1.orig/crontab.c
1058 +++ cron-3.0pl1/crontab.c
1063 +#include <signal.h>
1064 #include <sys/file.h>
1065 #include <sys/stat.h>
1071 -static char User[MAX_UNAME], RealUser[MAX_UNAME];
1072 +static char *User, *RealUser;
1073 static char Filename[MAX_FNAME];
1074 -static FILE *NewCrontab;
1075 +static FILE *NewCrontab = NULL;
1076 static int CheckErrorCount;
1077 static enum opt_t Option;
1078 static struct passwd *pw;
1079 @@ -124,11 +125,23 @@
1080 case opt_replace: if (replace_cmd() < 0)
1081 exitstatus = ERROR_EXIT;
1083 + /* The following was added to shut
1084 + -Wall up, but it will never be hit,
1085 + because the option parser will catch
1087 + case opt_unknown: usage("unknown option specified");
1095 +char *getoptarg = "u:lerx:";
1097 +char *getoptarg = "u:ler";
1102 parse_args(argc, argv)
1107 + struct stat statbuf;
1109 if (!(pw = getpwuid(getuid()))) {
1110 fprintf(stderr, "%s: your UID isn't in the passwd file.\n",
1111 @@ -143,30 +157,42 @@
1112 fprintf(stderr, "bailing out.\n");
1115 - strcpy(User, pw->pw_name);
1116 - strcpy(RealUser, User);
1117 + if (((User=strdup(pw->pw_name)) == NULL) ||
1118 + ((RealUser=strdup(pw->pw_name)) == NULL)) {
1119 + fprintf(stderr, "Memory allocation error\n");
1123 Option = opt_unknown;
1124 - while (EOF != (argch = getopt(argc, argv, "u:lerx:"))) {
1126 + while (EOF != (argch = getopt(argc, argv, getoptarg))) {
1130 if (!set_debug_flags(optarg))
1131 usage("bad debug option");
1132 + usage("unrecognized option");
1136 - if (getuid() != ROOT_UID)
1137 + if (!(pw = getpwnam(optarg)))
1139 + fprintf(stderr, "%s: user `%s' unknown\n",
1140 + ProgramName, optarg);
1143 + if ((getuid() != ROOT_UID) &&
1144 + (getuid() != pw->pw_uid))
1147 "must be privileged to use -u\n");
1150 - if (!(pw = getpwnam(optarg)))
1152 - fprintf(stderr, "%s: user `%s' unknown\n",
1153 - ProgramName, optarg);
1155 + if ((User=strdup(pw->pw_name)) == NULL) {
1156 + fprintf(stderr, "Memory allocation error\n");
1159 - (void) strcpy(User, optarg);
1162 if (Option != opt_unknown)
1165 if (argv[optind] != NULL) {
1166 Option = opt_replace;
1167 - (void) strcpy (Filename, argv[optind]);
1168 + (void) strncpy (Filename, argv[optind], (sizeof Filename)-1);
1169 + Filename[(sizeof Filename)-1] = '\0';
1172 usage("file name must be specified for replace");
1174 @@ -227,7 +255,16 @@
1178 - if (swap_uids() < OK) {
1179 + /* Make sure we opened a normal file. */
1180 + if (fstat(fileno(NewCrontab), &statbuf) < 0) {
1184 + if (!S_ISREG(statbuf.st_mode)) {
1185 + fprintf(stderr, "%s: Not a regular file.\n", Filename);
1188 + if (swap_uids_back() < OK) {
1189 perror("swapping uids back");
1192 @@ -244,9 +281,13 @@
1201 log_it(RealUser, Pid, "LIST", User);
1202 - (void) sprintf(n, CRON_TAB(User));
1203 + (void) snprintf(n, MAX_FNAME, CRON_TAB(User));
1204 if (!(f = fopen(n, "r"))) {
1205 if (errno == ENOENT)
1206 fprintf(stderr, "no crontab for %s\n", User);
1207 @@ -258,6 +299,30 @@
1208 /* file is open. copy to stdout, close.
1212 + /* DEBIAN: Don't list header lines unless CRONTAB_NOHEADER is
1214 + /* ignore the top few comments since we probably put them there.
1216 + if (!(ctnh = getenv("CRONTAB_NOHEADER")) ||
1217 + toupper(*ctnh) != 'N')
1219 + for (x = 0; x < NHEADER_LINES; x++) {
1227 + while (EOF != (ch = get_char(f)))
1235 while (EOF != (ch = get_char(f)))
1241 log_it(RealUser, Pid, "DELETE", User);
1242 - (void) sprintf(n, CRON_TAB(User));
1243 + (void) snprintf(n, MAX_FNAME, CRON_TAB(User));
1245 if (errno == ENOENT)
1246 fprintf(stderr, "no crontab for %s\n", User);
1247 @@ -295,13 +360,14 @@
1248 char n[MAX_FNAME], q[MAX_TEMPSTR], *editor;
1251 - struct stat statbuf;
1252 + struct stat statbuf, fsbuf;
1258 log_it(RealUser, Pid, "BEGIN EDIT", User);
1259 - (void) sprintf(n, CRON_TAB(User));
1260 + (void) snprintf(n, MAX_FNAME, CRON_TAB(User));
1261 if (!(f = fopen(n, "r"))) {
1262 if (errno != ENOENT) {
1264 @@ -315,11 +381,26 @@
1268 - (void) sprintf(Filename, "/tmp/crontab.%d", Pid);
1269 - if (-1 == (t = open(Filename, O_CREAT|O_EXCL|O_RDWR, 0600))) {
1272 + /* The support for TMPDIR is temporarily removed, because of
1273 + interactions with emacs */
1274 + if (getenv("TMPDIR")) {
1275 + strcpy(Filename, getenv("TMPDIR"));
1277 + strcpy(Filename,"/tmp");
1280 + strcpy(Filename,"/tmp");
1283 + (void) sprintf(Filename+strlen(Filename), "/crontab.XXXXXXXXXX");
1284 + if ((t = mkstemp(Filename)) == -1) {
1291 if (fchown(t, getuid(), getgid()) < 0) {
1293 @@ -362,6 +443,10 @@
1297 + if (fstat(t, &fsbuf) < 0) {
1298 + perror("unable to fstat temp file");
1303 if (ferror(NewCrontab)) {
1304 @@ -374,6 +459,11 @@
1308 + if (statbuf.st_dev != fsbuf.st_dev || statbuf.st_ino != fsbuf.st_ino) {
1309 + fprintf(stderr, "temp file must be edited in place\n");
1313 mtime = statbuf.st_mtime;
1315 if ((!(editor = getenv("VISUAL")))
1316 @@ -390,6 +480,10 @@
1317 * close and reopen the file around the edit.
1320 + /* Turn off signals. */
1321 + (void)signal(SIGHUP, SIG_IGN);
1322 + (void)signal(SIGINT, SIG_IGN);
1323 + (void)signal(SIGQUIT, SIG_IGN);
1324 switch (pid = fork()) {
1331 - sprintf(q, "%s %s", editor, Filename);
1332 + snprintf(q, MAX_TEMPSTR, "%s %s", editor, Filename);
1333 execlp(_PATH_BSHELL, _PATH_BSHELL, "-c", q, NULL);
1336 @@ -420,23 +514,37 @@
1340 - xpid = wait(&waiter);
1341 - if (xpid != pid) {
1342 - fprintf(stderr, "%s: wrong PID (%d != %d) from \"%s\"\n",
1343 - ProgramName, xpid, pid, editor);
1346 - if (WIFEXITED(waiter) && WEXITSTATUS(waiter)) {
1347 - fprintf(stderr, "%s: \"%s\" exited with status %d\n",
1348 - ProgramName, editor, WEXITSTATUS(waiter));
1351 - if (WIFSIGNALED(waiter)) {
1353 - "%s: \"%s\" killed; signal %d (%score dumped)\n",
1354 - ProgramName, editor, WTERMSIG(waiter),
1355 - WCOREDUMP(waiter) ?"" :"no ");
1358 + xpid = waitpid(pid, &waiter, WUNTRACED);
1360 + fprintf(stderr, "%s: waitpid() failed waiting for PID %d from \"%s\": %s\n",
1361 + ProgramName, pid, editor, strerror(errno));
1362 + } else if (xpid != pid) {
1363 + fprintf(stderr, "%s: wrong PID (%d != %d) from \"%s\"\n",
1364 + ProgramName, xpid, pid, editor);
1366 + } else if (WIFSTOPPED(waiter)) {
1367 + /* raise(WSTOPSIG(waiter)); Not needed and breaks in job control shell*/
1368 + } else if (WIFEXITED(waiter) && WEXITSTATUS(waiter)) {
1369 + fprintf(stderr, "%s: \"%s\" exited with status %d\n",
1370 + ProgramName, editor, WEXITSTATUS(waiter));
1372 + } else if (WIFSIGNALED(waiter)) {
1374 + "%s: \"%s\" killed; signal %d (%score dumped)\n",
1375 + ProgramName, editor, WTERMSIG(waiter),
1376 + WCOREDUMP(waiter) ?"" :"no ");
1381 + (void)signal(SIGHUP, SIG_DFL);
1382 + (void)signal(SIGINT, SIG_DFL);
1383 + (void)signal(SIGQUIT, SIG_DFL);
1384 + (void)signal(SIGTSTP, SIG_DFL);
1385 + if (statbuf.st_dev != fsbuf.st_dev || statbuf.st_ino != fsbuf.st_ino) {
1386 + fprintf(stderr, "temp file must be edited in place\n");
1389 if (fstat(t, &statbuf) < 0) {
1392 ProgramName, Filename);
1395 - fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n");
1396 + fprintf(stderr, "%s: panic: bad switch() in replace_cmd()\n",
1401 @@ -481,7 +590,14 @@
1403 log_it(RealUser, Pid, "END EDIT", User);
1407 +static char tn[MAX_FNAME];
1409 +static void sig_handler(int x)
1415 /* returns 0 on success
1416 * -1 on syntax error
1417 @@ -489,19 +605,51 @@
1421 - char n[MAX_FNAME], envstr[MAX_ENVSTR], tn[MAX_FNAME];
1422 + char n[MAX_FNAME], envstr[MAX_ENVSTR];
1427 time_t now = time(NULL);
1428 char **envp = env_init();
1432 - (void) sprintf(n, "tmp.%d", Pid);
1433 - (void) sprintf(tn, CRON_TAB(n));
1434 - if (!(tmp = fopen(tn, "w+"))) {
1435 + if (envp == NULL) {
1436 + fprintf(stderr, "%s: Cannot allocate memory.\n", ProgramName);
1440 + /* Assume privilege. This way we can only receive signals on our
1441 + input - the ones listed below (or from root - root's problem, not
1443 + saved_uid = getuid();
1444 + if (setuid(geteuid()) < 0) {
1449 + /* Assumes Linux-style signal handlers (takes int, returns void) */
1450 + /* Signal handlers, to ensure we do not leave temp files in the
1451 + spool dir. We don't remove these on exiting this function;
1452 + but that's OK, we exit immediately afterwards anyway. */
1453 + signal(SIGHUP, sig_handler);
1454 + signal(SIGINT, sig_handler);
1455 + signal(SIGQUIT, sig_handler);
1456 + signal(SIGTSTP, SIG_IGN);
1458 + (void) snprintf(tn, MAX_FNAME, CRON_TAB("tmp.XXXXXX"));
1465 + tmp = fdopen(fd, "w+");
1472 /* write a signature at the top of the file.
1474 @@ -517,19 +665,18 @@
1476 while (EOF != (ch = get_char(NewCrontab)))
1478 - ftruncate(fileno(tmp), ftell(tmp));
1479 - fflush(tmp); rewind(tmp);
1481 - if (ferror(tmp)) {
1482 + if (ferror(tmp) || fflush(tmp) || fsync(fd)) {
1483 fprintf(stderr, "%s: error while writing new crontab to %s\n",
1486 fclose(tmp); unlink(tn);
1490 /* check the syntax of the file being installed.
1494 /* BUG: was reporting errors after the EOF if there were any errors
1495 * in the file proper -- kludged it by stopping after first error.
1498 if (CheckErrorCount != 0) {
1499 fprintf(stderr, "errors in crontab file, can't install.\n");
1500 fclose(tmp); unlink(tn);
1501 + /* Give up privilege, in case we loop. */
1502 + if (setreuid(saved_uid, -1) < 0)
1511 - (void) sprintf(n, CRON_TAB(User));
1512 + (void) snprintf(n, sizeof(n), CRON_TAB(User));
1513 if (rename(tn, n)) {
1514 fprintf(stderr, "%s: error renaming %s to %s\n",
1515 ProgramName, tn, n);
1516 @@ -596,6 +746,11 @@
1517 log_it(RealUser, Pid, "REPLACE", User);
1521 + /* Give up privilege, just in case. */
1522 + /* Don't need to check for error; nothing happens beyond here but a log entry,
1523 + and the failure message is incorrect after the rename above. */
1524 + setreuid(saved_uid, -1);
1528 --- cron-3.0pl1.orig/database.c
1529 +++ cron-3.0pl1/database.c
1532 #define TMAX(a,b) ((a)>(b)?(a):(b))
1534 +/* Try to get maximum path name -- this isn't really correct, but we're
1535 +going to be lazy */
1540 +#define PATH_MAX MAXPATHLEN
1542 +#define PATH_MAX 2048
1545 +#endif /* ifndef PATH_MAX */
1547 static void process_crontab __P((char *, char *, char *,
1549 cron_db *, cron_db *));
1553 +static int valid_name (char *filename);
1554 +static user *get_next_system_crontab __P((user *));
1557 load_database(old_db)
1562 struct stat statbuf;
1563 struct stat syscron_stat;
1568 + struct stat syscrond_stat;
1569 + struct stat syscrond_file_stat;
1571 + char syscrond_fname[PATH_MAX+1];
1572 + int syscrond_change = 0;
1575 Debug(DLOAD, ("[%d] load_database()\n", getpid()))
1578 if (stat(SYSCRONTAB, &syscron_stat) < OK)
1579 syscron_stat.st_mtime = 0;
1582 + /* Check mod time of SYSCRONDIR. This won't tell us if a file
1583 + * in it changed, but will capture deletions, which the individual
1584 + * file check won't
1586 + if (stat(SYSCRONDIR, &syscrond_stat) < OK) {
1587 + log_it("CRON", getpid(), "STAT FAILED", SYSCRONDIR);
1588 + (void) exit(ERROR_EXIT);
1591 + /* If SYSCRONDIR was modified, we know that something is changed and
1592 + * there is no need for any further checks. If it wasn't, we should
1593 + * pass through the old list of files in SYSCRONDIR and check their
1594 + * mod time. Therefore a stopped hard drive won't be spun up, since
1595 + * we avoid reading of SYSCRONDIR and don't change its access time.
1596 + * This is especially important on laptops with APM.
1598 + if (old_db->sysd_mtime != syscrond_stat.st_mtime) {
1599 + syscrond_change = 1;
1601 + /* Look through the individual files */
1604 + Debug(DLOAD, ("[%d] system dir mtime unch, check files now.\n",
1607 + for (systab = old_db->head;
1608 + (systab = get_next_system_crontab (systab)) != NULL;
1609 + systab = systab->next) {
1611 + sprintf(syscrond_fname, "%s/%s", SYSCRONDIR,
1612 + systab->name + 8);
1614 + Debug(DLOAD, ("\t%s:", syscrond_fname))
1616 + if (stat(syscrond_fname, &syscrond_file_stat) < OK)
1617 + syscrond_file_stat.st_mtime = 0;
1619 + if (syscrond_file_stat.st_mtime != systab->mtime) {
1620 + syscrond_change = 1;
1623 + Debug(DLOAD, (" [checked]\n"))
1626 +#endif /* DEBIAN */
1628 /* if spooldir's mtime has not changed, we don't need to fiddle with
1632 * so is guaranteed to be different than the stat() mtime the first
1633 * time this function is called.
1635 - if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) {
1637 + if ((old_db->user_mtime == statbuf.st_mtime) &&
1638 + (old_db->sys_mtime == syscron_stat.st_mtime) &&
1639 + (!syscrond_change)) {
1641 + if ((old_db->user_mtime == statbuf.st_mtime) &&
1642 + (old_db->sys_mtime == syscron_stat.st_mtime)) {
1644 Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n",
1648 * actually changed. Whatever is left in the old database when
1649 * we're done is chaff -- crontabs that disappeared.
1651 - new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime);
1652 + new_db.user_mtime = statbuf.st_mtime;
1653 + new_db.sys_mtime = syscron_stat.st_mtime;
1655 + new_db.sysd_mtime = syscrond_stat.st_mtime;
1657 new_db.head = new_db.tail = NULL;
1659 if (syscron_stat.st_mtime) {
1665 + /* Read all the package crontabs. */
1666 + if (!(dir = opendir(SYSCRONDIR))) {
1667 + log_it("CRON", getpid(), "OPENDIR FAILED", SYSCRONDIR);
1668 + (void) exit(ERROR_EXIT);
1671 + while (NULL != (dp = readdir(dir))) {
1672 + char fname[MAXNAMLEN+1],
1673 + tabname[PATH_MAX+1];
1676 + /* avoid file names beginning with ".". this is good
1677 + * because we would otherwise waste two guaranteed calls
1678 + * to stat() for . and .., and also because package names
1679 + * starting with a period are just too nasty to consider.
1681 + if (dp->d_name[0] == '.')
1684 + /* skipfile names with letters outside the set
1685 + * [A-Za-z0-9_-], like run-parts.
1687 + if (!valid_name(dp->d_name))
1690 + /* Generate the "fname" */
1691 + (void) strcpy(fname,"*system*");
1692 + (void) strcat(fname, dp->d_name);
1693 + sprintf(tabname,"%s/%s", SYSCRONDIR, dp->d_name);
1695 + /* statbuf is used as working storage by process_crontab() --
1696 + current contents are irrelevant */
1697 + process_crontab("root", fname, tabname,
1698 + &statbuf, &new_db, old_db);
1704 /* we used to keep this dir open all the time, for the sake of
1705 * efficiency. however, we need to close it in every fork, and
1706 * we fork a lot more often than the mtime of the dir changes.
1709 while (NULL != (dp = readdir(dir))) {
1710 char fname[MAXNAMLEN+1],
1711 - tabname[MAXNAMLEN+1];
1712 + tabname[PATH_MAX+1];
1714 /* avoid file names beginning with ".". this is good
1715 * because we would otherwise waste two guaranteed calls
1719 (void) strcpy(fname, dp->d_name);
1720 - sprintf(tabname, CRON_TAB(fname));
1721 + snprintf(tabname, PATH_MAX+1, CRON_TAB(fname));
1723 process_crontab(fname, fname, tabname,
1724 &statbuf, &new_db, old_db);
1725 @@ -203,10 +322,19 @@
1726 int crontab_fd = OK - 1;
1730 + /* If the name begins with *system*, don't worry about password -
1731 + it's part of the system crontab */
1732 + if (strncmp(fname, "*system*", 8) && !(pw = getpwnam(uname))) {
1734 if (strcmp(fname, "*system*") && !(pw = getpwnam(uname))) {
1736 /* file doesn't have a user in passwd file.
1738 - log_it(fname, getpid(), "ORPHAN", "no passwd entry");
1739 + if (strncmp(fname, "tmp.", 4)) {
1740 + /* don't log these temporary files */
1741 + log_it(fname, getpid(), "ORPHAN", "no passwd entry");
1746 @@ -259,3 +387,35 @@
1753 +/* True or false? Is this a valid filename (upper/lower alpha, digits,
1754 + * underscores, and hyphens only?)
1757 +/* Same function, better compliance with ISO C */
1758 +static int valid_name (char *filename)
1760 + while (*filename) {
1761 + if (!(isalnum(*filename) ||
1762 + (*filename == '_') ||
1763 + (*filename == '-')))
1772 +get_next_system_crontab (curtab)
1775 + for ( ; curtab != NULL; curtab = curtab->next)
1776 + if (!strncmp(curtab->name, "*system*", 8) && curtab->name [8])
1782 --- cron-3.0pl1.orig/do_command.c
1783 +++ cron-3.0pl1/do_command.c
1788 -#include <sys/signal.h>
1789 +#include <signal.h>
1791 #if defined(sequent)
1792 # include <sys/universe.h>
1795 # include <syslog.h>
1797 +#if defined(USE_PAM)
1798 +#include <security/pam_appl.h>
1799 +static pam_handle_t *pamh = NULL;
1800 +static const struct pam_conv conv = {
1803 +#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \
1804 + fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \
1805 + syslog(LOG_ERR,"%s",pam_strerror(pamh, retcode)); \
1806 + pam_end(pamh, retcode); exit(1); \
1811 static void child_process __P((entry *, user *)),
1813 char *usernm, *mailto;
1816 +#if defined(USE_PAM)
1820 Debug(DPROC, ("[%d] child_process('%s')\n", getpid(), e->cmd))
1822 /* mark ourselves as different to PS command watchers by upshifting
1823 @@ -95,13 +112,32 @@
1824 usernm = env_get("LOGNAME", e->envp);
1825 mailto = env_get("MAILTO", e->envp);
1827 + /* Check for arguments */
1831 + /* These chars have to match those cron_popen()
1832 + * uses to split the command string */
1833 + mailto += strspn(mailto, " \t\n");
1834 + end = mailto + strcspn(mailto, " \t\n");
1835 + if (*mailto == '-' || *end != '\0') {
1836 + printf("Bad Mailto karma.\n");
1837 + log_it("CRON",getpid(),"error","bad mailto");
1843 /* our parent is watching for our death by catching SIGCHLD. we
1844 * do not care to watch for our children's deaths this way -- we
1845 * use wait() explictly. so we have to disable the signal (which
1846 * was inherited from the parent).
1849 + (void) signal(SIGCHLD, SIG_DFL);
1851 (void) signal(SIGCHLD, SIG_IGN);
1854 /* on system-V systems, we are ignoring SIGCLD. we have to stop
1855 * ignoring it now or the wait() in cron_pclose() won't work.
1856 @@ -122,13 +158,21 @@
1857 * command, and subsequent characters are the additional input to
1858 * the command. Subsequent %'s will be transformed into newlines,
1859 * but that happens later.
1861 + * If there are escaped %'s, remove the escape character.
1864 register int escaped = FALSE;
1868 - for (input_data = e->cmd; ch = *input_data; input_data++) {
1869 + for (input_data = p = e->cmd; (ch = *input_data);
1870 + input_data++, p++) {
1871 + if (p != input_data)
1874 + if (ch == '%' || ch == '\\')
1879 @@ -141,8 +185,21 @@
1886 +#if defined(USE_PAM)
1887 + retcode = pam_start("cron", usernm, &conv, &pamh);
1889 + retcode = pam_acct_mgmt(pamh, PAM_SILENT);
1891 + retcode = pam_open_session(pamh, PAM_SILENT);
1893 + retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED | PAM_SILENT);
1898 /* fork again, this time so we can exec the user's command.
1903 /* that's the last thing we'll log. close the log files.
1910 /* get new pgrp, void tty, etc.
1912 @@ -188,9 +243,12 @@
1913 /* grandchild process. make std{in,out} be the ends of
1914 * pipes opened by our daddy; make stderr go to stdout.
1916 - close(STDIN); dup2(stdin_pipe[READ_PIPE], STDIN);
1917 - close(STDOUT); dup2(stdout_pipe[WRITE_PIPE], STDOUT);
1918 - close(STDERR); dup2(STDOUT, STDERR);
1919 + /* Closes are unnecessary -- let dup2() do it */
1921 + /* close(STDIN) */; dup2(stdin_pipe[READ_PIPE], STDIN);
1922 + /* close(STDOUT) */; dup2(stdout_pipe[WRITE_PIPE], STDOUT);
1923 + /* close(STDERR)*/; dup2(STDOUT, STDERR);
1926 /* close the pipes we just dup'ed. The resources will remain.
1928 @@ -207,10 +265,16 @@
1929 * we set uid, we've lost root privledges.
1933 +# if defined(BSD) || defined(POSIX)
1934 initgroups(env_get("LOGNAME", e->envp), e->gid);
1936 - setuid(e->uid); /* we aren't root after this... */
1937 + if (setuid(e->uid) !=0) { /* we aren't root after this... */
1939 + snprintf(msg, 256, "do_command:setuid(%lu) failed: %s",
1940 + (unsigned long) e->uid, strerror(errno));
1941 + log_it("CRON",getpid(),"error",msg);
1944 chdir(env_get("HOME", e->envp));
1946 /* exec the command.
1947 @@ -227,6 +291,13 @@
1950 # endif /*DEBUGGING*/
1953 + struct sigaction oact;
1954 + sigaction(SIGCHLD, NULL, &oact);
1956 + fprintf(stdout,"error");
1958 execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);
1959 fprintf(stderr, "execl: couldn't exec `%s'\n", shell);
1963 * \x -> \x for all x != %
1965 - while (ch = *input_data++) {
1966 + while ((ch = *input_data++) != '\0') {
1971 auto char hostname[MAXHOSTNAMELEN];
1973 (void) gethostname(hostname, MAXHOSTNAMELEN);
1974 - (void) sprintf(mailcmd, MAILARGS,
1976 - if (!(mail = cron_popen(mailcmd, "w"))) {
1977 + (void) snprintf(mailcmd, sizeof(mailcmd),
1978 + MAILARGS, MAILCMD, mailto);
1979 + if (!(mail = cron_popen(mailcmd, "w", e))) {
1981 (void) _exit(ERROR_EXIT);
1985 # if defined(MAIL_DATE)
1986 fprintf(mail, "Date: %s\n",
1987 - arpadate(&TargetTime));
1988 + arpadate(&StartTime));
1989 # endif /* MAIL_DATE */
1990 for (env = e->envp; *env; env++)
1991 fprintf(mail, "X-Cron-Env: <%s>\n",
1993 if (mailto && status) {
1994 char buf[MAX_TEMPSTR];
1997 + snprintf(buf, MAX_TEMPSTR,
1998 "mailed %d byte%s of output but got status 0x%04x\n",
1999 bytes, (bytes==1)?"":"s",
2001 @@ -460,6 +531,11 @@
2002 Debug(DPROC, (", dumped core"))
2003 Debug(DPROC, ("\n"))
2005 +#if defined(USE_PAM)
2006 + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
2007 + retcode = pam_close_session(pamh, PAM_SILENT);
2008 + pam_end(pamh, retcode);
2013 --- cron-3.0pl1.orig/entry.c
2014 +++ cron-3.0pl1/entry.c
2017 char cmd[MAX_COMMAND];
2018 char envstr[MAX_ENVSTR];
2021 Debug(DPARS, ("load_entry()...about to eat comments\n"))
2024 bit_set(e->minute, 0);
2025 bit_set(e->hour, 0);
2026 bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
2027 + e->flags |= DOM_STAR;
2028 bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
2029 - bit_set(e->dow, 0);
2030 + bit_nset(e->dow, 0,0);
2031 } else if (!strcmp("daily", cmd) || !strcmp("midnight", cmd)) {
2032 bit_set(e->minute, 0);
2033 bit_set(e->hour, 0);
2034 @@ -149,10 +151,11 @@
2035 bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
2036 } else if (!strcmp("hourly", cmd)) {
2037 bit_set(e->minute, 0);
2038 - bit_set(e->hour, (LAST_HOUR-FIRST_HOUR+1));
2039 + bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
2040 bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
2041 bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
2042 bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
2043 + e->flags |= HR_STAR;
2049 Debug(DPARS, ("load_entry()...about to parse numerics\n"))
2052 + e->flags |= MIN_STAR;
2053 ch = get_list(e->minute, FIRST_MINUTE, LAST_MINUTE,
2054 PPC_NULL, ch, file);
2061 + e->flags |= HR_STAR;
2062 ch = get_list(e->hour, FIRST_HOUR, LAST_HOUR,
2063 PPC_NULL, ch, file);
2069 + /* If we used one of the @commands, we may be pointing at
2070 + blanks, and if we don't skip over them, we'll miss the user/command */
2071 + Skip_Blanks(ch, file);
2072 /* ch is the first character of a command, or a username */
2073 unget_char(ch, file);
2078 Debug(DPARS, ("load_entry()...uid %d, gid %d\n",e->uid,e->gid))
2079 + } else if (ch == '*') {
2084 e->uid = pw->pw_uid;
2085 @@ -247,24 +260,52 @@
2086 /* copy and fix up environment. some variables are just defaults and
2087 * others are overrides.
2089 - e->envp = env_copy(envp);
2090 + if ((e->envp = env_copy(envp)) == NULL) {
2094 if (!env_get("SHELL", e->envp)) {
2095 - sprintf(envstr, "SHELL=%s", _PATH_BSHELL);
2096 - e->envp = env_set(e->envp, envstr);
2097 + snprintf(envstr, MAX_ENVSTR, "SHELL=%s", _PATH_BSHELL);
2098 + if ((tenvp = env_set(e->envp, envstr))) {
2105 if (!env_get("HOME", e->envp)) {
2106 - sprintf(envstr, "HOME=%s", pw->pw_dir);
2107 - e->envp = env_set(e->envp, envstr);
2108 + snprintf(envstr, MAX_ENVSTR, "HOME=%s", pw->pw_dir);
2109 + if ((tenvp = env_set(e->envp, envstr))) {
2116 if (!env_get("PATH", e->envp)) {
2117 - sprintf(envstr, "PATH=%s", _PATH_DEFPATH);
2118 - e->envp = env_set(e->envp, envstr);
2119 + snprintf(envstr, MAX_ENVSTR, "PATH=%s", _PATH_DEFPATH);
2120 + if ((tenvp = env_set(e->envp, envstr))) {
2127 + snprintf(envstr, MAX_ENVSTR, "%s=%s", "LOGNAME", pw->pw_name);
2128 + if ((tenvp = env_set(e->envp, envstr))) {
2134 - sprintf(envstr, "%s=%s", "LOGNAME", pw->pw_name);
2135 - e->envp = env_set(e->envp, envstr);
2137 - sprintf(envstr, "%s=%s", "USER", pw->pw_name);
2138 - e->envp = env_set(e->envp, envstr);
2139 + snprintf(envstr, MAX_ENVSTR, "%s=%s", "USER", pw->pw_name);
2140 + if ((tenvp = env_set(e->envp, envstr))) {
2148 Debug(DPARS, ("load_entry()...about to parse command\n"))
2149 @@ -280,12 +321,16 @@
2153 + log_it("CRON",getpid(),"DEBUG","detected early eof");
2157 /* got the command in the 'cmd' string; save it in *e.
2159 - e->cmd = strdup(cmd);
2160 + if ((e->cmd = strdup(cmd)) == NULL) {
2165 Debug(DPARS, ("load_entry()...returning successfully\n"))
2167 @@ -294,6 +339,10 @@
2172 + env_free(e->envp);
2176 if (ecode != e_none && error_func)
2177 (*error_func)(ecodes[(int)ecode]);
2178 --- cron-3.0pl1.orig/env.c
2179 +++ cron-3.0pl1/env.c
2182 register char **p = (char **) malloc(sizeof(char **));
2191 for (count = 0; envp[count] != NULL; count++)
2193 p = (char **) malloc((count+1) * sizeof(char *)); /* 1 for the NULL */
2198 for (i = 0; i < count; i++)
2199 - p[i] = strdup(envp[i]);
2200 + if ((p[i] = strdup(envp[i])) == NULL) {
2202 + (void) free(p[i]);
2211 * save our new one there, and return the existing array.
2214 - envp[found] = strdup(envstr);
2215 + if ((envp[found] = strdup(envstr)) == NULL) {
2225 p = (char **) realloc((void *) envp,
2226 (unsigned) ((count+1) * sizeof(char **)));
2231 p[count] = p[count-1];
2232 - p[count-1] = strdup(envstr);
2233 + if ((p[count-1] = strdup(envstr)) == NULL) {
2240 @@ -115,15 +137,17 @@
2244 - char name[MAX_TEMPSTR], val[MAX_ENVSTR];
2245 + char name[MAX_ENVSTR], val[MAX_ENVSTR];
2249 fileline = LineNumber;
2251 - if (EOF == get_string(envstr, MAX_ENVSTR, f, "\n"))
2252 + if (EOF == get_string(envstr, MAX_ENVSTR - 1, f, "\n"))
2255 + envstr[MAX_ENVSTR - 1] = '\0';
2257 Debug(DPARS, ("load_env, read <%s>\n", envstr))
2259 name[0] = val[0] = '\0';
2264 + if (strlen(name) + 1 + strlen(val) >= MAX_ENVSTR-1)
2266 (void) sprintf(envstr, "%s=%s", name, val);
2267 Debug(DPARS, ("load_env, <%s> <%s> -> <%s>\n", name, val, envstr))
2270 register int len = strlen(name);
2271 register char *p, *q;
2273 - while (p = *envp++) {
2274 + while ((p = *envp++)) {
2275 if (!(q = strchr(p, '=')))
2277 if ((q - p) == len && !strncmp(p, name, len))
2278 --- cron-3.0pl1.orig/externs.h
2279 +++ cron-3.0pl1/externs.h
2281 # include <unistd.h>
2282 # include <string.h>
2283 # include <dirent.h>
2284 +# include <errno.h>
2285 # define DIR_T struct dirent
2287 # define WAIT_IS_INT 1
2288 --- cron-3.0pl1.orig/job.c
2289 +++ cron-3.0pl1/job.c
2291 if (j->e == e && j->u == u) { return; }
2293 /* build a job queue element */
2294 - j = (job*)malloc(sizeof(job));
2295 + if ((j = (job*)malloc(sizeof(job))) == NULL)
2297 j->next = (job*) NULL;
2300 --- cron-3.0pl1.orig/misc.c
2301 +++ cron-3.0pl1/misc.c
2302 @@ -263,11 +263,11 @@
2303 char buf[MAX_TEMPSTR];
2306 - (void) sprintf(pidfile, PIDFILE, PIDDIR);
2307 + (void) snprintf(pidfile, MAX_FNAME, PIDFILE, PIDDIR);
2308 if ((-1 == (fd = open(pidfile, O_RDWR|O_CREAT, 0644)))
2309 || (NULL == (fp = fdopen(fd, "r+")))
2311 - sprintf(buf, "can't open or create %s: %s",
2312 + snprintf(buf, MAX_TEMPSTR, "can't open or create %s: %s",
2313 pidfile, strerror(errno));
2314 fprintf(stderr, "%s: %s\n", ProgramName, buf);
2315 log_it("CRON", getpid(), "DEATH", buf);
2316 @@ -278,13 +278,14 @@
2317 int save_errno = errno;
2319 fscanf(fp, "%d", &otherpid);
2320 - sprintf(buf, "can't lock %s, otherpid may be %d: %s",
2321 + snprintf(buf, MAX_TEMPSTR, "can't lock %s, otherpid may be %d: %s",
2322 pidfile, otherpid, strerror(save_errno));
2323 fprintf(stderr, "%s: %s\n", ProgramName, buf);
2324 log_it("CRON", getpid(), "DEATH", buf);
2328 + snprintf(buf, MAX_TEMPSTR, "pidfile fd = %d", fd);
2329 + log_it("CRON", getpid(), "INFO", buf);
2330 (void) fcntl(fd, F_SETFD, 1);
2334 /* abandon fd and fp even though the file is open. we need to
2335 * keep it open and locked, but we don't need the handles elsewhere.
2340 /* get_char(file) : like getc() but increment LineNumber on newlines
2345 - Set_LineNum(LineNumber + 1)
2346 + Set_LineNum(LineNumber + 1);
2354 - Set_LineNum(LineNumber - 1)
2355 + Set_LineNum(LineNumber - 1);
2359 @@ -461,25 +463,26 @@
2364 #if defined(LOG_FILE)
2367 TIME_T now = time((TIME_T) 0);
2368 register struct tm *t = localtime(&now);
2372 -#if defined(SYSLOG)
2373 - static int syslog_open = 0;
2376 #if defined(LOG_FILE)
2377 /* we assume that MAX_TEMPSTR will hold the date, time, &punctuation.
2379 - msg = malloc(strlen(username)
2384 + msg_size = strlen(username) + strlen(event) + strlen(detail) + MAX_TEMPSTR;
2385 + msg = malloc(msg_size);
2386 + if (msg == NULL) {
2387 + /* damn, out of mem and we did not test that before... */
2388 + fprintf(stderr, "%s: Run OUT OF MEMORY while %s\n",
2389 + ProgramName, __FUNCTION__);
2393 LogFD = open(LOG_FILE, O_WRONLY|O_APPEND|O_CREAT, 0600);
2395 @@ -491,16 +494,16 @@
2399 - /* we have to sprintf() it because fprintf() doesn't always write
2400 + /* we have to snprintf() it because fprintf() doesn't always write
2401 * everything out in one chunk and this has to be atomically appended
2404 - sprintf(msg, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n",
2405 + snprintf(msg, msg_size, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n",
2407 t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid,
2410 - /* we have to run strlen() because sprintf() returns (char*) on old BSD
2411 + /* we have to run strlen() because snprintf() returns (char*) on old BSD
2413 if (LogFD < OK || write(LogFD, msg, strlen(msg)) < OK) {
2415 @@ -513,27 +516,30 @@
2419 - if (!syslog_open) {
2420 - /* we don't use LOG_PID since the pid passed to us by
2421 - * our client may not be our own. therefore we want to
2422 - * print the pid ourselves.
2425 - openlog(ProgramName, LOG_PID, LOG_CRON);
2428 + /* we don't use LOG_PID since the pid passed to us by
2429 + * our client may not be our own. therefore we want to
2430 + * print the pid ourselves.
2432 + /* SteveG says: That comment is not consistent with the
2433 + code, and makes no sense -- I suspect it's a remnant
2434 + of a cut-n-paster... */
2436 + openlog(ProgramName, LOG_PID, LOG_CRON);
2438 - openlog(ProgramName, LOG_PID);
2439 + openlog(ProgramName, LOG_PID);
2441 - syslog_open = TRUE; /* assume openlog success */
2444 - syslog(LOG_INFO, "(%s) %s (%s)\n", username, event, detail);
2446 + syslog(LOG_INFO, "(%s) %s (%s)", username, event, detail);
2453 fprintf(stderr, "log_it: (%s %d) %s (%s)\n",
2454 - username, pid, event, detail);
2455 + username, xpid, event, detail);
2459 @@ -541,10 +547,15 @@
2463 +#if defined(LOG_FILE)
2469 +#if defined(SYSLOG)
2475 @@ -604,8 +615,10 @@
2478 } else { /* parity character */
2479 - sprintf(dst, "\\%03o", ch);
2481 + /* well, the following snprintf is paranoid, but that will
2482 + * keep grep happy */
2483 + snprintf(dst, 5, "\\%03o", ch);
2488 @@ -622,39 +635,50 @@
2490 register char *dst = malloc(len*4 + 1);
2492 - mkprint(dst, src, len);
2494 + mkprint(dst, src, len);
2501 -/* Sat, 27 Feb 93 11:44:51 CST
2502 - * 123456789012345678901234567
2503 +/* Sat, 27 Feb 1993 11:44:51 -0800 (CST)
2504 + * 1234567890123456789012345678901234567
2510 - time_t t = clock ?*clock :time(0L);
2511 + static char ret[64]; /* zone name might be >3 chars */
2512 + time_t t = clock ? *clock : time(NULL);
2513 struct tm *tm = localtime(&t);
2514 - static char ret[30]; /* zone name might be >3 chars */
2516 - (void) sprintf(ret, "%s, %2d %s %2d %02d:%02d:%02d %s",
2517 - DowNames[tm->tm_wday],
2519 - MonthNames[tm->tm_mon],
2527 + int hours = tm->tm_gmtoff / 3600;
2528 + int minutes = (tm->tm_gmtoff - (hours * 3600)) / 60;
2531 + minutes = -minutes;
2533 + /* Defensive coding (almost) never hurts... */
2534 + len = strftime(ret, sizeof(ret), "%a, %e %b %Y %T ????? (%Z)", tm);
2540 + qmark = strchr(ret, '?');
2541 + if (qmark && len - (qmark - ret) >= 6) {
2542 + snprintf(qmark, 6, "% .2d%.2d", hours, minutes);
2547 #endif /*MAIL_DATE*/
2550 -#ifdef HAVE_SAVED_SUIDS
2551 +#ifdef HAVE_SAVED_UIDS
2552 static int save_euid;
2553 int swap_uids() { save_euid = geteuid(); return seteuid(getuid()); }
2554 int swap_uids_back() { return seteuid(save_euid); }
2555 --- cron-3.0pl1.orig/pathnames.h
2556 +++ cron-3.0pl1/pathnames.h
2558 * $Id: cron_3.0pl1-72.patch,v 1.1 2004-07-21 08:58:06 hackbard Exp $
2561 -#if (defined(BSD)) && (BSD >= 199103) || defined(__linux) || defined(AIX)
2562 +#if (defined(BSD)) && (BSD >= 199103) || defined(__linux__) || defined(AIX)
2567 * to; SPOOL_DIR, ALLOW_FILE, DENY_FILE, and LOG_FILE
2568 * are all relative to this directory.
2570 -#define CRONDIR "/var/cron"
2571 +#define CRONDIR "/var/spool/cron"
2574 /* SPOOLDIR is where the crontabs live.
2576 * newer than they were last time around (or which
2577 * didn't exist last time around...)
2579 -#define SPOOL_DIR "tabs"
2580 +#define SPOOL_DIR "crontabs"
2582 /* undefining these turns off their features. note
2583 * that ALLOW_FILE and DENY_FILE must both be defined
2585 * LOG_FILE or SYSLOG is defined, we don't log. If
2586 * both are defined, we log both ways.
2589 +#define ALLOW_FILE "/etc/cron.allow" /*-*/
2590 +#define DENY_FILE "/etc/cron.deny" /*-*/
2592 #define ALLOW_FILE "allow" /*-*/
2593 #define DENY_FILE "deny" /*-*/
2594 -#define LOG_FILE "log" /*-*/
2596 +/* #define LOG_FILE "log" -*/
2598 /* where should the daemon stick its PID?
2602 # define PIDDIR "/etc/"
2604 -#define PIDFILE "%scron.pid"
2605 +#define PIDFILE "%scrond.pid"
2607 /* 4.3BSD-style crontab */
2608 #define SYSCRONTAB "/etc/crontab"
2611 + /* where package specific crontabs live */
2612 +#define SYSCRONDIR "/etc/cron.d"
2614 /* what editor to use if no EDITOR or VISUAL
2615 * environment variable specified.
2617 -#if defined(_PATH_VI)
2618 +#if defined(DEBIAN)
2619 +# define EDITOR "/usr/bin/editor"
2620 +#elif defined(_PATH_VI)
2621 # define EDITOR _PATH_VI
2623 # define EDITOR "/usr/ucb/vi"
2626 #ifndef _PATH_DEFPATH
2627 # define _PATH_DEFPATH "/usr/bin:/bin"
2630 +#ifndef _PATH_DEFPATH_ROOT
2631 +# define _PATH_DEFPATH_ROOT "/usr/sbin:/usr/bin:/sbin:/bin"
2633 --- cron-3.0pl1.orig/popen.c
2634 +++ cron-3.0pl1/popen.c
2636 #endif /* not lint */
2639 -#include <sys/signal.h>
2640 +#include <signal.h>
2642 +#if defined(BSD) || defined(POSIX)
2647 +#define MAX_ARGS 100
2648 #define WANT_GLOBBING 0
2655 -cron_popen(program, type)
2656 +cron_popen(program, type, e)
2657 char *program, *type;
2665 + char *argv[MAX_ARGS + 1];
2670 extern char **glob(), **copyblk();
2673 - if (*type != 'r' && *type != 'w' || type[1])
2674 + if ((*type != 'r' && *type != 'w') || type[1])
2681 /* break up string into pieces */
2682 - for (argc = 0, cp = program;; cp = NULL)
2683 + for (argc = 0, cp = program; argc < MAX_ARGS; cp = NULL)
2684 if (!(argv[argc++] = strtok(cp, " \t\n")))
2686 + argv[MAX_ARGS] = NULL;
2689 /* glob each piece */
2690 @@ -114,6 +121,20 @@
2692 (void)close(pdes[1]);
2694 + /* Lose root privilege */
2696 +# if defined(BSD) || defined(POSIX)
2697 + initgroups(env_get("LOGNAME", e->envp), e->gid);
2699 + if (setuid(e->uid) !=0) {
2701 + snprintf(msg, 256, "popen: setuid(%lu) failed: %s",
2702 + (unsigned long) e->uid, strerror(errno));
2703 + log_it("CRON",getpid(),"error",msg);
2706 + chdir(env_get("HOME", e->envp));
2709 execvp(gargv[0], gargv);
2711 --- cron-3.0pl1.orig/user.c
2712 +++ cron-3.0pl1/user.c
2718 + char **envp, **tenvp;
2720 if (!(file = fdopen(crontab_fd, "r"))) {
2721 perror("fdopen on crontab_fd in load_user");
2724 /* file is open. build user entry, then read the crontab file.
2726 - u = (user *) malloc(sizeof(user));
2727 - u->name = strdup(name);
2728 + if ((u = (user *) malloc(sizeof(user))) == NULL) {
2732 + if ((u->name = strdup(name)) == NULL) {
2740 * init environment. this will be copied/augmented for each entry.
2742 - envp = env_init();
2743 + if ((envp = env_init()) == NULL) {
2755 - envp = env_set(envp, envstr);
2756 + if ((tenvp = env_set(envp, envstr))) {
2766 --- cron-3.0pl1.orig/debian/README.anacron
2767 +++ cron-3.0pl1/debian/README.anacron
2769 +To ease coordination with anacron, the invocation of the run-parts for
2770 +the /etc/cron.daily, /etc/cron.weekly, and /etc/cron.monthly directories
2771 +was changed to the form
2773 + test -e /usr/sbin/anacron || run-parts --report /etc/cron.daily
2775 +What this means is that if anacron has been installed, it will
2776 +be responsible for running those scripts. This is the standard
2777 +configuration of anacron: if you simply install both cron and anacron,
2778 +things will work as expected.
2780 +However, if you have modified your anacron configuration
2781 +(/etc/anacrontab), you may need to re-adjust it in order to accommodate
2783 --- cron-3.0pl1.orig/debian/README.debian
2784 +++ cron-3.0pl1/debian/README.debian
2787 +----------------------
2789 +This is the Debian GNU/Linux prepackaged version of Paul Vixie's cron
2792 +This package was put together by Ian Jackson <iwj10@cus.cam.ac.uk>,
2793 +from the standard sources to 3.0pl1, as posted to comp.sources.unix.
2794 +Ian obtained them from
2795 +src.doc.ic.ac.uk:/usenet/comp.sources.unix/volume27/vixie-cron.
2797 +The changes are essentially the configuration for Debian Linux in the
2798 +Makefile and pathnames.h, and the addition of support for the Debian
2799 +package maintenance scheme in the form of various files (now in the
2802 +The `checksecurity' script installed in /usr/sbin in the binary distribution
2803 +(found in ./debian in the source) was (probably) written by Ian Jackson,
2804 +and has been modified by Steve Greenland.
2806 +File locations that are different than that indicated in
2807 +the cron distributions README:
2809 +user crontabs: /var/spool/cron/crontabs/*
2810 +log file: /var/log/cron.log
2811 +allow file: /etc/cron.allow
2812 +deny file: /etc/cron.deny
2814 +Note that the location of the log file can be changed via syslog.conf.
2816 +1998: Added reading of crontab fragments from /etc/cron.d to support
2817 +other Debian package cron requirements. Files follow /etc/crontab
2818 +format (i.e. with user field), must meet run-parts(8) naming
2819 +convention (alphanumeric, underscore, hyphen only).
2821 +This package is now maintained by Steve Greenland
2822 +<stevegr@master.debian.org>.
2824 --- cron-3.0pl1.orig/debian/changelog
2825 +++ cron-3.0pl1/debian/changelog
2827 +cron (3.0pl1-72) unstable; urgency=low
2829 + * Add type usbdevfs to skipped "file systems" (this is /proc/bus/usb)
2830 + (closes: #113186,#113187)
2831 + * Removed 'xfs' from list of skipped file system types. Unfortunately,
2832 + it appears to be used by both the arla network file system and the SGI
2833 + XFS filesystem, and I must make the conservative choice. (closes: #113234)
2834 + * Remove extra diff in checksecurity. (closes: 113950)
2835 + * Add type none to skipped "file systems" (--bind mounts) (closes: #111395)
2837 + -- Steve Greenland <stevegr@debian.org> Mon, 1 Oct 2001 07:46:34 -0500
2839 +cron (3.0pl1-71) unstable; urgency=medium
2841 + * Fixed nasty typo in checksecurity. (closes: #112156)
2842 + * Note to release manager: either -71 should go into woody,
2845 + -- Steve Greenland <stevegr@debian.org> Thu, 13 Sep 2001 16:39:25 -0500
2847 +cron (3.0pl1-70) unstable; urgency=medium
2849 + * Catch full disk when writing new crontab. (closes: #110612)
2850 + * Don't modify backup file modes if no change (to prevent misleading
2851 + time mods). (closes: #104093)
2852 + * Remove obsolete reference to /bin/mail in crontab.5. (closes: #110962)
2853 + * Add Marc Merlin's checksecurity patches with more configuration
2854 + options. (closes: #89547, #63445)
2855 + * Make all setuid.{today,yesterday,etc.} files group adm. (closes: #109520)
2857 + -- Steve Greenland <stevegr@debian.org> Fri, 7 Sep 2001 18:27:37 -0500
2859 +cron (3.0pl1-69) unstable; urgency=low
2861 + * Don't run checksecurity on any partition mount nosuid or noexec.
2863 + * Don't run on devpts, either.
2865 + -- Steve Greenland <stevegr@debian.org> Sun, 20 May 2001 13:48:15 -0500
2867 +cron (3.0pl1-68) unstable; urgency=low
2869 + * Finally tracked down the problem with @{reboot,hourly,etc.} commands
2870 + in the root crontabs (/etc/crontab, /etc/cron.d/*) (closes:#62141, #84727)
2871 + * Minor cosmetic cleanup in lost+found output, from Matthijs Melchior
2874 + -- Steve Greenland <stevegr@debian.org> Sat, 19 May 2001 17:37:52 -0500
2876 +cron (3.0pl1-67) unstable; urgency=high
2878 + * With crontab -e, don't give uid root on re-edit.
2880 + -- Steve Greenland <stevegr@debian.org> Sun, 6 May 2001 11:41:50 -0500
2882 +cron (3.0pl1-66) unstable; urgency=low
2884 + * The "Julian Gilbey has been spending too much time proofreading"
2885 + release. Remove hyphens in cron.init (closes:#91323)
2886 + * change log_it() to open and close syslog every time, remove SIGPIPE
2887 + catcher, etc., all in attempt to keep PAM happy.
2888 + * Added original location to copyright file (closes:#88507)
2889 + * Allocate username dynamically in crontab.c (closes:#89040,#62268)
2890 + * Remove pam_limits.so from cron.pam file.
2892 + -- Steve Greenland <stevegr@debian.org> Tue, 27 Mar 2001 18:04:16 -0600
2894 +cron (3.0pl1-65) unstable; urgency=high
2896 + * Close reboot file /var/run/crond.reboot after creating it, duh. Leaving
2897 + it open allowed possible writes from cron jobs.
2899 + -- Steve Greenland <stevegr@debian.org> Mon, 26 Feb 2001 09:47:34 -0600
2901 +cron (3.0pl1-64) unstable; urgency=high
2902 + * The "President's Birthday" release.
2903 + * Add checks for setuid() failures, to avoid running user jobs as root.
2904 + (closes:#85609, #86775)
2905 + * Add portability flag -P to df (in /etc/cron.daily/standard) to
2906 + avoid problem with long device names. (closes:#86851)
2907 + * Convert from suidmanager to dpkg --statoverride.
2908 + * Remove unnecessary dependency on bsdutils (it's Essential)
2909 + * Change compat.h to not cause inclusion of sys/time.h (instead of
2910 + time.h), due to recent change in glibc. Why it was doing this, I have
2913 + -- Steve Greenland <stevegr@debian.org> Wed, 21 Feb 2001 16:26:57 -0600
2915 +cron (3.0pl1-63) unstable; urgency=medium
2917 + * Fix mistaken diagnostic in crontab ("Reached end of file
2918 + while reading environment").
2919 + * Fix "Too many arguments to [" error in postinst. (closes:#79725)
2921 + -- Steve Greenland <stevegr@debian.org> Sun, 28 Jan 2001 12:00:55 -0600
2923 +cron (3.0pl1-62) unstable; urgency=medium
2925 + * Change tracking of crontab directory mod times to deal with directories
2926 + with mtimes in the future. Thanks to Florian Lohoff for tracking down
2927 + the cause of this rare yet long-standing bug.
2928 + (closes:#51202, #57356, #64198, #77353)
2929 + * Run @reboot jobs only on reboot instead of cron restart.
2930 + (closes:#74762, #77563)
2931 + * Clarify which directory the lost+found files are in.
2932 + * Protect against reading other people's crontabs via temp file symlink
2935 + -- Steve Greenland <stevegr@debian.org> Sat, 27 Jan 2001 17:01:43 -0600
2937 +cron (3.0pl1-61) unstable; urgency=high
2939 + * Fix usage message in cron.init.
2940 + * Use pam only on non-Hurd. (closes:#75408)
2941 + * Move dpkg status backups to /var/backups.
2942 + * Apply security fix for temp file attack, thanks to Daniel Jacobowitz.
2943 + * Made /etc/pam.d/cron a conffile.
2945 + -- Steve Greenland <stevegr@debian.org> Fri, 17 Nov 2000 16:06:03 -0600
2947 +cron (3.0pl1-60) unstable; urgency=low
2949 + * Re-set log to LOG_CRON after PAM changes it to LOG_AUTH.(closes:#70028)
2951 + -- Steve Greenland <stevegr@debian.org> Thu, 31 Aug 2000 14:37:44 -0500
2953 +cron (3.0pl1-59) unstable; urgency=low
2955 + * Fixed typo of @cmp in standard.daily (closes:#69921,#69937,#69956)
2956 + * Add /etc/pam.d/cron, using standard Unix authorizations (closes:#69939)
2958 + -- Steve Greenland <stevegr@debian.org> Fri, 25 Aug 2000 14:02:47 -0500
2960 +cron (3.0pl1-58) unstable; urgency=low
2962 + * Fix use of PATH_MAX/MAXPATHLEN in database.c and other HURD issues
2964 + * Look in all (ext2) lost+found directories, not just
2965 + /lost+found (closes:#66629)
2966 + * Cosmetic changes to daily/standard (closes:#65078)
2967 + * Use diff -u0 in checksecurity to avoid useless context (closes:#60919)
2968 + * Note uppercasing of child processes in cron.8 (closes:#62103)
2969 + * Added Topi Mitterands PAM support patch - Thanks! (closes:#68366,#67586)
2970 + * Fix segfault in crontab -l (closes:#53735)
2971 + * Added Build-Depends.
2972 + * Added support for DEB_BUILD_OPTIONS, changed default compile to '-02 -Wall'
2973 + * Fixed various complaints generated by -Wall :-), except 'rcsid unused'
2975 + -- Steve Greenland <stevegr@debian.org> Wed, 23 Aug 2000 16:20:39 -0500
2977 +cron (3.0pl1-57) frozen unstable; urgency=low
2979 + * Release Manager: 61296 is RC bug;
2980 + * Change lockfile-progs "Depends" to "Suggests" (policy violation),
2981 + only try to use lockfile-create in /etc/cron.daily/standard if it is
2982 + installed (closes:#61296)
2984 + -- Steve Greenland <stevegr@debian.org> Wed, 29 Mar 2000 20:12:06 -0600
2986 +cron (3.0pl1-56) frozen unstable; urgency=medium
2988 + * Release Manager: 59115 is RC bug.
2989 + * set backup password files to root-only rw (closes:#59115)
2990 + * Fixed missing ntfs in checksecurity.conf (closes:#56939)
2992 + -- Steve Greenland <stevegr@debian.org> Mon, 28 Feb 2000 19:16:20 -0600
2994 +cron (3.0pl1-55) unstable; urgency=low
2996 + * Changed __linux feature checks to __linux__ (closes:#50240)
2997 + * Added '-u' to diff in checksecurity (closes:#51679)
2998 + * Moved checksecurity LOGDIR (formerly LOG) setting to config
2999 + file (closes:#49683)
3000 + * Fixed removal of lockfile in cron.daily/standard.
3002 + -- Steve Greenland <stevegr@debian.org> Sat, 18 Dec 1999 18:53:29 -0600
3004 +cron (3.0pl1-54) unstable; urgency=low
3006 + * Fixed spelling in checksecurity.8 (closes:#45281)
3007 + * Only look in /lost+found if it exists (closes:#46389)
3008 + * Only run @weekly jobs once a week (was looking at dom with OR
3009 + rather than AND.) (closes:#49437)
3010 + * Don't run more than one instance of /etc/cron.daily/standard (closes:#45487)
3011 + * Removed extra generation of TSTP in crontab -e. (closes:#48542)
3013 + -- Steve Greenland <stevegr@debian.org> Sun, 7 Nov 1999 15:09:48 -0600
3015 +cron (3.0pl1-53) unstable; urgency=medium
3017 + * Applied OpenBSD patches supplied Topi Miettinen. Big change is
3018 + better handling of timekeeping (in particular, changes to/from daylight
3019 + savings time) (closes:#8499).
3020 + * Redirect stdin, stdout, and stderr to /dev/null.
3021 + (closes:#37189, #23231, #30653).
3022 + * Fixed bit_set()/bit_nset() confusion that caused @hourly to not work, so
3023 + that functionality is now documented (closes:#43282).
3024 + * Changed warrantee to warranty in debian/copyright (but it's still
3025 + misspelled in the source files) (closes:#40312)
3026 + * Adjust checksecurity and cron_daily/standard to get consistent owner/perms
3027 + on /var/log/setuid* files. (closes:#15295)
3028 + * Add 'coda' to the list of nfs/afs like file systems in checksecurity.conf
3030 + * Fix version comparison to use dpkg --compare-versions, which is what I
3031 + should have done in the first place (closes:#42454)
3032 + * Add 'xfs' to the list of nfs/afs like file systems in checksecurity.conf,
3033 + as it appears that xfs==arla and arla==xfs. If there are other file systems
3034 + that show up as 'xfs', please let me know (closes:#37523)
3035 + * Don't rotate wtmp and btmp (closes:#42301).
3037 + -- Steve Greenland <stevegr@debian.org> Sat, 11 Sep 1999 18:42:37 -0500
3039 +cron (3.0pl1-52) unstable; urgency=high
3041 + * Patch to fix "Reverse DoS": user could send arbitrary options to
3042 + sendmail via MAILTO variable. Fix by not allowing spaces or leading
3043 + dashes in MAILTO, and run sendmail as user, not root.
3045 + -- Steve Greenland <stevegr@debian.org> Sun, 29 Aug 1999 21:50:28 -0500
3047 +cron (3.0pl1-51) unstable; urgency=low
3049 + * Changed default of "crontab -l" to NOT list the extra header lines. May
3050 + obtain original behaviour by setting "CRONTAB_NOHEADER=N".
3051 + * Fixed comment in misc.c that accidentally cause the SIGPIPE handler to
3052 + be reset more often than necessary.
3053 + * Don't checksecurity on ntfs file systems (closes:#33079)
3054 + * Added '-i' flag to sendmail command (closes:#36338)
3055 + * Added check for files in /lost+found (closes:#29791)
3056 + * Added preferential invocation of anacron for cron.{daily,weekly,monthly}
3058 + -- Steve Greenland <stevegr@master.debian.org> Thu, 27 May 1999 17:37:54 -0500
3060 +cron (3.0pl1-50) frozen unstable; urgency=low
3062 + * Fixed rules file *again* so that crontab suidness doesn't get
3063 + stepped on by debhelper under certain kernel versions.
3065 + -- Steve Greenland <stevegr@debian.org> Sat, 9 Jan 1999 14:17:09 -0600
3067 +cron (3.0pl1-49) frozen unstable; urgency=low
3069 + * Check for /etc/shadow and /etc/gshadow separately (closes:Bug#30232)
3071 + -- Steve Greenland <stevegr@master.debian.org> Wed, 2 Dec 1998 21:30:00 -0600
3073 +cron (3.0pl1-48) frozen unstable; urgency=low
3075 + * Fixed rules file so that crontab doesn't get suid bit removed by latest
3076 + version of debhelper. (closes:Bug#29683)
3078 + -- Steve Greenland <stevegr@master.debian.org> Mon, 30 Nov 1998 21:10:00 -0600
3080 +cron (3.0pl1-47) frozen unstable; urgency=high
3082 + * Removed close of {stdin,stdout,stderr}, as it appears that
3083 + some cron users expect it.
3085 + -- Steve Greenland <stevegr@master.debian.org> Mon, 2 Nov 1998 09:25:44 -0600
3087 +Cron (3.0pl1-46) frozen unstable; urgency=medium
3089 + * changed mention of /var/spool/crontabs to /var/spool/cron/crontabs, and
3090 + added example /etc/crontab. (closes:Bug#28458,Bug#23101)
3091 + * Incorporated buffer overflow patches. (closes:Bug#26705,Bug#26749)
3092 + * Added backup of /etc/shadow and /etc/gshadow in cron.daily/standard.
3093 + (closes:Bug#25853)
3094 + * Better daemonization (close stdin,stdout,stderr). (closes:Bug#23231)
3095 + * Do cron.daily a little earlier, try to avoid overlap with cron.weekly.
3096 + (closes:Bug#23023)
3097 + * Added note in crontab.1 and crontab.5 about trailing newline requirement.
3098 + (closes:Bug#16132)
3100 + -- Steve Greenland <stevegr@master.debian.org> Sun, 1 Nov 1998 19:10:45 -0600
3102 +cron (3.0pl1-45) frozen unstable; urgency=high
3104 + * Updated README and README.Debian w.r.t. file locations.
3105 + * Updated crontab.1 w.r.t. location of allow and deny files.
3106 + * Fixed problem in postinst when new install (instead of upgrade)
3107 + (closes:Bug#21426)
3108 + * Smarter algorithm for checking /etc/cron.d for changes, no longer
3109 + spins up laptop disks every minute. Thanks to Alexander "Shurik"
3110 + Shumakovitch for the fix.
3111 + * Re-did checksecurity to only report NFS/AFS insecure mounts
3112 + instead of running find on them (suggestion from Gregory Stark).
3114 + -- Steve Greenland <stevegr@master.debian.org> Sun, 26 Apr 1998 13:41:51 -0500
3116 +cron (3.0pl1-44) unstable; urgency=low
3118 + * Fixed standards version reference.
3119 + * Fixed init script "comment", sigh. Let this be a warning to you: NEVER EVER
3120 + change a file with doing a complete test, even if it is "just a comment".
3121 + (closes:Bug#19466,Bug#19492,Bug#19479,Bug#19595,Bug#19725,Bug#19840,
3122 + Bug#19845,Bug19852). Sheesh.
3124 + -- Steve Greenland <stevegr@master.debian.org> Tue, 17 Mar 1998 21:55:03 -0600
3126 +cron (3.0pl1-43) unstable; urgency=medium
3128 + * Removed support for TMPDIR. This is due to the problem it causes
3129 + with emacs -- emacs does different things with it's backup files
3130 + depending on whether or not the file is in /tmp. Emacs probably ought
3131 + to use TMPDIR instead of /tmp in its check. I've opened a "wishlist"
3132 + bug for crontab to support TMPDIR.
3133 + (closes: Bug#15985)
3134 + * When USE_SIGCHLD is defined, before running user process, set handling
3135 + for SIGCHLD to SIG_DFL, not SIG_IGN. Despite documentation that the
3136 + default for SIGCHLD is ignore, the behaviour is different.
3137 + (closes:Bug#17564,Bug#9075,Bug#16436,Bug#17814)
3138 + * Moved allow and deny files from /var/spool/cron to /etc/cron.{allow,deny}
3139 + (closes:Bug#14970)
3140 + * filenames in /etc/cron.d must comply with run-parts naming convention -
3141 + alpha-numeric, underscore, or hyphen. This ensures that conffile
3142 + remains (e.g. package.dpkg-dist) files don't get run.
3143 + * removed cronanacron command from /etc/crontab and distribution --
3144 + replaced by /etc/cron.d/anacron file (from anacron package, not cron).
3145 + * Documented /etc/cron.d dir in manpage and readme.debian
3146 + * modified checksecurity.conf to not check auto file systems.
3148 + * crontab -u `whoami` now works. (closes:Bug#8702)
3149 + * documented CRONTAB_NOHEADER in crontab.1
3150 + * /etc/crontab now uses run-parts(8) --report switch. (closes:Bug#18273)
3151 + * fixed initialization of oact in misc.c. (closes:Bug#17134)
3152 + * converted to use debhelper rather than debmake.
3153 + * changed date format in checksecurity so that we don't get false positives
3154 + after six months. (closes:Bug#19025)
3155 + * remove /etc/cron.{allow,deny} on purge
3157 + -- Steve Greenland <stevegr@master.debian.org> Mon, 9 Mar 1998 01:31:13 -0600
3159 +cron (3.0pl1-42) unstable; urgency=low
3161 + * Don't output header on 'crontab -l' if CRONTAB_NOHEADER is 'Y' (Bug#15642)
3162 + * Read files in /etc/cron.d in addition to /etc/crontab (Bug#16628,
3165 + -- Steve Greenland <stevegr@master.debian.org> Sun, 11 Jan 1998 18:32:26 -0600
3167 +cron (3.0pl1-41) unstable; urgency=low
3169 + * Updated crontab to use /usr/bin/editor if EDITOR and VISUAL undefined.
3170 + * Added support for TMPDIR from crontab (Bug#9309)
3171 + * Compress /usr/doc/cron/changelog.Debian -- this time for sure! (Bug#15296)
3173 + -- Steve Greenland <stevegr@master.debian.org> Fri, 28 Nov 1997 13:47:03 -0600
3175 +cron (3.0pl1-40) unstable; urgency=low
3177 + * Correct directory reference in standard.monthly to /var/log
3178 + (Bug#12315, Bug#13466)
3179 + * Added -DUSE_SIGCHLD to defs, needed for alpha (Bug#12855,Bug#8611).
3180 + May also fix Bug#9075.
3181 + * Changed check for suidmanager (Bug#9326)
3182 + * Checksecurity no longer checks fat or vfat filesystems (Bug#8845,
3184 + * Changed spaces in crontab to <TAB>, appearance only (Bug#13369)
3185 + * Removed bashism from standard.daily and checksecurity (Bug#9908,
3187 + * Added CHECKSECURITY_DISABLE flag to checksecurity.conf.
3188 + * Get the changelog names correct (Bug#14618)
3189 + * Correct day-of-month and month ranges in crontab.5 (Bug#15073)
3191 + -- Steve Greenland <stevegr@master.debian.org> Sun, 23 Nov 1997 22:58:05 -0600
3193 +cron (3.0pl1-39) unstable; urgency=low
3195 + * Added configuration variable to eliminate error messages from
3196 + checksecurity's find command
3197 + * Better integration with anacron: suggest anacron, call anacron
3198 + on a regular basis so that it can keeps it's status up-to-date. New
3199 + file /usr/sbin/cronanacron.
3200 + * Call savelog for /var/adm/btmp from /etc/cron.monthly/standard.
3202 + -- Steve Greenland <stevegr@master.debian.org> Sun, 24 Aug 1997 18:52:55 -0500
3204 +cron (3.0pl1-38) stable unstable; urgency=low
3206 + * When upgrading from -36 or -36.1, stop old cron daemon
3207 + in preinst, because the prerm's in those versions doesn't.
3208 + * Follow console message standard.
3210 + -- Steve Greenland <stevegr@master.debian.org> Sat, 18 Jan 1997 15:34:42 -0600
3212 +cron (3.0pl1-37) stable unstable; urgency=medium
3214 + * Corrected postinst,prerm, and postrm scripts -- Installs and
3215 + removes rc.d links, and re-starts cron after install.
3216 + * More fixes from the BSD crew, sent to me by Marek Michalkiewicz: mostly
3217 + checks for null pointers, but also a few Makefile fixes, and at least
3218 + one potential buffer overrun (but I know of no exploits).
3219 + * Left in suidmanager stuff, but corrected default permission to 4755,
3220 + per Debian standards.
3221 + * Added CHANGES file (as /usr/doc/cron/changelog.upstream.gz) to
3222 + distribution. Added upstream README to distribution.
3223 + * Moved files out of ./debian/extra into ./debian because dpkg-source
3224 + cannot deal with createing directories. Hmmph.
3225 + * Removed filereaper reference from standard.daily
3227 + -- Steve Greenland <stevegr@master.debian.org> Sun, 5 Jan 1997 18:23:14 -0600
3229 +cron (3.0pl1-36.1) stable unstable; urgency=HIGH
3231 + * Mended `find' invocation in debian/rules.
3232 + * Serious security hole (buffer overrun) fixed.
3233 + * Silly suidmanager stuff added by debmake. Pah.
3235 + -- Jon Rabone <jkr@master.debian.org> Wed, 18 Dec 1996 21:38:33 +0000
3237 +cron (3.0pl1-36) frozen unstable; urgency=low
3239 + * Removed DEBUG logging about SIGPIPE -- it's generated by every
3240 + child once syslogd has been restarted.
3242 + -- Steve Greenland <stevegr@master.debian.org> Mon, 2 Dec 1996 01:41:16 -0600
3244 +cron (3.0pl1-35) frozen unstable; urgency=low
3246 + * Converted to new source format
3247 + * Added code in misc.c to catch SIGPIPE and re-open syslog. This
3248 + is all in #if defined(DEBIAN), and should be removed when syslog(3)
3249 + is fixed. Also added -DDEBIAN to build commands in Makefile.
3251 + -- Steve Greenland <steveg@neuromancer.dmccorp.com> Sun, 1 Dec 1996 16:21:52 -0600
3254 --- cron-3.0pl1.orig/debian/checksecurity
3255 +++ cron-3.0pl1/debian/checksecurity
3258 +# Security checks script - run daily out of the system crontab
3262 +PATH=/sbin:/bin:/usr/sbin:/usr/bin
3268 +. /etc/checksecurity.conf
3270 +if [ "$CHECKSECURITY_DISABLE" = "TRUE" ] ; then
3274 +if [ -z "$CHECKSECURITY_GREPOUT" ]; then
3275 + CHECKSECURITY_GREPOUT="$^"
3278 +TMPSETUID=${LOGDIR:=/var/log}/setuid.new.tmp
3279 +TMPDIFF=${LOGDIR:=/var/log}/setuid.diff.tmp
3282 +# Check for NFS/AFS mounts that are not nosuid/nodev
3284 +if [ ! "$CHECKSECURITY_NONFSAFS" = "TRUE" ] ; then
3285 + # temporarily disable error exit, as grep may give errors if no nfs/afs
3288 + nfssys=`mount | grep -E 'nfs|afs' | grep -vE '\(.*(nosuid|noexec).*nodev.*\)'`
3289 + nfssyscnt=`echo $nfssys |grep "[a-z]"| wc -l`
3291 + if [ $nfssyscnt -gt 0 ] ; then
3292 + echo "The following NFS or AFS filesystems are mounted insecurely:"
3296 + echo "If this is intentional and you have supreme confidence in the"
3297 + echo "security of the server for these file systems, you may disable"
3298 + echo "this message by editing the value of CHECKSECURITY_NONFSAFS in"
3299 + echo "the file /etc/checksecurity.conf."
3303 +if [ "$CHECKSECURITY_NOFINDERRORS" = "TRUE" ] ; then
3309 +# This is the only way to pass '*' through a variable (NODEVDIRS) -- Marc
3311 +find `mount | grep -vE "$CHECKSECURITY_FILTER" | cut -d ' ' -f 3` \
3312 + -xdev \( $CHECKSECURITY_PATHFILTER \) -prune -o \
3313 + \( -type f -perm +06000 -o \
3314 + \( \( -type b -o -type c \) -a -not \( $CHECKSECURITY_DEVICEFILTER \) \) \) \
3315 + -printf "%8i %5m %3n %-10u %-10g %9s %t %h/%f\n" | sort >$TMPSETUID
3318 +if [ "$CHECKSECURITY_NOFINDERRORS" = "TRUE" ] ; then
3324 +test -f setuid.today || touch setuid.today
3326 +if cmp -s setuid.today $TMPSETUID >/dev/null
3330 + diff -u0 setuid.today $TMPSETUID >> $TMPDIFF || [ $? = 1 ]
3331 + echo "`hostname` changes to setuid programs and devices:"
3334 + if [ `cat $TMPDIFF | wc -l` -gt 0 -a ! -z "$CHECKSECURITY_EMAIL" ]; then
3335 + /usr/bin/mail -s "Setuid changes for `hostname -f` on `date '+%D %T'`" $CHECKSECURITY_EMAIL < $TMPDIFF
3338 + mv setuid.today setuid.yesterday
3339 + mv $TMPSETUID setuid.today
3340 + chown root.adm setuid.today
3344 --- cron-3.0pl1.orig/debian/checksecurity.8
3345 +++ cron-3.0pl1/debian/checksecurity.8
3348 +.TH CHECKSECURITY 8 "2 February 1997" "Debian Linux"
3350 +checksecurity \- check for changes to setuid programs
3356 +command scans the mounted files systems (subject to the filter defined
3357 +in /etc/checksecurity.conf) and compares the list of setuid programs to the
3358 +list created on the previous run. Any changes are printed to standard
3359 +output. Also, it generates a list of
3363 +filesystems that are mounted insecurely (i.e. they are missing the
3374 +on a daily basis, and the output stored in /var/log/setuid.changes.
3377 +.B checksecurity.conf
3378 +file defines several configuration variables:
3379 +.BR CHECKSECURITY_FILTER ,
3380 +.BR CHECKSECURITY_NOFINDERRORS ,
3381 +.BR CHECKSECURITY_DISABLE ,
3382 +.BR CHECKSECURITY_NONFSAFS ,
3383 +.BR CHECKSECURITY_EMAIL ,
3384 +.BR CHECKSECURITY_DEVICEFILTER ,
3385 +.BR CHECKSECURITY_PATHFILTER ,
3388 +Each is described below.
3391 +.B CHECKSECURITY_FILTER
3392 +environment variable which is the argument of 'grep -vE' applied to
3395 +command. In other words, the value of
3396 +.B CHECKSECURITY_FILTER
3397 +is a regular expression that removes matching lines from those
3398 +file systems that will be scanned. The default value removes
3399 +all file systems of type
3400 +.I proc, msdos, iso9660, ncpfs, nfs, afs,
3401 +.I smbfs, auto, ntfs, coda
3403 +anything mounted on /dev/fd*, anything mounted
3404 +on /mnt or /amd, and anything mounted with option nosuid or noexec.
3407 +.B checksecurity.conf
3408 +file is sourced from
3410 +so you could do some fairly tricky things to define
3411 +.BR CHECKSECURITY_FILTER .
3414 +.B CHECKSECURITY_NOFINDERRORS
3415 +environment variable, if set to the literal "TRUE", disables
3416 +find errors from checksecurity (actually, it re-routes them to
3421 +.B CHECKSECURITY_DISABLE
3422 +environment variable, if set to the literal "TRUE", disables
3423 +checksecurity entirely, as a sop to those who think it's safe to allow
3424 +random mounting of NFS and AFS disks without the nosuid or noexec flags.
3427 +.B CHECKSECURITY_NONFSAFS
3428 +environment variable, if set to the literal "TRUE", disables the message about
3432 +file systems that are mounted without the
3441 +.B CHECKSECURITY_EMAIL
3442 +variable defines who is sent a copy of the setuid.changes file.
3445 +.B CHECKSECURITY_DEVICEFILTER
3446 +variable specifies a
3448 +clause for which matching block and character device files will not be
3449 +monitored for changing owners and permissions. For example, if you
3450 +didn't want to check for permission changes on tty device files
3451 +beneath /dev, you could set the following:
3454 +CHECKSECURITY_DEVICEFILTER='-path /dev/tty*'
3457 +Note that any added or modified suid programs under that path would
3458 +still be detected. If you want to specify multiple expressions,
3459 +separate them with '-o', but there is no need to surround the whole
3460 +clause with parentheses. To disable this filter, specify it as
3461 +'-false' (which is the default).
3464 +.B CHECKSECURITY_PATHFILTER
3465 +variable specifies a
3467 +clause which will be pruned from the search path.
3468 +.B This means that the entire subtree will be completely skipped.
3472 +CHECKSECURITY_PATHFILTER='-path /var/ftp'
3475 +then the entire /var/ftp tree will be skipped. To disable this filter,
3476 +specify it as '-false' (which is the default).
3479 +sets the name of the directory which stores the files which track
3480 +the permission and ownership changes. By default, they are in
3484 +.I /etc/checksecurity.conf
3485 +checksecurity configuration file
3487 +.I /var/log/setuid.today
3488 +setuid files from the most recent run
3490 +.I /var/log/setuid.yesterday
3491 +setuid files from the previous run
3492 --- cron-3.0pl1.orig/debian/checksecurity.conf
3493 +++ cron-3.0pl1/debian/checksecurity.conf
3496 +# This is the checksecurity script configuration file
3498 +# These configuration variables mabye set:
3500 +# CHECKSECURITY_FILTER
3501 +# CHECKSECURITY_NOFINDERRORS
3502 +# CHECKSECURITY_DISABLE
3503 +# CHECKSECURITY_NONFSAFS
3504 +# CHECKSECURITY_EMAIL
3505 +# CHECKSECURITY_DEVICEFILTER
3506 +# CHECKSECURITY_PATHFILTER
3509 +# Each is described in it's own section below -- search for ####
3510 +# as a section divider.
3514 +# The CHECKSECURITY_FILTER variable is used as an argument to
3515 +# "grep -vE" to filter lines from the output of the "mount"
3518 +# The default is not check the following file systems:
3527 +# type auto (They'll typically be picked up on the nfs branch)
3529 +# type coda (similar to afs)
3531 +# type none (--bind mounts)
3533 +# floppies (i.e. /dev/fd<whatever>)
3534 +# anything on /mnt or /amd
3536 +# Note that behaviour for nfs/afs has changed as of release -45. We
3537 +# no longer run find across nfs/afs disks; instead we simply report
3538 +# afs/nfs disks that are mounted insecurely (without -onosuid|noexec,nodev).
3539 +# You can disable this report by going setting the CHECKSECURITY_NONFSAFS
3542 +# Use temp variables to build up CHECKSECURITY_FILTER, to make it
3543 +# a little more readable.
3545 +CS_NFSAFS='(nfs|afs|coda)'
3546 +# Uncomment the next line to get the old behaviour.
3547 +#CS_NFSAFS='(nfs|afs) \(.*(nosuid|noexec).*nodev.*\)'
3549 +CS_TYPES=' type (auto|proc|msdos|fat|vfat|iso9660|usbdevfs|ncpfs|smbfs|ntfs|devpts|none|'$CS_NFSAFS')'
3551 +CS_OPTS='\(.*(nosuid|noexec).*\)'
3557 +CHECKSECURITY_FILTER="$CS_TYPES|$CS_OPTS|$CS_DEVS|$CS_DIRS"
3559 +# Clear the temporary variables
3561 +unset CS_NFSAFS CS_TYPES CS_DIRS CS_OPTS
3565 +# The CHECKSECURITY_NOFINDERRORS, if set to "TRUE" (case sensitive),
3566 +# redirects any errors from the find command used in checksecurity
3569 +CHECKSECURITY_NOFINDERRORS="FALSE"
3572 +# The CHECKSECURITY_DISABLE, if set to "TRUE" (case sensitive),
3573 +# disables the running of checksecurity
3575 +CHECKSECURITY_DISABLE="FALSE"
3578 +# The CHECKSECURITY_NONFSAFS, if set to "TRUE" (case sensitive),
3579 +# disables the message about insecurely mounted nfs/afs disks
3581 +CHECKSECURITY_NONFSAFS="FALSE"
3584 +# If the CHECKSECURITY_EMAIL is set, the report is mailed to the given
3585 +# address. Note that if you set this, it is *assumed* that you have
3586 +# /usr/bin/mail that accepts -s; the mailx package provides this; or
3587 +# you can install mutt and create a link, or some other
3588 +# alternative. No, I'm not going to fix it to write the appropriate
3589 +# headers and use sendmail (although I'd consider patch), nor am I
3590 +# going to add a {Depends|Recommends|Suggests} to the cron package.
3591 +# Do not submit bugs about this unless you include the above mentioned
3592 +# patch. You enabled this option -- you take responsibility.
3594 +#CHECKSECURITY_EMAIL="root"
3597 +# The CHECKSECURITY_DEVICEFILTER lets you tell find not to report
3598 +# devices in those directories (if you choose the daily Emails,
3599 +# devices like /dev/pts/?, /dev/tty?, or /dev/urandom will change
3600 +# often and clutter your mailbox) Note that these directories are
3601 +# still searched for suid executables. Also not that *something* must
3602 +# be defined, which is why the default is "-false".
3604 +#CHECKSECURITY_DEVICEFILTER="-path /dev/*"
3605 +#CHECKSECURITY_DEVICEFILTER="-path /dev/* -o -path /home/ftp/dev/*"
3606 +CHECKSECURITY_DEVICEFILTER="-false"
3608 +# The CHECKSECURITY_PATHFILTER variable lets you set a pattern of
3609 +# pathnames that you don't want to check at all. You hopefully know
3610 +# what you're doing if you do this :-).
3612 +# CHECKSECURITY_PATHFILTER="-path /dev/rd* -o -path /var/home/ftp*"
3613 +CHECKSECURITY_PATHFILTER="-false"
3616 +# Location of setuid file databases. Probably should
3617 +# be in /var/lib/cron, but I don't want to move them now. After
3618 +# the release, maybe.
3621 --- cron-3.0pl1.orig/debian/conffiles.nopam
3622 +++ cron-3.0pl1/debian/conffiles.nopam
3624 +/etc/checksecurity.conf
3627 +/etc/cron.daily/standard
3628 +/etc/cron.monthly/standard
3629 --- cron-3.0pl1.orig/debian/conffiles.pam
3630 +++ cron-3.0pl1/debian/conffiles.pam
3632 +/etc/checksecurity.conf
3635 +/etc/cron.daily/standard
3636 +/etc/cron.monthly/standard
3638 --- cron-3.0pl1.orig/debian/control
3639 +++ cron-3.0pl1/debian/control
3643 +Priority: important
3644 +Maintainer: Steve Greenland <stevegr@debian.org>
3645 +Standards-Version: 3.5.2
3646 +Build-Depends: debhelper, libpam0g-dev
3650 +Depends: ${shlibs:Depends}, debianutils (>=1.7)
3651 +Recommends: exim | smail | sendmail | mail-transport-agent
3652 +Suggests: anacron (>=2.0-1), logrotate, lockfile-progs
3653 +Conflicts: suidmanager (<< 0.50)
3655 +Description: management of regular background processing
3656 + cron is a background process (`daemon') that runs programs at regular
3657 + intervals (for example, every minute, day, week or month); which
3658 + processes are run and at what times are specified in the `crontab'.
3660 + Users may also install crontabs so that processes are run on
3661 + their behalf, though this feature can be disabled or restricted to
3664 + Output from the commands is usually mailed to the system administrator
3665 + (or to the user in question); you should probably install a mail system
3666 + as well so that you can receive these messages.
3668 + This cron package is configured by default to do various standard
3669 + system maintenance tasks, such as ensuring that logfiles do not
3670 + grow endlessly and overflow the disk.
3672 + The lockfile-progs package is only a "Suggests" because of the poor
3673 + way that dselect handles "Recomments", but I do strongly suggest that
3674 + you install it; it prevents /etc/cron.daily/standard from running multiple
3675 + times if something gets jammed.
3676 --- cron-3.0pl1.orig/debian/copyright
3677 +++ cron-3.0pl1/debian/copyright
3679 +Copyright 1988,1990,1993,1994 by Paul Vixie;
3680 +All rights reserved
3682 +Distribute freely, except: don't remove my name from the source or
3683 +documentation (don't take credit for my work), mark your changes (don't
3684 +get me blamed for your possible bugs), don't alter or remove this
3685 +notice. May be sold if buildable source is provided to buyer. No
3686 +warranty of any kind, express or implied, is included with this
3687 +software; use at your own risk, responsibility for damages (if any) to
3688 +anyone resulting from the use of this software rests entirely with the
3692 +The original source for this package may be obtained from
3693 +ftp://ftp.vix.com/pub/vixie/cron-3.0.
3695 +Modifications for Debian GNU/Linux Copyright 1994 Ian Jackson;
3696 +checksecurity script:
3697 +Copyright (C) 1994 Ian Jackson
3698 +Copyright (C) 1996, 1997, 1998, 1999, 2000 Steve Greenland
3700 +The `checksecurity' script and its associated files (checksecurity.8
3701 +and checksecurity.conf) are free software; you can redistribute it
3702 +and/or modify it under the terms of the GNU General Public License as
3703 +published by the Free Software Foundation; either version 2, or (at
3704 +your option) any later version.
3706 +This program is distributed in the hope that it will be useful, but
3707 +WITHOUT ANY WARRANTY; without even the implied warranty of
3708 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3709 +General Public License for more details.
3711 +A copy of the GNU General Public License is available as
3712 +`/usr/share/common-licenses/GPL' in the
3713 +Debian GNU/Linux distribution or on the World Wide Web
3714 +at `http://www.gnu.org/copyleft/gpl.html'. You can also obtain it by
3715 +writing to the Free Software Foundation, Inc., 59 Temple Place - Suite
3716 +330, Boston, MA 02111-1307, USA.
3718 --- cron-3.0pl1.orig/debian/cron.init
3719 +++ cron-3.0pl1/debian/cron.init
3722 +# Start/stop the cron daemon.
3724 +test -f /usr/sbin/cron || exit 0
3727 +start) echo -n "Starting periodic command scheduler: cron"
3728 + start-stop-daemon --start --quiet --exec /usr/sbin/cron
3731 +stop) echo -n "Stopping periodic command scheduler: cron"
3732 + start-stop-daemon --stop --quiet --exec /usr/sbin/cron
3735 +restart) echo -n "Restarting periodic command scheduler: cron"
3736 + start-stop-daemon --stop --quiet --exec /usr/sbin/cron
3737 + start-stop-daemon --start --quiet --exec /usr/sbin/cron
3740 +reload|force-reload) echo -n "Reloading configuration files for periodic command scheduler: cron"
3741 + # cron reloads automatically
3744 +*) echo "Usage: /etc/init.d/cron start|stop|restart|reload|force-reload"
3749 --- cron-3.0pl1.orig/debian/cron.pam
3750 +++ cron-3.0pl1/debian/cron.pam
3753 +# The PAM configuration file for the cron daemon
3756 +account required pam_unix.so
3757 +auth required pam_unix.so nullok
3758 +auth required pam_env.so
3759 +session required pam_unix.so
3761 --- cron-3.0pl1.orig/debian/crontab.main
3762 +++ cron-3.0pl1/debian/crontab.main
3764 +# /etc/crontab: system-wide crontab
3765 +# Unlike any other crontab you don't have to run the `crontab'
3766 +# command to install the new version when you edit this file.
3767 +# This file also has a username field, that none of the other crontabs do.
3770 +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
3772 +# m h dom mon dow user command
3773 +25 6 * * * root test -e /usr/sbin/anacron || run-parts --report /etc/cron.daily
3774 +47 6 * * 7 root test -e /usr/sbin/anacron || run-parts --report /etc/cron.weekly
3775 +52 6 1 * * root test -e /usr/sbin/anacron || run-parts --report /etc/cron.monthly
3779 --- cron-3.0pl1.orig/debian/dirs
3780 +++ cron-3.0pl1/debian/dirs
3793 +var/spool/cron/crontabs
3794 --- cron-3.0pl1.orig/debian/postinst
3795 +++ cron-3.0pl1/debian/postinst
3800 +update-rc.d cron defaults 89 11 >/dev/null
3801 +# Copy existing allow/deny files
3802 +crondir="/var/spool/cron"
3804 +for fname in allow deny ; do
3805 + if [ -f $crondir/$fname ] ; then
3806 + if [ ! -f $/etc/cron.$fname ] ; then
3807 + mv $crondir/$fname /etc/cron.$fname
3809 + echo "Moving $crondir/$fname to /etc/cron.$fname to comply with Debian policy"
3814 + echo "Both $crondir/$fname and /etc/cron.$fname exist -- cron will"
3815 + echo "use /etc/cron.$fname"
3821 +# Check for upgrades from very old versions
3823 +if [ "$1" = "configure" -a -n "$2" ] && dpkg --compare-versions "$2" lt "3.0pl1-43" ; then
3825 + echo "The format of the setuid.today file (output from checksecurity) has"
3826 + echo "changed. This means that the first run of checksecurity after the "
3827 + echo "upgrade will produce a diff on every every file affected".
3832 +# Move dpkg status file backups, if necessary/possible.
3834 +( cd /var/lib/dpkg ;
3835 +for oldstat in status.yesterday.* ; do
3836 + if [ -f $oldstat ] ; then
3837 + newstat=`echo $oldstat | sed 's/yesterday\.//'`;
3838 + newstat=/var/backups/dpkg.$newstat;
3839 + if [ ! -f $newstat ] ; then
3840 + mv $oldstat $newstat ;
3845 +start-stop-daemon --start --quiet --oknodo --exec /usr/sbin/cron
3848 --- cron-3.0pl1.orig/debian/postrm
3849 +++ cron-3.0pl1/debian/postrm
3853 +if [ $1 = purge ]; then
3854 + update-rc.d cron remove >/dev/null
3855 + rm -f /etc/cron.allow /etc/cron.deny
3858 --- cron-3.0pl1.orig/debian/preinst
3859 +++ cron-3.0pl1/debian/preinst
3863 +# Needed because -36 and -36.1 included bad prerm scripts
3865 +if [ "$1" = "upgrade" -a \( "$2" = "3.0pl1-36" -o "$2" = "3.0pl1-36.1" \) ] ; then
3866 + #kill the running cron
3867 + start-stop-daemon --oknodo --quiet --stop --exec /usr/sbin/cron
3869 --- cron-3.0pl1.orig/debian/prerm
3870 +++ cron-3.0pl1/debian/prerm
3874 +/etc/init.d/cron stop
3877 --- cron-3.0pl1.orig/debian/rules
3878 +++ cron-3.0pl1/debian/rules
3882 +# Rules file for cron
3885 +# Uncomment this to turn on verbose mode.
3886 +#export DH_VERBOSE=1
3888 +DEB_OPTIM= -O2 -Wall
3889 +DEB_INSTALL = install
3890 +DEB_DEBUG_DEFS = -DDEBUGGING=0
3892 +ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
3893 + DEB_OPTIM = -g -Wall
3894 + DEB_DEBUG_DEFS= -DDEBUGGING=1
3896 +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
3900 +# Set system type (Linux, HURD, etc.)
3901 +DEB_HOST_GNU_SYSTEM = $(shell dpkg-architecture -qDEB_HOST_GNU_SYSTEM)
3902 +ifeq ($(DEB_HOST_GNU_SYSTEM), gnu)
3905 + CONFFILES = conffiles.nopam
3907 + PAM_DEFS = -DUSE_PAM
3909 + CONFFILES = conffiles.pam
3919 + # Add here commands to compile the package.
3920 + $(MAKE) OPTIM="$(DEB_OPTIM)" DEBUG_DEFS="$(DEB_DEBUG_DEFS)"
3929 + # Add here commands to clean up after the build process.
3931 + rm -f debian/conffiles
3934 +# Build architecture-independent files here.
3935 +binary-indep: build
3936 +# We have nothing to do by default.
3938 +# Build architecture-dependent files here.
3946 + # Add here commands to install the files into debian/tmp
3947 + $(MAKE) install DESTDIR=`pwd`/debian/tmp OPTIM="$(DEB_OPTIM)" INSTALL="$(DEB_INSTALL)" DEBUG_DEFS="$(DEB_DEBUG_DEFS)"
3948 + install -m 755 debian/checksecurity debian/tmp/usr/sbin/.
3949 + install -m 644 debian/checksecurity.conf debian/tmp/etc/.
3951 + cp -p debian/$(CONFFILES) debian/conffiles
3952 + dh_installdocs FEATURES THANKS README debian/README.anacron
3953 +# dh_installexamples
3956 + dh_installinit --noscripts
3957 + # Can't use dh_installcron because we don't have "normal" naming
3959 + install -m 644 debian/crontab.main debian/tmp/etc/crontab
3960 + install -m 755 debian/standard.daily \
3961 + debian/tmp/etc/cron.daily/standard
3962 + install -m 755 debian/standard.monthly \
3963 + debian/tmp/etc/cron.monthly/standard
3964 + dh_installmanpages crontab.1 crontab.5 cron.8 bitstring.3
3966 + dh_installchangelogs CHANGES
3970 + # dh_suidregister -- deliberately commented out, as it causes
3971 + # /usr/bin/crontab to be shipped non-suid.
3972 + # so does dh_fixperms when not run under fakeroot. sigh.
3973 + chmod u+s debian/tmp/usr/bin/crontab
3982 + @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false
3984 +binary: binary-indep binary-arch
3985 +.PHONY: build clean binary-indep binary-arch binary
3986 --- cron-3.0pl1.orig/debian/standard.daily
3987 +++ cron-3.0pl1/debian/standard.daily
3990 +# /etc/cron.daily/standard: standard daily maintenance script
3991 +# Written by Ian A. Murdock <imurdock@gnu.ai.mit.edu>
3992 +# Modified by Ian Jackson <ijackson@nyx.cs.du.edu>
3993 +# Modified by Steve Greenland <stevegr@debian.org>
3996 +LOCKFILE=/var/lock/cron.daily
4000 +# Avoid running more than one at a time -- could happen if the
4001 +# checksecurity script lands on a network drive.
4004 +if [ -x /usr/bin/lockfile-create ] ; then
4005 + lockfile-create $LOCKFILE
4006 + if [ $? -ne 0 ] ; then
4009 +Unable to run /etc/cron.daily/standard because lockfile $LOCKFILE
4010 +acquisition failed. This probably means that the previous days
4011 +instance is still running. Please check and correct if necessary.
4017 + # Keep lockfile fresh
4018 + lockfile-touch $LOCKFILE &
4023 +# Backup key system files
4027 + cmp -s passwd.bak /etc/passwd || (cp -p /etc/passwd passwd.bak &&
4028 + chmod 600 passwd.bak)
4029 + cmp -s group.bak /etc/group || (cp -p /etc/group group.bak &&
4030 + chmod 600 passwd.bak)
4031 + if [ -f /etc/shadow ] ; then
4032 + cmp -s shadow.bak /etc/shadow || (cp -p /etc/shadow shadow.bak &&
4033 + chmod 600 shadow.bak)
4035 + if [ -f /etc/gshadow ] ; then
4036 + cmp -s gshadow.bak /etc/gshadow || (cp -p /etc/gshadow gshadow.bak &&
4037 + chmod 600 gshadow.bak)
4042 + if ! cmp -s dpkg.status.0 /var/lib/dpkg/status ; then
4043 + cp -p /var/lib/dpkg/status dpkg.status
4044 + savelog -c 7 dpkg.status >/dev/null
4049 +savelog -c 7 -m 640 -u root -g adm setuid.changes >/dev/null
4050 +checksecurity >setuid.changes
4053 +# Check to see if any files are in lost+found directories and warn admin
4055 +# Get a list of the (potential) ext2 l+f directories
4056 +lflist=`df -P --type=ext2 |awk '$6 == "/" {$6 = ""} /\/dev\// {printf "%s/lost+found ", $6}'`
4058 +# In each directory, look for files
4059 +for lfdir in $lflist ; do
4060 + if [ -d "$lfdir" ] ; then
4061 + more_lost_found=`ls -1 "$lfdir" | grep -v 'lost+found$' | sed 's/^/ /'`
4062 + if [ -n "$more_lost_found" ] ; then
4063 + lost_found="$lost_found
4067 + # NOTE: above weird line breaks in string are intentional!
4072 +if [ -n "$lost_found" ]; then
4074 +Files were found in lost+found directories. This is probably
4075 +the result of a crash or bad shutdown, or possibly of a disk
4076 +problem. These files may contain important information. You
4077 +should examine them, and move them out of lost+found or delete
4078 +them if they are not important.
4080 +The following files were found:
4086 +# Clean up lockfile
4088 +if [ -x /usr/bin/lockfile-create ] ; then
4089 + kill $LOCKTOUCHPID
4090 + lockfile-remove $LOCKFILE
4092 --- cron-3.0pl1.orig/debian/standard.monthly
4093 +++ cron-3.0pl1/debian/standard.monthly
4096 +# /etc/cron.monthly/standard: standard monthly maintenance script
4098 +# rotation of wtmp and btmp taken over by logrotate