--- embedaddon/sudo/plugins/sudoers/logging.c 2012/05/29 12:26:49 1.1.1.2 +++ embedaddon/sudo/plugins/sudoers/logging.c 2012/10/09 09:29:52 1.1.1.3 @@ -73,6 +73,8 @@ static char *new_logline(const char *, int); extern sigjmp_buf error_jmp; +extern char **NewArgv; /* XXX - for auditing */ + #define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */ /* @@ -130,10 +132,12 @@ do_syslog(int pri, char *msg) size_t len, maxlen; char *p, *tmp, save; const char *fmt; +#ifdef HAVE_SETLOCALE + const char *old_locale = estrdup(setlocale(LC_ALL, NULL)); +#endif debug_decl(do_syslog, SUDO_DEBUG_LOGGING) #ifdef HAVE_SETLOCALE - const char *old_locale = estrdup(setlocale(LC_ALL, NULL)); if (!setlocale(LC_ALL, def_sudoers_locale)) setlocale(LC_ALL, "C"); #endif /* HAVE_SETLOCALE */ @@ -245,8 +249,8 @@ do_logfile(char *msg) /* * Log and mail the denial message, optionally informing the user. */ -void -log_denial(int status, int inform_user) +static void +log_denial(int status, bool inform_user) { char *logline, *message; debug_decl(log_denial, SUDO_DEBUG_LOGGING) @@ -300,6 +304,87 @@ log_denial(int status, int inform_user) } /* + * Log and audit that user was not allowed to run the command. + */ +void +log_failure(int status, int flags) +{ + debug_decl(log_failure, SUDO_DEBUG_LOGGING) + bool inform_user = true; + + /* Handle auditing first. */ + if (ISSET(status, FLAG_NO_USER | FLAG_NO_HOST)) + audit_failure(NewArgv, _("No user or host")); + else + audit_failure(NewArgv, _("validation failure")); + + /* The user doesn't always get to see the log message (path info). */ + if (!ISSET(status, FLAG_NO_USER | FLAG_NO_HOST) && def_path_info && + (flags == NOT_FOUND_DOT || flags == NOT_FOUND)) + inform_user = false; + log_denial(status, inform_user); + + if (!inform_user) { + /* + * We'd like to not leak path info at all here, but that can + * *really* confuse the users. To really close the leak we'd + * have to say "not allowed to run foo" even when the problem + * is just "no foo in path" since the user can trivially set + * their path to just contain a single dir. + */ + if (flags == NOT_FOUND) + warningx(_("%s: command not found"), user_cmnd); + else if (flags == NOT_FOUND_DOT) + warningx(_("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run."), user_cmnd, user_cmnd, user_cmnd); + } + + debug_return; +} + +/* + * Log and audit that user was not able to authenticate themselves. + */ +void +log_auth_failure(int status, int tries) +{ + int flags = NO_MAIL; + debug_decl(log_auth_failure, SUDO_DEBUG_LOGGING) + + /* Handle auditing first. */ + audit_failure(NewArgv, _("authentication failure")); + + /* + * Do we need to send mail? + * We want to avoid sending multiple messages for the same command + * so if we are going to send an email about the denial, that takes + * precedence. + */ + if (ISSET(status, VALIDATE_OK)) { + /* Command allowed, auth failed; do we need to send mail? */ + if (def_mail_badpass || def_mail_always) + flags = 0; + } else { + /* Command denied, auth failed; make sure we don't send mail twice. */ + if (def_mail_badpass && !should_mail(status)) + flags = 0; + /* Don't log the bad password message, we'll log a denial instead. */ + flags |= NO_LOG; + } + + /* + * If sudoers denied the command we'll log that separately. + */ + if (ISSET(status, FLAG_BAD_PASSWORD)) { + log_error(flags, ngettext("%d incorrect password attempt", + "%d incorrect password attempts", tries), tries); + } else if (ISSET(status, FLAG_NON_INTERACTIVE)) { + log_error(flags, _("a password is required")); + } + + debug_return; +} + +/* * Log and potentially mail the allowed command. */ void @@ -367,10 +452,12 @@ vlog_error(int flags, const char *fmt, va_list ap) /* * Log to syslog and/or a file. */ - if (def_syslog) - do_syslog(def_syslog_badpri, logline); - if (def_logfile) - do_logfile(logline); + if (!ISSET(flags, NO_LOG)) { + if (def_syslog) + do_syslog(def_syslog_badpri, logline); + if (def_logfile) + do_logfile(logline); + } efree(logline);