This patch will upgrade Sudo version 1.9.4 to Sudo version 1.9.4 patchlevel 1. To apply: $ cd sudo-1.9.4 $ patch -p1 < sudo-1.9.4p1.patch diff -urNa sudo-1.9.4/ChangeLog sudo-1.9.4p1/ChangeLog --- sudo-1.9.4/ChangeLog Mon Nov 30 06:44:59 2020 +++ sudo-1.9.4p1/ChangeLog Wed Dec 16 18:37:31 2020 @@ -1,8 +1,136 @@ +2020-12-16 Todd C. Miller + + * .hgtags: + Added tag SUDO_1_9_4p1 for changeset 8f65fd9f0f57 + [e27e424f9f56] [tip] <1.9> + + * merge sudo 1.9.4p1 from tip + [8f65fd9f0f57] [SUDO_1_9_4p1] <1.9> + + * plugins/sudoers/policy.c: + The lower bounds for the "closefrom" option is 3, not 4. This is a + regression introduced in sudo 1.8.9 with the strtonum() conversion. + Bug #950. + [fb06603b9a12] + +2020-12-15 Todd C. Miller + + * NEWS, configure, configure.ac: + Sudo 1.9.4p1 + [59c37ec1a128] + +2020-12-11 Todd C. Miller + + * doc/sudoers.man.in, doc/sudoers.mdoc.in: + Direct execution of a command is incompatible with using a log + server. + [91afbbde217a] + + * plugins/sudoers/audit.c: + Set sudoers_audit.close to NULL if not using a log server. + [231abb92a3b2] + +2020-12-07 Todd C. Miller + + * config.h.in, configure, configure.ac, src/sudo.c: + Define _DARWIN_UNLIMITED_GETGROUPS on macOS to suport > 16 groups. + On macOS 10.6 and above, getgroups(2) can return more than + NGROUPS_MAX if _DARWIN_UNLIMITED_GETGROUPS or _DARWIN_C_SOURCE is + defined. Bug #946 + [2e7d3c3cf18b] + +2020-12-05 Todd C. Miller + + * doc/sudo.conf.man.in, doc/sudo.conf.mdoc.in, examples/sudo.conf.in: + Comment out the default plugin lines in the example sudo.conf. Fixes + a problem when there are multiple versions of sudo installed and not + all suport the audit plugin, such as on macOS. GitHub issue #75 + [aaed5d7a3471] + + * plugins/sudoers/logging.c, plugins/sudoers/policy.c, + plugins/sudoers/sudoers.c, plugins/sudoers/sudoers.h: + Store the user-provided runas user and group name in struct + sudo_user. This makes it available for event logging in case the + name doesn't resolve. + [98d70ba8a2a6] + + * plugins/sudoers/logging.c: + Log submit group to event log. + [3e7ace99f7f8] + + * plugins/sudoers/logging.c, plugins/sudoers/sudoers.c, + plugins/sudoers/sudoers.h: + Store iolog_path in struct sudo_user for use in the event log. + [35bc39ec8ad5] + +2020-12-04 Todd C. Miller + + * plugins/sudoers/logging.c, plugins/sudoers/sudoers.c: + Defer lookup of runas user until sudoers_main() for better logging. + The log message now includes user info and the command attempted. + [f738f5ac5350] + + * lib/eventlog/eventlog.c: + Don't assume that just because command is non-NULL, argv is non- + NULL. + [4fac4ae88e4e] + + * plugins/sudoers/logging.c: + Fix a crash introduced in 1.9.4 when running command as an unknown + user. Bug #948 + [8b24c140ec7c] + +2020-12-03 Todd C. Miller + + * logsrvd/logsrvd.c: + When shutting down the server, close non-I/O log connections + immediately. Avoids a timeout during server shutdown while the + server waits for active connections to close. + [26bfda2c8f67] + + * src/sudo.c: + Audit errors from policy_init_session(), audit_accept(), and + audit_reject(). + [638e583754ac] + + * src/sudo.c: + Do not run the command if the audit accept function fails. Also add + warnings if the audit reject or error functions fail. + [ca94ef438961] + + * plugins/sudoers/log_client.c: + Reduce the number of error messages when we can't connect to the + audit server. Add the error string to "unable to connect to log + server" instead of using an extra error message for the connect(2) + failure. + [25ac7ac5bfdf] + + * plugins/sudoers/log_client.c: + Use correct error message when the TLS connection is dropped. Was: + "recv: Unknown error 0", now: "lost connection to log server". + [5c3f319b1f75] + +2020-12-02 Todd C. Miller + + * plugins/sudoers/alias.c, plugins/sudoers/gram.c, + plugins/sudoers/gram.h, plugins/sudoers/gram.y, + plugins/sudoers/parse.h: + Change alias_add() to return bool and set errno on failure. This + fixes a localization problem where the error message could have been + reported in the wrong locale. + [1859fe3da40c] + +2020-11-30 Todd C. Miller + + * lib/eventlog/eventlog.c: + Fix build when configured using --without-sendmail Bug #947 + [41db1aad85bb] + 2020-11-29 Todd C. Miller * .hgtags: Added tag SUDO_1_9_4 for changeset 74705fb3b956 - [45a5e742496e] [tip] <1.9> + [45a5e742496e] <1.9> * merge sudo 1.9.4 from tip [74705fb3b956] [SUDO_1_9_4] <1.9> diff -urNa sudo-1.9.4/NEWS sudo-1.9.4p1/NEWS --- sudo-1.9.4/NEWS Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/NEWS Wed Dec 16 18:34:30 2020 @@ -1,3 +1,35 @@ +What's new in Sudo 1.9.4p1 + + * Sudo on macOS now supports users with more than 16 groups without + needing to set "group_source" to "dynamic" in /etc/sudo.conf. + Previously, only the first 15 were used when matching group-based + rules in sudoers. Bug #946. + + * Fixed a regression introduced in version 1.9.4 where sudo would + not build when configured using the --without-sendmail option. + Bug #947. + + * Fixed a problem where if I/O logging was disabled and sudo was + unable to connect to sudo_logsrvd, the command would still be + allowed to run even when the "ignore_logfile_errors" sudoers + option was enabled. + + * Fixed a crash introduced in version 1.9.4 when attempting to run + a command as a non-existent user. Bug #948. + + * The installed sudo.conf file now has the default sudoers Plugin + lines commented out. This fixes a potential conflict when there + is both a system-installed version of sudo and a user-installed + version. GitHub issue #75. + + * Fixed a regression introduced in sudo 1.9.4 where sudo would run + the command as a child process even when a pseudo-terminal was + not in use and the "pam_session" and "pam_setcred" options were + disabled. GitHub issue #76. + + * Fixed a regression introduced in sudo 1.8.9 where the "closefrom" + sudoers option could not be set to a value of 3. Bug #950. + What's new in Sudo 1.9.4 * The sudoers parser will now detect when an upper-case reserved @@ -18,7 +50,7 @@ the sudoers plugin. * JSON log entries sent to syslog now use "minimal" JSON which - skips all non-essention whitespace. + skips all non-essential white space. * The sudoers plugin can now produce JSON-formatted logs. The "log_format" sudoers option can be used to select sudo or json diff -urNa sudo-1.9.4/config.h.in sudo-1.9.4p1/config.h.in --- sudo-1.9.4/config.h.in Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/config.h.in Wed Dec 16 18:34:30 2020 @@ -1371,6 +1371,11 @@ # undef _LINUX_SOURCE_COMPAT #endif +/* Enable unlimited getgroups(2) support on macOS. */ +#ifndef _DARWIN_UNLIMITED_GETGROUPS +# undef _DARWIN_UNLIMITED_GETGROUPS +#endif + /* Enable prototypes in GCC fixed includes on older systems. */ #ifndef __USE_FIXED_PROTOTYPES__ # undef __USE_FIXED_PROTOTYPES__ diff -urNa sudo-1.9.4/configure sudo-1.9.4p1/configure --- sudo-1.9.4/configure Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/configure Wed Dec 16 18:34:30 2020 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sudo 1.9.4. +# Generated by GNU Autoconf 2.69 for sudo 1.9.4p1. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='sudo' PACKAGE_TARNAME='sudo' -PACKAGE_VERSION='1.9.4' -PACKAGE_STRING='sudo 1.9.4' +PACKAGE_VERSION='1.9.4p1' +PACKAGE_STRING='sudo 1.9.4p1' PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/' PACKAGE_URL='' @@ -1584,7 +1584,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sudo 1.9.4 to adapt to many kinds of systems. +\`configure' configures sudo 1.9.4p1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1650,7 +1650,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sudo 1.9.4:";; + short | recursive ) echo "Configuration of sudo 1.9.4p1:";; esac cat <<\_ACEOF @@ -1924,7 +1924,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sudo configure 1.9.4 +sudo configure 1.9.4p1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2633,7 +2633,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sudo $as_me 1.9.4, which was +It was created by sudo $as_me 1.9.4p1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -16183,6 +16183,10 @@ done + # macOS >= 10.6 getgroups(2) can support more than > 16 groups + $as_echo "#define _DARWIN_UNLIMITED_GETGROUPS 1" >>confdefs.h + + # We need to force a flat namespace to make libc # symbol hooking work like it does on ELF. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -Wl,-force_flat_namespace" >&5 @@ -28751,7 +28755,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sudo $as_me 1.9.4, which was +This file was extended by sudo $as_me 1.9.4p1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -28817,7 +28821,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sudo config.status 1.9.4 +sudo config.status 1.9.4p1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urNa sudo-1.9.4/configure.ac sudo-1.9.4p1/configure.ac --- sudo-1.9.4/configure.ac Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/configure.ac Wed Dec 16 18:34:30 2020 @@ -18,7 +18,7 @@ dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. dnl AC_PREREQ([2.59]) -AC_INIT([sudo], [1.9.4], [https://bugzilla.sudo.ws/], [sudo]) +AC_INIT([sudo], [1.9.4p1], [https://bugzilla.sudo.ws/], [sudo]) AC_CONFIG_HEADERS([config.h pathnames.h]) AC_CONFIG_SRCDIR([src/sudo.c]) dnl @@ -2292,6 +2292,9 @@ # Undocumented API that dynamically allocates the groups. AC_CHECK_FUNCS([getgrouplist_2], [AC_CHECK_DECLS([getgrouplist_2])]) + # macOS >= 10.6 getgroups(2) can support more than > 16 groups + AC_DEFINE([_DARWIN_UNLIMITED_GETGROUPS]) + # We need to force a flat namespace to make libc # symbol hooking work like it does on ELF. AX_CHECK_LINK_FLAG([-Wl,-force_flat_namespace], [AX_APPEND_FLAG([-Wl,-force_flat_namespace], [SUDO_LDFLAGS])]) @@ -5017,6 +5020,11 @@ /* Enable Linux-compatible extensions on AIX. */ #ifndef _LINUX_SOURCE_COMPAT # undef _LINUX_SOURCE_COMPAT +#endif + +/* Enable unlimited getgroups(2) support on macOS. */ +#ifndef _DARWIN_UNLIMITED_GETGROUPS +# undef _DARWIN_UNLIMITED_GETGROUPS #endif /* Enable prototypes in GCC fixed includes on older systems. */ diff -urNa sudo-1.9.4/doc/sudo.conf.man.in sudo-1.9.4p1/doc/sudo.conf.man.in --- sudo-1.9.4/doc/sudo.conf.man.in Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/doc/sudo.conf.man.in Wed Dec 16 18:34:30 2020 @@ -17,7 +17,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .nr SL @SEMAN@ -.TH "SUDO.CONF" "@mansectform@" "October 30, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.TH "SUDO.CONF" "@mansectform@" "December 5, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .nh .if n .ad l .SH "NAME" @@ -708,9 +708,9 @@ # The plugin_options are optional. # # The sudoers plugin is used by default if no Plugin lines are present. -Plugin sudoers_policy sudoers.so -Plugin sudoers_io sudoers.so -Plugin sudoers_audit sudoers.so +#Plugin sudoers_policy sudoers.so +#Plugin sudoers_io sudoers.so +#Plugin sudoers_audit sudoers.so # # Sudo askpass: diff -urNa sudo-1.9.4/doc/sudo.conf.mdoc.in sudo-1.9.4p1/doc/sudo.conf.mdoc.in --- sudo-1.9.4/doc/sudo.conf.mdoc.in Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/doc/sudo.conf.mdoc.in Wed Dec 16 18:34:30 2020 @@ -16,7 +16,7 @@ .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" .nr SL @SEMAN@ -.Dd October 30, 2020 +.Dd December 5, 2020 .Dt SUDO.CONF @mansectform@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -642,9 +642,9 @@ # The plugin_options are optional. # # The sudoers plugin is used by default if no Plugin lines are present. -Plugin sudoers_policy sudoers.so -Plugin sudoers_io sudoers.so -Plugin sudoers_audit sudoers.so +#Plugin sudoers_policy sudoers.so +#Plugin sudoers_io sudoers.so +#Plugin sudoers_audit sudoers.so # # Sudo askpass: diff -urNa sudo-1.9.4/doc/sudoers.man.in sudo-1.9.4p1/doc/sudoers.man.in --- sudo-1.9.4/doc/sudoers.man.in Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/doc/sudoers.man.in Wed Dec 16 18:34:30 2020 @@ -25,7 +25,7 @@ .nr BA @BAMAN@ .nr LC @LCMAN@ .nr PS @PSMAN@ -.TH "SUDOERS" "@mansectform@" "October 30, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" +.TH "SUDOERS" "@mansectform@" "December 11, 2020" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .nh .if n .ad l .SH "NAME" @@ -3049,7 +3049,9 @@ \fIpam_setcred\fR, and \fIuse_pty\fR -are disabled and I/O logging has not been configured, +are disabled, +\fIlog_servers\fR +has not been set and I/O logging has not been configured, \fBsudo\fR will execute the command directly instead of running it as a child process. @@ -3070,7 +3072,9 @@ \fIpam_setcred\fR, and \fIuse_pty\fR -are disabled and I/O logging has not been configured, +are disabled, +\fIlog_servers\fR +has not been set and I/O logging has not been configured, \fBsudo\fR will execute the command directly instead of running it as a child process. diff -urNa sudo-1.9.4/doc/sudoers.mdoc.in sudo-1.9.4p1/doc/sudoers.mdoc.in --- sudo-1.9.4/doc/sudoers.mdoc.in Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/doc/sudoers.mdoc.in Wed Dec 16 18:34:30 2020 @@ -24,7 +24,7 @@ .nr BA @BAMAN@ .nr LC @LCMAN@ .nr PS @PSMAN@ -.Dd October 30, 2020 +.Dd December 11, 2020 .Dt SUDOERS @mansectform@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -2874,7 +2874,9 @@ .Em pam_setcred , and .Em use_pty -are disabled and I/O logging has not been configured, +are disabled, +.Em log_servers +has not been set and I/O logging has not been configured, .Nm sudo will execute the command directly instead of running it as a child process. @@ -2894,7 +2896,9 @@ .Em pam_setcred , and .Em use_pty -are disabled and I/O logging has not been configured, +are disabled, +.Em log_servers +has not been set and I/O logging has not been configured, .Nm sudo will execute the command directly instead of running it as a child process. diff -urNa sudo-1.9.4/examples/sudo.conf.in sudo-1.9.4p1/examples/sudo.conf.in --- sudo-1.9.4/examples/sudo.conf.in Sun Nov 29 15:12:48 2020 +++ sudo-1.9.4p1/examples/sudo.conf.in Wed Dec 16 18:34:30 2020 @@ -11,9 +11,9 @@ # The plugin_options are optional. # # The sudoers plugin is used by default if no Plugin lines are present. -Plugin sudoers_policy sudoers.so -Plugin sudoers_io sudoers.so -Plugin sudoers_audit sudoers.so +#Plugin sudoers_policy sudoers.so +#Plugin sudoers_io sudoers.so +#Plugin sudoers_audit sudoers.so # # Sudo askpass: diff -urNa sudo-1.9.4/lib/eventlog/eventlog.c sudo-1.9.4p1/lib/eventlog/eventlog.c --- sudo-1.9.4/lib/eventlog/eventlog.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/lib/eventlog/eventlog.c Wed Dec 16 18:34:30 2020 @@ -78,7 +78,7 @@ static FILE *eventlog_stub_open_log(int type, const char *logfile); static void eventlog_stub_close_log(int type, FILE *fp); -/* Eventlog config settings */ +/* Eventlog config settings (default values). */ static struct eventlog_config evl_conf = { EVLOG_NONE, /* type */ EVLOG_SUDO, /* format */ @@ -91,7 +91,11 @@ false, /* omit_hostname */ _PATH_SUDO_LOGFILE, /* logpath */ "%h %e %T", /* time_fmt */ +#ifdef _PATH_SUDO_SENDMAIL _PATH_SUDO_SENDMAIL, /* mailerpath */ +#else + NULL, /* mailerpath (disabled) */ +#endif "-t", /* mailerflags */ NULL, /* mailfrom */ MAILTO, /* mailto */ @@ -191,8 +195,10 @@ } if (evlog->command != NULL) { len += sizeof(LL_CMND_STR) - 1 + strlen(evlog->command); - for (i = 1; evlog->argv[i] != NULL; i++) - len += strlen(evlog->argv[i]) + 1; + if (evlog->argv != NULL) { + for (i = 1; evlog->argv[i] != NULL; i++) + len += strlen(evlog->argv[i]) + 1; + } } /* @@ -267,10 +273,12 @@ goto toobig; if (strlcat(line, evlog->command, len) >= len) goto toobig; - for (i = 1; evlog->argv[i] != NULL; i++) { - if (strlcat(line, " ", len) >= len || - strlcat(line, evlog->argv[i], len) >= len) - goto toobig; + if (evlog->argv != NULL) { + for (i = 1; evlog->argv[i] != NULL; i++) { + if (strlcat(line, " ", len) >= len || + strlcat(line, evlog->argv[i], len) >= len) + goto toobig; + } } } @@ -1436,8 +1444,10 @@ evl_conf.logpath = _PATH_SUDO_LOGFILE; if (evl_conf.time_fmt == NULL) evl_conf.time_fmt = "%h %e %T"; +#ifdef _PATH_SUDO_SENDMAIL if (evl_conf.mailerpath == NULL) evl_conf.mailerpath = _PATH_SUDO_SENDMAIL; +#endif if (evl_conf.mailerflags == NULL) evl_conf.mailerflags = "-t"; if (evl_conf.mailto == NULL) diff -urNa sudo-1.9.4/logsrvd/logsrvd.c sudo-1.9.4p1/logsrvd/logsrvd.c --- sudo-1.9.4/logsrvd/logsrvd.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/logsrvd/logsrvd.c Wed Dec 16 18:34:30 2020 @@ -745,15 +745,19 @@ debug_return; } - /* Schedule final commit point for each active connection. */ TAILQ_FOREACH(closure, &connections, entries) { closure->state = SHUTDOWN; sudo_ev_del(base, closure->read_ev); if (closure->log_io) { + /* Schedule final commit point for the connection. */ if (sudo_ev_add(base, closure->commit_ev, &tv, false) == -1) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "unable to add commit point event"); } + } else { + /* No commit point, close connection immediately. */ + sudo_ev_del(closure->evbase, closure->write_ev); + connection_closure_free(closure); } } diff -urNa sudo-1.9.4/plugins/sudoers/alias.c sudo-1.9.4p1/plugins/sudoers/alias.c --- sudo-1.9.4/plugins/sudoers/alias.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/alias.c Wed Dec 16 18:34:30 2020 @@ -110,30 +110,23 @@ /* * Add an alias to the aliases redblack tree. * Note that "file" must be a reference-counted string. - * Returns NULL on success and an error string on failure. + * Returns true on success and false on failure, setting errno. */ -const char * +bool alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type, char *file, int line, int column, struct member *members) { - static char errbuf[512]; struct alias *a; debug_decl(alias_add, SUDOERS_DEBUG_ALIAS); if (parse_tree->aliases == NULL) { - if ((parse_tree->aliases = alloc_aliases()) == NULL) { - /* XXX - return error code instead */ - strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf)); - debug_return_str(errbuf); - } + if ((parse_tree->aliases = alloc_aliases()) == NULL) + debug_return_bool(false); } a = calloc(1, sizeof(*a)); - if (a == NULL) { - /* XXX - return error code instead */ - strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf)); - debug_return_str(errbuf); - } + if (a == NULL) + debug_return_bool(false); a->name = name; a->type = type; /* a->used = false; */ @@ -143,18 +136,14 @@ HLTQ_TO_TAILQ(&a->members, members, entries); switch (rbinsert(parse_tree->aliases, a, NULL)) { case 1: - /* XXX - return error code instead, this is not translatable. */ - (void)snprintf(errbuf, sizeof(errbuf), - N_("Alias \"%s\" already defined"), name); alias_free(a); - debug_return_str(errbuf); + errno = EEXIST; + debug_return_bool(false); case -1: - /* XXX - return error code instead */ - (void)strlcpy(errbuf, N_("unable to allocate memory"), sizeof(errbuf)); alias_free(a); - debug_return_str(errbuf); + debug_return_bool(false); } - debug_return_str(NULL); + debug_return_bool(true); } /* diff -urNa sudo-1.9.4/plugins/sudoers/audit.c sudo-1.9.4p1/plugins/sudoers/audit.c --- sudo-1.9.4/plugins/sudoers/audit.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/audit.c Wed Dec 16 18:34:30 2020 @@ -182,9 +182,17 @@ info.plugin_args = plugin_options; ret = sudoers_init(&info, submit_envp); - /* The audit functions set audit_msg on failure. */ - if (ret != 1 && audit_msg != NULL) - *errstr = audit_msg; + if (ret == true) { + /* Unset close function if we don't need it to avoid extra process. */ +#ifdef SUDOERS_LOG_CLIENT + if (client_closure == NULL) +#endif + sudoers_audit.close = NULL; + } else { + /* The audit functions set audit_msg on failure. */ + if (audit_msg != NULL) + *errstr = audit_msg; + } debug_return_int(ret); } diff -urNa sudo-1.9.4/plugins/sudoers/gram.c sudo-1.9.4p1/plugins/sudoers/gram.c --- sudo-1.9.4/plugins/sudoers/gram.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/gram.c Wed Dec 16 18:34:30 2020 @@ -4,7 +4,7 @@ */ #include -/* A Bison parser, made by GNU Bison 3.7.3. */ +/* A Bison parser, made by GNU Bison 3.7.4. */ /* Bison implementation for Yacc-like parsers in C @@ -51,11 +51,11 @@ define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ -/* Identify Bison output. */ -#define YYBISON 1 +/* Identify Bison output, and Bison version. */ +#define YYBISON 30704 -/* Bison version. */ -#define YYBISON_VERSION "3.7.3" +/* Bison version string. */ +#define YYBISON_VERSION "3.7.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -157,8 +157,9 @@ static struct member *new_member(char *, int); static struct sudo_command *new_command(char *, char *); static struct command_digest *new_digest(int, char *); +static void alias_error(const char *name, int errnum); -#line 156 "gram.c" +#line 157 "gram.c" # ifndef YY_CAST # ifdef __cplusplus @@ -315,7 +316,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 79 "gram.y" +#line 80 "gram.y" struct cmndspec *cmndspec; struct defaults *defaults; @@ -329,7 +330,7 @@ char *string; int tok; -#line 327 "gram.c" +#line 328 "gram.c" }; typedef union YYSTYPE YYSTYPE; @@ -835,21 +836,21 @@ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 188, 188, 191, 194, 195, 198, 201, 204, 211, - 218, 224, 227, 230, 233, 236, 240, 244, 248, 252, - 258, 261, 267, 270, 276, 277, 283, 290, 297, 304, - 311, 320, 321, 325, 331, 345, 349, 355, 362, 369, - 376, 383, 392, 393, 452, 507, 514, 521, 528, 537, - 538, 544, 547, 568, 572, 578, 590, 602, 607, 611, - 616, 621, 626, 630, 635, 638, 643, 658, 667, 676, - 685, 702, 703, 704, 705, 706, 707, 708, 709, 710, - 711, 714, 720, 723, 727, 731, 739, 747, 758, 764, - 770, 776, 784, 787, 790, 793, 796, 799, 802, 805, - 808, 811, 814, 817, 820, 823, 826, 831, 838, 845, - 861, 862, 865, 865, 877, 880, 881, 887, 888, 891, - 891, 903, 906, 907, 913, 914, 917, 917, 929, 932, - 933, 936, 936, 948, 951, 952, 958, 962, 968, 975, - 982, 989, 996, 1005, 1006, 1012, 1016, 1022, 1029, 1036 + 0, 189, 189, 192, 195, 196, 199, 202, 205, 212, + 219, 225, 228, 231, 234, 237, 241, 245, 249, 253, + 259, 262, 268, 271, 277, 278, 284, 291, 298, 305, + 312, 321, 322, 326, 332, 346, 350, 356, 363, 370, + 377, 384, 393, 394, 453, 508, 515, 522, 529, 538, + 539, 545, 548, 569, 573, 579, 591, 603, 608, 612, + 617, 622, 627, 631, 636, 639, 644, 659, 668, 677, + 686, 703, 704, 705, 706, 707, 708, 709, 710, 711, + 712, 715, 721, 724, 728, 732, 740, 748, 759, 765, + 771, 777, 785, 788, 791, 794, 797, 800, 803, 806, + 809, 812, 815, 818, 821, 824, 827, 832, 839, 846, + 862, 863, 866, 866, 876, 879, 880, 886, 887, 890, + 890, 900, 903, 904, 910, 911, 914, 914, 924, 927, + 928, 931, 931, 941, 944, 945, 951, 955, 961, 968, + 975, 982, 989, 998, 999, 1005, 1009, 1015, 1022, 1029 }; #endif @@ -1618,31 +1619,31 @@ switch (yyn) { case 2: /* file: %empty */ -#line 188 "gram.y" +#line 189 "gram.y" { ; /* empty file */ } -#line 1620 "gram.c" +#line 1621 "gram.c" break; case 6: /* entry: '\n' */ -#line 198 "gram.y" +#line 199 "gram.y" { ; /* blank line */ } -#line 1628 "gram.c" +#line 1629 "gram.c" break; case 7: /* entry: error '\n' */ -#line 201 "gram.y" +#line 202 "gram.y" { yyerrok; } -#line 1636 "gram.c" +#line 1637 "gram.c" break; case 8: /* entry: include */ -#line 204 "gram.y" +#line 205 "gram.y" { if (!push_include((yyvsp[0].string), false)) { free((yyvsp[0].string)); @@ -1650,11 +1651,11 @@ } free((yyvsp[0].string)); } -#line 1648 "gram.c" +#line 1649 "gram.c" break; case 9: /* entry: includedir */ -#line 211 "gram.y" +#line 212 "gram.y" { if (!push_include((yyvsp[0].string), true)) { free((yyvsp[0].string)); @@ -1662,142 +1663,142 @@ } free((yyvsp[0].string)); } -#line 1660 "gram.c" +#line 1661 "gram.c" break; case 10: /* entry: userlist privileges '\n' */ -#line 218 "gram.y" +#line 219 "gram.y" { if (!add_userspec((yyvsp[-2].member), (yyvsp[-1].privilege))) { sudoerserror(N_("unable to allocate memory")); YYERROR; } } -#line 1671 "gram.c" +#line 1672 "gram.c" break; case 11: /* entry: USERALIAS useraliases '\n' */ -#line 224 "gram.y" +#line 225 "gram.y" { ; } -#line 1679 "gram.c" +#line 1680 "gram.c" break; case 12: /* entry: HOSTALIAS hostaliases '\n' */ -#line 227 "gram.y" +#line 228 "gram.y" { ; } -#line 1687 "gram.c" +#line 1688 "gram.c" break; case 13: /* entry: CMNDALIAS cmndaliases '\n' */ -#line 230 "gram.y" +#line 231 "gram.y" { ; } -#line 1695 "gram.c" +#line 1696 "gram.c" break; case 14: /* entry: RUNASALIAS runasaliases '\n' */ -#line 233 "gram.y" +#line 234 "gram.y" { ; } -#line 1703 "gram.c" +#line 1704 "gram.c" break; case 15: /* entry: DEFAULTS defaults_list '\n' */ -#line 236 "gram.y" +#line 237 "gram.y" { if (!add_defaults(DEFAULTS, NULL, (yyvsp[-1].defaults))) YYERROR; } -#line 1712 "gram.c" +#line 1713 "gram.c" break; case 16: /* entry: DEFAULTS_USER userlist defaults_list '\n' */ -#line 240 "gram.y" +#line 241 "gram.y" { if (!add_defaults(DEFAULTS_USER, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1721 "gram.c" +#line 1722 "gram.c" break; case 17: /* entry: DEFAULTS_RUNAS userlist defaults_list '\n' */ -#line 244 "gram.y" +#line 245 "gram.y" { if (!add_defaults(DEFAULTS_RUNAS, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1730 "gram.c" +#line 1731 "gram.c" break; case 18: /* entry: DEFAULTS_HOST hostlist defaults_list '\n' */ -#line 248 "gram.y" +#line 249 "gram.y" { if (!add_defaults(DEFAULTS_HOST, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1739 "gram.c" +#line 1740 "gram.c" break; case 19: /* entry: DEFAULTS_CMND cmndlist defaults_list '\n' */ -#line 252 "gram.y" +#line 253 "gram.y" { if (!add_defaults(DEFAULTS_CMND, (yyvsp[-2].member), (yyvsp[-1].defaults))) YYERROR; } -#line 1748 "gram.c" +#line 1749 "gram.c" break; case 20: /* include: INCLUDE WORD '\n' */ -#line 258 "gram.y" +#line 259 "gram.y" { (yyval.string) = (yyvsp[-1].string); } -#line 1756 "gram.c" +#line 1757 "gram.c" break; case 21: /* include: INCLUDE WORD error '\n' */ -#line 261 "gram.y" +#line 262 "gram.y" { yyerrok; (yyval.string) = (yyvsp[-2].string); } -#line 1765 "gram.c" +#line 1766 "gram.c" break; case 22: /* includedir: INCLUDEDIR WORD '\n' */ -#line 267 "gram.y" +#line 268 "gram.y" { (yyval.string) = (yyvsp[-1].string); } -#line 1773 "gram.c" +#line 1774 "gram.c" break; case 23: /* includedir: INCLUDEDIR WORD error '\n' */ -#line 270 "gram.y" +#line 271 "gram.y" { yyerrok; (yyval.string) = (yyvsp[-2].string); } -#line 1782 "gram.c" +#line 1783 "gram.c" break; case 25: /* defaults_list: defaults_list ',' defaults_entry */ -#line 277 "gram.y" +#line 278 "gram.y" { HLTQ_CONCAT((yyvsp[-2].defaults), (yyvsp[0].defaults), entries); (yyval.defaults) = (yyvsp[-2].defaults); } -#line 1791 "gram.c" +#line 1792 "gram.c" break; case 26: /* defaults_entry: DEFVAR */ -#line 283 "gram.y" +#line 284 "gram.y" { (yyval.defaults) = new_default((yyvsp[0].string), NULL, true); if ((yyval.defaults) == NULL) { @@ -1805,11 +1806,11 @@ YYERROR; } } -#line 1803 "gram.c" +#line 1804 "gram.c" break; case 27: /* defaults_entry: '!' DEFVAR */ -#line 290 "gram.y" +#line 291 "gram.y" { (yyval.defaults) = new_default((yyvsp[0].string), NULL, false); if ((yyval.defaults) == NULL) { @@ -1817,11 +1818,11 @@ YYERROR; } } -#line 1815 "gram.c" +#line 1816 "gram.c" break; case 28: /* defaults_entry: DEFVAR '=' WORD */ -#line 297 "gram.y" +#line 298 "gram.y" { (yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), true); if ((yyval.defaults) == NULL) { @@ -1829,11 +1830,11 @@ YYERROR; } } -#line 1827 "gram.c" +#line 1828 "gram.c" break; case 29: /* defaults_entry: DEFVAR '+' WORD */ -#line 304 "gram.y" +#line 305 "gram.y" { (yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '+'); if ((yyval.defaults) == NULL) { @@ -1841,11 +1842,11 @@ YYERROR; } } -#line 1839 "gram.c" +#line 1840 "gram.c" break; case 30: /* defaults_entry: DEFVAR '-' WORD */ -#line 311 "gram.y" +#line 312 "gram.y" { (yyval.defaults) = new_default((yyvsp[-2].string), (yyvsp[0].string), '-'); if ((yyval.defaults) == NULL) { @@ -1853,29 +1854,29 @@ YYERROR; } } -#line 1851 "gram.c" +#line 1852 "gram.c" break; case 32: /* privileges: privileges ':' privilege */ -#line 321 "gram.y" +#line 322 "gram.y" { HLTQ_CONCAT((yyvsp[-2].privilege), (yyvsp[0].privilege), entries); (yyval.privilege) = (yyvsp[-2].privilege); } -#line 1860 "gram.c" +#line 1861 "gram.c" break; case 33: /* privileges: privileges ':' error */ -#line 325 "gram.y" +#line 326 "gram.y" { yyerrok; (yyval.privilege) = (yyvsp[-2].privilege); } -#line 1869 "gram.c" +#line 1870 "gram.c" break; case 34: /* privilege: hostlist '=' cmndspeclist */ -#line 331 "gram.y" +#line 332 "gram.y" { struct privilege *p = calloc(1, sizeof(*p)); if (p == NULL) { @@ -1888,29 +1889,29 @@ HLTQ_INIT(p, entries); (yyval.privilege) = p; } -#line 1886 "gram.c" +#line 1887 "gram.c" break; case 35: /* ophost: host */ -#line 345 "gram.y" +#line 346 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 1895 "gram.c" +#line 1896 "gram.c" break; case 36: /* ophost: '!' host */ -#line 349 "gram.y" +#line 350 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 1904 "gram.c" +#line 1905 "gram.c" break; case 37: /* host: ALIAS */ -#line 355 "gram.y" +#line 356 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { @@ -1918,11 +1919,11 @@ YYERROR; } } -#line 1916 "gram.c" +#line 1917 "gram.c" break; case 38: /* host: ALL */ -#line 362 "gram.y" +#line 363 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { @@ -1930,11 +1931,11 @@ YYERROR; } } -#line 1928 "gram.c" +#line 1929 "gram.c" break; case 39: /* host: NETGROUP */ -#line 369 "gram.y" +#line 370 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), NETGROUP); if ((yyval.member) == NULL) { @@ -1942,11 +1943,11 @@ YYERROR; } } -#line 1940 "gram.c" +#line 1941 "gram.c" break; case 40: /* host: NTWKADDR */ -#line 376 "gram.y" +#line 377 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), NTWKADDR); if ((yyval.member) == NULL) { @@ -1954,11 +1955,11 @@ YYERROR; } } -#line 1952 "gram.c" +#line 1953 "gram.c" break; case 41: /* host: WORD */ -#line 383 "gram.y" +#line 384 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), WORD); if ((yyval.member) == NULL) { @@ -1966,11 +1967,11 @@ YYERROR; } } -#line 1964 "gram.c" +#line 1965 "gram.c" break; case 43: /* cmndspeclist: cmndspeclist ',' cmndspec */ -#line 393 "gram.y" +#line 394 "gram.y" { struct cmndspec *prev; prev = HLTQ_LAST((yyvsp[-2].cmndspec), cmndspec, entries); @@ -2028,11 +2029,11 @@ } (yyval.cmndspec) = (yyvsp[-2].cmndspec); } -#line 2026 "gram.c" +#line 2027 "gram.c" break; case 44: /* cmndspec: runasspec options cmndtag digcmnd */ -#line 452 "gram.y" +#line 453 "gram.y" { struct cmndspec *cs = calloc(1, sizeof(*cs)); if (cs == NULL) { @@ -2086,11 +2087,11 @@ cs->tags.setenv = IMPLIED; (yyval.cmndspec) = cs; } -#line 2084 "gram.c" +#line 2085 "gram.c" break; case 45: /* digestspec: SHA224_TOK ':' DIGEST */ -#line 507 "gram.y" +#line 508 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA224, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2098,11 +2099,11 @@ YYERROR; } } -#line 2096 "gram.c" +#line 2097 "gram.c" break; case 46: /* digestspec: SHA256_TOK ':' DIGEST */ -#line 514 "gram.y" +#line 515 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA256, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2110,11 +2111,11 @@ YYERROR; } } -#line 2108 "gram.c" +#line 2109 "gram.c" break; case 47: /* digestspec: SHA384_TOK ':' DIGEST */ -#line 521 "gram.y" +#line 522 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA384, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2122,11 +2123,11 @@ YYERROR; } } -#line 2120 "gram.c" +#line 2121 "gram.c" break; case 48: /* digestspec: SHA512_TOK ':' DIGEST */ -#line 528 "gram.y" +#line 529 "gram.y" { (yyval.digest) = new_digest(SUDO_DIGEST_SHA512, (yyvsp[0].string)); if ((yyval.digest) == NULL) { @@ -2134,28 +2135,28 @@ YYERROR; } } -#line 2132 "gram.c" +#line 2133 "gram.c" break; case 50: /* digestlist: digestlist ',' digestspec */ -#line 538 "gram.y" +#line 539 "gram.y" { HLTQ_CONCAT((yyvsp[-2].digest), (yyvsp[0].digest), entries); (yyval.digest) = (yyvsp[-2].digest); } -#line 2141 "gram.c" +#line 2142 "gram.c" break; case 51: /* digcmnd: opcmnd */ -#line 544 "gram.y" +#line 545 "gram.y" { (yyval.member) = (yyvsp[0].member); } -#line 2149 "gram.c" +#line 2150 "gram.c" break; case 52: /* digcmnd: digestlist opcmnd */ -#line 547 "gram.y" +#line 548 "gram.y" { struct sudo_command *c = (struct sudo_command *) (yyvsp[0].member)->name; @@ -2175,29 +2176,29 @@ HLTQ_TO_TAILQ(&c->digests, (yyvsp[-1].digest), entries); (yyval.member) = (yyvsp[0].member); } -#line 2173 "gram.c" +#line 2174 "gram.c" break; case 53: /* opcmnd: cmnd */ -#line 568 "gram.y" +#line 569 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2182 "gram.c" +#line 2183 "gram.c" break; case 54: /* opcmnd: '!' cmnd */ -#line 572 "gram.y" +#line 573 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2191 "gram.c" +#line 2192 "gram.c" break; case 55: /* chdirspec: CWD '=' WORD */ -#line 578 "gram.y" +#line 579 "gram.y" { if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') { if (strcmp((yyvsp[0].string), "*") != 0) { @@ -2208,11 +2209,11 @@ } (yyval.string) = (yyvsp[0].string); } -#line 2206 "gram.c" +#line 2207 "gram.c" break; case 56: /* chrootspec: CHROOT '=' WORD */ -#line 590 "gram.y" +#line 591 "gram.y" { if ((yyvsp[0].string)[0] != '/' && (yyvsp[0].string)[0] != '~') { if (strcmp((yyvsp[0].string), "*") != 0) { @@ -2223,83 +2224,83 @@ } (yyval.string) = (yyvsp[0].string); } -#line 2221 "gram.c" +#line 2222 "gram.c" break; case 57: /* timeoutspec: CMND_TIMEOUT '=' WORD */ -#line 602 "gram.y" +#line 603 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2229 "gram.c" +#line 2230 "gram.c" break; case 58: /* notbeforespec: NOTBEFORE '=' WORD */ -#line 607 "gram.y" +#line 608 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2237 "gram.c" +#line 2238 "gram.c" break; case 59: /* notafterspec: NOTAFTER '=' WORD */ -#line 611 "gram.y" +#line 612 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2245 "gram.c" +#line 2246 "gram.c" break; case 60: /* rolespec: ROLE '=' WORD */ -#line 616 "gram.y" +#line 617 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2253 "gram.c" +#line 2254 "gram.c" break; case 61: /* typespec: TYPE '=' WORD */ -#line 621 "gram.y" +#line 622 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2261 "gram.c" +#line 2262 "gram.c" break; case 62: /* privsspec: PRIVS '=' WORD */ -#line 626 "gram.y" +#line 627 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2269 "gram.c" +#line 2270 "gram.c" break; case 63: /* limitprivsspec: LIMITPRIVS '=' WORD */ -#line 630 "gram.y" +#line 631 "gram.y" { (yyval.string) = (yyvsp[0].string); } -#line 2277 "gram.c" +#line 2278 "gram.c" break; case 64: /* runasspec: %empty */ -#line 635 "gram.y" +#line 636 "gram.y" { (yyval.runas) = NULL; } -#line 2285 "gram.c" +#line 2286 "gram.c" break; case 65: /* runasspec: '(' runaslist ')' */ -#line 638 "gram.y" +#line 639 "gram.y" { (yyval.runas) = (yyvsp[-1].runas); } -#line 2293 "gram.c" +#line 2294 "gram.c" break; case 66: /* runaslist: %empty */ -#line 643 "gram.y" +#line 644 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) != NULL) { @@ -2315,11 +2316,11 @@ YYERROR; } } -#line 2313 "gram.c" +#line 2314 "gram.c" break; case 67: /* runaslist: userlist */ -#line 658 "gram.y" +#line 659 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { @@ -2329,11 +2330,11 @@ (yyval.runas)->runasusers = (yyvsp[0].member); /* $$->runasgroups = NULL; */ } -#line 2327 "gram.c" +#line 2328 "gram.c" break; case 68: /* runaslist: userlist ':' grouplist */ -#line 667 "gram.y" +#line 668 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { @@ -2343,11 +2344,11 @@ (yyval.runas)->runasusers = (yyvsp[-2].member); (yyval.runas)->runasgroups = (yyvsp[0].member); } -#line 2341 "gram.c" +#line 2342 "gram.c" break; case 69: /* runaslist: ':' grouplist */ -#line 676 "gram.y" +#line 677 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) == NULL) { @@ -2357,11 +2358,11 @@ /* $$->runasusers = NULL; */ (yyval.runas)->runasgroups = (yyvsp[0].member); } -#line 2355 "gram.c" +#line 2356 "gram.c" break; case 70: /* runaslist: ':' */ -#line 685 "gram.y" +#line 686 "gram.y" { (yyval.runas) = calloc(1, sizeof(struct runascontainer)); if ((yyval.runas) != NULL) { @@ -2377,106 +2378,106 @@ YYERROR; } } -#line 2375 "gram.c" +#line 2376 "gram.c" break; case 71: /* reserved_word: ALL */ -#line 702 "gram.y" +#line 703 "gram.y" { (yyval.string) = "ALL"; } -#line 2381 "gram.c" +#line 2382 "gram.c" break; case 72: /* reserved_word: CHROOT */ -#line 703 "gram.y" +#line 704 "gram.y" { (yyval.string) = "CHROOT"; } -#line 2387 "gram.c" +#line 2388 "gram.c" break; case 73: /* reserved_word: CWD */ -#line 704 "gram.y" +#line 705 "gram.y" { (yyval.string) = "CWD"; } -#line 2393 "gram.c" +#line 2394 "gram.c" break; case 74: /* reserved_word: CMND_TIMEOUT */ -#line 705 "gram.y" +#line 706 "gram.y" { (yyval.string) = "CMND_TIMEOUT"; } -#line 2399 "gram.c" +#line 2400 "gram.c" break; case 75: /* reserved_word: NOTBEFORE */ -#line 706 "gram.y" +#line 707 "gram.y" { (yyval.string) = "NOTBEFORE"; } -#line 2405 "gram.c" +#line 2406 "gram.c" break; case 76: /* reserved_word: NOTAFTER */ -#line 707 "gram.y" +#line 708 "gram.y" { (yyval.string) = "NOTAFTER"; } -#line 2411 "gram.c" +#line 2412 "gram.c" break; case 77: /* reserved_word: ROLE */ -#line 708 "gram.y" +#line 709 "gram.y" { (yyval.string) = "ROLE"; } -#line 2417 "gram.c" +#line 2418 "gram.c" break; case 78: /* reserved_word: TYPE */ -#line 709 "gram.y" +#line 710 "gram.y" { (yyval.string) = "TYPE"; } -#line 2423 "gram.c" +#line 2424 "gram.c" break; case 79: /* reserved_word: PRIVS */ -#line 710 "gram.y" +#line 711 "gram.y" { (yyval.string) = "PRIVS"; } -#line 2429 "gram.c" +#line 2430 "gram.c" break; case 80: /* reserved_word: LIMITPRIVS */ -#line 711 "gram.y" +#line 712 "gram.y" { (yyval.string) = "LIMITPRIVS"; } -#line 2435 "gram.c" +#line 2436 "gram.c" break; case 81: /* reserved_alias: reserved_word */ -#line 714 "gram.y" +#line 715 "gram.y" { sudoerserrorf(U_("syntax error, reserved word %s used as an alias name"), (yyvsp[0].string)); YYERROR; } -#line 2444 "gram.c" +#line 2445 "gram.c" break; case 82: /* options: %empty */ -#line 720 "gram.y" +#line 721 "gram.y" { init_options(&(yyval.options)); } -#line 2452 "gram.c" +#line 2453 "gram.c" break; case 83: /* options: options chdirspec */ -#line 723 "gram.y" +#line 724 "gram.y" { free((yyval.options).runcwd); (yyval.options).runcwd = (yyvsp[0].string); } -#line 2461 "gram.c" +#line 2462 "gram.c" break; case 84: /* options: options chrootspec */ -#line 727 "gram.y" +#line 728 "gram.y" { free((yyval.options).runchroot); (yyval.options).runchroot = (yyvsp[0].string); } -#line 2470 "gram.c" +#line 2471 "gram.c" break; case 85: /* options: options notbeforespec */ -#line 731 "gram.y" +#line 732 "gram.y" { (yyval.options).notbefore = parse_gentime((yyvsp[0].string)); free((yyvsp[0].string)); @@ -2485,11 +2486,11 @@ YYERROR; } } -#line 2483 "gram.c" +#line 2484 "gram.c" break; case 86: /* options: options notafterspec */ -#line 739 "gram.y" +#line 740 "gram.y" { (yyval.options).notafter = parse_gentime((yyvsp[0].string)); free((yyvsp[0].string)); @@ -2498,11 +2499,11 @@ YYERROR; } } -#line 2496 "gram.c" +#line 2497 "gram.c" break; case 87: /* options: options timeoutspec */ -#line 747 "gram.y" +#line 748 "gram.y" { (yyval.options).timeout = parse_timeout((yyvsp[0].string)); free((yyvsp[0].string)); @@ -2514,175 +2515,175 @@ YYERROR; } } -#line 2512 "gram.c" +#line 2513 "gram.c" break; case 88: /* options: options rolespec */ -#line 758 "gram.y" +#line 759 "gram.y" { #ifdef HAVE_SELINUX free((yyval.options).role); (yyval.options).role = (yyvsp[0].string); #endif } -#line 2523 "gram.c" +#line 2524 "gram.c" break; case 89: /* options: options typespec */ -#line 764 "gram.y" +#line 765 "gram.y" { #ifdef HAVE_SELINUX free((yyval.options).type); (yyval.options).type = (yyvsp[0].string); #endif } -#line 2534 "gram.c" +#line 2535 "gram.c" break; case 90: /* options: options privsspec */ -#line 770 "gram.y" +#line 771 "gram.y" { #ifdef HAVE_PRIV_SET free((yyval.options).privs); (yyval.options).privs = (yyvsp[0].string); #endif } -#line 2545 "gram.c" +#line 2546 "gram.c" break; case 91: /* options: options limitprivsspec */ -#line 776 "gram.y" +#line 777 "gram.y" { #ifdef HAVE_PRIV_SET free((yyval.options).limitprivs); (yyval.options).limitprivs = (yyvsp[0].string); #endif } -#line 2556 "gram.c" +#line 2557 "gram.c" break; case 92: /* cmndtag: %empty */ -#line 784 "gram.y" +#line 785 "gram.y" { TAGS_INIT((yyval.tag)); } -#line 2564 "gram.c" +#line 2565 "gram.c" break; case 93: /* cmndtag: cmndtag NOPASSWD */ -#line 787 "gram.y" +#line 788 "gram.y" { (yyval.tag).nopasswd = true; } -#line 2572 "gram.c" +#line 2573 "gram.c" break; case 94: /* cmndtag: cmndtag PASSWD */ -#line 790 "gram.y" +#line 791 "gram.y" { (yyval.tag).nopasswd = false; } -#line 2580 "gram.c" +#line 2581 "gram.c" break; case 95: /* cmndtag: cmndtag NOEXEC */ -#line 793 "gram.y" +#line 794 "gram.y" { (yyval.tag).noexec = true; } -#line 2588 "gram.c" +#line 2589 "gram.c" break; case 96: /* cmndtag: cmndtag EXEC */ -#line 796 "gram.y" +#line 797 "gram.y" { (yyval.tag).noexec = false; } -#line 2596 "gram.c" +#line 2597 "gram.c" break; case 97: /* cmndtag: cmndtag SETENV */ -#line 799 "gram.y" +#line 800 "gram.y" { (yyval.tag).setenv = true; } -#line 2604 "gram.c" +#line 2605 "gram.c" break; case 98: /* cmndtag: cmndtag NOSETENV */ -#line 802 "gram.y" +#line 803 "gram.y" { (yyval.tag).setenv = false; } -#line 2612 "gram.c" +#line 2613 "gram.c" break; case 99: /* cmndtag: cmndtag LOG_INPUT */ -#line 805 "gram.y" +#line 806 "gram.y" { (yyval.tag).log_input = true; } -#line 2620 "gram.c" +#line 2621 "gram.c" break; case 100: /* cmndtag: cmndtag NOLOG_INPUT */ -#line 808 "gram.y" +#line 809 "gram.y" { (yyval.tag).log_input = false; } -#line 2628 "gram.c" +#line 2629 "gram.c" break; case 101: /* cmndtag: cmndtag LOG_OUTPUT */ -#line 811 "gram.y" +#line 812 "gram.y" { (yyval.tag).log_output = true; } -#line 2636 "gram.c" +#line 2637 "gram.c" break; case 102: /* cmndtag: cmndtag NOLOG_OUTPUT */ -#line 814 "gram.y" +#line 815 "gram.y" { (yyval.tag).log_output = false; } -#line 2644 "gram.c" +#line 2645 "gram.c" break; case 103: /* cmndtag: cmndtag FOLLOWLNK */ -#line 817 "gram.y" +#line 818 "gram.y" { (yyval.tag).follow = true; } -#line 2652 "gram.c" +#line 2653 "gram.c" break; case 104: /* cmndtag: cmndtag NOFOLLOWLNK */ -#line 820 "gram.y" +#line 821 "gram.y" { (yyval.tag).follow = false; } -#line 2660 "gram.c" +#line 2661 "gram.c" break; case 105: /* cmndtag: cmndtag MAIL */ -#line 823 "gram.y" +#line 824 "gram.y" { (yyval.tag).send_mail = true; } -#line 2668 "gram.c" +#line 2669 "gram.c" break; case 106: /* cmndtag: cmndtag NOMAIL */ -#line 826 "gram.y" +#line 827 "gram.y" { (yyval.tag).send_mail = false; } -#line 2676 "gram.c" +#line 2677 "gram.c" break; case 107: /* cmnd: ALL */ -#line 831 "gram.y" +#line 832 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { @@ -2690,11 +2691,11 @@ YYERROR; } } -#line 2688 "gram.c" +#line 2689 "gram.c" break; case 108: /* cmnd: ALIAS */ -#line 838 "gram.y" +#line 839 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { @@ -2702,11 +2703,11 @@ YYERROR; } } -#line 2700 "gram.c" +#line 2701 "gram.c" break; case 109: /* cmnd: COMMAND */ -#line 845 "gram.y" +#line 846 "gram.y" { struct sudo_command *c; @@ -2721,148 +2722,140 @@ YYERROR; } } -#line 2719 "gram.c" +#line 2720 "gram.c" break; case 112: /* $@1: %empty */ -#line 865 "gram.y" +#line 866 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2728 "gram.c" +#line 2729 "gram.c" break; case 113: /* hostalias: ALIAS $@1 '=' hostlist */ -#line 868 "gram.y" +#line 869 "gram.y" { - const char *s; - s = alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS, - sudoers, alias_line, alias_column, (yyvsp[0].member)); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, (yyvsp[-3].string), HOSTALIAS, + sudoers, alias_line, alias_column, (yyvsp[0].member))) { + alias_error((yyvsp[-3].string), errno); YYERROR; } } -#line 2742 "gram.c" +#line 2741 "gram.c" break; case 116: /* hostlist: hostlist ',' ophost */ -#line 881 "gram.y" +#line 880 "gram.y" { HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2751 "gram.c" +#line 2750 "gram.c" break; case 119: /* $@2: %empty */ -#line 891 "gram.y" +#line 890 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2760 "gram.c" +#line 2759 "gram.c" break; case 120: /* cmndalias: ALIAS $@2 '=' cmndlist */ -#line 894 "gram.y" +#line 893 "gram.y" { - const char *s; - s = alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS, - sudoers, alias_line, alias_column, (yyvsp[0].member)); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, (yyvsp[-3].string), CMNDALIAS, + sudoers, alias_line, alias_column, (yyvsp[0].member))) { + alias_error((yyvsp[-3].string), errno); YYERROR; } } -#line 2774 "gram.c" +#line 2771 "gram.c" break; case 123: /* cmndlist: cmndlist ',' digcmnd */ -#line 907 "gram.y" +#line 904 "gram.y" { HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2783 "gram.c" +#line 2780 "gram.c" break; case 126: /* $@3: %empty */ -#line 917 "gram.y" +#line 914 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2792 "gram.c" +#line 2789 "gram.c" break; case 127: /* runasalias: ALIAS $@3 '=' userlist */ -#line 920 "gram.y" +#line 917 "gram.y" { - const char *s; - s = alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS, - sudoers, alias_line, alias_column, (yyvsp[0].member)); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, (yyvsp[-3].string), RUNASALIAS, + sudoers, alias_line, alias_column, (yyvsp[0].member))) { + alias_error((yyvsp[-3].string), errno); YYERROR; } } -#line 2806 "gram.c" +#line 2801 "gram.c" break; case 131: /* $@4: %empty */ -#line 936 "gram.y" +#line 931 "gram.y" { alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } -#line 2815 "gram.c" +#line 2810 "gram.c" break; case 132: /* useralias: ALIAS $@4 '=' userlist */ -#line 939 "gram.y" +#line 934 "gram.y" { - const char *s; - s = alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS, - sudoers, alias_line, alias_column, (yyvsp[0].member)); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, (yyvsp[-3].string), USERALIAS, + sudoers, alias_line, alias_column, (yyvsp[0].member))) { + alias_error((yyvsp[-3].string), errno); YYERROR; } } -#line 2829 "gram.c" +#line 2822 "gram.c" break; case 135: /* userlist: userlist ',' opuser */ -#line 952 "gram.y" +#line 945 "gram.y" { HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2838 "gram.c" +#line 2831 "gram.c" break; case 136: /* opuser: user */ -#line 958 "gram.y" +#line 951 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2847 "gram.c" +#line 2840 "gram.c" break; case 137: /* opuser: '!' user */ -#line 962 "gram.y" +#line 955 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2856 "gram.c" +#line 2849 "gram.c" break; case 138: /* user: ALIAS */ -#line 968 "gram.y" +#line 961 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { @@ -2870,11 +2863,11 @@ YYERROR; } } -#line 2868 "gram.c" +#line 2861 "gram.c" break; case 139: /* user: ALL */ -#line 975 "gram.y" +#line 968 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { @@ -2882,11 +2875,11 @@ YYERROR; } } -#line 2880 "gram.c" +#line 2873 "gram.c" break; case 140: /* user: NETGROUP */ -#line 982 "gram.y" +#line 975 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), NETGROUP); if ((yyval.member) == NULL) { @@ -2894,11 +2887,11 @@ YYERROR; } } -#line 2892 "gram.c" +#line 2885 "gram.c" break; case 141: /* user: USERGROUP */ -#line 989 "gram.y" +#line 982 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), USERGROUP); if ((yyval.member) == NULL) { @@ -2906,11 +2899,11 @@ YYERROR; } } -#line 2904 "gram.c" +#line 2897 "gram.c" break; case 142: /* user: WORD */ -#line 996 "gram.y" +#line 989 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), WORD); if ((yyval.member) == NULL) { @@ -2918,38 +2911,38 @@ YYERROR; } } -#line 2916 "gram.c" +#line 2909 "gram.c" break; case 144: /* grouplist: grouplist ',' opgroup */ -#line 1006 "gram.y" +#line 999 "gram.y" { HLTQ_CONCAT((yyvsp[-2].member), (yyvsp[0].member), entries); (yyval.member) = (yyvsp[-2].member); } -#line 2925 "gram.c" +#line 2918 "gram.c" break; case 145: /* opgroup: group */ -#line 1012 "gram.y" +#line 1005 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = false; } -#line 2934 "gram.c" +#line 2927 "gram.c" break; case 146: /* opgroup: '!' group */ -#line 1016 "gram.y" +#line 1009 "gram.y" { (yyval.member) = (yyvsp[0].member); (yyval.member)->negated = true; } -#line 2943 "gram.c" +#line 2936 "gram.c" break; case 147: /* group: ALIAS */ -#line 1022 "gram.y" +#line 1015 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), ALIAS); if ((yyval.member) == NULL) { @@ -2957,11 +2950,11 @@ YYERROR; } } -#line 2955 "gram.c" +#line 2948 "gram.c" break; case 148: /* group: ALL */ -#line 1029 "gram.y" +#line 1022 "gram.y" { (yyval.member) = new_member(NULL, ALL); if ((yyval.member) == NULL) { @@ -2969,11 +2962,11 @@ YYERROR; } } -#line 2967 "gram.c" +#line 2960 "gram.c" break; case 149: /* group: WORD */ -#line 1036 "gram.y" +#line 1029 "gram.y" { (yyval.member) = new_member((yyvsp[0].string), WORD); if ((yyval.member) == NULL) { @@ -2981,11 +2974,11 @@ YYERROR; } } -#line 2979 "gram.c" +#line 2972 "gram.c" break; -#line 2983 "gram.c" +#line 2976 "gram.c" default: break; } @@ -3179,7 +3172,7 @@ return yyresult; } -#line 1044 "gram.y" +#line 1037 "gram.y" /* Like yyerror() but takes a printf-style format string. */ void @@ -3252,6 +3245,15 @@ sudoerserrorf(NULL); else sudoerserrorf("%s", s); +} + +static void +alias_error(const char *name, int errnum) +{ + if (errnum == EEXIST) + sudoerserrorf(U_("Alias \"%s\" already defined"), name); + else + sudoerserror(N_("unable to allocate memory")); } static struct defaults * diff -urNa sudo-1.9.4/plugins/sudoers/gram.h sudo-1.9.4p1/plugins/sudoers/gram.h --- sudo-1.9.4/plugins/sudoers/gram.h Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/gram.h Wed Dec 16 18:34:30 2020 @@ -1,4 +1,4 @@ -/* A Bison parser, made by GNU Bison 3.7.3. */ +/* A Bison parser, made by GNU Bison 3.7.4. */ /* Bison interface for Yacc-like parsers in C @@ -167,7 +167,7 @@ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 79 "gram.y" +#line 80 "gram.y" struct cmndspec *cmndspec; struct defaults *defaults; diff -urNa sudo-1.9.4/plugins/sudoers/gram.y sudo-1.9.4p1/plugins/sudoers/gram.y --- sudo-1.9.4/plugins/sudoers/gram.y Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/gram.y Wed Dec 16 18:34:30 2020 @@ -74,6 +74,7 @@ static struct member *new_member(char *, int); static struct sudo_command *new_command(char *, char *); static struct command_digest *new_digest(int, char *); +static void alias_error(const char *name, int errnum); %} %union { @@ -866,11 +867,9 @@ alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } '=' hostlist { - const char *s; - s = alias_add(&parsed_policy, $1, HOSTALIAS, - sudoers, alias_line, alias_column, $4); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, $1, HOSTALIAS, + sudoers, alias_line, alias_column, $4)) { + alias_error($1, errno); YYERROR; } } @@ -892,11 +891,9 @@ alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } '=' cmndlist { - const char *s; - s = alias_add(&parsed_policy, $1, CMNDALIAS, - sudoers, alias_line, alias_column, $4); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, $1, CMNDALIAS, + sudoers, alias_line, alias_column, $4)) { + alias_error($1, errno); YYERROR; } } @@ -918,11 +915,9 @@ alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } '=' userlist { - const char *s; - s = alias_add(&parsed_policy, $1, RUNASALIAS, - sudoers, alias_line, alias_column, $4); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, $1, RUNASALIAS, + sudoers, alias_line, alias_column, $4)) { + alias_error($1, errno); YYERROR; } } @@ -937,11 +932,9 @@ alias_line = this_lineno; alias_column = sudolinebuf.toke_start + 1; } '=' userlist { - const char *s; - s = alias_add(&parsed_policy, $1, USERALIAS, - sudoers, alias_line, alias_column, $4); - if (s != NULL) { - sudoerserror(s); + if (!alias_add(&parsed_policy, $1, USERALIAS, + sudoers, alias_line, alias_column, $4)) { + alias_error($1, errno); YYERROR; } } @@ -1113,6 +1106,15 @@ sudoerserrorf(NULL); else sudoerserrorf("%s", s); +} + +static void +alias_error(const char *name, int errnum) +{ + if (errnum == EEXIST) + sudoerserrorf(U_("Alias \"%s\" already defined"), name); + else + sudoerserror(N_("unable to allocate memory")); } static struct defaults * diff -urNa sudo-1.9.4/plugins/sudoers/log_client.c sudo-1.9.4p1/plugins/sudoers/log_client.c --- sudo-1.9.4/plugins/sudoers/log_client.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/log_client.c Wed Dec 16 18:34:30 2020 @@ -472,7 +472,7 @@ } } if (timed_connect(sock, res->ai_addr, res->ai_addrlen, timo) == -1) { - cause = "connect"; + /* No need to set cause, caller's error message is sufficient. */ save_errno = errno; close(sock); errno = save_errno; @@ -567,10 +567,8 @@ STAILQ_FOREACH(server, closure->log_details->log_servers, entries) { free(copy); - if ((copy = strdup(server->str)) == NULL) { - cause = "strdup"; + if ((copy = strdup(server->str)) == NULL) break; - } if (!iolog_parse_host_port(copy, &host, &port, &tls, DEFAULT_PORT, DEFAULT_PORT_TLS)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, @@ -1721,7 +1719,10 @@ sudo_warnx("%s", errstr); goto bad; case SSL_ERROR_SYSCALL: - sudo_warn("recv"); + if (nread == 0) + sudo_warnx("%s", U_("lost connection to log server")); + else + sudo_warn("recv"); goto bad; default: errstr = ERR_reason_error_string(ERR_get_error()); @@ -1969,7 +1970,7 @@ /* Connect to log first available log server. */ if (!log_server_connect(closure)) { /* TODO: support offline logs if server unreachable */ - sudo_warnx("%s", U_("unable to connect to log server")); + sudo_warn("%s", U_("unable to connect to log server")); goto bad; } diff -urNa sudo-1.9.4/plugins/sudoers/logging.c sudo-1.9.4p1/plugins/sudoers/logging.c --- sudo-1.9.4/plugins/sudoers/logging.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/logging.c Wed Dec 16 18:34:30 2020 @@ -652,12 +652,17 @@ sudoers_to_eventlog(struct eventlog *evlog, char * const argv[], char * const envp[]) { + struct group *grp; debug_decl(sudoers_to_eventlog, SUDOERS_DEBUG_LOGGING); + /* We rely on the reference held by the group cache. */ + if ((grp = sudo_getgrgid(sudo_user.pw->pw_gid)) != NULL) + sudo_gr_delref(grp); + memset(evlog, 0, sizeof(*evlog)); - /* TODO: iolog_path */ evlog->iolog_file = sudo_user.iolog_file; - evlog->command = safe_cmnd; + evlog->iolog_path = sudo_user.iolog_path; + evlog->command = safe_cmnd ? safe_cmnd : (argv ? argv[0] : NULL); evlog->cwd = user_cwd; if (def_runchroot != NULL && strcmp(def_runchroot, "*") != 0) { evlog->runchroot = def_runchroot; @@ -669,13 +674,11 @@ } else { evlog->runcwd = user_cwd; } - if (runas_gr != NULL) { - evlog->rungroup = runas_gr->gr_name; - } - evlog->runuser = runas_pw->pw_name; + evlog->rungroup = runas_gr ? runas_gr->gr_name : sudo_user.runas_group; evlog->submithost = user_host; evlog->submituser = user_name; - /* TODO - submitgroup */ + if (grp != NULL) + evlog->submitgroup = grp->gr_name; evlog->ttyname = user_ttypath; evlog->argv = (char **)argv; evlog->env_add = (char **)sudo_user.env_vars; @@ -683,8 +686,15 @@ evlog->submit_time = sudo_user.submit_time; evlog->lines = sudo_user.lines; evlog->columns = sudo_user.cols; - evlog->runuid = runas_pw->pw_uid; - evlog->rungid = runas_pw->pw_gid; + if (runas_pw != NULL) { + evlog->rungid = runas_pw->pw_gid; + evlog->runuid = runas_pw->pw_uid; + evlog->runuser = runas_pw->pw_name; + } else { + evlog->rungid = (gid_t)-1; + evlog->runuid = (uid_t)-1; + evlog->runuser = sudo_user.runas_user; + } debug_return; } diff -urNa sudo-1.9.4/plugins/sudoers/parse.h sudo-1.9.4p1/plugins/sudoers/parse.h --- sudo-1.9.4/plugins/sudoers/parse.h Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/parse.h Wed Dec 16 18:34:30 2020 @@ -298,7 +298,7 @@ struct rbtree *alloc_aliases(void); void free_aliases(struct rbtree *aliases); bool no_aliases(struct sudoers_parse_tree *parse_tree); -const char *alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type, char *file, int line, int column, struct member *members); +bool alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type, char *file, int line, int column, struct member *members); const char *alias_type_to_string(int alias_type); struct alias *alias_get(struct sudoers_parse_tree *parse_tree, const char *name, int type); struct alias *alias_remove(struct sudoers_parse_tree *parse_tree, char *name, int type); diff -urNa sudo-1.9.4/plugins/sudoers/policy.c sudo-1.9.4p1/plugins/sudoers/policy.c --- sudo-1.9.4/plugins/sudoers/policy.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/policy.c Wed Dec 16 18:34:30 2020 @@ -86,7 +86,7 @@ * Fills in struct sudo_user and other common sudoers state. */ int -sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) +sudoers_policy_deserialize_info(void *v) { struct sudoers_open_info *info = v; char * const *cur; @@ -178,7 +178,7 @@ if (MATCHES(*cur, "closefrom=")) { errno = 0; p = *cur + sizeof("closefrom=") - 1; - user_closefrom = sudo_strtonum(p, 4, INT_MAX, &errstr); + user_closefrom = sudo_strtonum(p, 3, INT_MAX, &errstr); if (user_closefrom == 0) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; @@ -197,13 +197,13 @@ } if (MATCHES(*cur, "runas_user=")) { CHECK(*cur, "runas_user="); - *runas_user = *cur + sizeof("runas_user=") - 1; + sudo_user.runas_user = *cur + sizeof("runas_user=") - 1; SET(sudo_user.flags, RUNAS_USER_SPECIFIED); continue; } if (MATCHES(*cur, "runas_group=")) { CHECK(*cur, "runas_group="); - *runas_group = *cur + sizeof("runas_group=") - 1; + sudo_user.runas_group = *cur + sizeof("runas_group=") - 1; SET(sudo_user.flags, RUNAS_GROUP_SPECIFIED); continue; } diff -urNa sudo-1.9.4/plugins/sudoers/sudoers.c sudo-1.9.4p1/plugins/sudoers/sudoers.c --- sudo-1.9.4/plugins/sudoers/sudoers.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/sudoers.c Wed Dec 16 18:34:30 2020 @@ -92,8 +92,6 @@ int sudo_mode; static char *prev_user; -static char *runas_user; -static char *runas_group; static struct sudo_nss_list *snl; static bool unknown_runas_uid; static bool unknown_runas_gid; @@ -180,7 +178,7 @@ } /* Parse info from front-end. */ - sudo_mode = sudoers_policy_deserialize_info(info, &runas_user, &runas_group); + sudo_mode = sudoers_policy_deserialize_info(info); if (ISSET(sudo_mode, MODE_ERROR)) debug_return_int(-1); @@ -265,9 +263,9 @@ goto done; } - /* Stash pointer to the I/O log file for use when logging. */ - sudo_user.iolog_file = - iolog_path + sizeof("iolog_path=") - 1 + strlen(dir) + 1; + /* Stash pointer to the I/O log for the event log. */ + sudo_user.iolog_path = iolog_path + sizeof("iolog_path=") - 1; + sudo_user.iolog_file = sudo_user.iolog_path + 1 + strlen(dir); done: debug_return_str(iolog_path); @@ -395,6 +393,23 @@ } } + /* + * Set runas passwd/group entries based on command line or sudoers. + * Note that if runas_group was specified without runas_user we + * run the command as the invoking user. + */ + if (sudo_user.runas_group != NULL) { + if (!set_runasgr(sudo_user.runas_group, false)) + goto done; + if (!set_runaspw(sudo_user.runas_user ? + sudo_user.runas_user : user_name, false)) + goto done; + } else { + if (!set_runaspw(sudo_user.runas_user ? + sudo_user.runas_user : def_runas_default, false)) + goto done; + } + /* If given the -P option, set the "preserve_groups" flag. */ if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS)) def_preserve_groups = true; @@ -860,21 +875,6 @@ debug_return_bool(false); } - /* - * Set runas passwd/group entries based on command line or sudoers. - * Note that if runas_group was specified without runas_user we - * run the command as the invoking user. - */ - if (runas_group != NULL) { - if (!set_runasgr(runas_group, false)) - debug_return_bool(false); - if (!set_runaspw(runas_user ? runas_user : user_name, false)) - debug_return_bool(false); - } else { - if (!set_runaspw(runas_user ? runas_user : def_runas_default, false)) - debug_return_bool(false); - } - debug_return_bool(true); } @@ -1304,7 +1304,7 @@ if (pw == NULL) { if ((pw = sudo_getpwnam(user)) == NULL) { if (!quiet) - log_warningx(SLOG_RAW_MSG, N_("unknown user: %s"), user); + log_warningx(SLOG_AUDIT, N_("unknown user: %s"), user); debug_return_bool(false); } } @@ -1338,7 +1338,7 @@ if (gr == NULL) { if ((gr = sudo_getgrnam(group)) == NULL) { if (!quiet) - log_warningx(SLOG_RAW_MSG, N_("unknown group: %s"), group); + log_warningx(SLOG_AUDIT, N_("unknown group: %s"), group); debug_return_bool(false); } } @@ -1357,7 +1357,7 @@ debug_decl(cb_runas_default, SUDOERS_DEBUG_PLUGIN); /* Only reset runaspw if user didn't specify one. */ - if (!runas_user && !runas_group) + if (sudo_user.runas_user == NULL && sudo_user.runas_group == NULL) debug_return_bool(set_runaspw(sd_un->str, true)); debug_return_bool(true); } diff -urNa sudo-1.9.4/plugins/sudoers/sudoers.h sudo-1.9.4p1/plugins/sudoers/sudoers.h --- sudo-1.9.4/plugins/sudoers/sudoers.h Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/plugins/sudoers/sudoers.h Wed Dec 16 18:34:30 2020 @@ -87,6 +87,8 @@ struct stat *cmnd_stat; char *cwd; char *name; + char *runas_user; + char *runas_group; char *path; char *tty; char *ttypath; @@ -114,6 +116,7 @@ char *limitprivs; #endif char *iolog_file; + char *iolog_path; GETGROUPS_T *gids; int execfd; int ngids; @@ -416,7 +419,7 @@ void sudoers_debug_deregister(void); /* policy.c */ -int sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group); +int sudoers_policy_deserialize_info(void *v); bool sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], mode_t cmnd_umask, char *iolog_path, void *v); extern const char *path_ldap_conf; extern const char *path_ldap_secret; diff -urNa sudo-1.9.4/src/sudo.c sudo-1.9.4p1/src/sudo.c --- sudo-1.9.4/src/sudo.c Sun Nov 29 15:12:49 2020 +++ sudo-1.9.4p1/src/sudo.c Wed Dec 16 18:34:30 2020 @@ -431,9 +431,10 @@ if (maxgroups < 0) maxgroups = NGROUPS_MAX; + /* Note that macOS may return ngroups > NGROUPS_MAX. */ if ((ud->ngroups = getgroups(0, NULL)) > 0) { - /* Use groups from kernel if not too many or source is static. */ - if (ud->ngroups < maxgroups || group_source == GROUP_SOURCE_STATIC) { + /* Use groups from kernel if not at limit or source is static. */ + if (ud->ngroups != maxgroups || group_source == GROUP_SOURCE_STATIC) { ud->groups = reallocarray(NULL, ud->ngroups, sizeof(GETGROUPS_T)); if (ud->groups == NULL) goto done; @@ -1349,7 +1350,11 @@ &details->envp, &errstr); } sudo_debug_set_active_instance(sudo_debug_instance); - /* TODO: audit on error */ + if (ret != 1) { + audit_error(policy_plugin.name, SUDO_POLICY_PLUGIN, + errstr ? errstr : _("policy plugin error"), + details->info); + } } done: debug_return_int(ret); @@ -1625,6 +1630,47 @@ } /* + * Error from plugin or front-end. + * The error will not be sent to plugin source, if specified. + */ +static void +audit_error2(struct plugin_container *source, const char *plugin_name, + unsigned int plugin_type, const char *audit_msg, char * const command_info[]) +{ + struct plugin_container *plugin; + const char *errstr = NULL; + int ok; + debug_decl(audit_error2, SUDO_DEBUG_PCOMM); + + TAILQ_FOREACH(plugin, &audit_plugins, entries) { + if (plugin->u.audit->error == NULL) + continue; + + /* Avoid a loop if the audit plugin itself has an error. */ + if (plugin == source) + continue; + + sudo_debug_set_active_instance(plugin->debug_instance); + ok = plugin->u.audit->error(plugin_name, plugin_type, + audit_msg, command_info, &errstr); + sudo_debug_set_active_instance(sudo_debug_instance); + if (ok != 1) { + /* + * Don't propagate the error to other audit plugins. + * It is not worth the trouble to avoid potential loops. + */ + sudo_debug_printf(SUDO_DEBUG_ERROR, + "%s: plugin %s error failed, ret %d", __func__, + plugin->name, ok); + sudo_warnx(U_("%s: unable to log error event%s%s"), + plugin->name, errstr ? ": " : "", errstr ? errstr : ""); + } + } + + debug_return; +} + +/* * Command accepted by policy. * See command_info[] for additional info. * XXX - actual environment may be updated by policy_init_session(). @@ -1639,7 +1685,6 @@ int ok; debug_decl(audit_accept, SUDO_DEBUG_PCOMM); - /* XXX - kill command if can't audit accept event */ TAILQ_FOREACH(plugin, &audit_plugins, entries) { if (plugin->u.audit->accept == NULL) continue; @@ -1647,13 +1692,20 @@ sudo_debug_set_active_instance(plugin->debug_instance); ok = plugin->u.audit->accept(plugin_name, plugin_type, command_info, run_argv, run_envp, &errstr); + sudo_debug_set_active_instance(sudo_debug_instance); if (ok != 1) { - /* XXX - fatal error? log error with other audit modules? */ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: plugin %s accept failed, ret %d", __func__, plugin->name, ok); + sudo_warnx(U_("%s: unable to log accept event%s%s"), + plugin->name, errstr ? ": " : "", errstr ? errstr : ""); + + /* Notify other audit plugins and exit. */ + audit_error2(plugin, plugin->name, SUDO_AUDIT_PLUGIN, + errstr ? errstr : _("audit plugin error"), command_info); + audit_close(SUDO_PLUGIN_NO_STATUS, 0); + exit(EXIT_FAILURE); } - sudo_debug_set_active_instance(sudo_debug_instance); } debug_return; @@ -1678,47 +1730,31 @@ sudo_debug_set_active_instance(plugin->debug_instance); ok = plugin->u.audit->reject(plugin_name, plugin_type, audit_msg, command_info, &errstr); + sudo_debug_set_active_instance(sudo_debug_instance); if (ok != 1) { - /* TODO: notify other audit plugins of the error. */ sudo_debug_printf(SUDO_DEBUG_ERROR, "%s: plugin %s reject failed, ret %d", __func__, plugin->name, ok); + sudo_warnx(U_("%s: unable to log reject event%s%s"), + plugin->name, errstr ? ": " : "", errstr ? errstr : ""); + + /* Notify other audit plugins. */ + audit_error2(plugin, plugin->name, SUDO_AUDIT_PLUGIN, + errstr ? errstr : _("audit plugin error"), command_info); } - sudo_debug_set_active_instance(sudo_debug_instance); } debug_return; } /* - * Error from policy or I/O plugin. + * Error from plugin or front-end. */ void audit_error(const char *plugin_name, unsigned int plugin_type, const char *audit_msg, char * const command_info[]) { - struct plugin_container *plugin; - const char *errstr = NULL; - int ok; - debug_decl(audit_error, SUDO_DEBUG_PCOMM); - - TAILQ_FOREACH(plugin, &audit_plugins, entries) { - if (plugin->u.audit->error == NULL) - continue; - - sudo_debug_set_active_instance(plugin->debug_instance); - ok = plugin->u.audit->error(plugin_name, plugin_type, - audit_msg, command_info, &errstr); - if (ok != 1) { - /* TODO: notify other audit plugins of the error. */ - sudo_debug_printf(SUDO_DEBUG_ERROR, - "%s: plugin %s error failed, ret %d", __func__, - plugin->name, ok); - } - sudo_debug_set_active_instance(sudo_debug_instance); - } - - debug_return; + audit_error2(NULL, plugin_name, plugin_type, audit_msg, command_info); } static int