diff --git a/0001-Update-manual-for-symlink.patch b/0001-Update-manual-for-symlink.patch new file mode 100644 index 0000000..120a246 --- /dev/null +++ b/0001-Update-manual-for-symlink.patch @@ -0,0 +1,69 @@ +From 07ed1e70e6bf64c815baccde938702084036db78 Mon Sep 17 00:00:00 2001 +From: =?utf-8?q?Marcela=20Ma=C5=A1l=C3=A1=C5=88ov=C3=A1?= +Date: Mon, 22 Dec 2008 16:22:14 +0100 +Subject: [PATCH] Update manual for symlink. + +--- + man/cron.8 | 17 +++++++++-------- + man/crontab.5 | 17 +++++++++-------- + 2 files changed, 18 insertions(+), 16 deletions(-) + +diff --git a/man/cron.8 b/man/cron.8 +index 731896b..a80101a 100644 +--- a/man/cron.8 ++++ b/man/cron.8 +@@ -137,14 +137,15 @@ log file. This is useful in scripts which rotate and age log files. + Naturally this is not relevant if cron was built to use + .IR syslog (3). + .SH CAVEATS +-In this version of +-.BR cron +-, without the \fB-p\fP option, +-.I /etc/crontab +-must not be writable by any user other than root, +-no crontab files may be links, or linked to by any other file, +-and no crontab files may be executable, or be writable by any +-user other than their owner. ++The ++.BR crontab ++files have to be regular files or symlinks to regular files, they must not be executable ++or writable by anyone else than the owner. ++This requirement can be overridden by using the \fB-p\fP option on the crond command line. ++If inotify support is in use changes in the symlinked crontabs are not automatically ++noticed by the cron daemon. The cron daemon must receive a SIGHUP to reload the crontabs. ++This is a limitation of inotify API. ++ + .SH "SEE ALSO" + .IR crontab (1), + .IR crontab (5), +diff --git a/man/crontab.5 b/man/crontab.5 +index 098b3b0..208daca 100644 +--- a/man/crontab.5 ++++ b/man/crontab.5 +@@ -272,14 +272,15 @@ the 5 initial time and date fields, and are prefixed by the '@' character: + @hourly : Run once an hour, ie. "0 * * * *". + .fi + .SH CAVEATS +-In this version of +-.I cron +-, +-.I /etc/crontab +-must not be writable by any user other than root. +-No crontab files may be links, or linked to by any other file. +-No crontab files may be executable, or be writable by any user +-other than their owner. ++The ++.BR crontab ++files have to be regular files or symlinks to regular files, they must not be executable ++or writable by anyone else than the owner. ++This requirement can be overridden by using the \fB-p\fP option on the crond command line. ++If inotify support is in use changes in the symlinked crontabs are not automatically ++noticed by the cron daemon. The cron daemon must receive a SIGHUP to reload the crontabs. ++This is a limitation of inotify API. ++ + .SH AUTHOR + .nf + Paul Vixie +-- +1.6.0.6 + diff --git a/cronie-1.2-reload.patch b/cronie-1.2-reload.patch new file mode 100644 index 0000000..1cfb12a --- /dev/null +++ b/cronie-1.2-reload.patch @@ -0,0 +1,232 @@ +diff -up cronie-1.2/src/database.c.reload cronie-1.2/src/database.c +--- cronie-1.2/src/database.c.reload 2008-12-19 11:34:04.000000000 +0100 ++++ cronie-1.2/src/database.c 2008-12-22 14:22:30.000000000 +0100 +@@ -153,7 +153,7 @@ process_crontab(const char *uname, const + + #if defined WITH_INOTIFY + void +-check_inotify_database(cron_db *old_db, int fd) { ++check_inotify_database(cron_db *old_db) { + cron_db new_db; + DIR_T *dp; + DIR *dir; +@@ -167,17 +167,18 @@ check_inotify_database(cron_db *old_db, + time.tv_usec = 0; + + FD_ZERO(&rfds); +- FD_SET(fd, &rfds); ++ FD_SET(old_db->ifd, &rfds); + +- retval = select(fd + 1, &rfds, NULL, NULL, &time); ++ retval = select(old_db->ifd + 1, &rfds, NULL, NULL, &time); + if (retval == -1) { + if (errno != EINTR) + log_it("CRON", pid, "INOTIFY", "select failed", errno); + return; + } +- else if (FD_ISSET(fd, &rfds)) { ++ else if (FD_ISSET(old_db->ifd, &rfds)) { + new_db.head = new_db.tail = NULL; +- while ((retval=read(fd, buf, sizeof(buf))) == -1 && errno == EINTR); ++ new_db.ifd = old_db->ifd; ++ while ((retval=read(old_db->ifd, buf, sizeof(buf))) == -1 && errno == EINTR); + + if (retval == 0) { + /* this should not happen as the buffer is large enough */ +@@ -195,7 +196,7 @@ check_inotify_database(cron_db *old_db, + /* we must reinstate the watches here - TODO reinstate only watches + * which get IN_IGNORED event + */ +- set_cron_watched(fd); ++ set_cron_watched(old_db->ifd); + + /* TODO: parse the events and read only affected files */ + +@@ -269,7 +270,7 @@ overwrite_database(cron_db *old_db, cron + *old_db = *new_db; + } + +-void ++int + load_database(cron_db *old_db) { + struct stat statbuf, syscron_stat, crond_stat; + cron_db new_db; +@@ -318,7 +319,7 @@ load_database(cron_db *old_db) { + ){ + Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", + (long)pid)) +- return; ++ return 0; + } + + /* something's different. make a new database, moving unchanged +@@ -329,6 +330,9 @@ load_database(cron_db *old_db) { + new_db.mtime = TMAX(crond_stat.st_mtime, + TMAX(statbuf.st_mtime, syscron_stat.st_mtime)); + new_db.head = new_db.tail = NULL; ++#if defined WITH_INOTIFY ++ new_db.ifd = old_db->ifd; ++#endif + + if (syscron_stat.st_mtime) + process_crontab("root", NULL, SYSCRONTAB, &new_db, old_db); +@@ -382,6 +386,7 @@ load_database(cron_db *old_db) { + + overwrite_database(old_db, &new_db); + Debug(DLOAD, ("load_database is done\n")) ++ return 1; + } + + void +diff -up cronie-1.2/src/funcs.h.reload cronie-1.2/src/funcs.h +--- cronie-1.2/src/funcs.h.reload 2008-06-26 14:56:00.000000000 +0200 ++++ cronie-1.2/src/funcs.h 2008-12-22 12:12:30.000000000 +0100 +@@ -41,14 +41,13 @@ void set_cron_uid(void), + log_it(const char *, PID_T, const char *, const char *, int), + log_close(void); + #if defined WITH_INOTIFY +-void load_inotify_database(cron_db *, int ), +- set_cron_watched(int ), ++void set_cron_watched(int ), + set_cron_unwatched(int ), +- check_inotify_database(cron_db *, int ); ++ check_inotify_database(cron_db *); + #endif +-void load_database(cron_db *); + +-int job_runqueue(void), ++int load_database(cron_db *), ++ job_runqueue(void), + set_debug_flags(const char *), + get_char(FILE *), + get_string(char *, int, FILE *, char *), +diff -up cronie-1.2/src/structs.h.reload cronie-1.2/src/structs.h +--- cronie-1.2/src/structs.h.reload 2008-06-26 14:56:00.000000000 +0200 ++++ cronie-1.2/src/structs.h 2008-12-22 12:06:04.000000000 +0100 +@@ -60,6 +60,9 @@ typedef struct _user { + typedef struct _cron_db { + user *head, *tail; /* links */ + time_t mtime; /* last modtime on spooldir */ ++#ifdef WITH_INOTIFY ++ int ifd; ++#endif + } cron_db; + /* in the C tradition, we only create + * variables for the main program, just +diff -up cronie-1.2/src/cron.c.reload cronie-1.2/src/cron.c +--- cronie-1.2/src/cron.c.reload 2008-06-26 14:56:00.000000000 +0200 ++++ cronie-1.2/src/cron.c 2008-12-22 14:38:13.000000000 +0100 +@@ -79,7 +79,8 @@ set_cron_watched(int fd) { + int w; + + w = inotify_add_watch(fd, watchpaths[i], +- IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO | IN_MOVED_FROM | IN_MOVE_SELF | IN_DELETE); ++ IN_CREATE | IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO | ++ IN_MOVED_FROM | IN_MOVE_SELF | IN_DELETE | IN_DELETE_SELF); + if (w < 0) { + if (wd[i] != -1) { + log_it("CRON", pid, "This directory or file can't be watched", watchpaths[i], errno); +@@ -101,6 +102,27 @@ set_cron_watched(int fd) { + #endif + + static void ++handle_signals(cron_db *database) { ++ if (got_sighup) { ++ got_sighup = 0; ++#if defined WITH_INOTIFY ++ /* watches must be reinstated on reload */ ++ if (inotify_enabled) { ++ set_cron_unwatched(database->ifd); ++ inotify_enabled = 0; ++ } ++#endif ++ database->mtime = (time_t) 0; ++ log_close(); ++ } ++ ++ if (got_sigchld) { ++ got_sigchld = 0; ++ sigchld_reaper(); ++ } ++} ++ ++static void + usage(void) { + const char **dflags; + +@@ -216,7 +238,7 @@ main(int argc, char *argv[]) { + wd[i] = -2; + } + +- fd = inotify_init(); ++ database.ifd = fd = inotify_init(); + if (fd < 0) + log_it("CRON", pid, "INFO", "Inotify init failed", errno); + set_cron_watched(fd); +@@ -252,19 +274,19 @@ main(int argc, char *argv[]) { + * clock. Classify the change into one of 4 cases. + */ + timeDiff = timeRunning - virtualTime; +- if (inotify_enabled) { + #if defined WITH_INOTIFY +- check_inotify_database(&database, fd); +-#endif ++ if (inotify_enabled) { ++ check_inotify_database(&database); + } + else { +- load_database(&database); +-#if defined WITH_INOTIFY +- /* try reinstating the watches */ +- set_cron_watched(fd); +-#endif ++ if(load_database(&database)) ++ /* try reinstating the watches */ ++ set_cron_watched(fd); + } +- ++#else ++ load_database(&database); ++#endif ++ + /* shortcut for the most common case */ + if (timeDiff == 1) { + virtualTime = timeRunning; +@@ -354,17 +376,7 @@ main(int argc, char *argv[]) { + /* Jobs to be run (if any) are loaded; clear the queue. */ + job_runqueue(); + +- /* Check to see if we received a signal while running jobs. */ +- if (got_sighup) { +- got_sighup = 0; +- if (!inotify_enabled) +- database.mtime = (time_t) 0; +- log_close(); +- } +- if (got_sigchld) { +- got_sigchld = 0; +- sigchld_reaper(); +- } ++ handle_signals(&database); + } + + #if defined WITH_INOTIFY +@@ -502,16 +514,8 @@ cron_sleep(int target, cron_db *db) { + * If so, service the signal(s) then continue sleeping + * where we left off. + */ +- if (got_sighup) { +- got_sighup = 0; +- if (!inotify_enabled) +- db->mtime = (time_t) 0; +- log_close(); +- } +- if (got_sigchld) { +- got_sigchld = 0; +- sigchld_reaper(); +- } ++ handle_signals(db); ++ + t2 = time(NULL) + GMToff; + seconds_to_wait -= (int)(t2 - t1); + t1 = t2; diff --git a/cronie.spec b/cronie.spec index 1f2f377..0c11952 100644 --- a/cronie.spec +++ b/cronie.spec @@ -6,13 +6,16 @@ Summary: Cron daemon for executing programs at set times Name: cronie Version: 1.2 -Release: 4%{?dist} +Release: 5%{?dist} License: MIT and BSD Group: System Environment/Base URL: https://fedorahosted.org/cronie #Source0: https://fedorahosted.org/cronie/%{name}-%{version}.tar.gz Source0: http://mmaslano.fedorapeople.org/cronie/%{name}-%{version}.tar.gz Patch0: init.patch +Patch1: nofollow.patch +Patch2: cronie-1.2-reload.patch +Patch3: 0001-Update-manual-for-symlink.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: syslog, bash >= 2.0 @@ -48,6 +51,9 @@ SELinux. %prep %setup -q %patch0 -p1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 %build @@ -127,6 +133,10 @@ cp -a /var/lock/subsys/crond /var/lock/subsys/cronie > /dev/null 2>&1 ||: %config(noreplace) %{_sysconfdir}/cron.deny %changelog +* Tue Dec 23 2008 Marcela Mašláňová - 1.2-5 +- 477100 NO_FOLLOW was removed, reload after change in symlinked + crontab is needed, man updated. + * Fri Oct 24 2008 Marcela Mašláňová - 1.2-4 - update init script diff --git a/nofollow.patch b/nofollow.patch new file mode 100644 index 0000000..ff8a622 --- /dev/null +++ b/nofollow.patch @@ -0,0 +1,12 @@ +diff -up cronie-1.2/src/database.c.old cronie-1.2/src/database.c +--- cronie-1.2/src/database.c.old 2008-06-26 14:56:00.000000000 +0200 ++++ cronie-1.2/src/database.c 2008-12-19 12:21:15.000000000 +0100 +@@ -51,7 +51,7 @@ check_open(const char *tabname, const ch + int crontab_fd; + pid_t pid = getpid(); + +- if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) == -1) { ++ if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK, 0)) == -1) { + log_it(uname, pid, "CAN'T OPEN", tabname, errno); + return(-1); + }