version 1.1, 1999/11/18 16:29:01 |
version 1.2, 2000/03/27 03:44:38 |
|
|
#include "sudo.h" |
#include "sudo.h" |
|
|
#ifndef lint |
#ifndef lint |
static const char rcsid[] = "$Sudo: logging.c,v 1.139 1999/10/09 05:01:48 millert Exp $"; |
static const char rcsid[] = "$Sudo: logging.c,v 1.140 2000/03/13 16:05:05 millert Exp $"; |
#endif /* lint */ |
#endif /* lint */ |
|
|
static void do_syslog __P((int, char *)); |
static void do_syslog __P((int, char *)); |
|
|
{ |
{ |
FILE *mail; |
FILE *mail; |
char *p; |
char *p; |
int pfd[2], pid; |
int pfd[2], pid, status; |
|
#ifdef POSIX_SIGNALS |
|
sigset_t set, oset; |
|
#else |
|
int omask; |
|
#endif /* POSIX_SIGNALS */ |
|
|
/* Just return if mailer is disabled. */ |
/* Just return if mailer is disabled. */ |
if (!def_str(I_MAILERPATH) || !def_str(I_MAILTO)) |
if (!def_str(I_MAILERPATH) || !def_str(I_MAILTO)) |
return; |
return; |
|
|
if ((pid = fork()) > 0) { /* Child. */ |
#ifdef POSIX_SIGNALS |
|
(void) sigemptyset(&set); |
|
(void) sigaddset(&set, SIGCHLD); |
|
(void) sigprocmask(SIG_BLOCK, &set, &oset); |
|
#else |
|
omask = sigblock(sigmask(SIGCHLD)); |
|
#endif /* POSIX_SIGNALS */ |
|
|
/* We do an explicit wait() later on... */ |
if (pipe(pfd) == -1) { |
(void) signal(SIGCHLD, SIG_IGN); |
(void) fprintf(stderr, "%s: cannot open pipe: %s\n", |
|
Argv[0], strerror(errno)); |
|
exit(1); |
|
} |
|
|
if (pipe(pfd) == -1) { |
switch (pid = fork()) { |
(void) fprintf(stderr, "%s: cannot open pipe: %s\n", |
case -1: |
|
/* Error. */ |
|
(void) fprintf(stderr, "%s: cannot fork: %s\n", |
Argv[0], strerror(errno)); |
Argv[0], strerror(errno)); |
exit(1); |
exit(1); |
} |
break; |
|
case 0: |
|
{ |
|
char *argv[MAX_MAILFLAGS + 1]; |
|
char *mpath, *mflags; |
|
int i; |
|
|
switch (pid = fork()) { |
/* Child. */ |
case -1: |
(void) close(pfd[1]); |
/* Error. */ |
(void) dup2(pfd[0], STDIN_FILENO); |
/* XXX - parent will continue, return an exit val to |
(void) close(pfd[0]); |
let parent know and abort? */ |
|
(void) fprintf(stderr, "%s: cannot fork: %s\n", |
|
Argv[0], strerror(errno)); |
|
exit(1); |
|
break; |
|
case 0: |
|
{ |
|
char *argv[MAX_MAILFLAGS + 1]; |
|
char *mpath, *mflags; |
|
int i; |
|
|
|
/* Grandchild. */ |
/* Build up an argv based the mailer path and flags */ |
(void) close(pfd[1]); |
mflags = estrdup(def_str(I_MAILERFLAGS)); |
(void) dup2(pfd[0], STDIN_FILENO); |
mpath = estrdup(def_str(I_MAILERPATH)); |
(void) close(pfd[0]); |
if ((argv[0] = strrchr(mpath, ' '))) |
|
argv[0]++; |
|
else |
|
argv[0] = mpath; |
|
|
/* Build up an argv based the mailer path and flags */ |
i = 1; |
mflags = estrdup(def_str(I_MAILERFLAGS)); |
if ((p = strtok(mflags, " \t"))) { |
mpath = estrdup(def_str(I_MAILERPATH)); |
do { |
if ((argv[0] = strrchr(mpath, ' '))) |
argv[i] = p; |
argv[0]++; |
} while (++i < MAX_MAILFLAGS && (p = strtok(NULL, " \t"))); |
else |
|
argv[0] = mpath; |
|
|
|
i = 1; |
|
if ((p = strtok(mflags, " \t"))) { |
|
do { |
|
argv[i] = p; |
|
} while (++i < MAX_MAILFLAGS && (p = strtok(NULL, " \t"))); |
|
} |
|
argv[i] = NULL; |
|
|
|
/* Run mailer as root so user cannot kill it. */ |
|
set_perms(PERM_ROOT, 0); |
|
execv(mpath, argv); |
|
_exit(127); |
|
} |
} |
break; |
argv[i] = NULL; |
} |
|
|
|
mail = fdopen(pfd[1], "w"); |
/* Run mailer as root so user cannot kill it. */ |
(void) close(pfd[0]); |
set_perms(PERM_ROOT, 0); |
|
execv(mpath, argv); |
|
_exit(127); |
|
} |
|
break; |
|
} |
|
|
/* Pipes are all setup, send message via sendmail. */ |
mail = fdopen(pfd[1], "w"); |
(void) fprintf(mail, "To: %s\nFrom: %s\nSubject: ", |
(void) close(pfd[0]); |
def_str(I_MAILTO), user_name); |
|
for (p = def_str(I_MAILSUB); *p; p++) { |
/* Pipes are all setup, send message via sendmail. */ |
/* Expand escapes in the subject */ |
(void) fprintf(mail, "To: %s\nFrom: %s\nSubject: ", |
if (*p == '%' && *(p+1) != '%') { |
def_str(I_MAILTO), user_name); |
switch (*(++p)) { |
for (p = def_str(I_MAILSUB); *p; p++) { |
case 'h': |
/* Expand escapes in the subject */ |
(void) fputs(user_host, mail); |
if (*p == '%' && *(p+1) != '%') { |
break; |
switch (*(++p)) { |
case 'u': |
case 'h': |
(void) fputs(user_name, mail); |
(void) fputs(user_host, mail); |
break; |
break; |
default: |
case 'u': |
p--; |
(void) fputs(user_name, mail); |
break; |
break; |
} |
default: |
} else |
p--; |
(void) fputc(*p, mail); |
break; |
} |
} |
(void) fprintf(mail, "\n\n%s : %s : %s : %s\n\n", user_host, |
} else |
get_timestr(), user_name, line); |
(void) fputc(*p, mail); |
fclose(mail); |
|
reapchild(0); |
|
_exit(0); |
|
} else { |
|
/* Parent, just return unless there is an error. */ |
|
if (pid == -1) { |
|
(void) fprintf(stderr, "%s: cannot fork: %s\n", |
|
Argv[0], strerror(errno)); |
|
exit(1); |
|
} |
|
} |
} |
|
(void) fprintf(mail, "\n\n%s : %s : %s : %s\n\n", user_host, |
|
get_timestr(), user_name, line); |
|
fclose(mail); |
|
|
|
/* If mailer is done, wait for it now. If not reapchild will get it. */ |
|
#ifdef sudo_waitpid |
|
(void) sudo_waitpid(pid, &status, WNOHANG); |
|
#endif |
|
#ifdef POSIX_SIGNALS |
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL); |
|
#else |
|
(void) sigsetmask(omask); |
|
#endif /* POSIX_SIGNALS */ |
} |
} |
|
|
/* |
/* |
|
|
int status, serrno = errno; |
int status, serrno = errno; |
|
|
#ifdef sudo_waitpid |
#ifdef sudo_waitpid |
while (sudo_waitpid(-1, &status, WNOHANG) != -1) |
while (sudo_waitpid(-1, &status, WNOHANG) != -1 && errno == EINTR) |
; |
; |
#else |
#else |
(void) wait(&status); |
(void) wait(&status); |