]> granicus.if.org Git - cronie/commitdiff
Properly check the existence of the user at the time the job is run.
authorTomas Mraz <tmraz@fedoraproject.org>
Tue, 4 Nov 2014 16:53:04 +0000 (17:53 +0100)
committerTomas Mraz <tmraz@fedoraproject.org>
Tue, 4 Nov 2014 16:53:04 +0000 (17:53 +0100)
And do not ignore jobs for users that were not existing at database
reload.

src/cron.c
src/entry.c
src/env.c
src/funcs.h
src/job.c

index 901a655d1538c98e9f8284b1d8c6ba7723da70de..d8b2978df438d1dfbdb339eba6fafc68d07a66d0 100644 (file)
@@ -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. */
                        }
                }
        }
index fa69524406bfabcb54687f3caf628ef63de640c9..3638207aba637fc2a8be7927044fe9e029dda268 100644 (file)
@@ -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)) {
index 479e6cc63edaa1a98374a77b3c650e629b86e5b8..339dda12d6578fdb8fbf8d65ab00bb26e5f6689d 100644 (file)
--- a/src/env.c
+++ b/src/env.c
@@ -25,6 +25,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 #include <unistd.h>
 
 #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;
+}
index 76376b97ef50316a2f228ce0e3f758dfe16a5235..ddf9e2a3d05e5b5fd993f404b80be2b3e52f4696 100644 (file)
@@ -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 *);
index 8ad14dbc3648e373f482ce4e6df8135823a957d9..60a404a6726d4b286832b4ab64e1d8311ed740b7 100644 (file)
--- a/src/job.c
+++ b/src/job.c
 #include "config.h"
 
 #include <stdlib.h>
+#include <pwd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
 
 #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;