]> granicus.if.org Git - cronie/commitdiff
List corruption when items are removed from /etc/cron.d.
authormmaslano <mmaslano@redhat.com>
Fri, 17 Aug 2007 13:09:50 +0000 (15:09 +0200)
committermmaslano <mmaslano@redhat.com>
Fri, 24 Aug 2007 13:05:59 +0000 (15:05 +0200)
Variable tabname is filled with file or NULL and checked
when crontab is changed.

database.c
funcs.h
structs.h
user.c

index 5db27e95262ca14150b64538f879033172069ec5..12b9708f7b2f6cd83946a6d016609a69e5225b1a 100644 (file)
@@ -218,12 +218,15 @@ unlink_user(cron_db *db, user *u) {
 }
 
 user *
-find_user(cron_db *db, const char *name) {
+find_user(cron_db *db, const char *name, const char *tabname) {
        user *u;
 
        for (u = db->head;  u != NULL;  u = u->next)
-               if (strcmp(u->name, name) == 0)
-                       break;
+           if (  (strcmp(u->name, name) == 0) 
+               &&(   (tabname == NULL) 
+                  || ( strcmp(tabname, u->tabname) == 0 )
+                 )
+              ) break;
        return (u);
 }
 
@@ -234,6 +237,7 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
        struct passwd *pw = NULL;
        int crontab_fd = OK - 1;
        user *u;
+       int crond_crontab = (fname == NULL) && (strcmp(tabname, SYSCRONTAB) != 0);
 
        if (fname == NULL) {
                /* must be set to something for logging purposes.
@@ -280,7 +284,9 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
        }
 
        Debug(DLOAD, ("\t%s:", fname))
-       u = find_user(old_db, 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.
diff --git a/funcs.h b/funcs.h
index 5d900c664e61bbef6bf37923b8e34e87ab99d91a..395f2390d7e54082f524152ba62ec0df3c06819c 100644 (file)
--- a/funcs.h
+++ b/funcs.h
@@ -66,7 +66,7 @@ char          *env_get(char *, char **),
                **env_set(char **, char *);
 
 user           *load_user(int, struct passwd *, const char *, const char *, const char *),
-               *find_user(cron_db *, const char *);
+               *find_user(cron_db *, const char *, const char *);
 
 entry          *load_entry(FILE *, void (*)(), struct passwd *, char **);
 
index fc09cd57e33af451ad09b9fc3499e92a6604ea7b..a98b1cc35cce4dbf600bc86d8956a91abac55216 100644 (file)
--- a/structs.h
+++ b/structs.h
@@ -48,11 +48,12 @@ typedef     struct _entry {
 typedef        struct _user {
        struct _user    *next, *prev;   /* links */
        char            *name;
+        char            *tabname;       /* /etc/cron.d/ file name or NULL */
        time_t          mtime;          /* last modtime of crontab */
        entry           *crontab;       /* this person's crontab */
 #ifdef WITH_SELINUX
         security_context_t scontext;    /* SELinux security context */
-#endif
+#endif        
 } user;
 
 typedef        struct _cron_db {
diff --git a/user.c b/user.c
index bfde264f5cb75b55b1cf74f6f6786442c55d0539..923cca80a81183dcdf2111aeed0ed9288cc765af 100644 (file)
--- a/user.c
+++ b/user.c
@@ -99,6 +99,7 @@ free_user(user *u) {
        entry *e, *ne;
 
        free(u->name);
+       free(u->tabname);
        for (e = u->crontab;  e != NULL;  e = ne) {
                ne = e->next;
                free_entry(e);
@@ -130,12 +131,16 @@ load_user(int crontab_fd, struct passwd   *pw, const char *uname, const char *fnam
         */
        if ((u = (user *) malloc(sizeof(user))) == NULL)
                return (NULL);
-       if ((u->name = strdup(fname)) == NULL) {
+
+       if ( ((u->name = strdup(fname)) == NULL) 
+           ||((u->tabname = strdup(tabname)) == NULL)
+           ){
                save_errno = errno;
                free(u);
                errno = save_errno;
                return (NULL);
        }
+       
        u->crontab = NULL;
 
        /* init environment.  this will be copied/augmented for each entry.