From: mmaslano Date: Fri, 17 Aug 2007 13:09:50 +0000 (+0200) Subject: List corruption when items are removed from /etc/cron.d. X-Git-Tag: v4.2~54 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ec8048a0e05a9178c7206c47f3353b472524eb67;p=cronie List corruption when items are removed from /etc/cron.d. Variable tabname is filled with file or NULL and checked when crontab is changed. --- diff --git a/database.c b/database.c index 5db27e9..12b9708 100644 --- a/database.c +++ b/database.c @@ -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 5d900c6..395f239 100644 --- 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 **); diff --git a/structs.h b/structs.h index fc09cd5..a98b1cc 100644 --- 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 bfde264..923cca8 100644 --- 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.