On Sun, 15 Nov 2015 09:41:38 -0700, "Todd C. Miller" wrote: > This cleans up the remaining uses of stderr and perror() and uses > warn/err and/or syslog depending on whether stderr is hooked up at > the time. Also removes closelog() which is not needed since we are > headed for exec.
Here's the diff -uw version for easier reading. - todd Index: usr.sbin/cron/atrun.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/atrun.c,v retrieving revision 1.40 diff -u -p -u -w -r1.40 atrun.c --- usr.sbin/cron/atrun.c 14 Nov 2015 13:09:14 -0000 1.40 +++ usr.sbin/cron/atrun.c 15 Nov 2015 21:24:59 -0000 @@ -29,6 +29,7 @@ #include <bsd_auth.h> #include <ctype.h> #include <dirent.h> +#include <err.h> #include <errno.h> #include <fcntl.h> #include <limits.h> @@ -226,6 +227,8 @@ run_job(atjob *job, char *atfile) { struct stat sb; struct passwd *pw; + login_cap_t *lc; + auth_session_t *as; pid_t pid; long nuid, ngid; FILE *fp; @@ -388,12 +391,9 @@ run_job(atjob *job, char *atfile) /* Write log message now that we have our real pid. */ syslog(LOG_INFO, "(%s) ATJOB (%s)", pw->pw_name, atfile); - /* Close syslog file */ - closelog(); - /* Connect grandchild's stdin to the at job file. */ if (lseek(fd, 0, SEEK_SET) < 0) { - perror("lseek"); + syslog(LOG_ERR, "(CRON) LSEEK (%m)"); _exit(EXIT_FAILURE); } if (fd != STDIN_FILENO) { @@ -411,41 +411,50 @@ run_job(atjob *job, char *atfile) (void) setsid(); - { - login_cap_t *lc; - auth_session_t *as; + /* + * From this point on, anything written to stderr will be + * mailed to the user as output. + */ + + /* Setup execution environment as per login.conf */ if ((lc = login_getclass(pw->pw_class)) == NULL) { - fprintf(stderr, - "Cannot get login class for %s\n", + warnx("unable to get login class for %s", + pw->pw_name); + syslog(LOG_ERR, "(CRON) CAN'T GET LOGIN CLASS (%s)", pw->pw_name); _exit(EXIT_FAILURE); } - if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL)) { - fprintf(stderr, - "setusercontext failed for %s\n", + warn("setusercontext failed for %s", pw->pw_name); + syslog(LOG_ERR, "(%s) SETUSERCONTEXT FAILED (%m)", pw->pw_name); _exit(EXIT_FAILURE); } + + /* Run any approval scripts. */ as = auth_open(); if (as == NULL || auth_setpwd(as, pw) != 0) { - fprintf(stderr, "can't malloc\n"); + warn("auth_setpwd"); + syslog(LOG_ERR, "(%s) AUTH_SETPWD FAILED (%m)", + pw->pw_name); _exit(EXIT_FAILURE); } if (auth_approval(as, lc, pw->pw_name, "cron") <= 0) { - fprintf(stderr, "approval failed for %s\n", - pw->pw_name); + warnx("approval failed for %s", pw->pw_name); + syslog(LOG_ERR, "(%s) APPROVAL FAILED (%s)", + pw->pw_name, pw->pw_name); _exit(EXIT_FAILURE); } auth_close(as); login_close(lc); - } /* If this is a low priority job, nice ourself. */ - if (job->queue > 'b') - (void)setpriority(PRIO_PROCESS, 0, job->queue - 'b'); - + if (job->queue > 'b') { + if (setpriority(PRIO_PROCESS, 0, job->queue - 'b') != 0) + syslog(LOG_ERR, "(%s) CAN'T NICE (%m)", + pw->pw_name); + } (void) signal(SIGPIPE, SIG_DFL); @@ -458,7 +467,9 @@ run_job(atjob *job, char *atfile) nargv[1] = NULL; nenvp[0] = NULL; if (execve(_PATH_BSHELL, nargv, nenvp) != 0) { - perror("execve: " _PATH_BSHELL); + warn("unable to execute %s", _PATH_BSHELL); + syslog(LOG_ERR, "(%s) CAN'T EXEC (%s: %m)", pw->pw_name, + _PATH_BSHELL); _exit(EXIT_FAILURE); } break; @@ -473,7 +484,7 @@ run_job(atjob *job, char *atfile) /* Read piped output (if any) from the at job. */ if ((fp = fdopen(output_pipe[READ_PIPE], "r")) == NULL) { - perror("fdopen"); + syslog(LOG_ERR, "(%s) FDOPEN (%m)", pw->pw_name); (void) _exit(EXIT_FAILURE); } nread = fread(buf, 1, sizeof(buf), fp); @@ -489,11 +500,12 @@ run_job(atjob *job, char *atfile) strlcpy(hostname, "unknown", sizeof(hostname)); if (snprintf(mailcmd, sizeof mailcmd, MAILFMT, MAILARG) >= sizeof mailcmd) { - fprintf(stderr, "mailcmd too long\n"); + syslog(LOG_ERR, "(%s) ERROR (mailcmd too long)", + pw->pw_name); (void) _exit(EXIT_FAILURE); } if (!(mail = cron_popen(mailcmd, "w", pw, &mailpid))) { - perror(mailcmd); + syslog(LOG_ERR, "(%s) POPEN (%s)", pw->pw_name, mailcmd); (void) _exit(EXIT_FAILURE); } fprintf(mail, "From: %s (Atrun Service)\n", pw->pw_name); Index: usr.sbin/cron/cron.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/cron.c,v retrieving revision 1.72 diff -u -p -u -w -r1.72 cron.c --- usr.sbin/cron/cron.c 14 Nov 2015 13:11:32 -0000 1.72 +++ usr.sbin/cron/cron.c 15 Nov 2015 21:24:59 -0000 @@ -24,6 +24,7 @@ #include <sys/wait.h> #include <bitstring.h> +#include <err.h> #include <errno.h> #include <grp.h> #include <locale.h> @@ -100,6 +101,7 @@ main(int argc, char *argv[]) if (pledge("stdio rpath wpath cpath fattr getpw unix id dns proc exec", NULL) == -1) { + warn("pledge"); syslog(LOG_ERR, "(CRON) PLEDGE (%m)"); exit(EXIT_FAILURE); } @@ -107,6 +109,7 @@ main(int argc, char *argv[]) cronSock = open_socket(); if (putenv("PATH="_PATH_DEFPATH) < 0) { + warn("putenv"); syslog(LOG_ERR, "(CRON) DEATH (%m)"); exit(EXIT_FAILURE); } @@ -424,22 +427,21 @@ open_socket(void) sock = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (sock == -1) { - fprintf(stderr, "%s: can't create socket: %s\n", - __progname, strerror(errno)); + warn("socket"); syslog(LOG_ERR, "(CRON) DEATH (can't create socket)"); exit(EXIT_FAILURE); } bzero(&s_un, sizeof(s_un)); if (strlcpy(s_un.sun_path, _PATH_CRON_SOCK, sizeof(s_un.sun_path)) >= sizeof(s_un.sun_path)) { - fprintf(stderr, "%s: path too long\n", _PATH_CRON_SOCK); + warnc(ENAMETOOLONG, _PATH_CRON_SOCK); syslog(LOG_ERR, "(CRON) DEATH (socket path too long)"); exit(EXIT_FAILURE); } s_un.sun_family = AF_UNIX; if (connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == 0) { - fprintf(stderr, "%s: already running\n", __progname); + warnx("already running"); syslog(LOG_ERR, "(CRON) DEATH (already running)"); exit(EXIT_FAILURE); } @@ -450,14 +452,12 @@ open_socket(void) rc = bind(sock, (struct sockaddr *)&s_un, sizeof(s_un)); umask(omask); if (rc != 0) { - fprintf(stderr, "%s: can't bind socket: %s\n", - __progname, strerror(errno)); + warn("bind"); syslog(LOG_ERR, "(CRON) DEATH (can't bind socket)"); exit(EXIT_FAILURE); } if (listen(sock, SOMAXCONN)) { - fprintf(stderr, "%s: can't listen on socket: %s\n", - __progname, strerror(errno)); + warn("listen"); syslog(LOG_ERR, "(CRON) DEATH (can't listen on socket)"); exit(EXIT_FAILURE); } @@ -513,8 +513,7 @@ parse_args(int argc, char *argv[]) batch_maxload = strtod(optarg, &ep); if (*ep != '\0' || ep == optarg || errno == ERANGE || batch_maxload < 0) { - fprintf(stderr, "Illegal load average: %s\n", - optarg); + warnx("illegal load average: %s", optarg); usage(); } break; Index: usr.sbin/cron/do_command.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/do_command.c,v retrieving revision 1.54 diff -u -p -u -w -r1.54 do_command.c --- usr.sbin/cron/do_command.c 14 Nov 2015 13:09:14 -0000 1.54 +++ usr.sbin/cron/do_command.c 15 Nov 2015 21:24:59 -0000 @@ -23,6 +23,7 @@ #include <bitstring.h> /* for structs.h */ #include <bsd_auth.h> #include <ctype.h> +#include <err.h> #include <errno.h> #include <fcntl.h> #include <limits.h> @@ -76,8 +77,11 @@ child_process(entry *e, user *u) { FILE *in; int stdin_pipe[2], stdout_pipe[2]; - char *input_data, *usernm; + char **p, *input_data, *usernm; + auth_session_t *as; + login_cap_t *lc; int children = 0; + extern char **environ; /* mark ourselves as different to PS command watchers */ setproctitle("running job"); @@ -156,10 +160,6 @@ child_process(entry *e, user *u) } } - /* that's the last thing we'll log. close the log files. - */ - closelog(); - /* get new pgrp, void tty, etc. */ (void) setsid(); @@ -186,36 +186,36 @@ child_process(entry *e, user *u) } dup2(STDOUT_FILENO, STDERR_FILENO); - /* set our directory, uid and gid. Set gid first, since once - * we set uid, we've lost root privileges. + /* + * From this point on, anything written to stderr will be + * mailed to the user as output. */ - { - auth_session_t *as; - login_cap_t *lc; - char **p; - extern char **environ; /* XXX - should just pass in a login_cap_t * */ if ((lc = login_getclass(e->pwd->pw_class)) == NULL) { - fprintf(stderr, - "unable to get login class for %s\n", + warnx("unable to get login class for %s", + e->pwd->pw_name); + syslog(LOG_ERR, "(CRON) CAN'T GET LOGIN CLASS (%s)", e->pwd->pw_name); _exit(EXIT_FAILURE); } if (setusercontext(lc, e->pwd, e->pwd->pw_uid, LOGIN_SETALL) < 0) { - fprintf(stderr, - "setusercontext failed for %s\n", + warn("setusercontext failed for %s", e->pwd->pw_name); + syslog(LOG_ERR, "(%s) SETUSERCONTEXT FAILED (%m)", e->pwd->pw_name); _exit(EXIT_FAILURE); } as = auth_open(); if (as == NULL || auth_setpwd(as, e->pwd) != 0) { - fprintf(stderr, "can't malloc\n"); + warn("auth_setpwd"); + syslog(LOG_ERR, "(%s) AUTH_SETPWD FAILED (%m)", + e->pwd->pw_name); _exit(EXIT_FAILURE); } if (auth_approval(as, lc, usernm, "cron") <= 0) { - fprintf(stderr, "approval failed for %s\n", - e->pwd->pw_name); + warnx("approval failed for %s", e->pwd->pw_name); + syslog(LOG_ERR, "(%s) APPROVAL FAILED (%s)", + e->pwd->pw_name, e->pwd->pw_name); _exit(EXIT_FAILURE); } auth_close(as); @@ -233,7 +233,6 @@ child_process(entry *e, user *u) } } } - } chdir(env_get("HOME", e->envp)); (void) signal(SIGPIPE, SIG_DFL); @@ -245,8 +244,9 @@ child_process(entry *e, user *u) char *shell = env_get("SHELL", e->envp); execle(shell, shell, "-c", e->cmd, (char *)NULL, e->envp); - fprintf(stderr, "execle: couldn't exec `%s'\n", shell); - perror("execle"); + warn("unable to execute %s", shell); + syslog(LOG_ERR, "(%s) CAN'T EXEC (%s: %m)", + e->pwd->pw_name, shell); _exit(EXIT_FAILURE); } break; @@ -372,12 +372,15 @@ child_process(entry *e, user *u) gethostname(hostname, sizeof(hostname)); if (snprintf(mailcmd, sizeof mailcmd, MAILFMT, MAILARG) >= sizeof mailcmd) { - fprintf(stderr, "mailcmd too long\n"); + syslog(LOG_ERR, + "(%s) ERROR (mailcmd too long)", + e->pwd->pw_name); (void) _exit(EXIT_FAILURE); } if (!(mail = cron_popen(mailcmd, "w", e->pwd, &mailpid))) { - perror(mailcmd); + syslog(LOG_ERR, "(%s) POPEN (%s)", + e->pwd->pw_name, mailcmd); (void) _exit(EXIT_FAILURE); } fprintf(mail, "From: root (Cron Daemon)\n"); Index: usr.sbin/cron/popen.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/popen.c,v retrieving revision 1.29 diff -u -p -u -w -r1.29 popen.c --- usr.sbin/cron/popen.c 4 Nov 2015 20:28:17 -0000 1.29 +++ usr.sbin/cron/popen.c 15 Nov 2015 21:24:59 -0000 @@ -41,6 +41,7 @@ #include <sys/wait.h> #include <bitstring.h> /* for structs.h */ +#include <err.h> #include <errno.h> #include <login_cap.h> #include <pwd.h> @@ -48,6 +49,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <syslog.h> #include <unistd.h> #include <time.h> /* for structs.h */ @@ -91,8 +93,10 @@ cron_popen(char *program, char *type, st case 0: /* child */ if (pw) { if (setusercontext(0, pw, pw->pw_uid, LOGIN_SETALL) < 0) { - fprintf(stderr, - "setusercontext failed for %s\n", + syslog(LOG_ERR, + "(%s) SETUSERCONTEXT FAILED (%m)", + pw->pw_name); + warn("setusercontext failed for %s", pw->pw_name); _exit(EXIT_FAILURE); } Index: usr.sbin/cron/user.c =================================================================== RCS file: /cvs/src/usr.sbin/cron/user.c,v retrieving revision 1.17 diff -u -p -u -w -r1.17 user.c --- usr.sbin/cron/user.c 9 Nov 2015 01:12:27 -0000 1.17 +++ usr.sbin/cron/user.c 15 Nov 2015 21:24:59 -0000 @@ -22,9 +22,11 @@ #include <bitstring.h> /* for structs.h */ #include <ctype.h> #include <errno.h> +#include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <syslog.h> #include <time.h> /* for structs.h */ #include "macros.h" @@ -55,7 +57,7 @@ load_user(int crontab_fd, struct passwd char **envp, **tenvp; if (!(file = fdopen(crontab_fd, "r"))) { - perror("fdopen on crontab_fd in load_user"); + syslog(LOG_ERR, "(%s) FDOPEN (%m)", pw->pw_name); return (NULL); }