Package: cron Version: 3.0pl1-105 Severity: wishlist Tags: patch
The attached patch scans crond's spool dir for user crontabs and prints them if they have a corresponding password database entry. diff is against sid's cron
--- cron-3.0pl1.orig/crontab.c 2011-04-18 09:15:39.000000000 +0200 +++ cron-3.0pl1/crontab.c 2011-04-18 09:30:00.088726953 +0200 @@ -47,10 +47,10 @@ #define NHEADER_LINES 3 -enum opt_t { opt_unknown, opt_list, opt_delete, opt_edit, opt_replace }; +enum opt_t { opt_unknown, opt_list, opt_delete, opt_edit, opt_replace, opt_show_users }; #if DEBUGGING -static char *Options[] = { "???", "list", "delete", "edit", "replace" }; +static char *Options[] = { "???", "list", "delete", "edit", "replace", "show" }; #endif @@ -66,6 +66,7 @@ static void list_cmd __P((void)), delete_cmd __P((void)), edit_cmd __P((void)), + show_users_cmd __P((void)), poke_daemon __P((void)), check_error __P((char *)), parse_args __P((int c, char *v[])); @@ -82,11 +83,12 @@ { fprintf(stderr, "%s: usage error: %s\n", ProgramName, msg); fprintf(stderr, "usage:\t%s [-u user] file\n", ProgramName); - fprintf(stderr, "\t%s [ -u user ] [ -i ] { -e | -l | -r }\n", ProgramName); + fprintf(stderr, "\t%s [ -u user ] [ -i ] { -e | -l | -r | -s }\n", ProgramName); fprintf(stderr, "\t\t(default operation is replace, per 1003.2)\n"); fprintf(stderr, "\t-e\t(edit user's crontab)\n"); fprintf(stderr, "\t-l\t(list user's crontab)\n"); fprintf(stderr, "\t-r\t(delete user's crontab)\n"); + fprintf(stderr, "\t-s\t(show all user who have a crontab)\n"); fprintf(stderr, "\t-i\t(prompt before deleting user's crontab)\n"); exit(ERROR_EXIT); } @@ -138,6 +140,8 @@ break; case opt_edit: edit_cmd(); break; + case opt_show_users: show_users_cmd(); + break; case opt_replace: if (replace_cmd() < 0) exitstatus = ERROR_EXIT; break; @@ -153,9 +157,9 @@ } #if DEBUGGING -char *getoptarg = "u:lerix:"; +char *getoptarg = "u:lerisx:"; #else -char *getoptarg = "u:leri"; +char *getoptarg = "u:leris"; #endif @@ -229,6 +233,17 @@ case 'i': PromptOnDelete = 1; break; + case 's': + if (getuid() != ROOT_UID) + { + fprintf(stderr, + "must be privileged to use -s\n"); + exit(ERROR_EXIT); + } + if (Option != opt_unknown) + usage("only one operation permitted"); + Option = opt_show_users; + break; default: usage("unrecognized option"); } @@ -810,6 +825,28 @@ exit(1); } +static void +show_users_cmd() { + DIR *dir; + struct dirent *dp; + + if (!(dir = opendir(SPOOL_DIR))) { + fprintf(stderr, "%s: opendir() of %s failed: %s\n", + ProgramName, SPOOL_DIR, strerror(errno)); + return; + } + while (dir != NULL && NULL != (dp = readdir(dir))) { + char fname[MAXNAMLEN+1]; + if (dp->d_name[0] == '.') + continue; + (void) strcpy(fname, dp->d_name); + if ((pw = getpwnam(fname))) + fprintf(stdout, "%s\n", fname); + else + fprintf(stderr, "%s: WARNING: crontab found with no matching user: %s\n", ProgramName, fname); + } + return; +} /* returns 0 on success * -1 on syntax error * -2 on install error --- cron-3.0pl1.orig/crontab.1 2011-04-18 09:15:39.000000000 +0200 +++ cron-3.0pl1/crontab.1 2011-04-18 09:34:24.352726952 +0200 @@ -24,7 +24,7 @@ .SH SYNOPSIS crontab [ \-u user ] file .br -crontab [ \-u user ] [ \-i ] { \-e | \-l | \-r } +crontab [ \-u user ] [ \-i ] { \-e | \-l | \-r | \-s } .SH DESCRIPTION .I crontab is the program used to install, deinstall or list the tables @@ -101,6 +101,11 @@ default editor /usr/bin/editor is used. .PP The +.I -s +option shows all users who have a crontab (and warns about files in the +spool dir which have no corresponding password database entry). +.PP +The .I -i option modifies the \-r option to prompt the user for a 'y/Y' response before actually removing the crontab.