From 3044942227777537c27f6579e98b878e59fd1686 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 31 2019 14:52:42 +0000 Subject: import cronie-1.4.11-23.el7 --- diff --git a/.cronie.metadata b/.cronie.metadata new file mode 100644 index 0000000..a7c5a2d --- /dev/null +++ b/.cronie.metadata @@ -0,0 +1 @@ +1a8d3648f5b7082c50128a06377a1194da668899 SOURCES/cronie-1.4.11.tar.gz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..238f8b5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/cronie-1.4.11.tar.gz diff --git a/SOURCES/cronie-1.4.11-anacron-mailto.patch b/SOURCES/cronie-1.4.11-anacron-mailto.patch new file mode 100644 index 0000000..12078d0 --- /dev/null +++ b/SOURCES/cronie-1.4.11-anacron-mailto.patch @@ -0,0 +1,90 @@ +diff -up cronie-1.4.11/anacron/runjob.c.mailto cronie-1.4.11/anacron/runjob.c +--- cronie-1.4.11/anacron/runjob.c.mailto 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/anacron/runjob.c 2017-03-07 14:00:06.968348389 +0100 +@@ -88,10 +88,18 @@ static char * + username(void) + { + struct passwd *ps; ++ static char *user; ++ ++ if (user) ++ return user; + + ps = getpwuid(geteuid()); +- if (ps == NULL) die_e("getpwuid() error"); +- return ps->pw_name; ++ if (ps == NULL || ps->pw_name == NULL) die_e("getpwuid() error"); ++ ++ user = strdup(ps->pw_name); ++ if (user == NULL) die_e("memory allocation error"); ++ ++ return user; + } + + static void +@@ -167,6 +175,12 @@ launch_mailer(job_rec *jr) + pid_t pid; + struct stat buf; + ++ if (jr->mailto == NULL) ++ { ++ explain("Empty MAILTO set, not mailing output"); ++ return; ++ } ++ + /* Check that we have a way of sending mail. */ + if(stat(SENDMAIL, &buf)) + { +@@ -245,14 +259,12 @@ launch_job(job_rec *jr) + } + + setup_env(jr); +- ++ + /* Get the destination email address if set, or current user otherwise */ + mailto = getenv("MAILTO"); + +- if (mailto) +- jr->mailto = mailto; +- else +- jr->mailto = username (); ++ if (mailto == NULL) ++ mailto = username(); + + /* create temporary file for stdout and stderr of the job */ + temp_file(jr); fd = jr->output_fd; +@@ -262,11 +274,7 @@ launch_job(job_rec *jr) + xwrite(fd, username()); + xwrite(fd, ">\n"); + xwrite(fd, "To: "); +- if (mailto) { +- xwrite(fd, mailto); +- } else { +- xwrite(fd, username()); +- } ++ xwrite(fd, mailto); + xwrite(fd, "\n"); + xwrite(fd, "Content-Type: text/plain; charset=\""); + xwrite(fd, nl_langinfo(CODESET)); +@@ -277,6 +285,12 @@ launch_job(job_rec *jr) + xwrite(fd, hostname); + xwrite(fd, "\n\n"); + ++ if (*mailto == '\0') ++ jr->mailto = NULL; ++ else ++ /* ugly but works without strdup() */ ++ jr->mailto = mailto; ++ + jr->mail_header_size = file_size(fd); + + pid = xfork(); +@@ -305,7 +319,7 @@ tend_job(job_rec *jr, int status) + if (file_size(jr->output_fd) > jr->mail_header_size) mail_output = 1; + else mail_output = 0; + +- m = mail_output ? " (mailing output)" : ""; ++ m = mail_output ? " (produced output)" : ""; + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) + explain("Job `%s' terminated%s", jr->ident, m); + else if (WIFEXITED(status)) diff --git a/SOURCES/cronie-1.4.11-crontab-root.patch b/SOURCES/cronie-1.4.11-crontab-root.patch new file mode 100644 index 0000000..5002eec --- /dev/null +++ b/SOURCES/cronie-1.4.11-crontab-root.patch @@ -0,0 +1,12 @@ +diff -up cronie-1.4.11/src/crontab.c.root cronie-1.4.11/src/crontab.c +--- cronie-1.4.11/src/crontab.c.root 2017-03-07 13:52:23.000000000 +0100 ++++ cronie-1.4.11/src/crontab.c 2017-03-07 13:53:40.491278915 +0100 +@@ -170,7 +170,7 @@ int main(int argc, char *argv[]) { + } + + #if defined(WITH_PAM) +- if (cron_start_pam(pw) != PAM_SUCCESS) { ++ if (getuid() != 0 && cron_start_pam(pw) != PAM_SUCCESS) { + fprintf(stderr, + "You (%s) are not allowed to access to (%s) because of pam configuration.\n", + User, ProgramName); diff --git a/SOURCES/cronie-1.4.11-empty-var.patch b/SOURCES/cronie-1.4.11-empty-var.patch new file mode 100644 index 0000000..1fc00e8 --- /dev/null +++ b/SOURCES/cronie-1.4.11-empty-var.patch @@ -0,0 +1,12 @@ +diff -up cronie-1.4.11/src/env.c.empty-var cronie-1.4.11/src/env.c +--- cronie-1.4.11/src/env.c.empty-var 2017-03-07 15:17:14.604948015 +0100 ++++ cronie-1.4.11/src/env.c 2017-09-15 15:38:24.275112187 +0200 +@@ -255,7 +255,7 @@ int load_env(char *envstr, FILE * f) { + abort(); + } + } +- if (state != FINI && !(state == VALUE && !quotechar)) { ++ if (state != FINI && state != EQ2 && !(state == VALUE && !quotechar)) { + Debug(DPARS, ("load_env, not an env var, state = %d\n", state)); + fseek(f, filepos, 0); + Set_LineNum(fileline); diff --git a/SOURCES/cronie-1.4.11-fcntl_locking.patch b/SOURCES/cronie-1.4.11-fcntl_locking.patch new file mode 100644 index 0000000..66bcdcc --- /dev/null +++ b/SOURCES/cronie-1.4.11-fcntl_locking.patch @@ -0,0 +1,38 @@ +diff -up cronie-1.4.11/src/misc.c.ddd cronie-1.4.11/src/misc.c +--- cronie-1.4.11/src/misc.c.ddd 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/misc.c 2013-08-30 13:51:22.227040980 +0200 +@@ -75,7 +75,9 @@ static int LogFD = ERR; + static int syslog_open = FALSE; + #endif + +-#if defined(HAVE_FCNTL) && defined(F_SETLK) ++#if defined(HAVE_FLOCK) ++# define trylock_file(fd) flock((fd), LOCK_EX|LOCK_NB) ++#elif defined(HAVE_FCNTL) && defined(F_SETLK) + static int trylock_file(int fd) { + struct flock fl; + +@@ -89,8 +91,6 @@ static int trylock_file(int fd) { + } + #elif defined(HAVE_LOCKF) + # define trylock_file(fd) lockf((fd), F_TLOCK, 0) +-#elif defined(HAVE_FLOCK) +-# define trylock_file(fd) flock((fd), LOCK_EX|LOCK_NB) + #endif + + /* +@@ -346,6 +346,14 @@ void acquire_daemonlock(int closeflag) { + (void) fcntl(fd, F_SETFD, 1); + } + ++#if !defined(HAVE_FLOCK) ++ else { ++ /* Racy but better than nothing, just hope the parent exits */ ++ sleep(0); ++ trylock_file(fd); ++ } ++#endif ++ + sprintf(buf, "%ld\n", (long) pid); + (void) lseek(fd, (off_t) 0, SEEK_SET); + len = strlen(buf); diff --git a/SOURCES/cronie-1.4.11-inherit-path.patch b/SOURCES/cronie-1.4.11-inherit-path.patch new file mode 100644 index 0000000..ec42692 --- /dev/null +++ b/SOURCES/cronie-1.4.11-inherit-path.patch @@ -0,0 +1,25 @@ +diff --git a/src/entry.c b/src/entry.c +index 3638207..ce37756 100644 +--- a/src/entry.c ++++ b/src/entry.c +@@ -343,8 +343,18 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw, + e->envp = tenvp; + #ifndef LOGIN_CAP + /* If login.conf is in used we will get the default PATH later. */ +- if (ChangePath && !env_get("PATH", e->envp)) { +- if (glue_strings(envstr, sizeof envstr, "PATH", _PATH_DEFPATH, '=')) { ++ if (!env_get("PATH", e->envp)) { ++ char *defpath; ++ ++ if (ChangePath) ++ defpath = _PATH_DEFPATH; ++ else { ++ defpath = getenv("PATH"); ++ if (defpath == NULL) ++ defpath = _PATH_DEFPATH; ++ } ++ ++ if (glue_strings(envstr, sizeof envstr, "PATH", defpath, '=')) { + if ((tenvp = env_set(e->envp, envstr)) == NULL) { + ecode = e_memory; + goto eof; diff --git a/SOURCES/cronie-1.4.11-man-debug.patch b/SOURCES/cronie-1.4.11-man-debug.patch new file mode 100644 index 0000000..0178295 --- /dev/null +++ b/SOURCES/cronie-1.4.11-man-debug.patch @@ -0,0 +1,25 @@ +diff -up cronie-1.4.11/man/cron.8.old cronie-1.4.11/man/cron.8 +--- cronie-1.4.11/man/cron.8.old 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/man/cron.8 2013-10-04 16:34:31.248401373 +0200 +@@ -22,7 +22,7 @@ + .\" + .\" $Id: cron.8,v 1.8 2004/01/23 19:03:32 vixie Exp $ + .\" +-.TH CRON "8" "2013-01-02" "cronie" "System Administration" ++.TH CRON "8" "2013-09-26" "cronie" "System Administration" + .SH NAME + crond \- daemon to execute scheduled commands + .SH SYNOPSIS +@@ -160,7 +160,11 @@ will disable the sending of mail. + .TP + .B "\-n" + Tells the daemon to run in the foreground. This can be useful when +-starting it out of init. ++starting it out of init. With this option is needed to change pam setting. ++.I /etc/pam.d/crond ++must not enable ++.I pam_loginuid.so ++module. + .TP + .B "\-p" + Allows diff --git a/SOURCES/cronie-1.4.11-man-file.patch b/SOURCES/cronie-1.4.11-man-file.patch new file mode 100644 index 0000000..6309a68 --- /dev/null +++ b/SOURCES/cronie-1.4.11-man-file.patch @@ -0,0 +1,15 @@ +diff -up cronie-1.4.11/man/crontab.1.man-file cronie-1.4.11/man/crontab.1 +--- cronie-1.4.11/man/crontab.1.man-file 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/man/crontab.1 2017-03-07 13:56:19.650013901 +0100 +@@ -44,8 +44,9 @@ crontab \- maintains crontab files for i + .BR -c + .SH DESCRIPTION + .I Crontab +-is the program used to install, remove or list the tables used to serve +-the ++is the program used to install a crontab table ++.IR file , ++remove or list the existing tables used to serve the + .BR cron (8) + daemon. Each user can have their own crontab, and though these are files + in diff --git a/SOURCES/cronie-1.4.11-no-pam.patch b/SOURCES/cronie-1.4.11-no-pam.patch new file mode 100644 index 0000000..c042c19 --- /dev/null +++ b/SOURCES/cronie-1.4.11-no-pam.patch @@ -0,0 +1,23 @@ +diff -up cronie-1.4.11/src/security.c.no-pam cronie-1.4.11/src/security.c +--- cronie-1.4.11/src/security.c.no-pam 2017-03-07 15:17:14.610948157 +0100 ++++ cronie-1.4.11/src/security.c 2017-09-15 09:36:26.709112459 +0200 +@@ -86,6 +86,7 @@ static int cron_open_pam_session(struct + if (pam_session_opened != 0) \ + pam_close_session(pamh, PAM_SILENT); \ + pam_end(pamh, retcode); \ ++ pamh = NULL; \ + } \ + return(retcode); } + #endif +@@ -221,7 +222,10 @@ void cron_close_pam(void) { + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); + pam_close_session(pamh, PAM_SILENT); + } +- pam_end(pamh, PAM_SUCCESS); ++ if (pamh != NULL) { ++ pam_end(pamh, PAM_SUCCESS); ++ pamh = NULL; ++ } + #endif + } + diff --git a/SOURCES/cronie-1.4.11-pamenv.patch b/SOURCES/cronie-1.4.11-pamenv.patch new file mode 100644 index 0000000..6faae8f --- /dev/null +++ b/SOURCES/cronie-1.4.11-pamenv.patch @@ -0,0 +1,51 @@ +diff -up cronie-1.4.11/src/security.c.ppp cronie-1.4.11/src/security.c +--- cronie-1.4.11/src/security.c.ppp 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/security.c 2013-08-30 14:00:15.263788467 +0200 +@@ -129,15 +129,13 @@ int cron_set_job_security_context(entry + } + #endif + +- *jobenv = build_env(e->envp); +- + #ifdef WITH_SELINUX + /* we must get the crontab context BEFORE changing user, else + * we'll not be permitted to read the cron spool directory :-) + */ + security_context_t ucontext = 0; + +- if (cron_get_job_range(u, &ucontext, *jobenv) < OK) { ++ if (cron_get_job_range(u, &ucontext, e->envp) < OK) { + log_it(e->pwd->pw_name, getpid(), "ERROR", + "failed to get SELinux context", 0); + return -1; +@@ -165,6 +163,8 @@ int cron_set_job_security_context(entry + return -1; + } + ++ *jobenv = build_env(e->envp); ++ + time_t job_run_time = time(0L); + + if ((minutely_time > 0) && ((job_run_time / 60) != (minutely_time / 60))) { +@@ -615,11 +615,18 @@ int crontab_security_access(void) { + */ + static char **build_env(char **cronenv) { + #ifdef WITH_PAM +- char **jobenv; +- char **pamenv = pam_getenvlist(pamh); ++ char **jobenv = pam_getenvlist(pamh); + char *cronvar; + int count = 0; +- jobenv = env_copy(pamenv); ++ ++ if (jobenv == NULL) { ++ jobenv = env_init(); ++ if (jobenv == NULL) { ++ log_it("CRON", getpid(), ++ "ERROR", "Initialization of cron environment variables failed", 0); ++ return NULL; ++ } ++ } + + /* Now add the cron environment variables. Since env_set() + * overwrites existing variables, this will let cron's diff --git a/SOURCES/cronie-1.4.11-race-on-crontab-modification.patch b/SOURCES/cronie-1.4.11-race-on-crontab-modification.patch new file mode 100644 index 0000000..6374b96 --- /dev/null +++ b/SOURCES/cronie-1.4.11-race-on-crontab-modification.patch @@ -0,0 +1,114 @@ +diff -ru cronie-1.4.11/src/database.c cronie-1.4.11_patched/src/database.c +--- cronie-1.4.11/src/database.c 2018-10-19 15:29:55.630225195 +0200 ++++ cronie-1.4.11_patched/src/database.c 2018-10-19 15:32:14.552093860 +0200 +@@ -48,6 +48,7 @@ + #include "pathnames.h" + + #define TMAX(a,b) ((a)>(b)?(a):(b)) ++#define TMIN(a,b) ((a)<(b)?(a):(b)) + + /* size of the event structure, not counting name */ + #define EVENT_SIZE (sizeof (struct inotify_event)) +@@ -237,6 +238,8 @@ + if ((crontab_fd = check_open(tabname, uname, pw, &mtime)) == -1) + goto next_crontab; + ++ mtime = TMIN(new_db->mtime, mtime); ++ + Debug(DLOAD, ("\t%s:", fname)); + + if (old_db != NULL) +@@ -261,7 +264,7 @@ + * we finish with the crontab... + */ + Debug(DLOAD, (" [delete old data]")); +- unlink_user(old_db, u); ++ unlink_user(old_db, u); + free_user(u); + log_it(fname, getpid(), "RELOAD", tabname, 0); + } +@@ -328,18 +331,18 @@ + cron_db new_db; + DIR_T *dp; + DIR *dir; +- struct timeval time; ++ struct timeval timev; + fd_set rfds; + int retval; + char buf[BUF_LEN]; + pid_t pid = getpid(); +- time.tv_sec = 0; +- time.tv_usec = 0; ++ timev.tv_sec = 0; ++ timev.tv_usec = 0; + + FD_ZERO(&rfds); + FD_SET(old_db->ifd, &rfds); + +- retval = select(old_db->ifd + 1, &rfds, NULL, NULL, &time); ++ retval = select(old_db->ifd + 1, &rfds, NULL, NULL, &timev); + if (retval == -1) { + if (errno != EINTR) + log_it("CRON", pid, "INOTIFY", "select failed", errno); +@@ -348,6 +351,7 @@ + else if (FD_ISSET(old_db->ifd, &rfds)) { + new_db.head = new_db.tail = NULL; + new_db.ifd = old_db->ifd; ++ new_db.mtime = time(NULL) - 1; + while ((retval = read(old_db->ifd, buf, sizeof (buf))) == -1 && + errno == EINTR) ; + +@@ -452,14 +456,17 @@ + DIR *dir; + pid_t pid = getpid(); + int is_local = 0; ++ time_t now; + + 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) { ++ now = time(NULL); ++ ++ /* 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", pid, "STAT FAILED", SPOOL_DIR, errno); + statbuf.st_mtime = 0; + } +@@ -492,13 +499,17 @@ + * Note that old_db->mtime is initialized to 0 in main(), and + * so is guaranteed to be different than the stat() mtime the first + * time this function is called. ++ * ++ * We also use now - 1 as the upper bound of timestamp to avoid race, ++ * when a crontab is updated twice in a single second when we are ++ * just reading it. + */ +- if (old_db->mtime == TMAX(crond_stat.st_mtime, +- TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) ++ if (old_db->mtime == TMIN(now - 1, TMAX(crond_stat.st_mtime, ++ TMAX(statbuf.st_mtime, syscron_stat.st_mtime))) + ) { + Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", + (long) pid)); +- return 0; ++ return 0; + } + + /* something's different. make a new database, moving unchanged +@@ -506,8 +517,7 @@ + * actually changed. Whatever is left in the old database when + * we're done is chaff -- crontabs that disappeared. + */ +- new_db.mtime = TMAX(crond_stat.st_mtime, +- TMAX(statbuf.st_mtime, syscron_stat.st_mtime)); ++ new_db.mtime = now - 1; + new_db.head = new_db.tail = NULL; + #if defined WITH_INOTIFY + new_db.ifd = old_db->ifd; diff --git a/SOURCES/cronie-1.4.11-refresh-users.patch b/SOURCES/cronie-1.4.11-refresh-users.patch new file mode 100644 index 0000000..f757244 --- /dev/null +++ b/SOURCES/cronie-1.4.11-refresh-users.patch @@ -0,0 +1,243 @@ +diff -up cronie-1.4.11/src/cron.c.refresh-users cronie-1.4.11/src/cron.c +--- cronie-1.4.11/src/cron.c.refresh-users 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/cron.c 2015-04-21 14:43:11.205438697 +0200 +@@ -525,7 +525,6 @@ static void find_jobs(int vtime, cron_db + int minute, hour, dom, month, dow; + user *u; + entry *e; +- const char *uname; + + /* The support for the job-specific timezones is not perfect. There will + * be jobs missed or run twice during the DST change in the job timezone. +@@ -562,16 +561,11 @@ static void find_jobs(int vtime, cron_db + */ + for (u = db->head; u != NULL; u = u->next) { + for (e = u->crontab; e != NULL; e = e->next) { +- Debug(DSCH | DEXT, ("user [%s:%ld:%ld:...] cmd=\"%s\"\n", +- e->pwd->pw_name, (long) e->pwd->pw_uid, +- (long) e->pwd->pw_gid, e->cmd)); +- uname = e->pwd->pw_name; +- /* check if user exists in time of job is being run f.e. ldap */ +- if (getpwnam(uname) != NULL) { + time_t virtualSecond = (vtime - e->delay) * SECONDS_PER_MINUTE; + time_t virtualGMTSecond = virtualSecond - vGMToff; + job_tz = env_get("CRON_TZ", e->envp); + maketime(job_tz, orig_tz); ++ + /* here we test whether time is NOW */ + if (bit_test(e->minute, minute) && + bit_test(e->hour, hour) && +@@ -591,10 +585,9 @@ static void find_jobs(int vtime, cron_db + !(e->flags & (MIN_STAR | HR_STAR))) || + (doWild && (e->flags & (MIN_STAR | HR_STAR)))) + job_add(e, u); /*will add job, if it isn't in queue already for NOW. */ +- } +- } +- } +- } ++ } ++ } ++ } + if (orig_tz != NULL) + setenv("TZ", orig_tz, 1); + else +diff -up cronie-1.4.11/src/database.c.refresh-users cronie-1.4.11/src/database.c +--- cronie-1.4.11/src/database.c.refresh-users 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/database.c 2015-04-21 15:20:03.768846359 +0200 +@@ -152,10 +152,41 @@ check_orphans(cron_db *db) { + } + } + ++static int ++find_orphan(const char *uname, const char *fname, const char *tabname) { ++ orphan *o; ++ ++ for (o = orphans; o != NULL; o = o->next) { ++ if (uname && o->uname) { ++ if (strcmp(uname, o->uname) != 0) ++ continue; ++ } else if (uname != o->uname) ++ continue; ++ ++ if (fname && o->fname) { ++ if (strcmp(fname, o->fname) != 0) ++ continue; ++ } else if (fname != o->fname) ++ continue; ++ ++ if (tabname && o->tabname) { ++ if (strcmp(tabname, o->tabname) != 0) ++ continue; ++ } else if (tabname != o->tabname) ++ continue; ++ return 1; ++ } ++ ++ return 0; ++} ++ + static void + add_orphan(const char *uname, const char *fname, const char *tabname) { + orphan *o; + ++ if (find_orphan(uname, fname, tabname)) ++ return; ++ + o = calloc(1, sizeof(*o)); + if (o == NULL) + return; +diff -up cronie-1.4.11/src/entry.c.refresh-users cronie-1.4.11/src/entry.c +--- cronie-1.4.11/src/entry.c.refresh-users 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/entry.c 2015-04-21 14:40:13.473310662 +0200 +@@ -99,6 +99,7 @@ entry *load_entry(FILE * file, void (*er + char envstr[MAX_ENVSTR]; + char **tenvp; + char *p; ++ struct passwd temppw; + + Debug(DPARS, ("load_entry()...about to eat comments\n")); + +@@ -286,11 +287,15 @@ entry *load_entry(FILE * file, void (*er + + pw = getpwnam(username); + if (pw == NULL) { +- ecode = e_username; +- goto eof; +- } +- Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n", ++ Debug(DPARS, ("load_entry()...unknown user entry\n")); ++ memset(&temppw, 0, sizeof (temppw)); ++ temppw.pw_name = username; ++ temppw.pw_passwd = ""; ++ pw = &temppw; ++ } else { ++ Debug(DPARS, ("load_entry()...uid %ld, gid %ld\n", + (long) pw->pw_uid, (long) pw->pw_gid)); ++ } + } + + if ((e->pwd = pw_dup(pw)) == NULL) { +@@ -331,17 +336,11 @@ entry *load_entry(FILE * file, void (*er + else + log_it("CRON", getpid(), "ERROR", "can't set SHELL", 0); + } +- if (!env_get("HOME", e->envp)) { +- if (glue_strings(envstr, sizeof envstr, "HOME", pw->pw_dir, '=')) { +- if ((tenvp = env_set(e->envp, envstr)) == NULL) { +- ecode = e_memory; +- goto eof; +- } +- e->envp = tenvp; +- } +- else +- log_it("CRON", getpid(), "ERROR", "can't set HOME", 0); ++ if ((tenvp = env_update_home(e->envp, pw->pw_dir)) == NULL) { ++ ecode = e_memory; ++ goto eof; + } ++ e->envp = tenvp; + #ifndef LOGIN_CAP + /* If login.conf is in used we will get the default PATH later. */ + if (ChangePath && !env_get("PATH", e->envp)) { +diff -up cronie-1.4.11/src/env.c.refresh-users cronie-1.4.11/src/env.c +--- cronie-1.4.11/src/env.c.refresh-users 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/env.c 2015-04-21 14:40:13.473310662 +0200 +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + #include + + #include "globals.h" +@@ -291,3 +292,19 @@ char *env_get(const char *name, char **e + } + return (NULL); + } ++ ++char **env_update_home(char **envp, const char *dir) { ++ char envstr[MAX_ENVSTR]; ++ ++ if (dir == NULL || *dir == '\0' || env_get("HOME", envp)) { ++ return envp; ++ } ++ ++ if (glue_strings(envstr, sizeof envstr, "HOME", dir, '=')) { ++ envp = env_set(envp, envstr); ++ } ++ else ++ log_it("CRON", getpid(), "ERROR", "can't set HOME", 0); ++ ++ return envp; ++} +diff -up cronie-1.4.11/src/funcs.h.refresh-users cronie-1.4.11/src/funcs.h +--- cronie-1.4.11/src/funcs.h.refresh-users 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/funcs.h 2015-04-21 14:40:13.473310662 +0200 +@@ -82,7 +82,8 @@ char *env_get(const char *, char **), + *first_word(const char *, const char *), + **env_init(void), + **env_copy(char **), +- **env_set(char **, const char *); ++ **env_set(char **, const char *), ++ **env_update_home(char **, const char *); + + user *load_user(int, struct passwd *, const char *, const char *, const char *), + *find_user(cron_db *, const char *, const char *); +diff -up cronie-1.4.11/src/job.c.refresh-users cronie-1.4.11/src/job.c +--- cronie-1.4.11/src/job.c.refresh-users 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/src/job.c 2015-04-21 14:40:13.474310685 +0200 +@@ -22,6 +22,11 @@ + #include "config.h" + + #include ++#include ++#include ++#include ++#include ++#include + + #include "funcs.h" + #include "globals.h" +@@ -36,12 +41,42 @@ static job *jhead = NULL, *jtail = NULL; + + void job_add(entry * e, user * u) { + job *j; ++ struct passwd *newpwd; ++ struct passwd *temppwd; ++ const char *uname; + + /* if already on queue, keep going */ + for (j = jhead; j != NULL; j = j->next) + if (j->e == e && j->u == u) + return; + ++ uname = e->pwd->pw_name; ++ /* check if user exists in time of job is being run f.e. ldap */ ++ if ((temppwd = getpwnam(uname)) != NULL) { ++ char **tenvp; ++ ++ Debug(DSCH | DEXT, ("user [%s:%ld:%ld:...] cmd=\"%s\"\n", ++ e->pwd->pw_name, (long) temppwd->pw_uid, ++ (long) temppwd->pw_gid, e->cmd)); ++ if ((newpwd = pw_dup(temppwd)) == NULL) { ++ log_it(uname, getpid(), "ERROR", "memory allocation failed", errno); ++ return; ++ } ++ free(e->pwd); ++ e->pwd = newpwd; ++ ++ if ((tenvp = env_update_home(e->envp, e->pwd->pw_dir)) == NULL) { ++ log_it(uname, getpid(), "ERROR", "memory allocation failed", errno); ++ return; ++ } ++ e->envp = tenvp; ++ } else { ++ log_it(uname, getpid(), "ERROR", "getpwnam() failed",errno); ++ Debug(DSCH | DEXT, ("%s:%d pid=%d time=%ld getpwnam(%s) failed errno=%d error=%s\n", ++ __FILE__,__LINE__,getpid(),time(NULL),uname,errno,strerror(errno))); ++ return; ++ } ++ + /* build a job queue element */ + if ((j = (job *) malloc(sizeof (job))) == NULL) + return; diff --git a/SOURCES/cronie-1.4.11-restart-on-failure.patch b/SOURCES/cronie-1.4.11-restart-on-failure.patch new file mode 100644 index 0000000..5e9a7ff --- /dev/null +++ b/SOURCES/cronie-1.4.11-restart-on-failure.patch @@ -0,0 +1,12 @@ +diff -ru cronie-1.4.11/contrib/cronie.systemd cronie-1.4.11_patched/contrib/cronie.systemd +--- cronie-1.4.11/contrib/cronie.systemd 2018-11-27 15:26:46.797288342 +0100 ++++ cronie-1.4.11_patched/contrib/cronie.systemd 2018-11-27 15:26:19.479159225 +0100 +@@ -7,6 +7,8 @@ + ExecStart=/usr/sbin/crond -n $CRONDARGS + ExecReload=/bin/kill -HUP $MAINPID + KillMode=process ++Restart=on-failure ++RestartSec=30s + + [Install] + WantedBy=multi-user.target diff --git a/SOURCES/cronie-1.4.11-selinux-user.patch b/SOURCES/cronie-1.4.11-selinux-user.patch new file mode 100644 index 0000000..d2db9ec --- /dev/null +++ b/SOURCES/cronie-1.4.11-selinux-user.patch @@ -0,0 +1,55 @@ +diff -up cronie-1.4.11/src/security.c.selinux-user cronie-1.4.11/src/security.c +--- cronie-1.4.11/src/security.c.selinux-user 2017-03-07 13:52:23.076462218 +0100 ++++ cronie-1.4.11/src/security.c 2017-03-07 14:47:32.957371610 +0100 +@@ -41,8 +41,6 @@ + #ifdef WITH_SELINUX + # include + # include +-# include +-# include + # include + #endif + +@@ -476,7 +474,9 @@ get_security_context(const char *name, i + security_context_t scontext = NULL; + security_context_t file_context = NULL; + security_context_t rawcontext=NULL; +- int retval = 0; ++ context_t current_context = NULL; ++ int retval; ++ char *current_context_str = NULL; + char *seuser = NULL; + char *level = NULL; + +@@ -490,10 +490,29 @@ get_security_context(const char *name, i + log_it(name, getpid(), "getseuserbyname FAILED", name, 0); + return (security_getenforce() > 0); + } ++ ++ retval = get_default_context_with_level(seuser, level, NULL, &scontext); ++ } ++ else { ++ if (getcon(¤t_context_str) < 0) { ++ log_it(name, getpid(), "getcon FAILED", "", 0); ++ return (security_getenforce() > 0); ++ } ++ ++ current_context = context_new(current_context_str); ++ if (current_context == NULL) { ++ log_it(name, getpid(), "context_new FAILED", current_context_str, 0); ++ freecon(current_context_str); ++ return (security_getenforce() > 0); ++ } ++ ++ const char *current_user = context_user_get(current_context); ++ retval = get_default_context_with_level(current_user, level, NULL, &scontext); ++ ++ freecon(current_context_str); ++ context_free(current_context); + } + +- retval = get_default_context_with_level(name == NULL ? "system_u" : seuser, +- level, NULL, &scontext); + if (selinux_trans_to_raw_context(scontext, &rawcontext) == 0) { + freecon(scontext); + scontext = rawcontext; diff --git a/SOURCES/cronie-1.4.11-shutdown-msg.patch b/SOURCES/cronie-1.4.11-shutdown-msg.patch new file mode 100644 index 0000000..b47bbb5 --- /dev/null +++ b/SOURCES/cronie-1.4.11-shutdown-msg.patch @@ -0,0 +1,12 @@ +diff -up cronie-1.4.11/src/cron.c.shutdown-msg cronie-1.4.11/src/cron.c +--- cronie-1.4.11/src/cron.c.shutdown-msg 2015-04-21 15:29:14.218651528 +0200 ++++ cronie-1.4.11/src/cron.c 2015-04-21 15:29:30.212023639 +0200 +@@ -486,6 +486,8 @@ int main(int argc, char *argv[]) { + log_it("CRON", pid, "INFO", "Inotify close failed", errno); + #endif + ++ log_it("CRON", pid, "INFO", "Shutting down", 0); ++ + (void) unlink(_PATH_CRON_PID); + + return 0; diff --git a/SOURCES/cronie-1.4.11-smartcard-auth.patch b/SOURCES/cronie-1.4.11-smartcard-auth.patch new file mode 100644 index 0000000..931ed39 --- /dev/null +++ b/SOURCES/cronie-1.4.11-smartcard-auth.patch @@ -0,0 +1,14 @@ +diff -ru cronie-1.4.11/pam/crond cronie-1.4.11_patched/pam/crond +--- cronie-1.4.11/pam/crond 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11_patched/pam/crond 2018-12-04 16:01:53.220225842 +0100 +@@ -4,7 +4,7 @@ + # + # No PAM authentication called, auth modules not needed + account required pam_access.so +-account include password-auth ++account include system-auth + session required pam_loginuid.so +-session include password-auth +-auth include password-auth ++session include system-auth ++auth include system-auth diff --git a/SOURCES/cronie-1.4.11-temp-name.patch b/SOURCES/cronie-1.4.11-temp-name.patch new file mode 100644 index 0000000..00291f4 --- /dev/null +++ b/SOURCES/cronie-1.4.11-temp-name.patch @@ -0,0 +1,66 @@ +diff -up cronie-1.4.11/src/crontab.c.temp-name cronie-1.4.11/src/crontab.c +--- cronie-1.4.11/src/crontab.c.temp-name 2016-02-23 15:32:33.754463457 +0100 ++++ cronie-1.4.11/src/crontab.c 2016-02-23 15:33:17.401466818 +0100 +@@ -104,7 +104,7 @@ edit_cmd(void), + poke_daemon(void), + check_error(const char *), parse_args(int c, char *v[]), die(int) ATTRIBUTE_NORETURN; + static int replace_cmd(void), hostset_cmd(void), hostget_cmd(void); +-static char *host_specific_filename(const char *filename, int prefix); ++static char *host_specific_filename(const char *prefix, const char *suffix); + static const char *tmp_path(void); + + static void usage(const char *msg) ATTRIBUTE_NORETURN; +@@ -445,26 +445,27 @@ static const char *tmp_path(void) { + return tmpdir ? tmpdir : "/tmp"; + } + +-static char *host_specific_filename(const char *filename, int prefix) ++static char *host_specific_filename(const char *prefix, const char *suffix) + { + /* + * For cluster-wide use, where there is otherwise risk of the same +- * name being generated on more than one host at once, prefix with +- * "hostname." or suffix with ".hostname" as requested, and return +- * static buffer or NULL on failure. ++ * name being generated on more than one host at once, insert hostname ++ * separated with dots, and return static buffer or NULL on failure. + */ + + static char safename[MAX_FNAME]; +- char hostname[MAXHOSTNAMELEN]; ++ char hostname[MAX_FNAME]; + + if (gethostname(hostname, sizeof hostname) != 0) + return NULL; + + if (prefix) { +- if (!glue_strings(safename, sizeof safename, hostname, filename, '.')) ++ if (!glue_strings(safename, sizeof safename, prefix, hostname, '.')) + return NULL; +- } else { +- if (!glue_strings(safename, sizeof safename, filename, hostname, '.')) ++ strcpy(hostname, safename); ++ } ++ if (suffix) { ++ if (!glue_strings(safename, sizeof safename, hostname, suffix, '.')) + return NULL; + } + +@@ -745,7 +746,7 @@ static int replace_cmd(void) { + char *safename; + + +- safename = host_specific_filename("tmp.XXXXXXXXXX", 1); ++ safename = host_specific_filename("#tmp", "XXXXXXXXXX"); + if (!safename || !glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR, + safename, '/')) { + TempFilename[0] = '\0'; +@@ -911,7 +912,7 @@ static int hostset_cmd(void) { + if (!HostSpecified) + gethostname(Host, sizeof Host); + +- safename = host_specific_filename("tmp.XXXXXXXXXX", 1); ++ safename = host_specific_filename("#tmp", "XXXXXXXXXX"); + if (!safename || !glue_strings(TempFilename, sizeof TempFilename, SPOOL_DIR, + safename, '/')) { + TempFilename[0] = '\0'; diff --git a/SOURCES/cronie-check-config-param.patch b/SOURCES/cronie-check-config-param.patch new file mode 100644 index 0000000..2863e1f --- /dev/null +++ b/SOURCES/cronie-check-config-param.patch @@ -0,0 +1,30 @@ +diff -up cronie-1.4.11/anacron/readtab.c.bla cronie-1.4.11/anacron/readtab.c +--- cronie-1.4.11/anacron/readtab.c.bla 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/anacron/readtab.c 2014-01-27 17:47:41.362138084 +0100 +@@ -271,7 +271,8 @@ parse_tab_line(char *line) + if (strncmp(env_var, "START_HOURS_RANGE", 17) == 0) + { + r = match_rx("^([[:digit:]]+)-([[:digit:]]+)$", value, 2, &from, &to); +- if ((r == -1) || (from == NULL) || (to == NULL)) goto reg_invalid; ++ if (r == -1) goto reg_err; ++ if (r == 0) goto reg_invalid; + range_start = atoi(from); + range_stop = atoi(to); + if (range_stop < range_start) { +@@ -282,6 +283,8 @@ parse_tab_line(char *line) + } + if (strncmp(env_var, "RANDOM_DELAY", 12) == 0) { + r = match_rx("^([[:digit:]]+)$", value, 0); ++ if (r == -1) goto reg_err; ++ if (r == 0) goto reg_invalid; + if (r != -1) { + int i = random(); + double x = 0; +@@ -289,7 +292,6 @@ parse_tab_line(char *line) + random_number = (int)x; + Debug(("Randomized delay set: %d", random_number)); + } +- else goto reg_invalid; + } + if (strncmp(env_var, "PREFERRED_HOUR", 14) == 0) { + r = match_rx("^([[:digit:]]+)$", value, 1, &pref_hour); diff --git a/SOURCES/cronie-systemd.patch b/SOURCES/cronie-systemd.patch new file mode 100644 index 0000000..5a77a19 --- /dev/null +++ b/SOURCES/cronie-systemd.patch @@ -0,0 +1,11 @@ +diff -up cronie-1.4.11/contrib/cronie.systemd.sss cronie-1.4.11/contrib/cronie.systemd +--- cronie-1.4.11/contrib/cronie.systemd.sss 2013-07-18 14:27:08.000000000 +0200 ++++ cronie-1.4.11/contrib/cronie.systemd 2013-08-30 13:37:33.848391897 +0200 +@@ -5,6 +5,7 @@ After=syslog.target auditd.service syste + [Service] + EnvironmentFile=/etc/sysconfig/crond + ExecStart=/usr/sbin/crond -n $CRONDARGS ++KillMode=process + + [Install] + WantedBy=multi-user.target diff --git a/SOURCES/cronie-unitfile.patch b/SOURCES/cronie-unitfile.patch new file mode 100644 index 0000000..bd266ed --- /dev/null +++ b/SOURCES/cronie-unitfile.patch @@ -0,0 +1,16 @@ +diff -up cronie-1.4.11/contrib/cronie.systemd.old cronie-1.4.11/contrib/cronie.systemd +--- cronie-1.4.11/contrib/cronie.systemd.old 2014-01-27 14:31:47.696467385 +0100 ++++ cronie-1.4.11/contrib/cronie.systemd 2014-07-04 15:18:16.000000000 +0200 +@@ -1,10 +1,11 @@ + [Unit] + Description=Command Scheduler +-After=syslog.target auditd.service systemd-user-sessions.service time-sync.target ++After=auditd.service systemd-user-sessions.service time-sync.target + + [Service] + EnvironmentFile=/etc/sysconfig/crond + ExecStart=/usr/sbin/crond -n $CRONDARGS ++ExecReload=/bin/kill -HUP $MAINPID + KillMode=process + + [Install] diff --git a/SPECS/cronie.spec b/SPECS/cronie.spec new file mode 100644 index 0000000..99168de --- /dev/null +++ b/SPECS/cronie.spec @@ -0,0 +1,547 @@ +%bcond_without selinux +%bcond_without pam +%bcond_without audit +%bcond_without inotify + +Summary: Cron daemon for executing programs at set times +Name: cronie +Version: 1.4.11 +Release: 23%{?dist} +License: MIT and BSD and ISC and GPLv2+ +Group: System Environment/Base +URL: https://github.com/cronie-crond/cronie +Source0: https://github.com/cronie-crond/cronie/releases/download/cronie-%{version}/cronie-%{version}.tar.gz + +Patch0: cronie-systemd.patch +Patch1: cronie-1.4.11-fcntl_locking.patch +Patch2: cronie-1.4.11-pamenv.patch +Patch3: cronie-1.4.11-man-debug.patch +Patch4: cronie-check-config-param.patch +Patch5: cronie-unitfile.patch +Patch6: cronie-1.4.11-refresh-users.patch +Patch7: cronie-1.4.11-shutdown-msg.patch +Patch8: cronie-1.4.11-temp-name.patch +Patch9: cronie-1.4.11-anacron-mailto.patch +Patch10: cronie-1.4.11-crontab-root.patch +Patch11: cronie-1.4.11-man-file.patch +Patch12: cronie-1.4.11-selinux-user.patch +Patch13: cronie-1.4.11-no-pam.patch +Patch14: cronie-1.4.11-empty-var.patch +Patch15: cronie-1.4.11-race-on-crontab-modification.patch +Patch16: cronie-1.4.11-inherit-path.patch +Patch17: cronie-1.4.11-smartcard-auth.patch +Patch18: cronie-1.4.11-restart-on-failure.patch + +Requires: dailyjobs + +%if %{with selinux} +Requires: libselinux >= 2.0.64 +Buildrequires: libselinux-devel >= 2.0.64 +%endif +%if %{with pam} +Requires: pam >= 1.0.1 +Buildrequires: pam-devel >= 1.0.1 +%endif +%if %{with audit} +Buildrequires: audit-libs-devel >= 1.4.1 +%endif + +BuildRequires: systemd +Obsoletes: %{name}-sysvinit + +Requires(post): coreutils sed +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Requires(post): systemd + +%description +Cronie contains the standard UNIX daemon crond that runs specified programs at +scheduled times and related tools. It is a fork of the original vixie-cron and +has security and configuration enhancements like the ability to use pam and +SELinux. + +%package anacron +Summary: Utility for running regular jobs +Requires: crontabs +Group: System Environment/Base +Provides: dailyjobs +Provides: anacron = 2.4 +Obsoletes: anacron <= 2.3 +Requires(post): coreutils +Requires: %{name} = %{version}-%{release} + +%description anacron +Anacron is part of cronie that is used for running jobs with regular +periodicity which do not have exact time of day of execution. + +The default settings of anacron execute the daily, weekly, and monthly +jobs, but anacron allows setting arbitrary periodicity of jobs. + +Using anacron allows running the periodic jobs even if the system is often +powered off and it also allows randomizing the time of the job execution +for better utilization of resources shared among multiple systems. + +%package noanacron +Summary: Utility for running simple regular jobs in old cron style +Group: System Environment/Base +Provides: dailyjobs +Requires: crontabs +Requires: %{name} = %{version}-%{release} + +%description noanacron +Old style of running {hourly,daily,weekly,monthly}.jobs without anacron. No +extra features. + +%prep +%setup -q +%patch0 -p1 -b .systemd +%patch1 -p1 -b .locking +%patch2 -p1 -b .pamenv +%patch3 -p1 -b .man-debug +%patch4 -p1 -b .check-config +%patch5 -p1 -b .unitfile +%patch6 -p1 -b .refresh-users +%patch7 -p1 -b .shutdown-msg +%patch8 -p1 -b .temp-name +%patch9 -p1 -b .mailto +%patch10 -p1 -b .root +%patch11 -p1 -b .man-file +%patch12 -p1 -b .selinux-user +%patch13 -p1 -b .no-pam +%patch14 -p1 -b .empty-var +%patch15 -p1 -b .race-cond +%patch16 -p1 -b .inherit-path +%patch17 -p1 -b .smartcard-auth +%patch18 -p1 -b .restart + +%build +%configure \ +%if %{with pam} +--with-pam \ +%endif +%if %{with selinux} +--with-selinux \ +%endif +%if %{with audit} +--with-audit \ +%endif +%if %{with inotify} +--with-inotify \ +%endif +--enable-anacron \ +--enable-pie \ +--enable-relro + +make %{?_smp_mflags} + +%install +make install DESTDIR=$RPM_BUILD_ROOT DESTMAN=$RPM_BUILD_ROOT%{_mandir} +mkdir -pm700 $RPM_BUILD_ROOT%{_localstatedir}/spool/cron +mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ +mkdir -pm755 $RPM_BUILD_ROOT%{_sysconfdir}/cron.d/ +%if ! %{with pam} + rm -f $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/crond +%endif +install -m 600 crond.sysconfig $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/crond +touch $RPM_BUILD_ROOT%{_sysconfdir}/cron.deny +install -m 600 contrib/anacrontab $RPM_BUILD_ROOT%{_sysconfdir}/anacrontab +install -c -m755 contrib/0hourly $RPM_BUILD_ROOT%{_sysconfdir}/cron.d/0hourly +mkdir -pm 700 $RPM_BUILD_ROOT%{_sysconfdir}/cron.hourly +install -c -m755 contrib/0anacron $RPM_BUILD_ROOT%{_sysconfdir}/cron.hourly/0anacron +mkdir -p $RPM_BUILD_ROOT/var/spool/anacron +touch $RPM_BUILD_ROOT/var/spool/anacron/cron.daily +touch $RPM_BUILD_ROOT/var/spool/anacron/cron.weekly +touch $RPM_BUILD_ROOT/var/spool/anacron/cron.monthly + +# noanacron package +install -m 644 contrib/dailyjobs $RPM_BUILD_ROOT/%{_sysconfdir}/cron.d/dailyjobs + +# install systemd initscript +mkdir -p $RPM_BUILD_ROOT/usr/lib/systemd/system/ +install -m 644 contrib/cronie.systemd $RPM_BUILD_ROOT/usr/lib/systemd/system/crond.service + +%post +# run after an installation +%systemd_post crond.service + +%post anacron +[ -e /var/spool/anacron/cron.daily ] || touch /var/spool/anacron/cron.daily +[ -e /var/spool/anacron/cron.weekly ] || touch /var/spool/anacron/cron.weekly +[ -e /var/spool/anacron/cron.monthly ] || touch /var/spool/anacron/cron.monthly + +%preun +# run before a package is removed +%systemd_preun crond.service + +%postun +# run after a package is removed +%systemd_postun_with_restart crond.service + +%triggerun -- cronie-anacron < 1.4.1 +# empty /etc/crontab in case there are only old regular jobs +cp -a /etc/crontab /etc/crontab.rpmsave +sed -e '/^01 \* \* \* \* root run-parts \/etc\/cron\.hourly/d'\ + -e '/^02 4 \* \* \* root run-parts \/etc\/cron\.daily/d'\ + -e '/^22 4 \* \* 0 root run-parts \/etc\/cron\.weekly/d'\ + -e '/^42 4 1 \* \* root run-parts \/etc\/cron\.monthly/d' /etc/crontab.rpmsave > /etc/crontab +exit 0 + +%triggerun -- cronie < 1.4.7-2 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply crond +# to migrate them to systemd targets +/usr/bin/systemd-sysv-convert --save crond + +# The package is allowed to autostart: +/bin/systemctl enable crond.service >/dev/null 2>&1 + +/sbin/chkconfig --del crond >/dev/null 2>&1 || : +/bin/systemctl try-restart crond.service >/dev/null 2>&1 || : +/bin/systemctl daemon-reload >/dev/null 2>&1 || : + +%triggerin -- pam, glibc, libselinux +# changes in pam, glibc or libselinux can make crond crash +# when it calls pam +/bin/systemctl try-restart crond.service >/dev/null 2>&1 || : + +%files +%doc AUTHORS COPYING INSTALL README ChangeLog +%attr(755,root,root) %{_sbindir}/crond +%attr(4755,root,root) %{_bindir}/crontab +%{_mandir}/man8/crond.* +%{_mandir}/man8/cron.* +%{_mandir}/man5/crontab.* +%{_mandir}/man1/crontab.* +%dir %{_localstatedir}/spool/cron +%dir %{_sysconfdir}/cron.d +%if %{with pam} +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/pam.d/crond +%endif +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sysconfig/crond +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/cron.deny +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cron.d/0hourly +%attr(0644,root,root) /usr/lib/systemd/system/crond.service + +%files anacron +%{_sbindir}/anacron +%attr(0755,root,root) %{_sysconfdir}/cron.hourly/0anacron +%attr(0600,root,root) %config(noreplace) %{_sysconfdir}/anacrontab +%dir /var/spool/anacron +%ghost %attr(0600,root,root) %verify(not md5 size mtime) /var/spool/anacron/cron.daily +%ghost %attr(0600,root,root) %verify(not md5 size mtime) /var/spool/anacron/cron.weekly +%ghost %attr(0600,root,root) %verify(not md5 size mtime) /var/spool/anacron/cron.monthly +%{_mandir}/man5/anacrontab.* +%{_mandir}/man8/anacron.* + +%files noanacron +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cron.d/dailyjobs + +%changelog +* Wed Feb 13 2019 Marcel Plch - 1.4.11-23 +- Make cronie restart on failure +- Resolves: rhbz#1651730 + +* Tue Dec 04 2018 Marcel Plch - 1.4.11-22 +- Backport upstream patch to fix cron failing on + smart card authentication +- Resolves: rhbz#1650314 + +* Thu Nov 29 2018 Marcel Plch - 1.4.11-21 +- Backport upstream patch to fix -P behavior +- Resolves: rhbz#1536111 + +* Tue Oct 23 2018 Marcel Plch - 1.4.11-20 +- Fix race condition when crontab is modified the same second + before and after reading the crontab +- Resolves: rhbz#1638691 + +* Mon Oct 16 2017 Tomáš Mráz - 1.4.11-19 +- fix URL and source URL of the package (#1501726) + +* Fri Sep 15 2017 Tomáš Mráz - 1.4.11-18 +- fix regression - spurious PAM log message from crontab (#1479064) +- allow empty variables in crontabs (#1439217) + +* Wed Mar 29 2017 Tomáš Mráz - 1.4.11-17 +- make anacron not to contradict itself in syslog + (job output does not have to be necessarily mailed) + +* Tue Mar 7 2017 Tomáš Mráz - 1.4.11-16 +- disable mail from anacron with empty MAILTO +- crontab: do not block access with PAM when running as root +- improve the crontab man page +- do not hardcode system_u selinux user but use the user from + the current context + +* Tue Feb 23 2016 Tomáš Mráz - 1.4.11-15 +- crontab: use temporary filename properly ignored by crond + +* Tue Apr 21 2015 Tomáš Mráz - 1.4.11-14 +- mark the 0hourly and dailyjobs crontabs as config +- properly handle users for whose getpwnam() returns NULL temporarily +- log when crond is shutting down + +* Mon Jul 7 2014 Marcela Mašláňová - 1.4.11-13 +- reload in unit file was still missing +- Related: rhbz#1114815 + +* Fri Jul 4 2014 Marcela Mašláňová - 1.4.11-12 +- reload in unit file was missing +- Resolves: rhbz#1114815 + +* Mon Jan 27 2014 Marcela Mašláňová - 1.4.11-11 +- now it's work even on ppc64, all checks working correctly +- Related: rhbz#1031384 + +* Fri Jan 24 2014 Daniel Mach - 1.4.11-10 +- Mass rebuild 2014-01-24 + +* Wed Jan 22 2014 Marcela Mašláňová - 1.4.11-9 +- fix coverity warnings about dead code. Incorrect checking of values. +- Related: rhbz#1031384 + +* Mon Jan 20 2014 Marcela Mašláňová - 1.4.11-8 +- anacron do not execute jobs run from command line +- Related: rhbz#1031384 + +* Wed Jan 08 2014 Marcela Mašláňová - 1.4.11-7 +- anacron segfaults with certain config data +- Resolves: rhbz#1031384 + +* Fri Dec 27 2013 Daniel Mach - 1.4.11-6 +- Mass rebuild 2013-12-27 + +* Tue Oct 15 2013 Marcela Mašláňová - 1.4.11-5 +- Cronie doesn't work when is executed as stand alone without systemd (for + debuging issues) +- Fix another permission, hopefully all now. +- Resolves: rhbz#1012420, rhbz#1015567 + +* Fri Sep 13 2013 Marcela Mašláňová - 1.4.11-4 +- fix permission on configuration files, same as rhbz#706979 + +* Fri Aug 30 2013 Marcela Mašláňová - 1.4.11-3 +- 919290 systemd script use "KillMode=process" +- Fcntl locking has different semantics than flock. Prefer flock. + - 49225e172d156531ca142518d2638350752e373a +- Pull PAM environment variables also from session modules. + - c8e7d1b43c86a85441cb09cf7e08090f3ec1f384 + +* Mon Jul 22 2013 Marcela Mašláňová - 1.4.11-2 +- scriptlets are not created correctly if systemd is not in BR 986698 +- remove sub-package sysvinit, which is not needed anymore +- update license, anacron is under GPLv2+ + +* Thu Jul 18 2013 Marcela Mašláňová - 1.4.11-1 +- new release 1.4.11 (contains previous bug fixes from 1.4.10-5) + +* Tue Jun 11 2013 Tomáš Mráz - 1.4.10-5 +- add support for RANDOM_DELAY - delaying job startups +- pass some environment variables to processes (LANG, etc.) (#969761) +- do not use putenv() with string literals (#971516) + +* Wed Feb 13 2013 Fedora Release Engineering - 1.4.10-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Wed Jan 2 2013 Marcela Mašláňová - 1.4.10-3 +- change configuration files to 644 +- change 6755 to 4755 for crontab binary + +* Tue Nov 27 2012 Marcela Mašláňová - 1.4.10-1 +- New release 1.4.10 + +* Thu Nov 22 2012 Marcela Mašláňová - 1.4.9-1 +- New release 1.4.9 + +* Wed Sep 05 2012 Václav Pavlín - 1.4.8-13 +- Scriptlets replaced with new systemd macros (#850070) + +* Fri Jul 27 2012 Fedora Release Engineering - 1.4.8-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jan 13 2012 Fedora Release Engineering - 1.4.8-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Wed Oct 26 2011 Fedora Release Engineering - 1.4.8-10 +- Rebuilt for glibc bug#747377 + +* Tue Oct 25 2011 Tomáš Mráz - 1.4.8-9 +- make crond run a little bit later in the boot process (#747759) + +* Mon Oct 17 2011 Marcela Mašláňová - 1.4.8-8 +- change triggerun to fix 735802 during upgrade + +* Wed Jul 27 2011 Karsten Hopp 1.4.8-7 +- rebuild again, ppc still had the broken rpm in the buildroots + +* Thu Jul 21 2011 Rex Dieter 1.4.8-6 +- rebuild (broken rpm in buildroot) + +* Thu Jul 21 2011 Marcela Mašláňová - 1.4.8-5 +- fix permission of init.d/crond + +* Thu Jun 30 2011 Tomáš Mráz - 1.4.8-4 +- drop the without systemd build condition +- add the chkconfig readding trigger to the sysvinit subpackage + +* Wed Jun 29 2011 Tomáš Mráz - 1.4.8-3 +- start crond after auditd + +* Wed Jun 29 2011 Tomáš Mráz - 1.4.8-2 +- fix inotify support to not leak fds (#717505) + +* Tue Jun 28 2011 Marcela Mašláňová - 1.4.8-1 +- update to 1.4.8 +- create sub-package sysvinit for initscript + +* Mon May 9 2011 Marcela Mašláňová - 1.4.7-3 +- missing requirement on systemd-sysv for scriptlets + +* Thu May 05 2011 Tomáš Mráz - 1.4.7-2 +- use only systemd units with systemd +- add trigger for restart on glibc, libselinux or pam upgrades (#699189) + +* Tue Mar 15 2011 Marcela Mašláňová - 1.4.7-1 +- new release 1.4.7 + +* Tue Feb 08 2011 Fedora Release Engineering - 1.4.6-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jan 17 2011 Marcela Mašláňová - 1.4.6-8 +- enable crond even with systemctl + +* Thu Dec 16 2010 Marcela Mašláňová - 1.4.6-7 +- 663193 rewritten selinux support + +* Wed Dec 15 2010 Marcela Mašláňová - 1.4.6-6 +- apply selinux patch from dwalsh + +* Fri Dec 10 2010 Tomas Mraz - 1.4.6-5 +- do not lock jobs that fall out of allowed range - 661966 + +* Thu Dec 02 2010 Marcela Mašláňová - 1.4.6-4 +- fix post (thanks plautrba for review) + +* Tue Nov 30 2010 Marcela Mašláňová - 1.4.6-3 +- systemd init script 617320 + +* Tue Nov 30 2010 Marcela Mašláňová - 1.4.6-2 +- fix typos in man pages + +* Fri Oct 22 2010 Marcela Mašláňová - 1.4.6-1 +- update to 1.4.6 + +* Fri Aug 13 2010 Marcela Mašláňová - 1.4.5-4 +- 623908 fix fd leak in anacron, which caused denail of prelink + and others + +* Mon Aug 9 2010 Marcela Mašláňová - 1.4.5-2 +- remove sendmail from requirements. If it's not installed, it will + log into (r)syslog. + +* Mon Aug 2 2010 Marcela Mašláňová - 1.4.5-1 +- update to new release + +* Fri Feb 19 2010 Marcela Mašláňová - 1.4.4-1 +- update to new release + +* Mon Feb 15 2010 Marcela Mašláňová - 1.4.3-3 +- 564894 FTBFS DSOLinking + +* Thu Nov 5 2009 Marcela Mašláňová - 1.4.3-2 +- 533189 pam needs add a line and selinux needs defined one function + +* Fri Oct 30 2009 Marcela Mašláňová - 1.4.3-1 +- 531963 and 532482 creating noanacron package + +* Mon Oct 19 2009 Marcela Mašláňová - 1.4.2-2 +- 529632 service crond stop returns appropriate value + +* Mon Oct 12 2009 Marcela Mašláňová - 1.4.2-1 +- new release + +* Fri Aug 21 2009 Tomas Mraz - 1.4.1-3 +- rebuilt with new audit + +* Fri Aug 14 2009 Tomas Mraz - 1.4.1-2 +- create the anacron timestamps in correct post script + +* Fri Aug 14 2009 Marcela Mašláňová - 1.4.1-1 +- update to 1.4.1 +- create and own /var/spool/anacron/cron.{daily,weekly,monthly} to + remove false warning about non existent files +- Resolves: 517398 + +* Wed Aug 5 2009 Tomas Mraz - 1.4-4 +- 515762 move anacron provides and obsoletes to the anacron subpackage + +* Fri Jul 24 2009 Fedora Release Engineering - 1.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jul 20 2009 Marcela Mašláňová - 1.4-2 +- merge cronie and anacron in new release of cronie +- obsolete/provide anacron in spec + +* Thu Jun 18 2009 Marcela Mašláňová - 1.3-2 +- 506560 check return value of access + +* Mon Apr 27 2009 Marcela Mašláňová - 1.3-1 +- new release + +* Fri Apr 24 2009 Marcela Mašláňová - 1.2-8 +- 496973 close file descriptors after exec + +* Mon Mar 9 2009 Tomas Mraz - 1.2-7 +- rebuild + +* Tue Feb 24 2009 Fedora Release Engineering - 1.2-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* 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 + +* Thu Sep 25 2008 Marcela Maslanova - 1.2-3 +- add sendmail file into requirement, cause it's needed some MTA + +* Thu Sep 18 2008 Marcela Maslanova - 1.2-2 +- 462252 /etc/sysconfig/crond does not need to be executable + +* Thu Jun 26 2008 Marcela Maslanova - 1.2-1 +- update to 1.2 + +* 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. + +* Wed May 28 2008 Marcela Maslanova - 1.1-1 +- release 1.1 + +* Tue May 20 2008 Marcela Maslanova - 1.0-6 +- 446360 check for lock didn't call chkconfig + +* Tue Feb 12 2008 Marcela Maslanova - 1.0-5 +- upgrade from less than cronie-1.0-4 didn't add chkconfig + +* Wed Feb 6 2008 Marcela Maslanova - 1.0-4 +- 431366 after reboot wasn't cron in chkconfig + +* Tue Feb 5 2008 Marcela Maslanova - 1.0-3 +- 431366 trigger part => after update from vixie-cron on cronie will + be daemon running. + +* Wed Jan 30 2008 Marcela Maslanova - 1.0-2 +- change the provides on higher version than obsoletes + +* Tue Jan 8 2008 Marcela Maslanova - 1.0-1 +- packaging cronie +- thank's for help with packaging to my reviewers