diff --git a/cronie-1.1-cleanup.patch b/cronie-1.1-cleanup.patch new file mode 100644 index 0000000..3ebc2ca --- /dev/null +++ b/cronie-1.1-cleanup.patch @@ -0,0 +1,247 @@ +diff -up cronie-1.1/src/popen.c.cleanup cronie-1.1/src/popen.c +--- cronie-1.1/src/popen.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/popen.c 2008-06-17 17:00:51.000000000 +0200 +@@ -31,14 +31,6 @@ + */ + + #include +-#ifndef lint +-#if 0 +-static char rcsid[] = "Id: popen.c,v 1.5 1994/01/15 20:43:43 vixie Exp"; +-static char sccsid[] = "@(#)popen.c 5.7 (Berkeley) 2/14/89"; +-//#else +-//__RCSID("$NetBSD: popen.c,v 1.9 2005/03/16 02:53:55 xtraeme Exp $"); +-#endif +-#endif /* not lint */ + + #include + #include +diff -up cronie-1.1/src/do_command.c.cleanup cronie-1.1/src/do_command.c +--- cronie-1.1/src/do_command.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/do_command.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: do_command.c,v 1.9 2004/01/23 18:56:42 vixie Exp $"; +-#endif +- + #include + + static void child_process(entry *, user *); +diff -up cronie-1.1/src/user.c.cleanup cronie-1.1/src/user.c +--- cronie-1.1/src/user.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/user.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: user.c,v 1.5 2004/01/23 18:56:43 vixie Exp $"; +-#endif +- + /* vix 26jan87 [log is in RCS file] + */ + +diff -up cronie-1.1/src/cron.h.cleanup cronie-1.1/src/cron.h +--- cronie-1.1/src/cron.h.cleanup 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/cron.h 2008-06-17 17:00:51.000000000 +0200 +@@ -49,20 +49,3 @@ + #include "funcs.h" + #include "globals.h" + +-#ifdef WITH_PAM +-static pam_handle_t *pamh = NULL; +-static int pam_session_opened = 0; //global for open session +-static const struct pam_conv conv = { +- NULL +-}; +- +-#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ +- fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \ +- if (pamh != NULL) { \ +- if (pam_session_opened != 0) \ +- pam_close_session(pamh, PAM_SILENT); \ +- pam_end(pamh, retcode); \ +- } \ +- return(retcode); } +-#endif +- +diff -up cronie-1.1/src/pw_dup.c.cleanup cronie-1.1/src/pw_dup.c +--- cronie-1.1/src/pw_dup.c.cleanup 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/pw_dup.c 2008-06-17 17:00:51.000000000 +0200 +@@ -29,9 +29,6 @@ + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: pw_dup.c,v 1.2 2004/01/23 18:56:43 vixie Exp $"; +-#endif + + #include + #include +diff -up cronie-1.1/src/cron.c.cleanup cronie-1.1/src/cron.c +--- cronie-1.1/src/cron.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/cron.c 2008-06-17 17:03:04.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: cron.c,v 1.12 2004/01/23 18:56:42 vixie Exp $"; +-#endif +- + #define MAIN_PROGRAM + + #include +@@ -384,7 +380,7 @@ run_reboot_jobs(cron_db *db) { + + static void + find_jobs(int vtime, cron_db *db, int doWild, int doNonWild) { +- char orig_tz, *job_tz; ++ char *orig_tz, *job_tz; + time_t virtualSecond = vtime * SECONDS_PER_MINUTE; + struct tm *tm = gmtime(&virtualSecond); + int minute, hour, dom, month, dow; +diff -up cronie-1.1/src/job.c.cleanup cronie-1.1/src/job.c +--- cronie-1.1/src/job.c.cleanup 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/job.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: job.c,v 1.6 2004/01/23 18:56:43 vixie Exp $"; +-#endif +- + #include + + typedef struct _job { +diff -up cronie-1.1/src/crontab.c.cleanup cronie-1.1/src/crontab.c +--- cronie-1.1/src/crontab.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/crontab.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: crontab.c,v 1.12 2004/01/23 18:56:42 vixie Exp $"; +-#endif +- + /* crontab - install and manage per-user crontab files + * vix 02may87 [RCS has the rest of the log] + * vix 26jan87 [original] +@@ -655,7 +651,7 @@ replace_cmd(void) { + */ + /*fprintf(tmp, "# DO NOT EDIT THIS FILE - edit the master and reinstall.\n"); + *fprintf(tmp, "# (%s installed on %-24.24s)\n", Filename, ctime(&now)); +- *fprintf(tmp, "# (Cron version %s -- %s)\n", CRON_VERSION, rcsid); ++ *fprintf(tmp, "# (Cron version %s)\n", CRON_VERSION); + */ + #ifdef WITH_SELINUX + if ( selinux_context ) +diff -up cronie-1.1/src/entry.c.cleanup cronie-1.1/src/entry.c +--- cronie-1.1/src/entry.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/entry.c 2008-06-17 17:00:51.000000000 +0200 +@@ -20,10 +20,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: entry.c,v 1.17 2004/01/23 18:56:42 vixie Exp $"; +-#endif +- + /* vix 26jan87 [RCS'd; rest of log is in RCS file] + * vix 01jan87 [added line-level error recovery] + * vix 31dec86 [added /step to the from-to range, per bob@acornrc] +diff -up cronie-1.1/src/database.c.cleanup cronie-1.1/src/database.c +--- cronie-1.1/src/database.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/database.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: database.c,v 1.7 2004/01/23 18:56:42 vixie Exp $"; +-#endif +- + /* vix 26jan87 [RCS has the log] + */ + +diff -up cronie-1.1/src/security.c.cleanup cronie-1.1/src/security.c +--- cronie-1.1/src/security.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/security.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,6 +19,9 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + ++/* just a hack for now - change to proper check in configure.ac later */ ++#define _GNU_SOURCE ++ + #include + + #ifdef WITH_SELINUX +@@ -33,6 +36,25 @@ + #include + #endif + ++#ifdef WITH_PAM ++static pam_handle_t *pamh = NULL; ++static int pam_session_opened = 0; //global for open session ++static const struct pam_conv conv = { ++ NULL ++}; ++ ++static int cron_open_pam_session(struct passwd *pw); ++ ++#define PAM_FAIL_CHECK if (retcode != PAM_SUCCESS) { \ ++ fprintf(stderr,"\n%s\n",pam_strerror(pamh, retcode)); \ ++ if (pamh != NULL) { \ ++ if (pam_session_opened != 0) \ ++ pam_close_session(pamh, PAM_SILENT); \ ++ pam_end(pamh, retcode); \ ++ } \ ++ return(retcode); } ++#endif ++ + static char ** build_env(char **cronenv); + + #ifdef WITH_SELINUX +@@ -140,7 +162,7 @@ int cron_start_pam(struct passwd *pw) { + return retcode; + } + +-int cron_open_pam_session(struct passwd *pw) { ++static int cron_open_pam_session(struct passwd *pw) { + int retcode = 0; + + #if defined(WITH_PAM) +diff -up cronie-1.1/src/env.c.cleanup cronie-1.1/src/env.c +--- cronie-1.1/src/env.c.cleanup 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/env.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: env.c,v 1.10 2004/01/23 18:56:42 vixie Exp $"; +-#endif +- + #include + + char ** +diff -up cronie-1.1/src/misc.c.cleanup cronie-1.1/src/misc.c +--- cronie-1.1/src/misc.c.cleanup 2008-06-17 17:00:51.000000000 +0200 ++++ cronie-1.1/src/misc.c 2008-06-17 17:00:51.000000000 +0200 +@@ -19,10 +19,6 @@ + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +-#if !defined(lint) && !defined(LINT) +-static char rcsid[] = "$Id: misc.c,v 1.16 2004/01/23 18:56:43 vixie Exp $"; +-#endif +- + /* vix 26jan87 [RCS has the rest of the log] + * vix 30dec86 [written] + */ diff --git a/cronie-1.1-inotify-fixes.patch b/cronie-1.1-inotify-fixes.patch new file mode 100644 index 0000000..2947d87 --- /dev/null +++ b/cronie-1.1-inotify-fixes.patch @@ -0,0 +1,882 @@ +diff -up cronie-1.1/src/cron.c.inotify-fixes cronie-1.1/src/cron.c +--- cronie-1.1/src/cron.c.inotify-fixes 2008-06-18 22:49:02.000000000 +0200 ++++ cronie-1.1/src/cron.c 2008-06-18 23:15:15.000000000 +0200 +@@ -47,48 +47,56 @@ static int timeRunning, virtualTime, c + static long GMToff; + + #if defined WITH_INOTIFY +-int wd1, wd2, wd3, wd4; + +-void +-set_cron_watched(int fd) { +- pid_t pid = getpid(); +- +- wd1 = inotify_add_watch(fd, CRONDIR, IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); +- if (wd1 < 0) +- log_it("CRON", pid, "This directory can't be watched", CRONDIR, errno); ++#define NUM_WATCHES 3 + +- wd2 = inotify_add_watch(fd, RH_CROND_DIR, IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); +- if (wd2 < 0) +- log_it("CRON", pid, "This directory can't be watched", RH_CROND_DIR, errno); ++int wd[NUM_WATCHES]; ++const char *watchpaths[NUM_WATCHES] = { SPOOL_DIR, RH_CROND_DIR, SYSCRONTAB }; + +- wd3 = inotify_add_watch(fd, SYSCRONTAB, IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); +- if (wd3 < 0) +- log_it("CRON", pid, "This file can't be watched", SYSCRONTAB, errno); ++void ++set_cron_unwatched(int fd) { ++ int i; ++ ++ for (i = 0; i < sizeof(wd)/sizeof(wd[0]); ++i) { ++ if (wd[i] < 0) { ++ inotify_rm_watch(fd, wd[i]); ++ wd[i] = -1; ++ } ++ } ++} + +- wd4 = inotify_add_watch(fd, "/var/spool/cron/", IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); +- if (wd4 < 0) +- log_it("CRON", pid, "This directory can't be watched", "/var/spool/cron", errno); ++void ++set_cron_watched(int fd) { ++ pid_t pid = getpid(); ++ int i; + +- if (wd1 <0 || wd2<0 || wd3<0 || wd4<0) { ++ if (fd < 0) { + inotify_enabled = 0; +- log_it("CRON", pid, "INFO", "running without inotify support", 0); ++ return; + } +- else +- inotify_enabled = 1; +-} + +-void +-set_cron_unwatched(int fd) { +- int ret1, ret2, ret3, ret4; ++ for (i = 0; i < sizeof(wd)/sizeof(wd[0]); ++i) { ++ 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); ++ if (w < 0) { ++ if (wd[i] != -1) { ++ log_it("CRON", pid, "This directory or file can't be watched", watchpaths[i], errno); ++ log_it("CRON", pid, "INFO", "running without inotify support", 0); ++ } ++ inotify_enabled = 0; ++ set_cron_unwatched(fd); ++ return; ++ } ++ wd[i] = w; ++ } + +- if (wd1 >= 0) +- ret1 = inotify_rm_watch(fd, wd1); +- if (wd2 >= 0) +- ret2 = inotify_rm_watch(fd, wd2); +- if (wd3 >= 0) +- ret3 = inotify_rm_watch(fd, wd3); +- if (wd4 >= 0) +- ret4 = inotify_rm_watch(fd, wd4); ++ if (!inotify_enabled) { ++ log_it("CRON", pid, "INFO", "running with inotify support", 0); ++ } ++ ++ inotify_enabled = 1; + } + #endif + +@@ -110,12 +118,8 @@ main(int argc, char *argv[]) { + int fd; + char *cs; + pid_t pid = getpid(); +- + #if defined WITH_INOTIFY +- int fildes; +- fildes = inotify_init(); +- if (fildes < 0) +- log_it("CRON", pid, "INFO", "Inotify init failed", errno); ++ int i; + #endif + + ProgramName = argv[0]; +@@ -146,9 +150,6 @@ main(int argc, char *argv[]) { + + acquire_daemonlock(0); + set_cron_uid(); +-#if defined WITH_INOTIFY +- set_cron_watched(fildes); +-#endif + set_cron_cwd(); + + if (putenv("PATH="_PATH_DEFPATH) < 0) { +@@ -191,10 +192,7 @@ main(int argc, char *argv[]) { + if (fd != STDERR) + (void) close(fd); + } +- if (inotify_enabled) +- log_it("CRON", getpid(), "STARTUP INOTIFY", PACKAGE_VERSION, 0); +- else +- log_it("CRON", getpid(), "STARTUP", PACKAGE_VERSION, 0); ++ log_it("CRON", getpid(), "STARTUP", PACKAGE_VERSION, 0); + break; + default: + /* parent process should just die */ +@@ -202,18 +200,28 @@ main(int argc, char *argv[]) { + } + } + ++ pid = getpid(); + acquire_daemonlock(0); + database.head = NULL; + database.tail = NULL; +- if (inotify_enabled) { ++ database.mtime = (time_t) 0; ++ ++ load_database(&database); ++ + #if defined WITH_INOTIFY +- load_inotify_database(&database, fildes); +-#endif +- } +- else { +- database.mtime = (time_t) 0; +- load_database(&database); ++ for (i = 0; i < sizeof(wd)/sizeof(wd[0]); ++i) { ++ /* initialize to negative number other than -1 ++ * so an eventual error is reported for the first time ++ */ ++ wd[i] = -2; + } ++ ++ fd = inotify_init(); ++ if (fd < 0) ++ log_it("CRON", pid, "INFO", "Inotify init failed", errno); ++ set_cron_watched(fd); ++#endif ++ + set_time(TRUE); + run_reboot_jobs(&database); + timeRunning = virtualTime = clockTime; +@@ -246,12 +254,17 @@ main(int argc, char *argv[]) { + timeDiff = timeRunning - virtualTime; + if (inotify_enabled) { + #if defined WITH_INOTIFY +- check_inotify_database(&database, fildes); ++ check_inotify_database(&database, fd); + #endif + } +- else ++ else { + load_database(&database); +- ++#if defined WITH_INOTIFY ++ /* try reinstating the watches */ ++ set_cron_watched(fd); ++#endif ++ } ++ + /* shortcut for the most common case */ + if (timeDiff == 1) { + virtualTime = timeRunning; +@@ -275,7 +288,7 @@ main(int argc, char *argv[]) { + * minute until caught up. + */ + Debug(DSCH, ("[%ld], normal case %d minutes to go\n", +- (long)getpid(), timeDiff)) ++ (long)pid, timeDiff)) + do { + if (job_runqueue()) + sleep(10); +@@ -297,7 +310,7 @@ main(int argc, char *argv[]) { + * housekeeping. + */ + Debug(DSCH, ("[%ld], DST begins %d minutes to go\n", +- (long)getpid(), timeDiff)) ++ (long)pid, timeDiff)) + /* run wildcard jobs for current minute */ + find_jobs(timeRunning, &database, TRUE, FALSE); + +@@ -323,7 +336,7 @@ main(int argc, char *argv[]) { + * change until we are caught up. + */ + Debug(DSCH, ("[%ld], DST ends %d minutes to go\n", +- (long)getpid(), timeDiff)) ++ (long)pid, timeDiff)) + find_jobs(timeRunning, &database, TRUE, FALSE); + break; + default: +@@ -332,7 +345,7 @@ main(int argc, char *argv[]) { + * jump virtual time, and run everything + */ + Debug(DSCH, ("[%ld], clock jumped\n", +- (long)getpid())) ++ (long)pid)) + virtualTime = timeRunning; + find_jobs(timeRunning, &database, TRUE, TRUE); + } +@@ -353,14 +366,13 @@ main(int argc, char *argv[]) { + sigchld_reaper(); + } + } +- /* here stay ifdef, because some of the watches can be used even +- * if inotify is disabled +- */ ++ + #if defined WITH_INOTIFY +- set_cron_unwatched(fildes); ++ if (inotify_enabled) ++ set_cron_unwatched(fd); + +- if (fildes >= 0 && close(fildes) < 0) +- log_it("CRON", pid, "INFO", "Inotify can't remove watches", errno); ++ if (fd >= 0 && close(fd) < 0) ++ log_it("CRON", pid, "INFO", "Inotify close failed", errno); + #endif + } + +diff -up cronie-1.1/src/database.c.inotify-fixes cronie-1.1/src/database.c +--- cronie-1.1/src/database.c.inotify-fixes 2008-06-18 22:49:02.000000000 +0200 ++++ cronie-1.1/src/database.c 2008-06-18 22:49:02.000000000 +0200 +@@ -32,14 +32,10 @@ + /* reasonable guess as to size of 1024 events */ + #define BUF_LEN (1024 * (EVENT_SIZE + 16)) + +-#if defined WITH_INOTIFY +-/* state say if we change the crontable */ +-#define RELOAD 1 +-void unlink_inotify_database(cron_db *, cron_db , int); +-#endif ++void overwrite_database(cron_db *, cron_db *); + + static void process_crontab(const char *, const char *, +- const char *, struct stat *, ++ const char *, + cron_db *, cron_db *); + + static int not_a_crontab( DIR_T *dp ); +@@ -48,10 +44,9 @@ static int not_a_crontab( DIR_T *dp ); + static void max_mtime( char *dir_name, struct stat *max_st ); + /* record max mtime of any file under dir_name in max_st */ + +-#if defined WITH_INOTIFY + int + check_open(const char *tabname, const char *fname, const char *uname, +- struct passwd *pw) { ++ struct passwd *pw, time_t *mtime) { + struct stat statbuf; + int crontab_fd; + pid_t pid = getpid(); +@@ -60,12 +55,13 @@ check_open(const char *tabname, const ch + log_it(uname, pid, "CAN'T OPEN", tabname, errno); + return(-1); + } ++ if (fstat(crontab_fd, &statbuf) < OK) { ++ log_it(uname, pid, "STAT FAILED", tabname, errno); ++ close(crontab_fd); ++ return(-1); ++ } ++ *mtime = statbuf.st_mtime; + if (PermitAnyCrontab == 0) { +- if (fstat(crontab_fd, &statbuf) < OK) { +- log_it(uname, pid, "STAT FAILED", tabname, errno); +- close(crontab_fd); +- return(-1); +- } + if (!S_ISREG(statbuf.st_mode)) { + log_it(uname, pid, "NOT REGULAR", tabname, 0); + close(crontab_fd); +@@ -92,12 +88,12 @@ check_open(const char *tabname, const ch + } + + void +-process_inotify_crontab(const char *uname, const char *fname, const char *tabname, +- cron_db *new_db, cron_db *old_db, int fd, int state) { ++process_crontab(const char *uname, const char *fname, const char *tabname, ++ cron_db *new_db, cron_db *old_db) { + struct passwd *pw = NULL; + int crontab_fd = -1; + user *u; +- struct stat statbuf; ++ time_t mtime; + int crond_crontab = (fname == NULL) && (strcmp(tabname, SYSCRONTAB) != 0); + + if (fname == NULL) { +@@ -111,43 +107,42 @@ process_inotify_crontab(const char *unam + goto next_crontab; + } + ++ if ((crontab_fd = check_open(tabname, fname, uname, pw, &mtime)) == -1) ++ goto next_crontab; ++ + Debug(DLOAD, ("\t%s:", fname)) +- u = find_user(old_db, fname, crond_crontab ? tabname : NULL ); /* goes only through database in memory */ + +- /* in first run is database empty. Check permission when -p ISN'T used. */ +- if (u == NULL) { +- if ((crontab_fd = check_open(tabname, fname, uname, pw)) == -1) +- goto next_crontab; +- } +- else { /* second and other runs */ ++ u = find_user(old_db, fname, crond_crontab ? tabname : NULL ); /* find user in old_db */ ++ ++ if (u != NULL) { + /* if crontab has not changed since we last read it +- * in, then we can just use our existing entry. +- */ +- /* 6 because we want string reload or none */ +- if (state != RELOAD) { ++ * in, then we can just use our existing entry. ++ */ ++ if (u->mtime == mtime) { + Debug(DLOAD, (" [no change, using old data]")) + unlink_user(old_db, u); + link_user(new_db, u); + goto next_crontab; + } +- /* before we fall through to the code that will reload +- * the user, let's deallocate and unlink the user in +- * the old database. This is more a point of memory +- * efficiency than anything else, since all leftover +- * users will be deleted from the old database when +- * we finish with the crontab... +- */ +- if ((crontab_fd = check_open(tabname, fname, uname, pw)) == -1) +- goto next_crontab; + ++ /* before we fall through to the code that will reload ++ * the user, let's deallocate and unlink the user in ++ * the old database. This is more a point of memory ++ * efficiency than anything else, since all leftover ++ * users will be deleted from the old database when ++ * we finish with the crontab... ++ */ + Debug(DLOAD, (" [delete old data]")) + unlink_user(old_db, u); + free_user(u); +- Debug(DSCH, ("RELOAD %s\n", tabname)) ++ log_it(fname, getpid(), "RELOAD", tabname, 0); + } +- u = load_user(crontab_fd, pw, uname, fname, tabname); /* touch the disk */ +- if (u != NULL) ++ ++ u = load_user(crontab_fd, pw, uname, fname, tabname); /* read the file */ ++ if (u != NULL) { ++ u->mtime = mtime; + link_user(new_db, u); ++ } + + next_crontab: + if (crontab_fd != -1) { +@@ -156,57 +151,7 @@ process_inotify_crontab(const char *unam + } + } + +-void +-load_inotify_database(cron_db *old_db, int fd) { +- cron_db new_db; +- DIR_T *dp; +- DIR *dir; +- pid_t pid = getpid(); +- +- new_db.head = new_db.tail = NULL; +- process_inotify_crontab("root", NULL, SYSCRONTAB, &new_db, old_db, fd, RELOAD); +- +- /* RH_CROND_DIR /etc/cron.d */ +- if (!(dir = opendir(RH_CROND_DIR))) { +- log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); +- (void) exit(ERROR_EXIT); +- } +- while (NULL != (dp = readdir(dir))) { +- char tabname[MAXNAMLEN+1]; +- +- if (not_a_crontab(dp)) +- continue; +- +- if (!glue_strings(tabname, sizeof tabname, RH_CROND_DIR, dp->d_name, '/')) +- continue; +- +- process_inotify_crontab("root", NULL, tabname, &new_db, old_db, fd, RELOAD); +- } +- closedir(dir); +- /* SPOOL_DIR */ +- if (!(dir = opendir(SPOOL_DIR))) { +- log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); +- (void) exit(ERROR_EXIT); +- } +- +- while (NULL != (dp = readdir(dir))) { +- char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; +- +- if (not_a_crontab(dp)) +- continue; +- +- strncpy(fname, dp->d_name, MAXNAMLEN); +- +- if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/')) +- continue; +- +- process_inotify_crontab(fname, fname, tabname, &new_db, old_db, fd, RELOAD); +- } +- closedir(dir); +- +- unlink_inotify_database(old_db, new_db, fd); +-} +- ++#if defined WITH_INOTIFY + void + check_inotify_database(cron_db *old_db, int fd) { + cron_db new_db; +@@ -218,7 +163,7 @@ check_inotify_database(cron_db *old_db, + char buf[BUF_LEN]; + pid_t pid = getpid(); + +- time.tv_sec = 1; ++ time.tv_sec = 0; + time.tv_usec = 0; + + FD_ZERO(&rfds); +@@ -226,110 +171,83 @@ check_inotify_database(cron_db *old_db, + + retval = select(fd + 1, &rfds, NULL, NULL, &time); + if (retval == -1) { +- log_it("CRON", pid, "INOTIFY", "select failed", errno); ++ if (errno != EINTR) ++ log_it("CRON", pid, "INOTIFY", "select failed", errno); ++ return; + } + else if (FD_ISSET(fd, &rfds)) { + new_db.head = new_db.tail = NULL; +- if (read(fd, buf, sizeof(buf)) == -1) +- log_it("CRON", pid, "INOTIFY", "read failed", errno); +- process_inotify_crontab("root", NULL, SYSCRONTAB, &new_db, old_db, fd, RELOAD); ++ while ((retval=read(fd, buf, sizeof(buf))) == -1 && errno == EINTR); + +- if (!(dir = opendir(RH_CROND_DIR))) { +- log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); +- (void) exit(ERROR_EXIT); ++ if (retval == 0) { ++ /* this should not happen as the buffer is large enough */ ++ errno = ENOMEM; + } +- while (NULL != (dp = readdir(dir))) { +- char tabname[MAXNAMLEN+1]; +- +- if (not_a_crontab(dp)) +- continue; + +- if (!glue_strings(tabname, sizeof tabname, RH_CROND_DIR, dp->d_name, '/')) +- continue; +- process_inotify_crontab("root", NULL, tabname, &new_db, old_db, fd, RELOAD); +- } +- closedir(dir); +- +- if (!(dir = opendir(SPOOL_DIR))) { +- log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); ++ if (retval <= 0) { ++ log_it("CRON", pid, "INOTIFY", "read failed", errno); ++ /* something fatal must have occured we have no other reasonable ++ * way how to handle this failure than exit. ++ */ + (void) exit(ERROR_EXIT); + } +- while (NULL != (dp = readdir(dir))) { +- char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; ++ ++ /* we must reinstate the watches here - TODO reinstate only watches ++ * which get IN_IGNORED event ++ */ ++ set_cron_watched(fd); + +- if (not_a_crontab(dp)) +- continue; ++ /* TODO: parse the events and read only affected files */ + +- strncpy(fname, dp->d_name, MAXNAMLEN); ++ process_crontab("root", NULL, SYSCRONTAB, &new_db, old_db); + +- if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, dp->d_name, '/')) +- continue; +- process_inotify_crontab(fname, fname, tabname, &new_db, old_db, fd, RELOAD); +- } +- closedir(dir); +- } +- else { +- new_db.head = new_db.tail = NULL; +- process_inotify_crontab("root", NULL, SYSCRONTAB, &new_db, old_db, fd, !RELOAD); + if (!(dir = opendir(RH_CROND_DIR))) { + log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); +- (void) exit(ERROR_EXIT); ++ } else { ++ while (NULL != (dp = readdir(dir))) { ++ char tabname[MAXNAMLEN+1]; ++ ++ if (not_a_crontab(dp)) ++ continue; ++ ++ if (!glue_strings(tabname, sizeof tabname, RH_CROND_DIR, dp->d_name, '/')) ++ continue; ++ process_crontab("root", NULL, tabname, &new_db, old_db); ++ } ++ closedir(dir); + } + +- while (NULL != (dp = readdir(dir))) { +- char tabname[MAXNAMLEN+1]; +- +- if (not_a_crontab(dp)) +- continue; +- +- if (!glue_strings(tabname, sizeof tabname, RH_CROND_DIR, dp->d_name, '/')) +- continue; +- process_inotify_crontab("root", NULL, tabname, &new_db, old_db, fd, !RELOAD); +- } +- closedir(dir); +- + if (!(dir = opendir(SPOOL_DIR))) { + log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); +- (void) exit(ERROR_EXIT); +- } ++ } else { ++ while (NULL != (dp = readdir(dir))) { ++ char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; + +- while (NULL != (dp = readdir(dir))) { +- char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; ++ if (not_a_crontab(dp)) ++ continue; + +- if (not_a_crontab(dp)) +- continue; ++ strncpy(fname, dp->d_name, MAXNAMLEN); + +- strncpy(fname, dp->d_name, MAXNAMLEN); +- +- if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/')) +- continue; +- +- process_inotify_crontab(fname, fname, tabname, &new_db, old_db, fd, !RELOAD); ++ if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, dp->d_name, '/')) ++ continue; ++ process_crontab(fname, fname, tabname, &new_db, old_db); ++ } ++ closedir(dir); + } +- closedir(dir); +- } +- FD_CLR(fd, &rfds); +- +- unlink_inotify_database(old_db, new_db, fd); +-} + +-void +-unlink_inotify_database(cron_db *old_db, cron_db new_db, int fd) { +- user *u, *nu; +- /* whatever's left in the old database is now junk. +- */ +- Debug(DLOAD, ("unlinking old database:\n")) +- for (u = old_db->head; u != NULL; u = nu) { +- Debug(DLOAD, ("\t%s\n", u->name)) +- nu = u->next; +- unlink_user(old_db, u); +- free_user(u); ++ /* if we don't do this, then when our children eventually call ++ * getpwnam() in do_command.c's child_process to verify MAILTO=, ++ * they will screw us up (and v-v). ++ */ ++ endpwent(); ++ } ++ else { ++ /* just return as no db reload is needed */ ++ return; + } + +- /* overwrite the database control block with the new one. +- */ +- *old_db = new_db; +- Debug(DLOAD, ("load_database is done\n")) ++ overwrite_database(old_db, &new_db); ++ Debug(DLOAD, ("check_inotify_database is done\n")) + } + + /*void +@@ -358,12 +276,29 @@ read_dir(char *dir_name, cron_db *new_db + #endif + + void ++overwrite_database(cron_db *old_db, cron_db *new_db) { ++ user *u, *nu; ++ /* whatever's left in the old database is now junk. ++ */ ++ Debug(DLOAD, ("unlinking old database:\n")) ++ for (u = old_db->head; u != NULL; u = nu) { ++ Debug(DLOAD, ("\t%s\n", u->name)) ++ nu = u->next; ++ unlink_user(old_db, u); ++ free_user(u); ++ } ++ ++ /* overwrite the database control block with the new one. ++ */ ++ *old_db = *new_db; ++} ++ ++void + load_database(cron_db *old_db) { + struct stat statbuf, syscron_stat, crond_stat; + cron_db new_db; + DIR_T *dp; + DIR *dir; +- user *u, *nu; + pid_t pid = getpid(); + + Debug(DLOAD, ("[%ld] load_database()\n", (long)pid)) +@@ -374,22 +309,22 @@ load_database(cron_db *old_db) { + */ + if (stat(SPOOL_DIR, &statbuf) < OK) { + log_it("CRON", pid, "STAT FAILED", SPOOL_DIR, errno); +- (void) exit(ERROR_EXIT); ++ statbuf.st_mtime = 0; ++ } else { ++ /* As pointed out in Red Hat bugzilla 198019, with modern Linux it ++ * is possible to modify a file without modifying the mtime of the ++ * containing directory. Hence, we must check the mtime of each file: ++ */ ++ max_mtime(SPOOL_DIR, &statbuf); + } +- +- /* As pointed out in Red Hat bugzilla 198019, with modern Linux it +- * is possible to modify a file without modifying the mtime of the +- * containing directory. Hence, we must check the mtime of each file: +- */ +- max_mtime(SPOOL_DIR, &statbuf); + + if (stat(RH_CROND_DIR, &crond_stat) < OK) { + log_it("CRON", pid, "STAT FAILED", RH_CROND_DIR, errno); +- (void) exit(ERROR_EXIT); ++ crond_stat.st_mtime = 0; ++ } else { ++ max_mtime(RH_CROND_DIR, &crond_stat); + } + +- max_mtime(RH_CROND_DIR, &crond_stat); +- + /* track system crontab file + */ + if (stat(SYSCRONTAB, &syscron_stat) < OK) +@@ -420,27 +355,24 @@ load_database(cron_db *old_db) { + new_db.head = new_db.tail = NULL; + + if (syscron_stat.st_mtime) +- process_crontab("root", NULL, SYSCRONTAB, &syscron_stat, +- &new_db, old_db); ++ process_crontab("root", NULL, SYSCRONTAB, &new_db, old_db); + + if (!(dir = opendir(RH_CROND_DIR))) { + log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); +- (void) exit(ERROR_EXIT); +- } +- +- while (NULL != (dp = readdir(dir))) { +- char tabname[MAXNAMLEN+1]; ++ } else { ++ while (NULL != (dp = readdir(dir))) { ++ char tabname[MAXNAMLEN+1]; + +- if ( not_a_crontab( dp ) ) +- continue; ++ if ( not_a_crontab( dp ) ) ++ continue; + +- if (!glue_strings(tabname, sizeof tabname, RH_CROND_DIR, dp->d_name, '/')) +- continue; /* XXX log? */ ++ if (!glue_strings(tabname, sizeof tabname, RH_CROND_DIR, dp->d_name, '/')) ++ continue; /* XXX log? */ + +- process_crontab("root", NULL, tabname, +- &crond_stat, &new_db, old_db); ++ process_crontab("root", NULL, tabname, &new_db, old_db); ++ } ++ closedir(dir); + } +- closedir(dir); + + /* we used to keep this dir open all the time, for the sake of + * efficiency. however, we need to close it in every fork, and +@@ -449,24 +381,22 @@ load_database(cron_db *old_db) { + + if (!(dir = opendir(SPOOL_DIR))) { + log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); +- (void) exit(ERROR_EXIT); +- } +- +- while (NULL != (dp = readdir(dir))) { +- char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; ++ } else { ++ while (NULL != (dp = readdir(dir))) { ++ char fname[MAXNAMLEN+1], tabname[MAXNAMLEN+1]; + +- if ( not_a_crontab( dp ) ) +- continue; ++ if ( not_a_crontab( dp ) ) ++ continue; + +- strncpy(fname, dp->d_name, MAXNAMLEN); ++ strncpy(fname, dp->d_name, MAXNAMLEN); + +- if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/')) +- continue; /* XXX log? */ ++ if (!glue_strings(tabname, sizeof tabname, SPOOL_DIR, fname, '/')) ++ continue; /* XXX log? */ + +- process_crontab(fname, fname, tabname, +- &statbuf, &new_db, old_db); ++ process_crontab(fname, fname, tabname, &new_db, old_db); ++ } ++ closedir(dir); + } +- closedir(dir); + + /* if we don't do this, then when our children eventually call + * getpwnam() in do_command.c's child_process to verify MAILTO=, +@@ -474,19 +404,7 @@ load_database(cron_db *old_db) { + */ + endpwent(); + +- /* whatever's left in the old database is now junk. +- */ +- Debug(DLOAD, ("unlinking old database:\n")) +- for (u = old_db->head; u != NULL; u = nu) { +- Debug(DLOAD, ("\t%s\n", u->name)) +- nu = u->next; +- unlink_user(old_db, u); +- free_user(u); +- } +- +- /* overwrite the database control block with the new one. +- */ +- *old_db = new_db; ++ overwrite_database(old_db, &new_db); + Debug(DLOAD, ("load_database is done\n")) + } + +@@ -527,100 +445,6 @@ find_user(cron_db *db, const char *name, + return (u); + } + +-static void +-process_crontab(const char *uname, const char *fname, const char *tabname, +- struct stat *statbuf, cron_db *new_db, cron_db *old_db) +-{ +- struct passwd *pw = NULL; +- int crontab_fd = OK - 1; +- user *u; +- int crond_crontab = (fname == NULL) && (strcmp(tabname, SYSCRONTAB) != 0); +- pid_t pid = getpid(); +- +- if (fname == NULL) { +- /* must be set to something for logging purposes. +- */ +- fname = "*system*"; +- } else if ((pw = getpwnam(uname)) == NULL) { +- /* file doesn't have a user in passwd file. +- */ +- log_it(fname, pid, "ORPHAN", "no passwd entry", 0); +- goto next_crontab; +- } +- +- if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < OK) { +- /* crontab not accessible? +- */ +- log_it(fname, pid, "CAN'T OPEN", tabname, errno); +- goto next_crontab; +- } +- +- if (fstat(crontab_fd, statbuf) < OK) { +- log_it(fname, pid, "FSTAT FAILED", tabname, errno); +- goto next_crontab; +- } +- +- if ( PermitAnyCrontab == 0 ) +- { +- if (!S_ISREG(statbuf->st_mode)) { +- log_it(fname, pid, "NOT REGULAR", tabname, 0); +- goto next_crontab; +- } +- if ((statbuf->st_mode & 07533) != 0400) { +- log_it(fname, pid, "BAD FILE MODE", tabname, 0); +- goto next_crontab; +- } +- if (statbuf->st_uid != ROOT_UID && (pw == NULL || +- statbuf->st_uid != pw->pw_uid || strcmp(uname, pw->pw_name) != 0)) { +- log_it(fname, pid, "WRONG FILE OWNER", tabname, 0); +- goto next_crontab; +- } +- if (pw && statbuf->st_nlink != 1) { +- log_it(fname, pid, "BAD LINK COUNT", tabname, 0); +- goto next_crontab; +- } +- } +- +- Debug(DLOAD, ("\t%s:", fname)) +- +- u = find_user(old_db, fname, crond_crontab ? tabname : NULL ); +- +- if (u != NULL) { +- /* if crontab has not changed since we last read it +- * in, then we can just use our existing entry. +- */ +- if (u->mtime == statbuf->st_mtime) { +- Debug(DLOAD, (" [no change, using old data]")) +- unlink_user(old_db, u); +- link_user(new_db, u); +- goto next_crontab; +- } +- +- /* before we fall through to the code that will reload +- * the user, let's deallocate and unlink the user in +- * the old database. This is more a point of memory +- * efficiency than anything else, since all leftover +- * users will be deleted from the old database when +- * we finish with the crontab... +- */ +- Debug(DLOAD, (" [delete old data]")) +- unlink_user(old_db, u); +- free_user(u); +- log_it(fname, pid, "RELOAD", tabname, 0); +- } +- u = load_user(crontab_fd, pw, uname, fname, tabname); +- if (u != NULL) { +- u->mtime = statbuf->st_mtime; +- link_user(new_db, u); +- } +- +- next_crontab: +- if (crontab_fd >= OK) { +- Debug(DLOAD, (" [done]\n")) +- close(crontab_fd); +- } +-} +- + static int not_a_crontab( DIR_T *dp ) + { + int len; +@@ -660,11 +484,10 @@ static void max_mtime( char *dir_name, s + DIR * dir; + DIR_T *dp; + struct stat st; +- pid_t pid = getpid(); + + if (!(dir = opendir(dir_name))) { +- log_it("CRON", pid, "OPENDIR FAILED", dir_name, errno); +- (void) exit(ERROR_EXIT); ++ max_st->st_mtime = 0; ++ return; + } + + while (NULL != (dp = readdir(dir))) diff --git a/cronie-1.1-keycreatecon.patch b/cronie-1.1-keycreatecon.patch new file mode 100644 index 0000000..2ea199b --- /dev/null +++ b/cronie-1.1-keycreatecon.patch @@ -0,0 +1,34 @@ +diff -up cronie-1.1/src/security.c.keycreatecon cronie-1.1/src/security.c +--- cronie-1.1/src/security.c.keycreatecon 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/security.c 2008-06-17 10:08:39.000000000 +0200 +@@ -356,7 +356,7 @@ static int cron_change_selinux_range(use + #endif + syslog(LOG_ERR, + "CRON (%s) ERROR:" +- "Unauthorized range %s in MLS_LEVEL for user %s ", ++ "Unauthorized range %s in MLS_LEVEL for user %s", + u->name, (char*)ucontext, u->scontext); + return -1; + } +@@ -370,18 +370,18 @@ static int cron_change_selinux_range(use + } + } + +- if ((setexeccon(ucontext) < 0) && (setkeycreatecon(ucontext))) { ++ if (setexeccon(ucontext) < 0 || setkeycreatecon(ucontext) < 0) { + if (security_getenforce() > 0) { + syslog(LOG_ERR, + "CRON (%s) ERROR:" +- "Could not set exec context to %s for user", ++ "Could not set exec or keycreate context to %s for user", + u->name, (char*)ucontext); + return -1; + } + else { + syslog(LOG_ERR, + "CRON (%s) ERROR:" +- "Could not set exec context to %s for user, " ++ "Could not set exec or keycreate context to %s for user," + " but SELinux in permissive mode, continuing", + u->name, (char*)ucontext); + diff --git a/cronie-1.1-logging.patch b/cronie-1.1-logging.patch new file mode 100644 index 0000000..aff8e7e --- /dev/null +++ b/cronie-1.1-logging.patch @@ -0,0 +1,1073 @@ +diff -up cronie-1.1/src/crontab.c.logging cronie-1.1/src/crontab.c +--- cronie-1.1/src/crontab.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/crontab.c 2008-06-17 16:41:55.000000000 +0200 +@@ -115,7 +115,7 @@ main(int argc, char *argv[]) { + "You (%s) are not allowed to use this program (%s)\n", + User, ProgramName); + fprintf(stderr, "See crontab(1) for more information\n"); +- log_it(RealUser, Pid, "AUTH", "crontab command not allowed"); ++ log_it(RealUser, Pid, "AUTH", "crontab command not allowed", 0); + exit(ERROR_EXIT); + } + +@@ -293,7 +293,7 @@ list_cmd(void) { + FILE *f; + int ch; + +- log_it(RealUser, Pid, "LIST", User); ++ log_it(RealUser, Pid, "LIST", User, 0); + if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) { + fprintf(stderr, "path too long\n"); + exit(ERROR_EXIT); +@@ -326,7 +326,7 @@ delete_cmd(void) { + ) exit(0); + } + +- log_it(RealUser, Pid, "DELETE", User); ++ log_it(RealUser, Pid, "DELETE", User, 0); + if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) { + fprintf(stderr, "path too long\n"); + exit(ERROR_EXIT); +@@ -366,7 +366,7 @@ edit_cmd(void) { + PID_T pid, xpid; + int uid; + +- log_it(RealUser, Pid, "BEGIN EDIT", User); ++ log_it(RealUser, Pid, "BEGIN EDIT", User, 0); + if (!glue_strings(n, sizeof n, SPOOL_DIR, User, '/')) { + fprintf(stderr, "path too long\n"); + exit(ERROR_EXIT); +@@ -607,7 +607,7 @@ edit_cmd(void) { + remove: + unlink(Filename); + done: +- log_it(RealUser, Pid, "END EDIT", User); ++ log_it(RealUser, Pid, "END EDIT", User, 0); + } + + /* returns 0 on success +@@ -758,7 +758,7 @@ replace_cmd(void) { + goto done; + } + TempFilename[0] = '\0'; +- log_it(RealUser, Pid, "REPLACE", User); ++ log_it(RealUser, Pid, "REPLACE", User, 0); + + poke_daemon(); + +diff -up cronie-1.1/src/entry.c.logging cronie-1.1/src/entry.c +--- cronie-1.1/src/entry.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/entry.c 2008-06-17 16:41:55.000000000 +0200 +@@ -284,7 +284,7 @@ load_entry(FILE *file, void (*error_func + } + e->envp = tenvp; + } else +- log_it("CRON", getpid(), "error", "can't set SHELL"); ++ log_it("CRON", getpid(), "error", "can't set SHELL", 0); + } + if (!env_get("HOME", e->envp)) { + if (glue_strings(envstr, sizeof envstr, "HOME", +@@ -295,7 +295,7 @@ load_entry(FILE *file, void (*error_func + } + e->envp = tenvp; + } else +- log_it("CRON", getpid(), "error", "can't set HOME"); ++ log_it("CRON", getpid(), "error", "can't set HOME", 0); + } + #ifndef LOGIN_CAP + /* If login.conf is in used we will get the default PATH later. */ +@@ -308,7 +308,7 @@ load_entry(FILE *file, void (*error_func + } + e->envp = tenvp; + } else +- log_it("CRON", getpid(), "error", "can't set PATH"); ++ log_it("CRON", getpid(), "error", "can't set PATH", 0); + } + #endif /* LOGIN_CAP */ + if (glue_strings(envstr, sizeof envstr, "LOGNAME", +@@ -319,7 +319,7 @@ load_entry(FILE *file, void (*error_func + } + e->envp = tenvp; + } else +- log_it("CRON", getpid(), "error", "can't set LOGNAME"); ++ log_it("CRON", getpid(), "error", "can't set LOGNAME", 0); + #if defined(BSD) || defined(__linux) + if (glue_strings(envstr, sizeof envstr, "USER", + pw->pw_name, '=')) { +@@ -329,7 +329,7 @@ load_entry(FILE *file, void (*error_func + } + e->envp = tenvp; + } else +- log_it("CRON", getpid(), "error", "can't set USER"); ++ log_it("CRON", getpid(), "error", "can't set USER", 0); + #endif + + Debug(DPARS, ("load_entry()...about to parse command\n")) +diff -up cronie-1.1/src/do_command.c.logging cronie-1.1/src/do_command.c +--- cronie-1.1/src/do_command.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/do_command.c 2008-06-17 16:41:55.000000000 +0200 +@@ -30,8 +30,10 @@ static int safe_p(const char *, const c + + void + do_command(entry *e, user *u) { ++ pid_t pid = getpid(); ++ + Debug(DPROC, ("[%ld] do_command(%s, (%s,%ld,%ld))\n", +- (long)getpid(), e->cmd, u->name, ++ (long)pid, e->cmd, u->name, + (long)e->pwd->pw_uid, (long)e->pwd->pw_gid)) + + /* fork to become asynchronous -- parent process is done immediately, +@@ -43,7 +45,7 @@ do_command(entry *e, user *u) { + */ + switch (fork()) { + case -1: +- log_it("CRON", getpid(), "error", "can't fork"); ++ log_it("CRON", pid, "can't fork", "do_command", errno); + break; + case 0: + /* child process */ +@@ -57,7 +59,7 @@ do_command(entry *e, user *u) { + /* parent process */ + break; + } +- Debug(DPROC, ("[%ld] main process returning to work\n",(long)getpid())) ++ Debug(DPROC, ("[%ld] main process returning to work\n",(long)pid)) + } + + static void +@@ -66,6 +68,7 @@ child_process(entry *e, user *u) { + char *input_data, *usernm, *mailto; + int children = 0; + char **jobenv=0L; ++ pid_t pid = getpid(); + + /* Set up the Red Hat security context for both mail/minder and job processes: + */ +@@ -105,13 +108,13 @@ child_process(entry *e, user *u) { + */ + if( pipe(stdin_pipe) == -1 ) /* child's stdin */ + { +- log_it("CRON", getpid(), "pipe() failed:", strerror(errno)); ++ log_it("CRON", pid, "pipe() failed", "stdin_pipe", errno); + return; + } + + if( pipe(stdout_pipe) == -1 ) /* child's stdout */ + { +- log_it("CRON", getpid(), "pipe() failed:", strerror(errno)); ++ log_it("CRON", pid, "pipe() failed", "stdout_pipe", errno); + return; + } + +@@ -157,7 +160,7 @@ child_process(entry *e, user *u) { + */ + switch (fork()) { + case -1: +- log_it("CRON", getpid(), "error", "can't fork"); ++ log_it("CRON", pid, "can't fork", "child_process", errno); + cron_close_pam(); + exit(ERROR_EXIT); + /*NOTREACHED*/ +@@ -173,7 +176,7 @@ child_process(entry *e, user *u) { + if ((e->flags & DONT_LOG) == 0) { + char *x = mkprints((u_char *)e->cmd, strlen(e->cmd)); + +- log_it(usernm, getpid(), "CMD", x); ++ log_it(usernm, getpid(), "CMD", x, 0); + free(x); + } + +@@ -490,7 +493,7 @@ child_process(entry *e, user *u) { + "mailed %d byte%s of output but got status 0x%04x\n", + bytes, (bytes==1)?"":"s", + status); +- log_it(usernm, getpid(), "MAIL", buf); ++ log_it(usernm, getpid(), "MAIL", buf, 0); + } + + } /*if data from grandchild*/ +@@ -537,7 +540,7 @@ safe_p(const char *usernm, const char *s + if (isascii(ch) && isprint(ch) && + (isalnum(ch) || (!first && strchr(safe_delim, ch)))) + continue; +- log_it(usernm, getpid(), "UNSAFE", s); ++ log_it(usernm, getpid(), "UNSAFE", s, 0); + return (FALSE); + } + return (TRUE); +diff -up cronie-1.1/src/cron.c.logging cronie-1.1/src/cron.c +--- cronie-1.1/src/cron.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/cron.c 2008-06-17 16:41:55.000000000 +0200 +@@ -55,27 +55,27 @@ int wd1, wd2, wd3, wd4; + + void + set_cron_watched(int fd) { +- int ret1, ret2, ret3; ++ pid_t pid = getpid(); + + wd1 = inotify_add_watch(fd, CRONDIR, IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); + if (wd1 < 0) +- log_it("CRON",getpid(),"This directory can't be watched",strerror(errno)); ++ log_it("CRON", pid, "This directory can't be watched", CRONDIR, errno); + + wd2 = inotify_add_watch(fd, RH_CROND_DIR, IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); + if (wd2 < 0) +- log_it("CRON",getpid(),"This directory can't be watched",strerror(errno)); ++ log_it("CRON", pid, "This directory can't be watched", RH_CROND_DIR, errno); + + wd3 = inotify_add_watch(fd, SYSCRONTAB, IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); + if (wd3 < 0) +- log_it("CRON",getpid(),"This file can't be watched ",strerror(errno)); ++ log_it("CRON", pid, "This file can't be watched", SYSCRONTAB, errno); + + wd4 = inotify_add_watch(fd, "/var/spool/cron/", IN_MODIFY | IN_DELETE | IN_CREATE | IN_ATTRIB); + if (wd4 < 0) +- log_it("CRON",getpid(),"This file can't be watched ",strerror(errno)); ++ log_it("CRON", pid, "This directory can't be watched", "/var/spool/cron", errno); + + if (wd1 <0 || wd2<0 || wd3<0 || wd4<0) { + inotify_enabled = 0; +- syslog(LOG_INFO, "CRON (%s) ERROR: run without inotify support"); ++ log_it("CRON", pid, "INFO", "running without inotify support", 0); + } + else + inotify_enabled = 1; +@@ -113,12 +113,13 @@ main(int argc, char *argv[]) { + cron_db database; + int fd; + char *cs; ++ pid_t pid = getpid(); + + #if defined WITH_INOTIFY + int fildes; + fildes = inotify_init(); + if (fildes < 0) +- syslog(LOG_ERR, "Inotify init failed %m"); ++ log_it("CRON", pid, "INFO", "Inotify init failed", errno); + #endif + + ProgramName = argv[0]; +@@ -155,7 +156,7 @@ main(int argc, char *argv[]) { + set_cron_cwd(); + + if (putenv("PATH="_PATH_DEFPATH) < 0) { +- log_it("CRON", getpid(), "DEATH", "can't malloc"); ++ log_it("CRON", pid, "DEATH", "can't putenv PATH", errno); + exit(1); + } + +@@ -181,7 +182,7 @@ main(int argc, char *argv[]) { + } else if (NoFork == 0) { + switch (fork()) { + case -1: +- log_it("CRON",getpid(),"DEATH","can't fork"); ++ log_it("CRON", pid, "DEATH", "can't fork", errno); + exit(0); + break; + case 0: +@@ -195,9 +196,9 @@ main(int argc, char *argv[]) { + (void) close(fd); + } + if (inotify_enabled) +- log_it("CRON",getpid(),"STARTUP INOTIFY",PACKAGE_VERSION); ++ log_it("CRON", getpid(), "STARTUP INOTIFY", PACKAGE_VERSION, 0); + else +- log_it("CRON",getpid(),"STARTUP",PACKAGE_VERSION); ++ log_it("CRON", getpid(), "STARTUP", PACKAGE_VERSION, 0); + break; + default: + /* parent process should just die */ +@@ -362,10 +363,8 @@ main(int argc, char *argv[]) { + #if defined WITH_INOTIFY + set_cron_unwatched(fildes); + +- int ret; +- ret = close(fildes); +- if (ret) +- syslog(LOG_ERR, "Inotify can't remove watches %m"); ++ if (fildes >= 0 && close(fildes) < 0) ++ log_it("CRON", pid, "INFO", "Inotify can't remove watches", errno); + #endif + } + +diff -up cronie-1.1/src/popen.c.logging cronie-1.1/src/popen.c +--- cronie-1.1/src/popen.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/popen.c 2008-06-17 16:41:55.000000000 +0200 +@@ -110,7 +110,9 @@ cron_popen(char *program, const char *ty + } + + if (execvp(argv[0], argv) < 0) { +- syslog(LOG_ERR, "CRON: Exec of (%s) failed: (%s)", program, strerror(errno)); ++ int save_errno = errno; ++ ++ log_it("CRON", getpid(), "EXEC FAILED", program, save_errno); + if (*type != 'r') { + while (0 != (out = read(STDIN, buf, PIPE_BUF))) { + if ((out == -1) && (errno != EINTR)) +diff -up cronie-1.1/src/database.c.logging cronie-1.1/src/database.c +--- cronie-1.1/src/database.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/database.c 2008-06-17 16:41:55.000000000 +0200 +@@ -58,35 +58,36 @@ check_open(const char *tabname, const ch + struct passwd *pw) { + struct stat statbuf; + int crontab_fd; ++ pid_t pid = getpid(); + + if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) == -1) { +- log_it("CRON", getpid(), "CAN'T OPEN", tabname); ++ log_it(uname, pid, "CAN'T OPEN", tabname, errno); + return(-1); + } + if (PermitAnyCrontab == 0) { + if (fstat(crontab_fd, &statbuf) < OK) { +- log_it("CRON", getpid(), "STAT FAILED", tabname); ++ log_it(uname, pid, "STAT FAILED", tabname, errno); + close(crontab_fd); + return(-1); + } + if (!S_ISREG(statbuf.st_mode)) { +- syslog(LOG_INFO, "NOT REGULAR %s", tabname); ++ log_it(uname, pid, "NOT REGULAR", tabname, 0); + close(crontab_fd); + return(-1); + } + if ((statbuf.st_mode & 07533) != 0400) { +- log_it(fname, getpid(), "BAD FILE MODE", tabname); ++ log_it(uname, pid, "BAD FILE MODE", tabname, 0); + close(crontab_fd); + return(-1); + } + if (statbuf.st_uid != ROOT_UID && (pw == NULL || + statbuf.st_uid != pw->pw_uid || strcmp(uname, pw->pw_name) != 0)) { +- log_it(fname, getpid(), "WRONG FILE OWNER", tabname); ++ log_it(uname, pid, "WRONG FILE OWNER", tabname, 0); + close(crontab_fd); + return(-1); + } + if (pw && statbuf.st_nlink != 1) { +- log_it(fname, getpid(), "BAD LINK COUNT", tabname); ++ log_it(uname, pid, "BAD LINK COUNT", tabname, 0); + close(crontab_fd); + return(-1); + } +@@ -110,7 +111,7 @@ process_inotify_crontab(const char *unam + } else if ((pw = getpwnam(uname)) == NULL) { + /* file doesn't have a user in passwd file. + */ +- log_it("CRON", getpid(), "ORPHAN", "no passwd entry"); ++ log_it(uname, getpid(), "ORPHAN", "no passwd entry", 0); + goto next_crontab; + } + +@@ -164,13 +165,14 @@ load_inotify_database(cron_db *old_db, i + cron_db new_db; + DIR_T *dp; + DIR *dir; ++ pid_t pid = getpid(); + + new_db.head = new_db.tail = NULL; + process_inotify_crontab("root", NULL, SYSCRONTAB, &new_db, old_db, fd, RELOAD); + + /* RH_CROND_DIR /etc/cron.d */ + if (!(dir = opendir(RH_CROND_DIR))) { +- log_it("CRON", getpid(), "OPENDIR FAILED", RH_CROND_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); + (void) exit(ERROR_EXIT); + } + while (NULL != (dp = readdir(dir))) { +@@ -187,7 +189,7 @@ load_inotify_database(cron_db *old_db, i + closedir(dir); + /* SPOOL_DIR */ + if (!(dir = opendir(SPOOL_DIR))) { +- syslog(LOG_INFO, "CRON: OPENDIR FAILED %s", SPOOL_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -218,6 +220,7 @@ check_inotify_database(cron_db *old_db, + fd_set rfds; + int retval = 0; + char buf[BUF_LEN]; ++ pid_t pid = getpid(); + + time.tv_sec = 1; + time.tv_usec = 0; +@@ -227,17 +230,16 @@ check_inotify_database(cron_db *old_db, + + retval = select(fd + 1, &rfds, NULL, NULL, &time); + if (retval == -1) { +- perror("select()"); +- syslog(LOG_INFO, "CRON: select failed: %s", strerror(errno)); ++ log_it("CRON", pid, "INOTIFY", "select failed", errno); + } + else if (FD_ISSET(fd, &rfds)) { + new_db.head = new_db.tail = NULL; + if (read(fd, buf, sizeof(buf)) == -1) +- log_it("CRON", getpid(), "reading problem",buf); ++ log_it("CRON", pid, "INOTIFY", "read failed", errno); + process_inotify_crontab("root", NULL, SYSCRONTAB, &new_db, old_db, fd, RELOAD); + + if (!(dir = opendir(RH_CROND_DIR))) { +- log_it("CRON", getpid(), "OPENDIR FAILED", RH_CROND_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); + (void) exit(ERROR_EXIT); + } + while (NULL != (dp = readdir(dir))) { +@@ -253,7 +255,7 @@ check_inotify_database(cron_db *old_db, + closedir(dir); + + if (!(dir = opendir(SPOOL_DIR))) { +- syslog(LOG_INFO, "CRON: OPENDIR FAILED %s", SPOOL_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); + (void) exit(ERROR_EXIT); + } + while (NULL != (dp = readdir(dir))) { +@@ -274,7 +276,7 @@ check_inotify_database(cron_db *old_db, + new_db.head = new_db.tail = NULL; + process_inotify_crontab("root", NULL, SYSCRONTAB, &new_db, old_db, fd, !RELOAD); + if (!(dir = opendir(RH_CROND_DIR))) { +- log_it("CRON", getpid(), "OPENDIR FAILED", RH_CROND_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -291,7 +293,7 @@ check_inotify_database(cron_db *old_db, + closedir(dir); + + if (!(dir = opendir(SPOOL_DIR))) { +- syslog(LOG_INFO, "CRON: OPENDIR FAILED %s", SPOOL_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -366,15 +368,16 @@ load_database(cron_db *old_db) { + DIR_T *dp; + DIR *dir; + user *u, *nu; ++ pid_t pid = getpid(); + +- Debug(DLOAD, ("[%ld] load_database()\n", (long)getpid())) ++ Debug(DLOAD, ("[%ld] load_database()\n", (long)pid)) + + /* before we start loading any data, do a stat on SPOOL_DIR + * so that if anything changes as of this moment (i.e., before we've + * cached any of the database), we'll see the changes next time. + */ + if (stat(SPOOL_DIR, &statbuf) < OK) { +- log_it("CRON", getpid(), "STAT FAILED", SPOOL_DIR); ++ log_it("CRON", pid, "STAT FAILED", SPOOL_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -385,7 +388,7 @@ load_database(cron_db *old_db) { + max_mtime(SPOOL_DIR, &statbuf); + + if (stat(RH_CROND_DIR, &crond_stat) < OK) { +- log_it("CRON", getpid(), "STAT FAILED", RH_CROND_DIR); ++ log_it("CRON", pid, "STAT FAILED", RH_CROND_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -407,7 +410,7 @@ load_database(cron_db *old_db) { + TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) + ){ + Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", +- (long)getpid())) ++ (long)pid)) + return; + } + +@@ -425,7 +428,7 @@ load_database(cron_db *old_db) { + &new_db, old_db); + + if (!(dir = opendir(RH_CROND_DIR))) { +- log_it("CRON", getpid(), "OPENDIR FAILED", RH_CROND_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", RH_CROND_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -449,7 +452,7 @@ load_database(cron_db *old_db) { + */ + + if (!(dir = opendir(SPOOL_DIR))) { +- log_it("CRON", getpid(), "OPENDIR FAILED", SPOOL_DIR); ++ log_it("CRON", pid, "OPENDIR FAILED", SPOOL_DIR, errno); + (void) exit(ERROR_EXIT); + } + +@@ -536,6 +539,7 @@ process_crontab(const char *uname, const + int crontab_fd = OK - 1; + user *u; + int crond_crontab = (fname == NULL) && (strcmp(tabname, SYSCRONTAB) != 0); ++ pid_t pid = getpid(); + + if (fname == NULL) { + /* must be set to something for logging purposes. +@@ -544,39 +548,39 @@ process_crontab(const char *uname, const + } else if ((pw = getpwnam(uname)) == NULL) { + /* file doesn't have a user in passwd file. + */ +- log_it(fname, getpid(), "ORPHAN", "no passwd entry"); ++ log_it(fname, pid, "ORPHAN", "no passwd entry", 0); + goto next_crontab; + } + + if ((crontab_fd = open(tabname, O_RDONLY|O_NONBLOCK|O_NOFOLLOW, 0)) < OK) { + /* crontab not accessible? + */ +- log_it(fname, getpid(), "CAN'T OPEN", tabname); ++ log_it(fname, pid, "CAN'T OPEN", tabname, errno); + goto next_crontab; + } + + if (fstat(crontab_fd, statbuf) < OK) { +- log_it(fname, getpid(), "FSTAT FAILED", tabname); ++ log_it(fname, pid, "FSTAT FAILED", tabname, errno); + goto next_crontab; + } + + if ( PermitAnyCrontab == 0 ) + { + if (!S_ISREG(statbuf->st_mode)) { +- log_it(fname, getpid(), "NOT REGULAR", tabname); ++ log_it(fname, pid, "NOT REGULAR", tabname, 0); + goto next_crontab; + } + if ((statbuf->st_mode & 07533) != 0400) { +- log_it(fname, getpid(), "BAD FILE MODE", tabname); ++ log_it(fname, pid, "BAD FILE MODE", tabname, 0); + goto next_crontab; + } + if (statbuf->st_uid != ROOT_UID && (pw == NULL || + statbuf->st_uid != pw->pw_uid || strcmp(uname, pw->pw_name) != 0)) { +- log_it(fname, getpid(), "WRONG FILE OWNER", tabname); ++ log_it(fname, pid, "WRONG FILE OWNER", tabname, 0); + goto next_crontab; + } + if (pw && statbuf->st_nlink != 1) { +- log_it(fname, getpid(), "BAD LINK COUNT", tabname); ++ log_it(fname, pid, "BAD LINK COUNT", tabname, 0); + goto next_crontab; + } + } +@@ -606,7 +610,7 @@ process_crontab(const char *uname, const + Debug(DLOAD, (" [delete old data]")) + unlink_user(old_db, u); + free_user(u); +- log_it(fname, getpid(), "RELOAD", tabname); ++ log_it(fname, pid, "RELOAD", tabname, 0); + } + u = load_user(crontab_fd, pw, uname, fname, tabname); + if (u != NULL) { +@@ -660,9 +664,10 @@ static void max_mtime( char *dir_name, s + DIR * dir; + DIR_T *dp; + struct stat st; ++ pid_t pid = getpid(); + + if (!(dir = opendir(dir_name))) { +- log_it("CRON", getpid(), "OPENDIR FAILED", dir_name); ++ log_it("CRON", pid, "OPENDIR FAILED", dir_name, errno); + (void) exit(ERROR_EXIT); + } + +diff -up cronie-1.1/src/misc.c.logging cronie-1.1/src/misc.c +--- cronie-1.1/src/misc.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/misc.c 2008-06-17 16:41:55.000000000 +0200 +@@ -287,6 +287,7 @@ acquire_daemonlock(int closeflag) { + char *ep; + long otherpid=-1; + ssize_t num, len; ++ pid_t pid = getpid(); + + if (closeflag) { + /* close stashed fd for child so we don't leak it. */ +@@ -301,10 +302,11 @@ acquire_daemonlock(int closeflag) { + pidfile = _PATH_CRON_PID; + /* Initial mode is 0600 to prevent flock() race/DoS. */ + if ((fd = open(pidfile, O_RDWR|O_CREAT, 0600)) == -1) { +- sprintf(buf, "can't open or create %s: %s", +- pidfile, strerror(errno)); +- fprintf(stderr, "%s: %s\n", ProgramName, buf); +- log_it("CRON", getpid(), "DEATH", buf); ++ int save_errno = errno; ++ sprintf(buf, "can't open or create %s", ++ pidfile); ++ fprintf(stderr, "%s: %s: %s\n", ProgramName, buf, strerror(save_errno)); ++ log_it("CRON", pid, "DEATH", buf, save_errno); + exit(ERROR_EXIT); + } + +@@ -315,33 +317,31 @@ acquire_daemonlock(int closeflag) { + if ((num = read(fd, buf, sizeof(buf) - 1)) > 0 && + (otherpid = strtol(buf, &ep, 10)) > 0 && + ep != buf && *ep == '\n' && otherpid != LONG_MAX) { +- sprintf(buf, +- "can't lock %s, otherpid may be %ld: %s", +- pidfile, otherpid, strerror(save_errno)); ++ snprintf(buf, sizeof(buf), ++ "can't lock %s, otherpid may be %ld", ++ pidfile, otherpid); + } else { +- sprintf(buf, +- "can't lock %s, otherpid unknown: %s", +- pidfile, strerror(save_errno)); ++ snprintf(buf, sizeof(buf), ++ "can't lock %s, otherpid unknown", ++ pidfile); + } +- sprintf(buf, "can't lock %s, otherpid may be %ld: %s", +- pidfile, otherpid, strerror(save_errno)); +- fprintf(stderr, "%s: %s\n", ProgramName, buf); +- log_it("CRON", getpid(), "DEATH", buf); ++ fprintf(stderr, "%s: %s: %s\n", ProgramName, buf, strerror(save_errno)); ++ log_it("CRON", pid, "DEATH", buf, save_errno); + exit(ERROR_EXIT); + } + (void) fchmod(fd, 0644); + (void) fcntl(fd, F_SETFD, 1); + } + +- sprintf(buf, "%ld\n", (long)getpid()); ++ sprintf(buf, "%ld\n", (long)pid); + (void) lseek(fd, (off_t)0, SEEK_SET); + len = strlen(buf); + if( (num = write(fd, buf, len)) != len ) +- log_it("CRON", getpid(), "write() failed:", strerror(errno)); ++ log_it("CRON", pid, "ERROR", "write() failed", errno); + else + { + if( ftruncate(fd, num) == -1 ) +- log_it("CRON", getpid(), "ftruncate() failed:", strerror(errno)); ++ log_it("CRON", pid, "ERROR", "ftruncate() failed", errno); + } + + /* abandon fd even though the file is open. we need to keep +@@ -477,7 +477,7 @@ allowed(const char *username, const char + if( ( getuid() == 0 ) && (!isallowed) ) + { + snprintf(buf,sizeof(buf),"root used -u for user %s not in cron.allow",username); +- log_it("crontab",getpid(),"warning",buf); ++ log_it("crontab", getpid(), "warning", buf, 0); + isallowed = TRUE; + } + } else if ((fp = fopen(deny_file, "r")) != NULL) { +@@ -486,7 +486,7 @@ allowed(const char *username, const char + if( ( getuid() == 0 ) && (!isallowed) ) + { + snprintf(buf,sizeof(buf),"root used -u for user %s in cron.deny",username); +- log_it("crontab",getpid(),"warning",buf); ++ log_it("crontab", getpid(), "warning", buf, 0); + isallowed = TRUE; + } + } +@@ -502,7 +502,7 @@ allowed(const char *username, const char + } + + void +-log_it(const char *username, PID_T xpid, const char *event, const char *detail) { ++log_it(const char *username, PID_T xpid, const char *event, const char *detail, int err) { + #if defined(LOG_FILE) || DEBUGGING + PID_T pid = xpid; + #endif +@@ -542,10 +542,12 @@ log_it(const char *username, PID_T xpid, + * everything out in one chunk and this has to be atomically appended + * to the log file. + */ +- snprintf(msg, msg_size, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)\n", ++ snprintf(msg, msg_size, "%s (%02d/%02d-%02d:%02d:%02d-%d) %s (%s)%s%s\n", + username, + t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, pid, +- event, detail); ++ event, detail, ++ err != 0 ? ": " : "", ++ err != 0 ? strerror(err) : ""); + + /* we have to run strlen() because sprintf() returns (char*) on old BSD + */ +@@ -569,14 +571,20 @@ log_it(const char *username, PID_T xpid, + syslog_open = TRUE; /* assume openlog success */ + } + +- syslog(LOG_INFO, "(%s) %s (%s)", username, event, detail); ++ syslog(err != 0 ? LOG_ERR : LOG_INFO, ++ "(%s) %s (%s)%s%s", username, event, detail, ++ err != 0 ? ": " : "", ++ err != 0 ? strerror(err) : ""); ++ + + #endif /*SYSLOG*/ + + #if DEBUGGING + if (DebugFlags) { +- fprintf(stderr, "log_it: (%s %ld) %s (%s)\n", +- username, (long)pid, event, detail); ++ fprintf(stderr, "log_it: (%s %ld) %s (%s)%s%s\n", ++ username, (long)pid, event, detail, ++ err != 0 ? ": " : "", ++ err != 0 ? strerror(err) : ""); + } + #endif + } +diff -up cronie-1.1/src/funcs.h.logging cronie-1.1/src/funcs.h +--- cronie-1.1/src/funcs.h.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/funcs.h 2008-06-17 16:41:55.000000000 +0200 +@@ -38,7 +38,7 @@ void set_cron_uid(void), + free_entry(entry *), + acquire_daemonlock(int), + skip_comments(FILE *), +- log_it(const char *, int, const char *, const char *), ++ log_it(const char *, int, const char *, const char *, int), + log_close(void); + #if defined WITH_INOTIFY + void load_inotify_database(cron_db *, int ), +diff -up cronie-1.1/src/security.c.logging cronie-1.1/src/security.c +--- cronie-1.1/src/security.c.logging 2008-06-17 16:41:55.000000000 +0200 ++++ cronie-1.1/src/security.c 2008-06-17 16:42:23.000000000 +0200 +@@ -49,6 +49,9 @@ void cron_restore_default_security_conte + + int cron_set_job_security_context(entry *e, user *u, char ***jobenv) { + time_t minutely_time = 0; ++#ifdef WITH_PAM ++ int ret; ++#endif + + if ((e->flags & MIN_STAR)==MIN_STAR) { + /* "minute-ly" job: Every minute for given hour/dow/month/dom. +@@ -59,8 +62,8 @@ int cron_set_job_security_context(entry + } + + #ifdef WITH_PAM +- if (cron_start_pam(e->pwd) != 0) { +- syslog(LOG_INFO, "CRON (%s): failed to open PAM security session: %s", e->pwd->pw_name, pam_strerror(pamh,cron_start_pam(e->pwd))); ++ if ((ret=cron_start_pam(e->pwd)) != 0) { ++ log_it(e->pwd->pw_name, getpid(), "FAILED to authorize user with PAM", pam_strerror(pamh, ret), 0); + return -1; + } + #endif +@@ -74,14 +77,12 @@ int cron_set_job_security_context(entry + security_context_t ucontext=0; + + if (cron_get_job_range(u, &ucontext, *jobenv) < OK) { +- syslog(LOG_ERR, "CRON (%s) ERROR: failed to get selinux context: %s", +- e->pwd->pw_name, strerror(errno)); ++ log_it(e->pwd->pw_name, getpid(), "ERROR", "failed to get SELinux context", 0); + return -1; + } + + if (cron_change_selinux_range(u, ucontext) != 0) { +- syslog(LOG_INFO,"CRON (%s) ERROR: failed to change SELinux context", +- e->pwd->pw_name); ++ log_it(e->pwd->pw_name, getpid(),"ERROR", "failed to change SELinux context", 0); + if ( ucontext ) + freecon(ucontext); + return -1; +@@ -90,19 +91,18 @@ int cron_set_job_security_context(entry + freecon(ucontext); + #endif + #ifdef WITH_PAM +- if (cron_open_pam_session(e->pwd) != 0) { +- syslog(LOG_INFO, "CRON (%s) ERROR: failed to open PAM security session: %s", e->pwd->pw_name, strerror(errno)); ++ if ((ret=cron_open_pam_session(e->pwd)) != 0) { ++ log_it(e->pwd->pw_name, getpid(), "FAILED to open PAM security session", pam_strerror(pamh, ret), 0); + return -1; + } + #endif + + if (cron_change_user(e->pwd, env_get("HOME", *jobenv)) != 0) { +- syslog(LOG_INFO, "CRON (%s) ERROR: failed to open change cron user: %s", e->pwd->pw_name, strerror(errno)); ++ log_it(e->pwd->pw_name, getpid(), "ERROR", "failed to change user", 0); + return -1; + } + + log_close(); +- openlog(ProgramName, LOG_PID, LOG_CRON); + + time_t job_run_time = time(0L); + +@@ -111,12 +111,15 @@ int cron_set_job_security_context(entry + * (eg. by network authentication method timeouts), skip it. + */ + struct tm tmS, tmN; ++ char buf[256]; ++ + localtime_r(&job_run_time, &tmN); + localtime_r(&minutely_time,&tmS); +- syslog(LOG_ERR, +- "(%s) error: Job execution of per-minute job scheduled for " +- "%.2u:%.2u delayed into subsequent minute %.2u:%.2u. Skipping job run.", +- e->pwd->pw_name, tmS.tm_hour, tmS.tm_min, tmN.tm_hour, tmN.tm_min); ++ ++ snprintf(buf, sizeof(buf), "Job execution of per-minute job scheduled for " ++ "%.2u:%.2u delayed into subsequent minute %.2u:%.2u. Skipping job run.", ++ tmS.tm_hour, tmS.tm_min, tmN.tm_hour, tmN.tm_min); ++ log_it(e->pwd->pw_name, getpid(), "INFO", buf, 0); + return -1; + } + return 0; +@@ -163,27 +166,27 @@ void cron_close_pam(void) { + } + + int cron_change_user(struct passwd *pw, char *homedir) { ++ pid_t pid = getpid(); + /* set our directory, uid and gid. Set gid first, since once + * we set uid, we've lost root privledges. + */ + if (setgid(pw->pw_gid) != 0) { +- log_it("CRON", getpid(), "setgid failed:", strerror(errno)); ++ log_it("CRON", pid, "ERROR", "setgid failed", errno); + return -1; + } + + if (initgroups(pw->pw_name, pw->pw_gid) != 0) { +- log_it("CRON", getpid(), "initgroups failed:", strerror(errno)); ++ log_it("CRON", pid, "ERROR", "initgroups failed", errno); + return -1; + } + + if (setuid( pw->pw_uid ) != 0) { +- log_it("CRON", getpid(), "setuid failed:", strerror(errno)); ++ log_it("CRON", pid, "ERROR", "setuid failed", errno); + return -1; + } + + if (chdir(homedir) == -1) { +- log_it("CRON", getpid(), "chdir(HOME) failed:", strerror(errno)); +- log_it("CRON", getpid(), homedir, strerror(errno)); ++ log_it("CRON", pid, "ERROR chdir failed", homedir, errno); + return -1; + } + return 0; +@@ -254,12 +257,12 @@ int cron_get_job_context(user *u, void * + if (getfilecon( crontab, file_contextp ) == -1) { + if (security_getenforce() > 0) { + log_it(u->name, getpid(), "getfilecon FAILED for SELINUX_ROLE_TYPE", +- sroletype); ++ sroletype, 0); + return -1; + } else if (access( crontab, F_OK ) == 0) + log_it(u->name, getpid(), + "getfilecon FAILED but SELinux in permissive mode, continuing " +- "- SELINUX_ROLE_TYPE=", sroletype); ++ "- SELINUX_ROLE_TYPE", sroletype, 0); + } + } + #endif +@@ -282,25 +285,25 @@ static int cron_get_job_range(user *u, s + if ((range = env_get("MLS_LEVEL",jobenv)) != 0L) { + context_t ccon; + if (!(ccon = context_new(u->scontext))) { +- log_it(u->name, getpid(), "context_new FAILED for MLS_LEVEL", range); ++ log_it(u->name, getpid(), "context_new FAILED for MLS_LEVEL", range, 0); + return -1; + } + + if (context_range_set(ccon, range)) { + log_it(u->name, getpid(), "context_range_set FAILED for MLS_LEVEL", +- range); ++ range, 0); + return -1; + } + + if (!(*ucontextp = context_str(ccon))) { + log_it(u->name, getpid(), "context_str FAILED for MLS_LEVEL", +- range); ++ range, 0); + return -1; + } + + if (!(*ucontextp = strdup(*ucontextp))) { + log_it(u->name, getpid(), "strdup FAILED for MLS_LEVEL", +- range); ++ range, 0); + return -1; + } + context_free(ccon); +@@ -311,7 +314,7 @@ static int cron_get_job_range(user *u, s + } + else if (!(*ucontextp = strdup(u->scontext))) { + log_it(u->name, getpid(), "strdup FAILED for MLS_LEVEL", +- range); ++ range, 0); + return -1; + } + +@@ -321,6 +324,8 @@ static int cron_get_job_range(user *u, s + + #ifdef WITH_SELINUX + static int cron_change_selinux_range(user *u,security_context_t ucontext) { ++ char *msg = NULL; ++ + if (is_selinux_enabled() <= 0) + return 0; + +@@ -329,14 +334,14 @@ static int cron_change_selinux_range(use + { + log_it( u->name, getpid(), + "NULL security context for user", +- ""); ++ "", 0); + return -1; + } + else { + log_it( u->name, getpid(), + "NULL security context for user, " + "but SELinux in permissive mode, continuing", +- ""); ++ "", 0); + return 0; + } + } +@@ -345,46 +350,48 @@ static int cron_change_selinux_range(use + if (!cron_authorize_range( u->scontext, ucontext)) { + if (security_getenforce() > 0) { + #ifdef WITH_AUDIT +- char *msg = NULL; + if (asprintf(&msg, "cron: Unauthorized MLS range acct=%s new_scontext=%s old_scontext=%s", + u->name, (char*)ucontext, u->scontext) >= 0) { + int audit_fd = audit_open(); + audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE, msg, NULL, NULL, NULL, 0); + close(audit_fd); ++ free(msg); + } +- free(msg); + #endif +- syslog(LOG_ERR, +- "CRON (%s) ERROR:" +- "Unauthorized range %s in MLS_LEVEL for user %s", +- u->name, (char*)ucontext, u->scontext); ++ if (asprintf(&msg, "Unauthorized range in %s for user range in %s", ++ (char*)ucontext, u->scontext) >= 0) { ++ log_it(u->name, getpid(), "ERROR", msg, 0); ++ free(msg); ++ } + return -1; + } + else { +- syslog(LOG_INFO, +- "CRON (%s) WARNING:" +- "Unauthorized range %s in MLS_LEVEL for user %s," +- " but SELinux in permissive mode, continuing", +- u->name, (char*)ucontext, u->scontext); ++ if (asprintf(&msg, "Unauthorized range in %s for user range in %s," ++ " but SELinux in permissive mod, continuing", ++ (char*)ucontext, u->scontext) >= 0) { ++ log_it(u->name, getpid(), "WARNING", msg, 0); ++ free(msg); ++ } + } + } + } + + if (setexeccon(ucontext) < 0 || setkeycreatecon(ucontext) < 0) { + if (security_getenforce() > 0) { +- syslog(LOG_ERR, +- "CRON (%s) ERROR:" +- "Could not set exec or keycreate context to %s for user", +- u->name, (char*)ucontext); ++ if (asprintf(&msg, "Could not set exec or keycreate context to %s for user", ++ (char*)ucontext) >= 0) { ++ log_it(u->name, getpid(), "ERROR", msg, 0); ++ free(msg); ++ } + return -1; + } + else { +- syslog(LOG_ERR, +- "CRON (%s) ERROR:" +- "Could not set exec or keycreate context to %s for user," +- " but SELinux in permissive mode, continuing", +- u->name, (char*)ucontext); +- ++ if (asprintf(&msg, "Could not set exec or keycreate context to %s for user," ++ " but SELinux in permissive mode, continuing", ++ (char*)ucontext) >= 0) { ++ log_it(u->name, getpid(), "WARNING", msg, 0); ++ free(msg); ++ } + return 0; + } + } +@@ -410,7 +417,7 @@ int get_security_context( const char *na + + if (name != NULL) { + if (getseuserbyname(name, &seuser, &level) < 0) { +- log_it(name, getpid(), "getseuserbyname FAILED", name); ++ log_it(name, getpid(), "getseuserbyname FAILED", name, 0); + return (security_getenforce() > 0); + } + } +@@ -420,21 +427,21 @@ int get_security_context( const char *na + free(level); + if (retval) { + if (security_getenforce() > 0) { +- log_it(name, getpid(), "No SELinux security context",tabname); ++ log_it(name, getpid(), "No SELinux security context", tabname, 0); + return -1; + } else { +- log_it(name, getpid(), "No security context but SELinux in permissive mode, continuing",tabname); ++ log_it(name, getpid(), "No security context but SELinux in permissive mode, continuing", tabname, 0); + return 0; + } + } + + if (fgetfilecon(crontab_fd, &file_context) < OK) { + if (security_getenforce() > 0) { +- log_it(name, getpid(), "getfilecon FAILED", tabname); ++ log_it(name, getpid(), "getfilecon FAILED", tabname, 0); + freecon(scontext); + return -1; + } else { +- log_it(name, getpid(), "getfilecon FAILED but SELinux in permissive mode, continuing", tabname); ++ log_it(name, getpid(), "getfilecon FAILED but SELinux in permissive mode, continuing", tabname, 0); + *rcontext=scontext; + return 0; + } +@@ -444,13 +451,13 @@ int get_security_context( const char *na + freecon(scontext); + freecon(file_context); + if (security_getenforce() > 0) { +- log_it(name, getpid(), "Unauthorized SELinux context", tabname); ++ log_it(name, getpid(), "Unauthorized SELinux context", tabname, 0); + return -1; + } + else { + log_it(name, getpid(), + "Unauthorized SELinux context, but SELinux in permissive mode, continuing", +- tabname); ++ tabname, 0); + return 0; + } + } +@@ -496,7 +503,7 @@ static char ** build_env(char **cronenv) + + while ((cronvar = cronenv[count++])) { + if (!(jobenv = env_set(jobenv, cronvar))) { +- syslog(LOG_ERR, "Setting Cron environment variable %s failed", cronvar); ++ log_it("CRON", getpid(), "Setting Cron environment variable failed", cronvar, 0); + return NULL; + } + } +diff -up cronie-1.1/src/user.c.logging cronie-1.1/src/user.c +--- cronie-1.1/src/user.c.logging 2008-05-30 11:29:46.000000000 +0200 ++++ cronie-1.1/src/user.c 2008-06-17 16:41:55.000000000 +0200 +@@ -32,7 +32,7 @@ static const char *FileName; + + static void + log_error(const char *msg) { +- syslog(LOG_ERR,"CRON: error in (%s) problem is (%s)",FileName,msg); ++ log_it("CRON", getpid(), msg, FileName, 0); + } + + void +@@ -59,7 +59,8 @@ load_user(int crontab_fd, struct passwd + char **envp, **tenvp; + + if (!(file = fdopen(crontab_fd, "r"))) { +- perror("fdopen on crontab_fd in load_user"); ++ int save_errno = errno; ++ log_it(uname, getpid(), "FAILED", "fdopen on crontab_fd in load_user", save_errno); + return (NULL); + } + diff --git a/cronie.spec b/cronie.spec index f721280..d35b946 100644 --- a/cronie.spec +++ b/cronie.spec @@ -6,12 +6,17 @@ Summary: Cron daemon for executing programs at set times Name: cronie Version: 1.1 -Release: 2%{?dist} +Release: 3%{?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 +Patch1: cronie-1.1-keycreatecon.patch +Patch2: cronie-1.1-logging.patch +Patch3: cronie-1.1-cleanup.patch +Patch4: cronie-1.1-inotify-fixes.patch + Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: syslog, bash >= 2.0 @@ -45,6 +50,10 @@ SELinux. %prep %setup -q +%patch1 -p1 -b .keycreatecon +%patch2 -p1 -b .logging +%patch3 -p1 -b .cleanup +%patch4 -p1 -b .inotify-fixes %build @@ -124,6 +133,12 @@ cp -a /var/lock/subsys/crond /var/lock/subsys/cronie > /dev/null 2>&1 ||: %config(noreplace) %{_sysconfdir}/cron.deny %changelog +* Tue Jun 17 2008 Tomas Mraz - 1.1-3 +- fix setting keycreate context +- unify logging a bit +- cleanup some warnings and fix a typo in TZ code +- 450993 improve and fix inotify support + * Wed Jun 4 2008 Marcela Maslanova - 1.1-2 - 49864 upgrade/update problem. Syntax error in spec.