From: Todd C. Miller Date: Wed, 11 Feb 2009 01:18:02 +0000 (+0000) Subject: Add bsm audit support from Christian S.J. Peron X-Git-Tag: SUDO_1_7_1~58 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f492e530569d49a79c7043f0f238f2b6ff04511f;p=sudo Add bsm audit support from Christian S.J. Peron --- diff --git a/Makefile.in b/Makefile.in index 98c3e3933..836e2e963 100644 --- a/Makefile.in +++ b/Makefile.in @@ -102,14 +102,15 @@ SHELL = /bin/sh PROGS = @PROGS@ -SRCS = aix.c alias.c alloc.c check.c closefrom.c def_data.c defaults.c env.c \ - error.c fileops.c find_path.c fnmatch.c getcwd.c getprogname.c \ - getspwuid.c gettime.c glob.c goodpath.c gram.c gram.y interfaces.c \ - isblank.c lbuf.c ldap.c list.c logging.c match.c mkstemp.c memrchr.c \ - parse.c pwutil.c set_perms.c sigaction.c snprintf.c strcasecmp.c \ - strerror.c strlcat.c strlcpy.c sudo.c sudo_noexec.c sudo_edit.c \ - sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l tsgetgrpw.c \ - utimes.c visudo.c zero_bytes.c redblack.c selinux.c sesh.c $(AUTH_SRCS) +SRCS = aix.c alias.c alloc.c bsm_audit.c check.c closefrom.c def_data.c \ + defaults.c env.c error.c fileops.c find_path.c fnmatch.c getcwd.c \ + getprogname.c getspwuid.c gettime.c glob.c goodpath.c gram.c gram.y \ + interfaces.c isblank.c lbuf.c ldap.c list.c logging.c match.c mkstemp.c \ + memrchr.c parse.c pwutil.c set_perms.c sigaction.c snprintf.c \ + strcasecmp.c strerror.c strlcat.c strlcpy.c sudo.c sudo_noexec.c \ + sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l \ + tsgetgrpw.c utimes.c visudo.c zero_bytes.c redblack.c selinux.c sesh.c \ + $(AUTH_SRCS) AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \ auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \ @@ -226,6 +227,8 @@ alias.o: $(srcdir)/alias.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdi $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alias.c alloc.o: $(srcdir)/alloc.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/alloc.c +bsm_audit.o: $(srcdir)/bsm_audit.c $(SUDODEP) bsm_audit.h + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/bsm_audit.c check.o: $(srcdir)/check.c $(SUDODEP) $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/check.c closefrom.o: $(srcdir)/closefrom.c config.h diff --git a/auth/sudo_auth.c b/auth/sudo_auth.c index 834924cc1..a7fefb234 100644 --- a/auth/sudo_auth.c +++ b/auth/sudo_auth.c @@ -100,6 +100,9 @@ verify_user(pw, prompt) char *p; sudo_auth *auth; sigaction_t sa, osa; +#ifdef HAVE_BSM_AUDIT + extern char **NewArgv; +#endif /* Enable suspend during password entry. */ sigemptyset(&sa.sa_mask); @@ -108,11 +111,15 @@ verify_user(pw, prompt) (void) sigaction(SIGTSTP, &sa, &osa); /* Make sure we have at least one auth method. */ - if (auth_switch[0].name == NULL) + if (auth_switch[0].name == NULL) { +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "no authentication methods"); +#endif log_error(0, "%s %s %s", "There are no authentication methods compiled into sudo!", "If you want to turn off authentication, use the", "--disable-authentication configure option."); + } /* Set FLAG_ONEANDONLY if there is only one auth method. */ if (auth_switch[1].name == NULL) @@ -127,8 +134,12 @@ verify_user(pw, prompt) status = (auth->init)(pw, &prompt, auth); if (status == AUTH_FAILURE) CLR(auth->flags, FLAG_CONFIGURED); - else if (status == AUTH_FATAL) /* XXX log */ + else if (status == AUTH_FATAL) { /* XXX log */ +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "authentication failure"); +#endif exit(1); /* assume error msg already printed */ + } if (NEEDS_USER(auth)) set_perms(PERM_ROOT); @@ -145,8 +156,12 @@ verify_user(pw, prompt) status = (auth->setup)(pw, &prompt, auth); if (status == AUTH_FAILURE) CLR(auth->flags, FLAG_CONFIGURED); - else if (status == AUTH_FATAL) /* XXX log */ + else if (status == AUTH_FATAL) {/* XXX log */ +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "authentication failure"); +#endif exit(1); /* assume error msg already printed */ + } if (NEEDS_USER(auth)) set_perms(PERM_ROOT); @@ -193,8 +208,12 @@ cleanup: set_perms(PERM_USER); status = (auth->cleanup)(pw, auth); - if (status == AUTH_FATAL) /* XXX log */ + if (status == AUTH_FATAL) { /* XXX log */ +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "authentication failure"); +#endif exit(1); /* assume error msg already printed */ + } if (NEEDS_USER(auth)) set_perms(PERM_ROOT); @@ -212,12 +231,18 @@ cleanup: flags = 0; else flags = NO_MAIL; +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "authentication failure"); +#endif log_error(flags, "%d incorrect password attempt%s", def_passwd_tries - counter, (def_passwd_tries - counter == 1) ? "" : "s"); } /* FALLTHROUGH */ case AUTH_FATAL: +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "authentication failure"); +#endif exit(1); } /* NOTREACHED */ diff --git a/bsm_audit.c b/bsm_audit.c new file mode 100644 index 000000000..6075e9dc1 --- /dev/null +++ b/bsm_audit.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2009 Christian S.J. Peron + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static int +audit_sudo_selected(int sf) +{ + auditinfo_addr_t ainfo_addr; + struct au_mask *mask; + auditinfo_t ainfo; + int rc, sorf; + + if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) < 0) { + if (errno == ENOSYS) { + if (getaudit(&ainfo) < 0) + log_error(0, "getaudit: failed"); + mask = &ainfo.ai_mask; + } else + log_error(0, "getaudit: failed"); + } else + mask = &ainfo_addr.ai_mask; + sorf = (sf == 0) ? AU_PRS_SUCCESS : AU_PRS_FAILURE; + rc = au_preselect(AUE_sudo, mask, sorf, AU_PRS_REREAD); + return (rc); +} + +void +audit_success(char **exec_args) +{ + auditinfo_addr_t ainfo_addr; + auditinfo_t ainfo; + token_t *tok; + au_id_t auid; + long au_cond; + int aufd; + pid_t pid; + + pid = getpid(); + /* + * If we are not auditing, don't cut an audit record; just return. + */ + if (auditon(A_GETCOND, (caddr_t)&au_cond, sizeof(long)) < 0) { + if (errno == ENOSYS) + return; + log_error(0, "Could not determine audit condition"); + } + if (au_cond == AUC_NOAUDIT) + return; + /* + * Check to see if the preselection masks are interested in seeing + * this event. + */ + if (!audit_sudo_selected(0)) + return; + if (getauid(&auid) < 0) + log_error(0, "getauid failed"); + if ((aufd = au_open()) == -1) + log_error(0, "au_open: failed"); + if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { + tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(), + getuid(), pid, pid, &ainfo_addr.ai_termid); + } else if (errno == ENOSYS) { + /* + * NB: We should probably watch out for ERANGE here. + */ + if (getaudit(&ainfo) < 0) + log_error(0, "getaudit: failed"); + tok = au_to_subject(auid, geteuid(), getegid(), getuid(), + getuid(), pid, pid, &ainfo.ai_termid); + } else + log_error(0, "getaudit: failed"); + if (tok == NULL) + log_error(0, "au_to_subject: failed"); + au_write(aufd, tok); + tok = au_to_exec_args(exec_args); + if (tok == NULL) + log_error(0, "au_to_exec_args: failed"); + au_write(aufd, tok); + tok = au_to_return32(0, 0); + if (tok == NULL) + log_error(0, "au_to_return32: failed"); + au_write(aufd, tok); + if (au_close(aufd, 1, AUE_sudo) == -1) + log_error(0, "unable to commit audit record"); +} + +void +audit_failure(char **exec_args, char const *const fmt, ...) +{ + auditinfo_addr_t ainfo_addr; + auditinfo_t ainfo; + char text[256]; + token_t *tok; + long au_cond; + au_id_t auid; + va_list ap; + pid_t pid; + int aufd; + + pid = getpid(); + /* + * If we are not auditing, don't cut an audit record; just return. + */ + if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) { + if (errno == ENOSYS) + return; + log_error(0, "Could not determine audit condition"); + } + if (au_cond == AUC_NOAUDIT) + return; + if (!audit_sudo_selected(1)) + return; + if (getauid(&auid) < 0) + log_error(0, "getauid: failed"); + if ((aufd = au_open()) == -1) + log_error(0, "au_open: failed"); + if (getaudit_addr(&ainfo_addr, sizeof(ainfo_addr)) == 0) { + tok = au_to_subject_ex(auid, geteuid(), getegid(), getuid(), + getuid(), pid, pid, &ainfo_addr.ai_termid); + } else if (errno == ENOSYS) { + if (getaudit(&ainfo) < 0) + log_error(0, "getaudit: failed"); + tok = au_to_subject(auid, geteuid(), getegid(), getuid(), + getuid(), pid, pid, &ainfo.ai_termid); + } else + log_error(0, "getaudit: failed"); + if (tok == NULL) + log_error(0, "au_to_subject: failed"); + au_write(aufd, tok); + tok = au_to_exec_args(exec_args); + if (tok == NULL) + log_error(0, "au_to_exec_args: failed"); + au_write(aufd, tok); + va_start(ap, fmt); + (void) vsnprintf(text, sizeof(text), fmt, ap); + va_end(ap); + tok = au_to_text(text); + if (tok == NULL) + log_error(0, "au_to_text: failed"); + au_write(aufd, tok); + tok = au_to_return32(EPERM, 1); + if (tok == NULL) + log_error(0, "au_to_return32: failed"); + au_write(aufd, tok); + if (au_close(aufd, 1, AUE_sudo) == -1) + log_error(0, "unable to commit audit record"); +} diff --git a/bsm_audit.h b/bsm_audit.h new file mode 100644 index 000000000..a23234b9b --- /dev/null +++ b/bsm_audit.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2009 Christian S.J. Peron + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SUDO_BSM_AUDIT_H +#define _SUDO_BSM_AUDIT_H + +void audit_success(char **); +void audit_failure(char **, char const *const, ...); + +#endif /* _SUDO_BSM_AUDIT_H */ diff --git a/configure b/configure index 0bf4e23cf..d4cab1a0d 100755 --- a/configure +++ b/configure @@ -799,6 +799,7 @@ LIBS build_alias host_alias target_alias +HAVE_BSM_AUDIT LIBTOOL CFLAGS PROGS @@ -1517,6 +1518,7 @@ Optional Packages: --with-CC C compiler to use --with-rpath pass -R flag in addition to -L for lib paths --with-blibpath=PATH pass -blibpath flag to ld for additional lib paths + --with-bsm-audit enable BSM audit support --with-incpath additional places to look for include files --with-libpath additional places to look for libraries --with-libraries additional libraries to link with @@ -2103,6 +2105,7 @@ echo "$as_me: Configuring Sudo version 1.7" >&6;} + timeout=5 @@ -2235,6 +2238,26 @@ fi +# Check whether --with-bsm-audit was given. +if test "${with_bsm_audit+set}" = set; then + withval=$with_bsm_audit; case $with_bsm_audit in + yes) cat >>confdefs.h <<\_ACEOF +#define HAVE_BSM_AUDIT 1 +_ACEOF + + SUDO_LIBS="${SUDO_LIBS} -lbsm" + SUDO_OBJS="${SUDO_OBJS} bsm_audit.o" + ;; + no) ;; + *) { { echo "$as_me:$LINENO: error: \"--with-bsm-audit does not take an argument.\"" >&5 +echo "$as_me: error: \"--with-bsm-audit does not take an argument.\"" >&2;} + { (exit 1); exit 1; }; } + ;; +esac +fi + + + # Check whether --with-incpath was given. if test "${with_incpath+set}" = set; then withval=$with_incpath; case $with_incpath in @@ -6209,7 +6232,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 6212 "configure"' > conftest.$ac_ext + echo '#line 6235 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -8068,11 +8091,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8071: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8094: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8075: \$? = $ac_status" >&5 + echo "$as_me:8098: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8358,11 +8381,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8361: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8384: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8365: \$? = $ac_status" >&5 + echo "$as_me:8388: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -8462,11 +8485,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8465: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8488: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8469: \$? = $ac_status" >&5 + echo "$as_me:8492: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10822,7 +10845,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <conf$$subs.sed <<_ACEOF +insults!$insults$ac_delim root_sudo!$root_sudo$ac_delim path_info!$path_info$ac_delim ldap_conf!$ldap_conf$ac_delim @@ -24297,7 +24321,7 @@ KRB5CONFIG!$KRB5CONFIG$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 41; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 42; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 @@ -24918,6 +24942,8 @@ fi + + diff --git a/configure.in b/configure.in index 36c6305f9..1e00c5c48 100644 --- a/configure.in +++ b/configure.in @@ -13,6 +13,7 @@ AC_MSG_NOTICE([Configuring Sudo version 1.7]) dnl dnl Variables that get substituted in the Makefile and man pages dnl +AC_SUBST(HAVE_BSM_AUDIT) AC_SUBST(LIBTOOL) AC_SUBST(CFLAGS) AC_SUBST(PROGS) @@ -201,6 +202,20 @@ AC_ARG_WITH(blibpath, [ --with-blibpath[=PATH] pass -blibpath flag to ld for ;; esac]) +dnl +dnl Handle BSM auditing support. +dnl +AC_ARG_WITH(bsm-audit, [ --with-bsm-audit enable BSM audit support], +[case $with_bsm_audit in + yes) AC_DEFINE(HAVE_BSM_AUDIT) + SUDO_LIBS="${SUDO_LIBS} -lbsm" + SUDO_OBJS="${SUDO_OBJS} bsm_audit.o" + ;; + no) ;; + *) AC_MSG_ERROR(["--with-bsm-audit does not take an argument."]) + ;; +esac]) + AC_ARG_WITH(incpath, [ --with-incpath additional places to look for include files], [case $with_incpath in yes) AC_MSG_ERROR(["must give --with-incpath an argument."]) @@ -2539,6 +2554,7 @@ AH_TEMPLATE(HAL_INSULTS, [Define to 1 if you want 2001-like insults.]) AH_TEMPLATE(HAVE_AFS, [Define to 1 if you use AFS.]) AH_TEMPLATE(HAVE_AIXAUTH, [Define to 1 if you use AIX general authentication.]) AH_TEMPLATE(HAVE_BSD_AUTH_H, [Define to 1 if you use BSD authentication.]) +AH_TEMPLATE(HAVE_BSM_AUDIT, [Define to 1 to enable BSM auditing.]) AH_TEMPLATE(HAVE_DCE, [Define to 1 if you use OSF DCE.]) AH_TEMPLATE(HAVE_DD_FD, [Define to 1 if your `DIR' contains dd_fd.]) AH_TEMPLATE(HAVE_DIRFD, [Define to 1 if you have the `dirfd' function or macro.]) diff --git a/sudo.c b/sudo.c index 2ff8927fa..423382110 100644 --- a/sudo.c +++ b/sudo.c @@ -101,6 +101,10 @@ #include "interfaces.h" #include "version.h" +#ifdef HAVE_BSM_AUDIT +# include "bsm_audit.h" +#endif + #ifndef lint __unused static const char rcsid[] = "$Sudo$"; #endif /* lint */ @@ -382,9 +386,12 @@ main(argc, argv, envp) /* Bail if a tty is required and we don't have one. */ if (def_requiretty) { - if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) + if ((fd = open(_PATH_TTY, O_RDWR|O_NOCTTY)) == -1) { +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "no tty"); +#endif log_error(NO_MAIL, "sorry, you must have a tty to run sudo"); - else + } else (void) close(fd); } @@ -419,10 +426,17 @@ main(argc, argv, envp) if (ISSET(validated, VALIDATE_OK)) { /* Finally tell the user if the command did not exist. */ - if (cmnd_status == NOT_FOUND_DOT) + if (cmnd_status == NOT_FOUND_DOT) { +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "command in current directory"); +#endif errorx(1, "ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.", user_cmnd, user_cmnd, user_cmnd); - else if (cmnd_status == NOT_FOUND) + } else if (cmnd_status == NOT_FOUND) { +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "%s: command not found", user_cmnd); +#endif errorx(1, "%s: command not found", user_cmnd); + } /* If user specified env vars make sure sudoers allows it. */ if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) { @@ -509,13 +523,20 @@ main(argc, argv, envp) closefrom(def_closefrom + 1); #ifndef PROFILING - if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) + if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0) { +#ifdef HAVE_BSM_AUDIT + syslog(LOG_AUTH|LOG_ERR, "fork"); + audit_success(NewArgv); +#endif exit(0); - else { + } else { #ifdef HAVE_SELINUX if (is_selinux_enabled() > 0 && user_role != NULL) selinux_exec(user_role, user_type, NewArgv, ISSET(sudo_mode, MODE_LOGIN_SHELL)); +#endif +#ifdef HAVE_BSM_AUDIT + audit_success(NewArgv); #endif execv(safe_cmnd, NewArgv); } @@ -533,6 +554,9 @@ main(argc, argv, envp) } warning("unable to execute %s", safe_cmnd); exit(127); } else if (ISSET(validated, FLAG_NO_USER | FLAG_NO_HOST)) { +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "No user or host"); +#endif log_denial(validated, 1); exit(1); } else { @@ -554,6 +578,9 @@ main(argc, argv, envp) /* Just tell the user they are not allowed to run foo. */ log_denial(validated, 1); } +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "validation failure"); +#endif exit(1); } exit(0); /* not reached */ @@ -1315,8 +1342,12 @@ set_runaspw(user) if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); } else { - if ((runas_pw = sudo_getpwnam(user)) == NULL) + if ((runas_pw = sudo_getpwnam(user)) == NULL) { +#ifdef HAVE_BSM_AUDIT + audit_failure(NewArgv, "unknown user: %s", user); +#endif log_error(NO_MAIL|MSG_ONLY, "unknown user: %s", user); + } } }