=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/sudo/Attic/logging.c,v retrieving revision 1.20 retrieving revision 1.21 diff -c -r1.20 -r1.21 *** src/usr.bin/sudo/Attic/logging.c 2008/07/31 16:44:03 1.20 --- src/usr.bin/sudo/Attic/logging.c 2008/11/14 11:58:08 1.21 *************** *** 1,5 **** /* ! * Copyright (c) 1994-1996,1998-2007 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above --- 1,5 ---- /* ! * Copyright (c) 1994-1996, 1998-2008 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above *************** *** 48,59 **** #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ - #ifdef HAVE_ERR_H - # include - #else - # include "emul/err.h" - #endif /* HAVE_ERR_H */ #include #include #include #include --- 48,55 ---- #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ #include + #include #include #include #include *************** *** 62,76 **** #include "sudo.h" #ifndef lint ! __unused static const char rcsid[] = "$Sudo: logging.c,v 1.168.2.16 2008/06/22 20:23:57 millert Exp $"; #endif /* lint */ static void do_syslog __P((int, char *)); static void do_logfile __P((char *)); static void send_mail __P((char *)); ! static void mail_auth __P((int, char *)); static char *get_timestr __P((void)); static void mysyslog __P((int, const char *, ...)); #define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */ --- 58,73 ---- #include "sudo.h" #ifndef lint ! __unused static const char rcsid[] = "$Sudo: logging.c,v 1.203 2008/11/09 14:13:12 millert Exp $"; #endif /* lint */ static void do_syslog __P((int, char *)); static void do_logfile __P((char *)); static void send_mail __P((char *)); ! static int should_mail __P((int)); static char *get_timestr __P((void)); static void mysyslog __P((int, const char *, ...)); + static char *new_logline __P((const char *, int)); #define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */ *************** *** 273,328 **** } /* ! * Two main functions, log_error() to log errors and log_auth() to ! * log allow/deny messages. */ void ! log_auth(status, inform_user) int status; int inform_user; { - char *evstr = NULL; char *message; char *logline; - int pri; ! if (ISSET(status, VALIDATE_OK)) ! pri = def_syslog_goodpri; ! else ! pri = def_syslog_badpri; ! ! /* Set error message, if any. */ ! if (ISSET(status, VALIDATE_OK)) ! message = ""; ! else if (ISSET(status, FLAG_NO_USER)) ! message = "user NOT in sudoers ; "; else if (ISSET(status, FLAG_NO_HOST)) ! message = "user NOT authorized on host ; "; ! else if (ISSET(status, VALIDATE_NOT_OK)) ! message = "command not allowed ; "; else ! message = "unknown error ; "; ! if (sudo_user.env_vars != NULL) { ! size_t len = 7; /* " ; ENV=" */ ! struct list_member *cur; ! for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next) ! len += strlen(cur->value) + 1; ! evstr = emalloc(len); ! strlcpy(evstr, " ; ENV=", len); ! for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next) { ! strlcat(evstr, cur->value, len); ! strlcat(evstr, " ", len); /* NOTE: last one will fail */ ! } ! } ! easprintf(&logline, "%sTTY=%s ; PWD=%s ; USER=%s%s ; COMMAND=%s%s%s", ! message, user_tty, user_cwd, *user_runas, evstr ? evstr : "", ! user_cmnd, user_args ? " " : "", user_args ? user_args : ""); ! mail_auth(status, logline); /* send mail based on status */ /* Inform the user if they failed to authenticate. */ ! if (inform_user && ISSET(status, VALIDATE_NOT_OK)) { if (ISSET(status, FLAG_NO_USER)) (void) fprintf(stderr, "%s is not in the sudoers file. %s", user_name, "This incident will be reported.\n"); --- 270,300 ---- } /* ! * Log and mail the denial message, optionally informing the user. */ void ! log_denial(status, inform_user) int status; int inform_user; { char *message; char *logline; ! /* Set error message. */ ! if (ISSET(status, FLAG_NO_USER)) ! message = "user NOT in sudoers"; else if (ISSET(status, FLAG_NO_HOST)) ! message = "user NOT authorized on host"; else ! message = "command not allowed"; ! logline = new_logline(message, 0); ! if (should_mail(status)) ! send_mail(logline); /* send mail based on status */ /* Inform the user if they failed to authenticate. */ ! if (inform_user) { if (ISSET(status, FLAG_NO_USER)) (void) fprintf(stderr, "%s is not in the sudoers file. %s", user_name, "This incident will be reported.\n"); *************** *** 334,357 **** user_name, user_shost); else (void) fprintf(stderr, ! "Sorry, user %s is not allowed to execute '%s%s%s' as %s on %s.\n", user_name, user_cmnd, user_args ? " " : "", ! user_args ? user_args : "", *user_runas, user_host); } /* * Log via syslog and/or a file. */ if (def_syslog) ! do_syslog(pri, logline); if (def_logfile) do_logfile(logline); - efree(evstr); efree(logline); } void #ifdef __STDC__ log_error(int flags, const char *fmt, ...) #else --- 306,356 ---- user_name, user_shost); else (void) fprintf(stderr, ! "Sorry, user %s is not allowed to execute '%s%s%s' as %s%s%s on %s.\n", user_name, user_cmnd, user_args ? " " : "", ! user_args ? user_args : "", ! list_pw ? list_pw->pw_name : runas_pw ? ! runas_pw->pw_name : user_name, runas_gr ? ":" : "", ! runas_gr ? runas_gr->gr_name : "", user_host); } /* * Log via syslog and/or a file. */ if (def_syslog) ! do_syslog(def_syslog_badpri, logline); if (def_logfile) do_logfile(logline); efree(logline); } + /* + * Log and potentially mail the allowed command. + */ void + log_allowed(status) + int status; + { + char *logline; + + logline = new_logline(NULL, 0); + + if (should_mail(status)) + send_mail(logline); /* send mail based on status */ + + /* + * Log via syslog and/or a file. + */ + if (def_syslog) + do_syslog(def_syslog_goodpri, logline); + if (def_logfile) + do_logfile(logline); + + efree(logline); + } + + void #ifdef __STDC__ log_error(int flags, const char *fmt, ...) #else *************** *** 364,370 **** int serrno = errno; char *message; char *logline; - char *evstr = NULL; va_list ap; #ifdef __STDC__ va_start(ap, fmt); --- 363,368 ---- *************** *** 379,431 **** evasprintf(&message, fmt, ap); va_end(ap); - if (sudo_user.env_vars != NULL) { - size_t len = 7; /* " ; ENV=" */ - struct list_member *cur; - for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next) - len += strlen(cur->value) + 1; - evstr = emalloc(len); - strlcpy(evstr, " ; ENV=", len); - for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next) { - strlcat(evstr, cur->value, len); - strlcat(evstr, " ", len); /* NOTE: last one will fail */ - } - } - if (ISSET(flags, MSG_ONLY)) logline = message; ! else if (ISSET(flags, USE_ERRNO)) { ! if (user_args) { ! easprintf(&logline, ! "%s: %s ; TTY=%s ; PWD=%s ; USER=%s%s ; COMMAND=%s %s", ! message, strerror(serrno), user_tty, user_cwd, *user_runas, ! evstr ? evstr : "", user_cmnd, user_args); ! } else { ! easprintf(&logline, ! "%s: %s ; TTY=%s ; PWD=%s ; USER=%s%s ; COMMAND=%s", message, ! strerror(serrno), user_tty, user_cwd, *user_runas, ! evstr ? evstr : "", user_cmnd); ! } ! } else { ! if (user_args) { ! easprintf(&logline, ! "%s ; TTY=%s ; PWD=%s ; USER=%s%s ; COMMAND=%s %s", message, ! user_tty, user_cwd, *user_runas, evstr ? evstr : "", ! user_cmnd, user_args); ! } else { ! easprintf(&logline, ! "%s ; TTY=%s ; PWD=%s ; USER=%s%s ; COMMAND=%s", message, ! user_tty, user_cwd, *user_runas, evstr ? evstr : "", user_cmnd); ! } ! } /* * Tell the user. */ ! if (ISSET(flags, USE_ERRNO)) ! warn("%s", message); ! else ! warnx("%s", message); /* * Send a copy of the error via mail. --- 377,397 ---- evasprintf(&message, fmt, ap); va_end(ap); if (ISSET(flags, MSG_ONLY)) logline = message; ! else ! logline = new_logline(message, ISSET(flags, USE_ERRNO) ? serrno : 0); /* * Tell the user. */ ! if (!ISSET(flags, NO_STDERR)) { ! if (ISSET(flags, USE_ERRNO)) ! warning("%s", message); ! else ! warningx("%s", message); ! } ! efree(message); /* * Send a copy of the error via mail. *************** *** 441,452 **** if (def_logfile) do_logfile(logline); - efree(message); if (logline != message) efree(logline); ! if (!ISSET(flags, NO_EXIT)) exit(1); } #define MAX_MAILFLAGS 63 --- 407,419 ---- if (def_logfile) do_logfile(logline); if (logline != message) efree(logline); ! if (!ISSET(flags, NO_EXIT)) { ! cleanup(0); exit(1); + } } #define MAX_MAILFLAGS 63 *************** *** 481,491 **** /* Fork and return, child will daemonize. */ switch (pid = fork()) { case -1: ! /* Error */ ! err(1, "cannot fork"); break; case 0: ! /* Child */ switch (pid = fork()) { case -1: /* Error. */ --- 448,458 ---- /* Fork and return, child will daemonize. */ switch (pid = fork()) { case -1: ! /* Error. */ ! error(1, "cannot fork"); break; case 0: ! /* Child. */ switch (pid = fork()) { case -1: /* Error. */ *************** *** 500,506 **** } break; default: ! /* Parent */ do { #ifdef HAVE_WAITPID rv = waitpid(pid, &status, 0); --- 467,473 ---- } break; default: ! /* Parent. */ do { #ifdef HAVE_WAITPID rv = waitpid(pid, &status, 0); *************** *** 514,520 **** /* Daemonize - disassociate from session/tty. */ #ifdef HAVE_SETSID if (setsid() == -1) ! warn("setsid"); #else setpgrp(0, 0); # ifdef TIOCNOTTY --- 481,487 ---- /* Daemonize - disassociate from session/tty. */ #ifdef HAVE_SETSID if (setsid() == -1) ! warning("setsid"); #else setpgrp(0, 0); # ifdef TIOCNOTTY *************** *** 531,541 **** (void) dup2(fd, STDERR_FILENO); } ! /* Close password and other fds so we don't leak. */ ! endpwent(); closefrom(STDERR_FILENO + 1); /* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */ sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; --- 498,510 ---- (void) dup2(fd, STDERR_FILENO); } ! /* Close password, group and other fds so we don't leak. */ ! sudo_endpwent(); ! sudo_endgrent(); closefrom(STDERR_FILENO + 1); /* Ignore SIGPIPE in case mailer exits prematurely (or is missing). */ + zero_bytes(&sa, sizeof(sa)); sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sa.sa_handler = SIG_IGN; *************** *** 601,609 **** (void) close(pfd[0]); mail = fdopen(pfd[1], "w"); ! /* Pipes are all setup, send message via sendmail. */ (void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ", ! def_mailto, user_name, "auto-generated"); for (p = def_mailsub; *p; p++) { /* Expand escapes in the subject */ if (*p == '%' && *(p+1) != '%') { --- 570,578 ---- (void) close(pfd[0]); mail = fdopen(pfd[1], "w"); ! /* Pipes are all setup, send message. */ (void) fprintf(mail, "To: %s\nFrom: %s\nAuto-Submitted: %s\nSubject: ", ! def_mailto, def_mailfrom ? def_mailfrom : user_name, "auto-generated"); for (p = def_mailsub; *p; p++) { /* Expand escapes in the subject */ if (*p == '%' && *(p+1) != '%') { *************** *** 626,665 **** fclose(mail); do { #ifdef HAVE_WAITPID ! rv = waitpid(pid, &status, 0); #else ! rv = wait(&status); #endif } while (rv == -1 && errno == EINTR); _exit(0); } /* ! * Send mail based on the value of "status" and compile-time options. */ ! static void ! mail_auth(status, line) int status; - char *line; { - int mail_mask; ! /* If any of these bits are set in status, we send mail. */ ! if (def_mail_always) ! mail_mask = ! VALIDATE_ERROR|VALIDATE_OK|FLAG_NO_USER|FLAG_NO_HOST|VALIDATE_NOT_OK; ! else { ! mail_mask = VALIDATE_ERROR; ! if (def_mail_no_user) ! SET(mail_mask, FLAG_NO_USER); ! if (def_mail_no_host) ! SET(mail_mask, FLAG_NO_HOST); ! if (def_mail_no_perms) ! SET(mail_mask, VALIDATE_NOT_OK); ! } ! ! if ((status & mail_mask) != 0) ! send_mail(line); } /* --- 595,620 ---- fclose(mail); do { #ifdef HAVE_WAITPID ! rv = waitpid(pid, &status, 0); #else ! rv = wait(&status); #endif } while (rv == -1 && errno == EINTR); _exit(0); } /* ! * Determine whether we should send mail based on "status" and defaults options. */ ! static int ! should_mail(status) int status; { ! return(def_mail_always || ISSET(status, VALIDATE_ERROR) || ! (def_mail_no_user && ISSET(status, FLAG_NO_USER)) || ! (def_mail_no_host && ISSET(status, FLAG_NO_HOST)) || ! (def_mail_no_perms && !ISSET(status, VALIDATE_OK))); } /* *************** *** 695,698 **** --- 650,762 ---- s[15] = '\0'; /* don't care about year */ return(s); + } + + #define LL_TTY_STR "TTY=" + #define LL_CWD_STR "PWD=" /* XXX - should be CWD= */ + #define LL_USER_STR "USER=" + #define LL_GROUP_STR "GROUP=" + #define LL_ENV_STR "ENV=" + #define LL_CMND_STR "COMMAND=" + + /* + * Allocate and fill in a new logline. + */ + static char * + new_logline(message, serrno) + const char *message; + int serrno; + { + size_t len = 0; + char *evstr = NULL; + char *errstr = NULL; + char *line; + + /* + * Compute line length + */ + if (message != NULL) + len += strlen(message) + 3; + if (serrno) { + errstr = strerror(serrno); + len += strlen(errstr) + 3; + } + len += sizeof(LL_TTY_STR) + 2 + strlen(user_tty); + len += sizeof(LL_CWD_STR) + 2 + strlen(user_cwd); + if (runas_pw != NULL) + len += sizeof(LL_USER_STR) + 2 + strlen(runas_pw->pw_name); + if (runas_gr != NULL) + len += sizeof(LL_GROUP_STR) + 2 + strlen(runas_gr->gr_name); + if (sudo_user.env_vars != NULL) { + size_t evlen = 0; + struct list_member *cur; + for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next) + evlen += strlen(cur->value) + 1; + evstr = emalloc(evlen); + evstr[0] = '\0'; + for (cur = sudo_user.env_vars; cur != NULL; cur = cur->next) { + strlcat(evstr, cur->value, evlen); + strlcat(evstr, " ", evlen); /* NOTE: last one will fail */ + } + len += sizeof(LL_ENV_STR) + 2 + evlen; + } + len += sizeof(LL_CMND_STR) - 1 + strlen(user_cmnd); + if (user_args != NULL) + len += strlen(user_args) + 1; + + /* + * Allocate and build up the line. + */ + line = emalloc(++len); + line[0] = '\0'; + + if (message != NULL) { + if (strlcat(line, message, len) >= len || + strlcat(line, errstr ? " : " : " ; ", len) >= len) + goto toobig; + } + if (serrno) { + if (strlcat(line, errstr, len) >= len || + strlcat(line, " ; ", len) >= len) + goto toobig; + } + if (strlcat(line, LL_TTY_STR, len) >= len || + strlcat(line, user_tty, len) >= len || + strlcat(line, " ; ", len) >= len) + goto toobig; + if (strlcat(line, LL_CWD_STR, len) >= len || + strlcat(line, user_cwd, len) >= len || + strlcat(line, " ; ", len) >= len) + goto toobig; + if (runas_pw != NULL) { + if (strlcat(line, LL_USER_STR, len) >= len || + strlcat(line, runas_pw->pw_name, len) >= len || + strlcat(line, " ; ", len) >= len) + goto toobig; + } + if (runas_gr != NULL) { + if (strlcat(line, LL_GROUP_STR, len) >= len || + strlcat(line, runas_gr->gr_name, len) >= len || + strlcat(line, " ; ", len) >= len) + goto toobig; + } + if (evstr != NULL) { + if (strlcat(line, LL_ENV_STR, len) >= len || + strlcat(line, evstr, len) >= len || + strlcat(line, " ; ", len) >= len) + goto toobig; + efree(evstr); + } + if (strlcat(line, LL_CMND_STR, len) >= len || + strlcat(line, user_cmnd, len) >= len) + goto toobig; + if (user_args != NULL) { + if (strlcat(line, " ", len) >= len || + strlcat(line, user_args, len) >= len) + goto toobig; + } + + return (line); + toobig: + errorx(1, "internal error: insufficient space for log line"); }