diff --git a/cronie-1.4.12-pam-no-root.patch b/cronie-1.4.12-pam-no-root.patch deleted file mode 100644 index 464d83b..0000000 --- a/cronie-1.4.12-pam-no-root.patch +++ /dev/null @@ -1,126 +0,0 @@ -diff --git a/src/crontab.c b/src/crontab.c -index 22571ff..d165a06 100644 ---- a/src/crontab.c -+++ b/src/crontab.c -@@ -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/src/security.c b/src/security.c -index 4eee004..1668890 100644 ---- a/src/security.c -+++ b/src/security.c -@@ -88,6 +88,7 @@ static int cron_open_pam_session(struct passwd *pw); - if (pam_session_opened != 0) \ - pam_close_session(pamh, PAM_SILENT); \ - pam_end(pamh, retcode); \ -+ pamh = NULL; \ - } \ - return(retcode); } - #endif -@@ -122,7 +123,8 @@ int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED, - } - - #ifdef WITH_PAM -- if ((ret = cron_start_pam(e->pwd)) != 0) { -+ /* PAM is called only for non-root users or non-system crontab */ -+ if ((!u->system || e->pwd->pw_uid != 0) && (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; -@@ -152,7 +154,7 @@ int cron_set_job_security_context(entry *e, user *u ATTRIBUTE_UNUSED, - freecon(ucontext); - #endif - #ifdef WITH_PAM -- if ((ret = cron_open_pam_session(e->pwd)) != 0) { -+ if (pamh != NULL && (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; -@@ -223,7 +225,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 - } - -@@ -243,7 +248,9 @@ int cron_change_groups(struct passwd *pw) { - #if defined(WITH_PAM) - /* credentials may take form of supplementary groups so reinitialize - * them here */ -- pam_setcred(pamh, PAM_REINITIALIZE_CRED | PAM_SILENT); -+ if (pamh != NULL) { -+ pam_setcred(pamh, PAM_REINITIALIZE_CRED | PAM_SILENT); -+ } - #endif - - return 0; -@@ -614,18 +621,19 @@ int crontab_security_access(void) { - * crontab environment - */ - static char **build_env(char **cronenv) { -+ char **jobenv; - #ifdef WITH_PAM -- char **jobenv = pam_getenvlist(pamh); - char *cronvar; - int count = 0; - -- if (jobenv == NULL) { -- jobenv = env_init(); -- if (jobenv == NULL) { -+ if (pamh == NULL || (jobenv=pam_getenvlist(pamh)) == NULL) { -+#endif -+ jobenv = env_copy(cronenv); -+ if (jobenv == NULL) - log_it("CRON", getpid(), - "ERROR", "Initialization of cron environment variables failed", 0); -- return NULL; -- } -+ return jobenv; -+#ifdef WITH_PAM - } - - /* Now add the cron environment variables. Since env_set() -@@ -640,7 +648,5 @@ static char **build_env(char **cronenv) { - } - } - return jobenv; --#else -- return env_copy(cronenv); - #endif - } -diff --git a/src/structs.h b/src/structs.h -index 272777a..6d3c15b 100644 ---- a/src/structs.h -+++ b/src/structs.h -@@ -67,6 +67,7 @@ typedef struct _user { - time_t mtime; /* last modtime of crontab */ - entry *crontab; /* this person's crontab */ - security_context_t scontext; /* SELinux security context */ -+ int system; /* is it a system crontab */ - } user; - - typedef struct _orphan { -diff --git a/src/user.c b/src/user.c -index 20c0d96..e950db7 100644 ---- a/src/user.c -+++ b/src/user.c -@@ -89,6 +89,8 @@ load_user (int crontab_fd, struct passwd *pw, const char *uname, - goto done; - } - -+ u->system = pw == NULL; -+ - /* init environment. this will be copied/augmented for each entry. - */ - if ((envp = env_init()) == NULL) { diff --git a/cronie-1.4.12-refresh-users.patch b/cronie-1.4.12-refresh-users.patch deleted file mode 100644 index ab681a9..0000000 --- a/cronie-1.4.12-refresh-users.patch +++ /dev/null @@ -1,280 +0,0 @@ -diff --git a/src/cron.c b/src/cron.c -index 901a655..d8b2978 100644 ---- a/src/cron.c -+++ b/src/cron.c -@@ -525,7 +525,6 @@ static void find_jobs(int vtime, cron_db * db, int doWild, int doNonWild, long v - 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,40 +561,30 @@ static void find_jobs(int vtime, cron_db * db, int doWild, int doNonWild, long v - */ - 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) && -- bit_test(e->month, month) && -- (((e->flags & DOM_STAR) || (e->flags & DOW_STAR)) -- ? (bit_test(e->dow, dow) && bit_test(e->dom, dom)) -+ 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) && -+ bit_test(e->month, month) && -+ (((e->flags & DOM_STAR) || (e->flags & DOW_STAR)) -+ ? (bit_test(e->dow, dow) && bit_test(e->dom, dom)) - : (bit_test(e->dow, dow) || bit_test(e->dom, dom)) -- ) -- ) { -- if (job_tz != NULL && vGMToff != GMToff) -- /* do not try to run the jobs from different timezones -- * during the DST switch of the default timezone. -- */ -- continue; -- -- if ((doNonWild && -- !(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. */ -- } -- } -- 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))); -+ ) -+ ) { -+ if (job_tz != NULL && vGMToff != GMToff) -+ /* do not try to run the jobs from different timezones -+ * during the DST switch of the default timezone. -+ */ -+ continue; -+ -+ if ((doNonWild && -+ !(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. */ - } - } - } -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 --git a/src/entry.c b/src/entry.c -index fa69524..3638207 100644 ---- a/src/entry.c -+++ b/src/entry.c -@@ -99,6 +99,7 @@ entry *load_entry(FILE * file, void (*error_func) (), struct passwd *pw, - 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 (*error_func) (), struct passwd *pw, - - 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 (*error_func) (), struct passwd *pw, - 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 --git a/src/env.c b/src/env.c -index 479e6cc..7cc5aed 100644 ---- a/src/env.c -+++ b/src/env.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - - #include "globals.h" -@@ -295,3 +296,19 @@ char *env_get(const char *name, char **envp) { - } - 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 --git a/src/funcs.h b/src/funcs.h -index 76376b9..ddf9e2a 100644 ---- a/src/funcs.h -+++ b/src/funcs.h -@@ -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 --git a/src/job.c b/src/job.c -index 8ad14db..60a404a 100644 ---- a/src/job.c -+++ b/src/job.c -@@ -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/cronie-1.5.0-temp-name.patch b/cronie-1.5.0-temp-name.patch new file mode 100644 index 0000000..039f79f --- /dev/null +++ b/cronie-1.5.0-temp-name.patch @@ -0,0 +1,73 @@ +commit 1222a0d414c52214e1ecc023889595945496acbb +Author: Tomas Mraz +Date: Mon Jul 13 11:19:55 2015 +0200 + + In crontab command use a temporary filename that is ignored by crond. + +diff --git a/src/crontab.c b/src/crontab.c +index d165a06..e7a4878 100644 +--- a/src/crontab.c ++++ b/src/crontab.c +@@ -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/cronie.spec b/cronie.spec index 158f50d..a1da6f1 100644 --- a/cronie.spec +++ b/cronie.spec @@ -6,11 +6,12 @@ Summary: Cron daemon for executing programs at set times Name: cronie Version: 1.5.0 -Release: 2%{?dist} +Release: 3%{?dist} License: MIT and BSD and ISC and GPLv2+ Group: System Environment/Base URL: https://fedorahosted.org/cronie Source0: https://fedorahosted.org/releases/c/r/cronie/%{name}-%{version}.tar.gz +Patch1: cronie-1.5.0-temp-name.patch Requires: dailyjobs @@ -75,6 +76,7 @@ extra features. %prep %setup -q +%patch1 -p1 -b .temp-name %build %configure \ @@ -201,6 +203,9 @@ exit 0 %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cron.d/dailyjobs %changelog +* Mon Jul 13 2015 Tomáš Mráz - 1.5.0-3 +- the temp file name used by crontab needs to be ignored by crond + * Wed Jun 17 2015 Fedora Release Engineering - 1.5.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild