]> granicus.if.org Git - cronie/commitdiff
Check orphaned crontabs for adoption.
authorTomas Mraz <tmraz@fedoraproject.org>
Tue, 21 Jun 2011 18:26:38 +0000 (20:26 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Tue, 21 Jun 2011 18:26:38 +0000 (20:26 +0200)
src/cron.c
src/database.c
src/funcs.h
src/structs.h

index df45f447be37b725ad1b92aaffab56a28fa77f0b..7dc2958ad7db181819cefc7554f5d44af6a70fee 100644 (file)
@@ -307,6 +307,7 @@ int main(int argc, char *argv[]) {
                 * clock.  Classify the change into one of 4 cases.
                 */
                timeDiff = timeRunning - virtualTime;
+               check_orphans(&database);
 #if defined WITH_INOTIFY
                if (inotify_enabled) {
                        check_inotify_database(&database);
index d1d97ede9b5d76c3dae37d68b9fbdee1279f85ec..b0f2254fee86c6ae6fa862a07916fe469c9256e5 100644 (file)
@@ -93,12 +93,81 @@ check_open(const char *tabname, const char *fname, const char *uname,
        return (crontab_fd);
 }
 
+static orphan *orphans;
+
+static void
+free_orphan(orphan *o) {
+       free(o->tabname);
+       free(o->fname);
+       free(o->uname);
+       free(o);
+}
+
+void
+check_orphans(cron_db *db) {
+       orphan *prev_orphan = NULL;
+       orphan *o = orphans;
+
+       while (o != NULL) {
+               if (getpwnam(o->uname) != NULL) {
+                       orphan *next = o->next;
+
+                       if (prev_orphan == NULL) {
+                               orphans = next;
+                       } else {
+                               prev_orphan->next = next;
+                       }
+
+                       process_crontab(o->uname, o->fname, o->tabname,
+                               db, NULL);
+
+                       /* process_crontab could have added a new orphan */
+                       if (prev_orphan == NULL && orphans != next) {
+                               prev_orphan = orphans;
+                       }
+                       free_orphan(o);
+                       o = next;
+               } else {
+                       prev_orphan = o;
+                       o = o->next;
+               }
+       }
+}
+
+static void
+add_orphan(const char *uname, const char *fname, const char *tabname) {
+       orphan *o;
+
+       o = calloc(1, sizeof(*o));
+       if (o == NULL)
+               return;
+
+       if (uname)
+               if ((o->uname=strdup(uname)) == NULL)
+                       goto cleanup;
+
+       if (fname)
+               if ((o->fname=strdup(fname)) == NULL)
+                       goto cleanup;
+
+       if (tabname)
+               if ((o->tabname=strdup(tabname)) == NULL)
+                       goto cleanup;
+
+       o->next = orphans;
+       orphans = o;
+       return;
+
+cleanup:
+       free_orphan(o);
+}
+
 static void
 process_crontab(const char *uname, const char *fname, const char *tabname,
        cron_db * new_db, cron_db * old_db) {
        struct passwd *pw = NULL;
        int crontab_fd = -1;
-       user *u;
+       user *u = NULL;
        time_t mtime;
        int crond_crontab = (fname == NULL) && (strcmp(tabname, SYSCRONTAB) != 0);
 
@@ -111,6 +180,8 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
                /* file doesn't have a user in passwd file.
                 */
                log_it(uname, getpid(), "ORPHAN", "no passwd entry", 0);
+               add_orphan(uname, fname, tabname);
+
                goto next_crontab;
        }
 
@@ -119,6 +190,7 @@ process_crontab(const char *uname, const char *fname, const char *tabname,
 
        Debug(DLOAD, ("\t%s:", fname))
 
+       if (old_db != NULL)
                u = find_user(old_db, fname, crond_crontab ? tabname : NULL);   /* find user in old_db */
 
        if (u != NULL) {
index afeceddc1618a2fca3b32312c17eee9dfeff4dde..aee4a99f96539b9eaeb99b69bc2ce9ab2f5f677d 100644 (file)
@@ -39,7 +39,8 @@ void          set_cron_uid(void),
                acquire_daemonlock(int),
                skip_comments(FILE *),
                log_it(const char *, PID_T, const char *, const char *, int),
-               log_close(void);
+               log_close(void),
+               check_orphans(cron_db *);
 #if defined WITH_INOTIFY
 void           set_cron_watched(int ),
                set_cron_unwatched(int ),
index fec51865a3a0ca704f71aad63e5a6e13bca7d773..16cd1803892043172149456a926b709c12a896f6 100644 (file)
@@ -57,6 +57,13 @@ typedef      struct _user {
        security_context_t      scontext;    /* SELinux security context */
 } user;
 
+typedef        struct _orphan {
+       struct _orphan  *next;          /* link */
+       char            *uname;
+       char            *fname;
+       char            *tabname;
+} orphan;
+
 typedef        struct _cron_db {
        user            *head, *tail;   /* links */
        time_t          mtime;          /* last modtime on spooldir */