Package: cron Version: 3.0pl1-121 Severity: wishlist Tags: patch The attached patches make it possible for cron to log cron job output to syslog.
Patch 1 adds a new log level 16, which unconditionally logs cron job output. Patch 2 adds a new log level 32, which logs cron job output if and only if the output will not get mailed, such as if the system has no MTA. Using this log level will ensure that cron job output won't get discarded. Patch 3 enables log level 32 by default in the Debian package via /etc/default/cron. This will ensure that the Debian package of cron automatically uses an MTA if available, or syslog if not. Patch 4 updates the Suggests and Recommends of the Debian packages, to suggest both a syslog daemon and a mail-transport-agent, but recommend just one or the other; thus, the recommended configuration will always capture cron job output in one way or another. This patch also updates cron to use default-mta rather than hardcoded MTAs. I included corresponding updates to debian/changelog for convenience, but if updates occur to the changelog before the application of these patches, they'll probably fail to apply; however, merging should prove trivial if so. Please consider applying these patches. Thanks, Josh Triplett
>From acb04be1e5d49f72b6bf6513b294c393b68f18f9 Mon Sep 17 00:00:00 2001 From: Josh Triplett <j...@joshtriplett.org> Date: Sun, 22 Apr 2012 19:20:54 -0700 Subject: [PATCH 1/4] Add a new log level to log all cron job output. --- cron.8 | 5 ++-- cron.h | 1 + debian/changelog | 4 +++ debian/cron.default | 1 + do_command.c | 70 ++++++++++++++++++++++++++------------------------- 5 files changed, 45 insertions(+), 36 deletions(-) diff --git a/cron.8 b/cron.8 index 586d9e5..5985700 100644 --- a/cron.8 +++ b/cron.8 @@ -54,11 +54,12 @@ will log the end of all cron jobs will log all failed jobs (exit status != 0) .IP \fB8\fR will log the process number of all cron jobs +.IP \fB16\fR +will log the full output of all cron jobs .RE .IP The default is to log the start of all jobs (1). Logging will be disabled -if \fIlevels\fR is set to zero (0). A value of fifteen (15) will select all -options. +if \fIlevels\fR is set to zero (0). A value of 31 will select all options. .SH NOTES .PP .I cron diff --git a/cron.h b/cron.h index d1b2bcf..d0cf070 100644 --- a/cron.h +++ b/cron.h @@ -139,6 +139,7 @@ typedef int time_min; #define CRON_LOG_JOBEND 0x02 #define CRON_LOG_JOBFAILED 0x04 #define CRON_LOG_JOBPID 0x08 +#define CRON_LOG_JOBOUTPUT 0x10 #define SECONDS_PER_MINUTE 60 diff --git a/debian/changelog b/debian/changelog index 139c800..99891b5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,11 +1,15 @@ cron (3.0pl1-122) UNRELEASED; urgency=low + [ Javier Fernández-Sanguino Peña ] * debian/standard.daily: Apply patch from Steve Allison to prevent checking two times the same filesystem. This prevents bogus warnings about missing lost+found in schroot bind mounts (Closes: #660879) * debian/rules: Apply patch from Steve Langasek to add cross compiler support to cron (Closes: #666892) + [ Josh Triplett ] + * Add a new log level to log all cron job output. + -- Javier Fernández-Sanguino Peña <j...@debian.org> Mon, 09 Apr 2012 17:23:01 +0200 cron (3.0pl1-121) unstable; urgency=low diff --git a/debian/cron.default b/debian/cron.default index c69934f..ed4383d 100644 --- a/debian/cron.default +++ b/debian/cron.default @@ -23,6 +23,7 @@ READ_ENV="yes" # 2 log end of jobs # 4 log jobs with exit status != 0 # 8 log the process identifier of child process (in all logs) +# 16 log the full output of all cron jobs # #EXTRA_OPTS="" diff --git a/do_command.c b/do_command.c index 18d097d..c2fc9f7 100644 --- a/do_command.c +++ b/do_command.c @@ -511,6 +511,7 @@ child_process(e, u) // since sendmail may time out, and to write info about the exit // status. + register FILE *mail = NULL; long pos; struct stat mcsb; int statret; @@ -522,26 +523,25 @@ child_process(e, u) Debug(DPROC|DEXT, ("[%d] got %ld bytes data from grandchild tmpfile\n", getpid(), (long) pos)) if (pos == 0) - goto mail_finished; + goto output_finished; // get name of recipient. if (mailto == NULL) mailto = usernm; else if (!*mailto) - goto mail_finished; + goto mail_headers_finished; /* Don't send mail if MAILCMD is not available */ if ((statret = stat(MAILCMD, &mcsb)) != 0) { Debug(DPROC|DEXT, ("%s not found, not sending mail\n", MAILCMD)) if (pos > 0) { - log_it("CRON", getpid(), "info", "No MTA installed, discarding output"); + log_it("CRON", getpid(), "info", "No MTA installed, not mailing output"); } - goto mail_finished; + goto mail_headers_finished; } else { Debug(DPROC|DEXT, ("%s found, will send mail\n", MAILCMD)) } - register FILE *mail = NULL; register int bytes = 1; register char **env; @@ -556,7 +556,7 @@ child_process(e, u) MAILARGS, MAILCMD, mailto); if (!(mail = cron_popen(mailcmd, "w", e))) { perror(MAILCMD); - (void) _exit(ERROR_EXIT); + goto mail_headers_finished; } fprintf(mail, "From: root (Cron Daemon)\n"); fprintf(mail, "To: %s\n", mailto); @@ -601,47 +601,49 @@ child_process(e, u) *env); fputc('\n', mail); +mail_headers_finished: // Append the actual output of the child to the mail + if (!mail && !(log_level & CRON_LOG_JOBOUTPUT)) + goto output_finished; + char buf[4096]; - int ret, remain; - while(1) { - if ((ret = fread(buf, 1, sizeof(buf), tmpout)) == 0) - break; - for (remain = ret; remain != 0; ) { - ret = fwrite(buf, 1, remain, mail); - if (ret > 0) { - remain -= ret; - continue; - } - // XXX error - break; - } + while(fgets(buf, sizeof(buf), tmpout) != NULL) { + size_t len; + len = strlen(buf); + if (buf[len-1] == '\n') + buf[len-1] = '\0'; + if (mail) + fprintf(mail, "%s\n", buf); + if (log_level & CRON_LOG_JOBOUTPUT) + log_it(usernm, job_pid, "CMD OUTPUT", buf); } - Debug(DPROC, ("[%d] closing pipe to mail\n", getpid())) - status = cron_pclose(mail); + if (mail) { + Debug(DPROC, ("[%d] closing pipe to mail\n", getpid())) + status = cron_pclose(mail); - /* if there was output and we could not mail it, - * log the facts so the poor user can figure out - * what's going on. - */ - if (status) { - char buf[MAX_TEMPSTR]; - snprintf(buf, MAX_TEMPSTR, - "mailed %d byte%s of output; " - "but got status 0x%04x, " - "\n", - bytes, (bytes==1)?"":"s", status); - log_it(usernm, getpid(), "MAIL", buf); + /* if there was output and we could not mail it, + * log the facts so the poor user can figure out + * what's going on. + */ + if (status) { + char buf[MAX_TEMPSTR]; + snprintf(buf, MAX_TEMPSTR, + "mailed %d byte%s of output; " + "but got status 0x%04x, " + "\n", + bytes, (bytes==1)?"":"s", status); + log_it(usernm, getpid(), "MAIL", buf); + } } if (ferror(tmpout)) { log_it(usernm, getpid(), "MAIL", "stream error reading output"); } -mail_finished: +output_finished: fclose(tmpout); if (log_level & CRON_LOG_JOBEND) { -- 1.7.10
>From 3347bcc09c7285f0f67cec2b04db944cf9205be6 Mon Sep 17 00:00:00 2001 From: Josh Triplett <j...@joshtriplett.org> Date: Sun, 22 Apr 2012 20:04:51 -0700 Subject: [PATCH 2/4] Add a new log level to log cron job output when not mailing that output. --- cron.8 | 6 ++++-- cron.h | 1 + debian/changelog | 3 ++- debian/cron.default | 3 ++- do_command.c | 11 ++++------- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/cron.8 b/cron.8 index 5985700..76d699b 100644 --- a/cron.8 +++ b/cron.8 @@ -55,11 +55,13 @@ will log all failed jobs (exit status != 0) .IP \fB8\fR will log the process number of all cron jobs .IP \fB16\fR -will log the full output of all cron jobs +will log the full output of all cron jobs, even when also mailing that output +.IP \fB32\fR +will log the full output of all cron jobs when not mailing that output .RE .IP The default is to log the start of all jobs (1). Logging will be disabled -if \fIlevels\fR is set to zero (0). A value of 31 will select all options. +if \fIlevels\fR is set to zero (0). A value of 63 will select all options. .SH NOTES .PP .I cron diff --git a/cron.h b/cron.h index d0cf070..8ceb90d 100644 --- a/cron.h +++ b/cron.h @@ -140,6 +140,7 @@ typedef int time_min; #define CRON_LOG_JOBFAILED 0x04 #define CRON_LOG_JOBPID 0x08 #define CRON_LOG_JOBOUTPUT 0x10 +#define CRON_LOG_JOBOUTPUT_IF_NO_MAIL 0x20 #define SECONDS_PER_MINUTE 60 diff --git a/debian/changelog b/debian/changelog index 99891b5..6f82878 100644 --- a/debian/changelog +++ b/debian/changelog @@ -8,7 +8,8 @@ cron (3.0pl1-122) UNRELEASED; urgency=low cron (Closes: #666892) [ Josh Triplett ] - * Add a new log level to log all cron job output. + * Add two new log levels: -L 16 logs all cron job output, and -L 32 logs all + cron job output when not already mailing that output. -- Javier Fernández-Sanguino Peña <j...@debian.org> Mon, 09 Apr 2012 17:23:01 +0200 diff --git a/debian/cron.default b/debian/cron.default index ed4383d..92845f9 100644 --- a/debian/cron.default +++ b/debian/cron.default @@ -23,7 +23,8 @@ READ_ENV="yes" # 2 log end of jobs # 4 log jobs with exit status != 0 # 8 log the process identifier of child process (in all logs) -# 16 log the full output of all cron jobs +# 16 log the full output of all cron jobs even when also mailing that output +# 32 log the full output of all cron jobs when not mailing that output # #EXTRA_OPTS="" diff --git a/do_command.c b/do_command.c index c2fc9f7..cb93fa8 100644 --- a/do_command.c +++ b/do_command.c @@ -534,8 +534,9 @@ child_process(e, u) /* Don't send mail if MAILCMD is not available */ if ((statret = stat(MAILCMD, &mcsb)) != 0) { Debug(DPROC|DEXT, ("%s not found, not sending mail\n", MAILCMD)) - if (pos > 0) { - log_it("CRON", getpid(), "info", "No MTA installed, not mailing output"); + if (pos > 0 && !(log_level & CRON_LOG_JOBOUTPUT) && !(log_level & CRON_LOG_JOBOUTPUT_IF_NO_MAIL)) { + log_it("CRON", getpid(), "info", "No MTA installed and not configured to log output; discarding output"); + goto output_finished; } goto mail_headers_finished; } else { @@ -603,10 +604,6 @@ child_process(e, u) mail_headers_finished: // Append the actual output of the child to the mail - - if (!mail && !(log_level & CRON_LOG_JOBOUTPUT)) - goto output_finished; - char buf[4096]; while(fgets(buf, sizeof(buf), tmpout) != NULL) { @@ -616,7 +613,7 @@ mail_headers_finished: buf[len-1] = '\0'; if (mail) fprintf(mail, "%s\n", buf); - if (log_level & CRON_LOG_JOBOUTPUT) + if ((log_level & CRON_LOG_JOBOUTPUT) || (!mail && (log_level & CRON_LOG_JOBOUTPUT_IF_NO_MAIL))) log_it(usernm, job_pid, "CMD OUTPUT", buf); } -- 1.7.10
>From 1306416db838e6e22eae0f72049382d0a0d78c1e Mon Sep 17 00:00:00 2001 From: Josh Triplett <j...@joshtriplett.org> Date: Sun, 22 Apr 2012 20:14:26 -0700 Subject: [PATCH 3/4] In /etc/default/cron, change the default log level to -L 35, to ensure that cron job output gets logged on systems without an MTA. --- debian/changelog | 2 ++ debian/cron.default | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 6f82878..d33c247 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,8 @@ cron (3.0pl1-122) UNRELEASED; urgency=low [ Josh Triplett ] * Add two new log levels: -L 16 logs all cron job output, and -L 32 logs all cron job output when not already mailing that output. + * In /etc/default/cron, change the default log level to -L 35, to ensure + that cron job output gets logged on systems without an MTA. -- Javier Fernández-Sanguino Peña <j...@debian.org> Mon, 09 Apr 2012 17:23:01 +0200 diff --git a/debian/cron.default b/debian/cron.default index 92845f9..08d2439 100644 --- a/debian/cron.default +++ b/debian/cron.default @@ -26,7 +26,7 @@ READ_ENV="yes" # 16 log the full output of all cron jobs even when also mailing that output # 32 log the full output of all cron jobs when not mailing that output # -#EXTRA_OPTS="" +EXTRA_OPTS="-L 35" # Uncomment to disable lost+found check #CHECK_LOSTFOUND=no -- 1.7.10
>From 138dcb1bb8d65525ce05969295268bf7b695e993 Mon Sep 17 00:00:00 2001 From: Josh Triplett <j...@joshtriplett.org> Date: Sun, 22 Apr 2012 20:26:42 -0700 Subject: [PATCH 4/4] Update Recommends, Suggests, and package description. * Update Recommends and Suggests: * Recommends at least one of a syslog daemon or a mail transport agent, to ensure that the recommended configuration will capture cron job output somewhere. * Separately, suggest a syslog daemon and suggest a mail transport agent. * Use default-mta rather than hard-coding specific MTAs. * Update package description to document the requirement for either a syslog daemon or a mail transport agent to capture cron job output. --- debian/changelog | 8 ++++++++ debian/control | 10 ++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/debian/changelog b/debian/changelog index d33c247..e500460 100644 --- a/debian/changelog +++ b/debian/changelog @@ -12,6 +12,14 @@ cron (3.0pl1-122) UNRELEASED; urgency=low cron job output when not already mailing that output. * In /etc/default/cron, change the default log level to -L 35, to ensure that cron job output gets logged on systems without an MTA. + * Update Recommends and Suggests: + * Recommends at least one of a syslog daemon or a mail transport agent, to + ensure that the recommended configuration will capture cron job output + somewhere. + * Separately, suggest a syslog daemon and suggest a mail transport agent. + * Use default-mta rather than hard-coding specific MTAs. + * Update package description to document the requirement for either a syslog + daemon or a mail transport agent to capture cron job output. -- Javier Fernández-Sanguino Peña <j...@debian.org> Mon, 09 Apr 2012 17:23:01 +0200 diff --git a/debian/control b/debian/control index 89ea77a..6f178a1 100644 --- a/debian/control +++ b/debian/control @@ -25,9 +25,11 @@ Depends: lsb-base (>= 3.0-10), libpam-runtime (>= 1.0.1-11) Recommends: - exim4 | postfix | mail-transport-agent + rsyslog | system-log-daemon | default-mta | mail-transport-agent Suggests: anacron (>=2.0-1), + default-mta | mail-transport-agent, + rsyslog | system-log-daemon, logrotate, checksecurity Breaks: @@ -39,9 +41,9 @@ Description: process scheduling daemon specified in a crontab. By default, users may also create crontabs of their own so that processes are run on their behalf. . - Output from the commands is usually mailed to the system administrator - (or to the user in question); you should probably install a mail system - as well so that you can receive these messages. + Output from cron jobs is either mailed to the user or logged to the system + log. You should install a syslog daemon if you want to log cron job output, or + install a mail transport agent if you want to receive cron job output by email. . This cron package is configured by default to do some basic daily system maintenance tasks. Other packages, such as checksecurity, can provide further -- 1.7.10