diff --git a/NEWS b/NEWS
index ac487052ee..673fff1404 100644
--- a/NEWS
+++ b/NEWS
@@ -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 @@ What's new in Sudo 1.9.4
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 --git a/config.h.in b/config.h.in
index 45f54445b6..b48acabb7c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -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 --git a/configure b/configure
index 984b96460e..715b956212 100755
--- a/configure
+++ b/configure
@@ -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 @@ MAKEFLAGS=
# 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 @@ if test "$ac_init_help" = "long"; then
# 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 @@ fi
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 @@ fi
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 @@ cat >config.log <<_ACEOF
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 @@ fi
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 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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 @@ _ACEOF
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 --git a/configure.ac b/configure.ac
index 5ddec69ae2..744ebf64c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,7 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
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 @@ case "$host" in
# 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])])
@@ -5019,6 +5022,11 @@ AH_BOTTOM([/* Symbol visibility controls */
# 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 --git a/doc/sudo.conf.man.in b/doc/sudo.conf.man.in
index f544fc979e..36a3c00b69 100644
--- a/doc/sudo.conf.man.in
+++ b/doc/sudo.conf.man.in
@@ -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 @@ front end configuration
# 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 --git a/doc/sudo.conf.mdoc.in b/doc/sudo.conf.mdoc.in
index c3c3477fb3..2d572e5ee3 100644
--- a/doc/sudo.conf.mdoc.in
+++ b/doc/sudo.conf.mdoc.in
@@ -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 @@ front end configuration
# 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 --git a/doc/sudoers.man.in b/doc/sudoers.man.in
index 7597cc99aa..c193506045 100644
--- a/doc/sudoers.man.in
+++ b/doc/sudoers.man.in
@@ -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 @@ If
\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 @@ If
\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 --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
index 27c1873ee5..cb1b9ad979 100644
--- a/doc/sudoers.mdoc.in
+++ b/doc/sudoers.mdoc.in
@@ -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 @@ If
.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 @@ If
.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 --git a/examples/sudo.conf.in b/examples/sudo.conf.in
index d4342b2cea..5e36034f23 100644
--- a/examples/sudo.conf.in
+++ b/examples/sudo.conf.in
@@ -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 --git a/lib/eventlog/eventlog.c b/lib/eventlog/eventlog.c
index 8b190b7ce0..2da61f91f4 100644
--- a/lib/eventlog/eventlog.c
+++ b/lib/eventlog/eventlog.c
@@ -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 @@ static struct eventlog_config evl_conf = {
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 @@ new_logline(int flags, const char *message, const char *errstr,
}
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 @@ new_logline(int flags, const char *message, const char *errstr,
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 @@ eventlog_setconf(struct eventlog_config *conf)
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 --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c
index f25244439f..d01c62eff6 100644
--- a/logsrvd/logsrvd.c
+++ b/logsrvd/logsrvd.c
@@ -745,15 +745,19 @@ server_shutdown(struct sudo_event_base *base)
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 --git a/plugins/sudoers/alias.c b/plugins/sudoers/alias.c
index 3cfe5f90fa..caaa984a06 100644
--- a/plugins/sudoers/alias.c
+++ b/plugins/sudoers/alias.c
@@ -110,30 +110,23 @@ alias_put(struct alias *a)
/*
* 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 @@ alias_add(struct sudoers_parse_tree *parse_tree, char *name, int type,
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 --git a/plugins/sudoers/audit.c b/plugins/sudoers/audit.c
index d858ed32c6..f72c4d4cbd 100644
--- a/plugins/sudoers/audit.c
+++ b/plugins/sudoers/audit.c
@@ -182,9 +182,17 @@ sudoers_audit_open(unsigned int version, sudo_conv_t conversation,
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 --git a/plugins/sudoers/gram.c b/plugins/sudoers/gram.c
index 3985ca7bf0..abd299bc46 100644
--- a/plugins/sudoers/gram.c
+++ b/plugins/sudoers/gram.c
@@ -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 defaults *new_default(char *, char *, short);
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 @@ extern int sudoersdebug;
#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 @@ union YYSTYPE
char *string;
int tok;
-#line 327 "gram.c"
+#line 328 "gram.c"
};
typedef union YYSTYPE YYSTYPE;
@@ -835,21 +836,21 @@ static const yytype_int8 yytranslate[] =
/* 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 @@ yyparse (void)
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 @@ yyparse (void)
}
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 @@ yyparse (void)
}
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
}
(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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
}
(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 @@ yyparse (void)
}
(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 @@ yyparse (void)
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 @@ yyparse (void)
(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 @@ yyparse (void)
(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 @@ yyparse (void)
/* $$->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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
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 @@ yyparse (void)
YYERROR;
}
}
-#line 2979 "gram.c"
+#line 2972 "gram.c"
break;
-#line 2983 "gram.c"
+#line 2976 "gram.c"
default: break;
}
@@ -3179,7 +3172,7 @@ yyparse (void)
return yyresult;
}
-#line 1044 "gram.y"
+#line 1037 "gram.y"
/* Like yyerror() but takes a printf-style format string. */
void
@@ -3254,6 +3247,15 @@ sudoerserror(const char *s)
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 *
new_default(char *var, char *val, short op)
{
diff --git a/plugins/sudoers/gram.h b/plugins/sudoers/gram.h
index c5eb881126..1827de81d5 100644
--- a/plugins/sudoers/gram.h
+++ b/plugins/sudoers/gram.h
@@ -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 @@ extern int sudoersdebug;
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
union YYSTYPE
{
-#line 79 "gram.y"
+#line 80 "gram.y"
struct cmndspec *cmndspec;
struct defaults *defaults;
diff --git a/plugins/sudoers/gram.y b/plugins/sudoers/gram.y
index 7253e2dd08..b9439f37bb 100644
--- a/plugins/sudoers/gram.y
+++ b/plugins/sudoers/gram.y
@@ -74,6 +74,7 @@ static struct defaults *new_default(char *, char *, short);
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 @@ hostalias : ALIAS {
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 @@ cmndalias : ALIAS {
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 @@ runasalias : ALIAS {
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 @@ useralias : ALIAS {
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;
}
}
@@ -1115,6 +1108,15 @@ sudoerserror(const char *s)
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 *
new_default(char *var, char *val, short op)
{
diff --git a/plugins/sudoers/log_client.c b/plugins/sudoers/log_client.c
index 769a0ba552..5cfab23d83 100644
--- a/plugins/sudoers/log_client.c
+++ b/plugins/sudoers/log_client.c
@@ -472,7 +472,7 @@ connect_server(const char *host, const char *port, bool tls,
}
}
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 @@ log_server_connect(struct client_closure *closure)
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 @@ server_msg_cb(int fd, int what, void *v)
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 @@ log_server_open(struct log_details *details, struct timespec *now,
/* 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 --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c
index af42d4288e..e0d46280c4 100644
--- a/plugins/sudoers/logging.c
+++ b/plugins/sudoers/logging.c
@@ -652,12 +652,17 @@ void
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 @@ sudoers_to_eventlog(struct eventlog *evlog, char * const argv[],
} 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 @@ sudoers_to_eventlog(struct eventlog *evlog, char * const argv[],
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 --git a/plugins/sudoers/parse.h b/plugins/sudoers/parse.h
index 9e545ff1b0..6bd2c1ebdd 100644
--- a/plugins/sudoers/parse.h
+++ b/plugins/sudoers/parse.h
@@ -298,7 +298,7 @@ struct cmnd_info {
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 --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
index 5a6982688e..6f1787f181 100644
--- a/plugins/sudoers/policy.c
+++ b/plugins/sudoers/policy.c
@@ -86,7 +86,7 @@ parse_bool(const char *line, int varlen, int *flags, int fval)
* 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 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
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 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
}
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 --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
index ce2c10cd25..98c62511ef 100644
--- a/plugins/sudoers/sudoers.c
+++ b/plugins/sudoers/sudoers.c
@@ -92,8 +92,6 @@ bool force_umask;
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 @@ sudoers_init(void *info, char * const envp[])
}
/* 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 @@ format_iolog_path(void)
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 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
}
}
+ /*
+ * 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 @@ init_vars(char * const envp[])
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 @@ set_runaspw(const char *user, bool quiet)
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 @@ set_runasgr(const char *group, bool quiet)
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 @@ cb_runas_default(const union sudo_defs_val *sd_un)
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 --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
index 4bc97fc115..bece1ebad5 100644
--- a/plugins/sudoers/sudoers.h
+++ b/plugins/sudoers/sudoers.h
@@ -87,6 +87,8 @@ struct sudo_user {
struct stat *cmnd_stat;
char *cwd;
char *name;
+ char *runas_user;
+ char *runas_group;
char *path;
char *tty;
char *ttypath;
@@ -114,6 +116,7 @@ struct sudo_user {
char *limitprivs;
#endif
char *iolog_file;
+ char *iolog_path;
GETGROUPS_T *gids;
int execfd;
int ngids;
@@ -416,7 +419,7 @@ bool sudoers_debug_register(const char *plugin_path, struct sudo_conf_debug_file
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 --git a/src/sudo.c b/src/sudo.c
index 799b36b19f..9d60e1b6d5 100644
--- a/src/sudo.c
+++ b/src/sudo.c
@@ -431,9 +431,10 @@ get_user_groups(struct user_details *ud)
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 @@ policy_init_session(struct command_details *details)
&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);
@@ -1624,6 +1629,47 @@ audit_show_version(int verbose)
debug_return;
}
+/*
+ * 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.
@@ -1639,7 +1685,6 @@ audit_accept(const char *plugin_name, unsigned int plugin_type,
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 @@ audit_accept(const char *plugin_name, unsigned int plugin_type,
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 @@ audit_reject(const char *plugin_name, unsigned int plugin_type,
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