commit
097925b414
@ -1,199 +0,0 @@
|
||||
From 807e17ceedf2500aeca67b37f62463ee112d63c4 Mon Sep 17 00:00:00 2001
|
||||
From: Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
Date: Mon, 09 Dec 2019 17:14:06 -0700
|
||||
Subject: [PATCH] Fix CVE-2019-19234
|
||||
|
||||
Add a new flag "allow_unknown_runas_id" to control matching of unknown IDs.
|
||||
Previous, sudo would always allow unknown user or group IDs if the
|
||||
sudoers entry permitted it. This included the "ALL" alias.
|
||||
With this change, the admin must explicitly enable support for unknown IDs.
|
||||
|
||||
---
|
||||
doc/sudoers.man.in | 17 +++++++++++++++++
|
||||
doc/sudoers.mdoc.in | 16 ++++++++++++++++
|
||||
plugins/sudoers/def_data.c | 4 ++++
|
||||
plugins/sudoers/def_data.h | 2 ++
|
||||
plugins/sudoers/def_data.in | 3 +++
|
||||
plugins/sudoers/defaults.c | 1 +
|
||||
plugins/sudoers/sudoers.c | 28 ++++++++++++++++++++++++++--
|
||||
7 files changed, 69 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in
|
||||
index e2470b5..45a600f 100644
|
||||
--- a/doc/sudoers.man.in
|
||||
+++ b/doc/sudoers.man.in
|
||||
@@ -2869,6 +2869,23 @@ This flag is
|
||||
\fIoff\fR
|
||||
by default.
|
||||
.TP 18n
|
||||
+runas_allow_unknown_id
|
||||
+If enabled, allow matching of runas user and group IDs that are
|
||||
+not present in the password or group databases.
|
||||
+In addition to explicitly matching unknown user or group IDs in a
|
||||
+\fRRunas_List\fR,
|
||||
+this option also allows the
|
||||
+\fBALL\fR
|
||||
+alias to match unknown IDs.
|
||||
+This flag is
|
||||
+\fIoff\fR
|
||||
+by default.
|
||||
+.sp
|
||||
+This setting is only supported by version 1.8.30 or higher.
|
||||
+Older versions of
|
||||
+\fBsudo\fR
|
||||
+always allowed matching of unknown user and group IDs.
|
||||
+.TP 18n
|
||||
runaspw
|
||||
If set,
|
||||
\fBsudo\fR
|
||||
diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
|
||||
index 2053b5d..6a511d9 100644
|
||||
--- a/doc/sudoers.mdoc.in
|
||||
+++ b/doc/sudoers.mdoc.in
|
||||
@@ -2698,6 +2698,22 @@ when running a command or editing a file.
|
||||
This flag is
|
||||
.Em off
|
||||
by default.
|
||||
+.It runas_allow_unknown_id
|
||||
+If enabled, allow matching of runas user and group IDs that are
|
||||
+not present in the password or group databases.
|
||||
+In addition to explicitly matching unknown user or group IDs in a
|
||||
+.Li Runas_List ,
|
||||
+this option also allows the
|
||||
+.Sy ALL
|
||||
+alias to match unknown IDs.
|
||||
+This flag is
|
||||
+.Em off
|
||||
+by default.
|
||||
+.Pp
|
||||
+This setting is only supported by version 1.8.30 or higher.
|
||||
+Older versions of
|
||||
+.Nm sudo
|
||||
+always allowed matching of unknown user and group IDs.
|
||||
.It runaspw
|
||||
If set,
|
||||
.Nm sudo
|
||||
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
||||
index 07e3433..97eaf79 100644
|
||||
--- a/plugins/sudoers/def_data.c
|
||||
+++ b/plugins/sudoers/def_data.c
|
||||
@@ -494,6 +494,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
N_("Ignore case when matching group names"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "runas_allow_unknown_id", T_FLAG,
|
||||
+ N_("Allow the use of unknown runas user and/or group ID"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
||||
index 65f10c3..55878c9 100644
|
||||
--- a/plugins/sudoers/def_data.h
|
||||
+++ b/plugins/sudoers/def_data.h
|
||||
@@ -226,6 +226,8 @@
|
||||
#define def_case_insensitive_user (sudo_defs_table[I_CASE_INSENSITIVE_USER].sd_un.flag)
|
||||
#define I_CASE_INSENSITIVE_GROUP 113
|
||||
#define def_case_insensitive_group (sudo_defs_table[I_CASE_INSENSITIVE_GROUP].sd_un.flag)
|
||||
+#define I_RUNAS_ALLOW_UNKNOWN_ID 114
|
||||
+#define def_runas_allow_unknown_id (sudo_defs_table[I_RUNAS_ALLOW_UNKNOWN_ID].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
||||
index 99d4360..cf0eead 100644
|
||||
--- a/plugins/sudoers/def_data.in
|
||||
+++ b/plugins/sudoers/def_data.in
|
||||
@@ -357,3 +357,6 @@ case_insensitive_user
|
||||
case_insensitive_group
|
||||
T_FLAG
|
||||
"Ignore case when matching group names"
|
||||
+runas_allow_unknown_id
|
||||
+ T_FLAG
|
||||
+ "Allow the use of unknown runas user and/or group ID"
|
||||
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
|
||||
index 4c8c262..d5b1d9c 100644
|
||||
--- a/plugins/sudoers/defaults.c
|
||||
+++ b/plugins/sudoers/defaults.c
|
||||
@@ -574,6 +574,7 @@ init_defaults(void)
|
||||
def_sudoedit_checkdir = true;
|
||||
def_iolog_mode = S_IRUSR|S_IWUSR;
|
||||
def_fdexec = digest_only;
|
||||
+ def_runas_allow_unknown_id = false;
|
||||
|
||||
/* Syslog options need special care since they both strings and ints */
|
||||
#if (LOGGING & SLOG_SYSLOG)
|
||||
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
|
||||
index 1267949..b393d70 100644
|
||||
--- a/plugins/sudoers/sudoers.c
|
||||
+++ b/plugins/sudoers/sudoers.c
|
||||
@@ -101,6 +101,8 @@ 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;
|
||||
|
||||
#ifdef __linux__
|
||||
static struct rlimit nproclimit;
|
||||
@@ -332,6 +334,22 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
}
|
||||
}
|
||||
|
||||
+ /* Defer uid/gid checks until after defaults have been updated. */
|
||||
+ if (unknown_runas_uid && !def_runas_allow_unknown_id) {
|
||||
+ audit_failure(NewArgc, NewArgv, N_("unknown user: %s"),
|
||||
+ runas_pw->pw_name);
|
||||
+ sudo_warnx(U_("unknown user: %s"), runas_pw->pw_name);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (runas_gr != NULL) {
|
||||
+ if (unknown_runas_gid && !def_runas_allow_unknown_id) {
|
||||
+ audit_failure(NewArgc, NewArgv, N_("unknown group: %s"),
|
||||
+ runas_gr->gr_name);
|
||||
+ sudo_warnx(U_("unknown group: %s"), runas_gr->gr_name);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Look up the timestamp dir owner if one is specified.
|
||||
*/
|
||||
@@ -1124,12 +1142,15 @@ set_runaspw(const char *user, bool quiet)
|
||||
struct passwd *pw = NULL;
|
||||
debug_decl(set_runaspw, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
+ unknown_runas_uid = false;
|
||||
if (*user == '#') {
|
||||
const char *errstr;
|
||||
uid_t uid = sudo_strtoid(user + 1, NULL, NULL, &errstr);
|
||||
if (errstr == NULL) {
|
||||
- if ((pw = sudo_getpwuid(uid)) == NULL)
|
||||
+ if ((pw = sudo_getpwuid(uid)) == NULL){
|
||||
+ unknown_runas_uid = true;
|
||||
pw = sudo_fakepwnam(user, user_gid);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (pw == NULL) {
|
||||
@@ -1155,12 +1176,15 @@ set_runasgr(const char *group, bool quiet)
|
||||
struct group *gr = NULL;
|
||||
debug_decl(set_runasgr, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
+ unknown_runas_gid = false;
|
||||
if (*group == '#') {
|
||||
const char *errstr;
|
||||
gid_t gid = sudo_strtoid(group + 1, NULL, NULL, &errstr);
|
||||
if (errstr == NULL) {
|
||||
- if ((gr = sudo_getgrgid(gid)) == NULL)
|
||||
+ if ((gr = sudo_getgrgid(gid)) == NULL) {
|
||||
+ unknown_runas_gid = true;
|
||||
gr = sudo_fakegrnam(group);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
if (gr == NULL) {
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,485 +0,0 @@
|
||||
From 1078336fb8769eb9e022d088f5b2db443bb775d6 Mon Sep 17 00:00:00 2001
|
||||
From: Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
Date: Mon, 09 Dec 2019 19:29:45 -0700
|
||||
Subject: [PATCH] Fix CVE-2019-19234
|
||||
|
||||
Add runas_check_shell flag to require a runas user to have a valid shell.
|
||||
Not enabled by default.
|
||||
---
|
||||
MANIFEST | 1 +
|
||||
config.h.in | 3 +
|
||||
configure | 26 +++++++++
|
||||
configure.ac | 6 +-
|
||||
doc/sudoers.man.in | 22 +++++++
|
||||
doc/sudoers.mdoc.in | 20 +++++++
|
||||
include/sudo_compat.h | 11 ++++
|
||||
lib/util/Makefile.in | 12 ++++
|
||||
lib/util/getusershell.c | 138 ++++++++++++++++++++++++++++++++++++++++++++
|
||||
mkdep.pl | 2 +-
|
||||
plugins/sudoers/check.c | 25 ++++++++
|
||||
plugins/sudoers/def_data.c | 4 ++
|
||||
plugins/sudoers/def_data.h | 2 +
|
||||
plugins/sudoers/def_data.in | 3 +
|
||||
plugins/sudoers/sudoers.c | 7 +++
|
||||
plugins/sudoers/sudoers.h | 1 +
|
||||
16 files changed, 281 insertions(+), 2 deletions(-)
|
||||
create mode 100644 lib/util/getusershell.c
|
||||
|
||||
diff --git a/MANIFEST b/MANIFEST
|
||||
index 08d7f25..d883174 100644
|
||||
--- a/MANIFEST
|
||||
+++ b/MANIFEST
|
||||
@@ -111,6 +111,7 @@ lib/util/gethostname.c
|
||||
lib/util/getline.c
|
||||
lib/util/getopt_long.c
|
||||
lib/util/gettime.c
|
||||
+lib/util/getusershell.c
|
||||
lib/util/gidlist.c
|
||||
lib/util/glob.c
|
||||
lib/util/inet_ntop.c
|
||||
diff --git a/config.h.in b/config.h.in
|
||||
index 9b83b12..c65a6f7 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -337,6 +337,9 @@
|
||||
/* Define to 1 if you have the `getuserattr' function. */
|
||||
#undef HAVE_GETUSERATTR
|
||||
|
||||
+/* Define to 1 if you have the `getusershell' function. */
|
||||
+#undef HAVE_GETUSERSHELL
|
||||
+
|
||||
/* Define to 1 if you have the `getutid' function. */
|
||||
#undef HAVE_GETUTID
|
||||
|
||||
diff --git a/configure b/configure
|
||||
index e1b5dbb..658768e 100755
|
||||
--- a/configure
|
||||
+++ b/configure
|
||||
@@ -19418,6 +19418,32 @@ done
|
||||
fi
|
||||
done
|
||||
|
||||
+for ac_func in getusershell
|
||||
+do :
|
||||
+ ac_fn_c_check_func "$LINENO" "getusershell" "ac_cv_func_getusershell"
|
||||
+if test "x$ac_cv_func_getusershell" = xyes; then :
|
||||
+ cat >>confdefs.h <<_ACEOF
|
||||
+#define HAVE_GETUSERSHELL 1
|
||||
+_ACEOF
|
||||
+
|
||||
+else
|
||||
+
|
||||
+ case " $LIBOBJS " in
|
||||
+ *" getusershell.$ac_objext "* ) ;;
|
||||
+ *) LIBOBJS="$LIBOBJS getusershell.$ac_objext"
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+
|
||||
+ for _sym in sudo_getusershell; do
|
||||
+ COMPAT_EXP="${COMPAT_EXP}${_sym}
|
||||
+"
|
||||
+ done
|
||||
+
|
||||
+
|
||||
+fi
|
||||
+done
|
||||
+
|
||||
for ac_func in reallocarray
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 962a032..c6d6c55 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1,7 +1,7 @@
|
||||
dnl
|
||||
dnl Use the top-level autogen.sh script to generate configure and config.h.in
|
||||
dnl
|
||||
-dnl Copyright (c) 1994-1996,1998-2018 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
+dnl Copyright (c) 1994-1996,1998-2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
dnl
|
||||
AC_PREREQ([2.59])
|
||||
AC_INIT([sudo], [1.8.27], [https://bugzilla.sudo.ws/], [sudo])
|
||||
@@ -2839,6 +2839,10 @@ AC_CHECK_FUNCS([vsyslog], [], [
|
||||
SUDO_APPEND_COMPAT_EXP(sudo_vsyslog)
|
||||
COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }vsyslog_test"
|
||||
])
|
||||
+AC_CHECK_FUNCS([getusershell], [], [
|
||||
+ AC_LIBOBJ(getusershell)
|
||||
+ SUDO_APPEND_COMPAT_EXP(sudo_getusershell)
|
||||
+])
|
||||
dnl
|
||||
dnl 4.4BSD-based systems can force the password or group file to be held open
|
||||
dnl
|
||||
diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in
|
||||
index 45a600f..8a97a55 100644
|
||||
--- a/doc/sudoers.man.in
|
||||
+++ b/doc/sudoers.man.in
|
||||
@@ -2886,6 +2886,28 @@ Older versions of
|
||||
\fBsudo\fR
|
||||
always allowed matching of unknown user and group IDs.
|
||||
.TP 18n
|
||||
+runas_check_shell
|
||||
+.br
|
||||
+If enabled,
|
||||
+\fBsudo\fR
|
||||
+will only run commands as a user whose shell appears in the
|
||||
+\fI/etc/shells\fR
|
||||
+file, even if the invoking user's
|
||||
+\fRRunas_List\fR
|
||||
+would otherwise permit it.
|
||||
+If no
|
||||
+\fI/etc/shells\fR
|
||||
+file is present, a system-dependent list of built-in default shells is used.
|
||||
+On many operating systems, system users such as
|
||||
+\(lqbin\(rq,
|
||||
+do not have a valid shell and this flag can be used to prevent
|
||||
+commands from being run as those users.
|
||||
+This flag is
|
||||
+\fIoff\fR
|
||||
+by default.
|
||||
+.sp
|
||||
+This setting is only supported by version 1.8.30 or higher.
|
||||
+.TP 18n
|
||||
runaspw
|
||||
If set,
|
||||
\fBsudo\fR
|
||||
diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
|
||||
index 6a511d9..ec7ed4f 100644
|
||||
--- a/doc/sudoers.mdoc.in
|
||||
+++ b/doc/sudoers.mdoc.in
|
||||
@@ -2714,6 +2714,26 @@ This setting is only supported by version 1.8.30 or higher.
|
||||
Older versions of
|
||||
.Nm sudo
|
||||
always allowed matching of unknown user and group IDs.
|
||||
+.It runas_check_shell
|
||||
+If enabled,
|
||||
+.Nm sudo
|
||||
+will only run commands as a user whose shell appears in the
|
||||
+.Pa /etc/shells
|
||||
+file, even if the invoking user's
|
||||
+.Li Runas_List
|
||||
+would otherwise permit it.
|
||||
+If no
|
||||
+.Pa /etc/shells
|
||||
+file is present, a system-dependent list of built-in default shells is used.
|
||||
+On many operating systems, system users such as
|
||||
+.Dq bin ,
|
||||
+do not have a valid shell and this flag can be used to prevent
|
||||
+commands from being run as those users.
|
||||
+This flag is
|
||||
+.Em off
|
||||
+by default.
|
||||
+.Pp
|
||||
+This setting is only supported by version 1.8.30 or higher.
|
||||
.It runaspw
|
||||
If set,
|
||||
.Nm sudo
|
||||
diff --git a/include/sudo_compat.h b/include/sudo_compat.h
|
||||
index 5c32840..3faa167 100644
|
||||
--- a/include/sudo_compat.h
|
||||
+++ b/include/sudo_compat.h
|
||||
@@ -409,6 +409,17 @@ __dso_public ssize_t sudo_getline(char **bufp, size_t *bufsizep, FILE *fp);
|
||||
# undef getline
|
||||
# define getline(_a, _b, _c) sudo_getline((_a), (_b), (_c))
|
||||
#endif /* HAVE_GETLINE */
|
||||
+#ifndef HAVE_GETUSERSHELL
|
||||
+__dso_public char *sudo_getusershell(void);
|
||||
+# undef getusershell
|
||||
+# define getusershell() sudo_getusershell()
|
||||
+__dso_public void sudo_setusershell(void);
|
||||
+# undef setusershell
|
||||
+# define setusershell() sudo_setusershell()
|
||||
+__dso_public void sudo_endusershell(void);
|
||||
+# undef endusershell
|
||||
+# define endusershell() sudo_endusershell()
|
||||
+#endif /* HAVE_GETUSERSHELL */
|
||||
#ifndef HAVE_UTIMENSAT
|
||||
__dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
|
||||
# undef utimensat
|
||||
diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in
|
||||
index cadfcf2..aa21ac9 100644
|
||||
--- a/lib/util/Makefile.in
|
||||
+++ b/lib/util/Makefile.in
|
||||
@@ -630,6 +630,18 @@ gettime.i: $(srcdir)/gettime.c $(incdir)/compat/stdbool.h \
|
||||
$(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
gettime.plog: gettime.i
|
||||
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gettime.c --i-file $< --output-file $@
|
||||
+getusershell.lo: $(srcdir)/getusershell.c $(incdir)/compat/stdbool.h \
|
||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
|
||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
+ $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getusershell.c
|
||||
+getusershell.i: $(srcdir)/getusershell.c $(incdir)/compat/stdbool.h \
|
||||
+ $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
+ $(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
|
||||
+ $(incdir)/sudo_util.h $(top_builddir)/config.h
|
||||
+ $(CC) -E -o $@ $(CPPFLAGS) $<
|
||||
+getusershell.plog: getusershell.i
|
||||
+ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getusershell.c --i-file $< --output-file $@
|
||||
gidlist.lo: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \
|
||||
$(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \
|
||||
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
|
||||
diff --git a/lib/util/getusershell.c b/lib/util/getusershell.c
|
||||
new file mode 100644
|
||||
index 0000000..6aeae3b
|
||||
--- /dev/null
|
||||
+++ b/lib/util/getusershell.c
|
||||
@@ -0,0 +1,138 @@
|
||||
+/*
|
||||
+ * SPDX-License-Identifier: ISC
|
||||
+ *
|
||||
+ * Copyright (c) 2019 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
+ *
|
||||
+ * Permission to use, copy, modify, and distribute this software for any
|
||||
+ * purpose with or without fee is hereby granted, provided that the above
|
||||
+ * copyright notice and this permission notice appear in all copies.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * This is an open source non-commercial project. Dear PVS-Studio, please check it.
|
||||
+ * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#define DEFAULT_TEXT_DOMAIN "sudo"
|
||||
+#include "sudo_gettext.h" /* must be included before sudo_compat.h */
|
||||
+
|
||||
+#include "sudo_compat.h"
|
||||
+#include "sudo_debug.h"
|
||||
+#include "sudo_util.h"
|
||||
+
|
||||
+static char **allowed_shells, **current_shell;
|
||||
+static char *default_shells[] = {
|
||||
+ "/bin/sh",
|
||||
+ "/bin/ksh",
|
||||
+ "/bin/ksh93",
|
||||
+ "/bin/bash",
|
||||
+ "/bin/dash",
|
||||
+ "/bin/zsh",
|
||||
+ "/bin/csh",
|
||||
+ "/bin/tcsh",
|
||||
+ NULL
|
||||
+};
|
||||
+
|
||||
+static char **
|
||||
+read_shells(void)
|
||||
+{
|
||||
+ size_t maxshells = 16, nshells = 0;
|
||||
+ size_t linesize = 0;
|
||||
+ char *line = NULL;
|
||||
+ FILE *fp;
|
||||
+ debug_decl(read_shells, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if ((fp = fopen("/etc/shells", "r")) == NULL)
|
||||
+ goto bad;
|
||||
+
|
||||
+ free(allowed_shells);
|
||||
+ allowed_shells = reallocarray(NULL, maxshells, sizeof(char *));
|
||||
+ if (allowed_shells == NULL)
|
||||
+ goto bad;
|
||||
+
|
||||
+ while (sudo_parseln(&line, &linesize, NULL, fp, PARSELN_CONT_IGN) != -1) {
|
||||
+ if (nshells + 1 >= maxshells) {
|
||||
+ char **new_shells;
|
||||
+
|
||||
+ new_shells = reallocarray(NULL, maxshells + 16, sizeof(char *));
|
||||
+ if (new_shells == NULL)
|
||||
+ goto bad;
|
||||
+ allowed_shells = new_shells;
|
||||
+ maxshells += 16;
|
||||
+ }
|
||||
+ if ((allowed_shells[nshells] = strdup(line)) == NULL)
|
||||
+ goto bad;
|
||||
+ nshells++;
|
||||
+ }
|
||||
+ allowed_shells[nshells] = NULL;
|
||||
+
|
||||
+ free(line);
|
||||
+ fclose(fp);
|
||||
+ debug_return_ptr(allowed_shells);
|
||||
+bad:
|
||||
+ free(line);
|
||||
+ if (fp != NULL)
|
||||
+ fclose(fp);
|
||||
+ while (nshells != 0)
|
||||
+ free(allowed_shells[--nshells]);
|
||||
+ free(allowed_shells);
|
||||
+ allowed_shells = NULL;
|
||||
+ debug_return_ptr(default_shells);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sudo_setusershell(void)
|
||||
+{
|
||||
+ debug_decl(setusershell, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ current_shell = read_shells();
|
||||
+
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sudo_endusershell(void)
|
||||
+{
|
||||
+ debug_decl(endusershell, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if (allowed_shells != NULL) {
|
||||
+ char **shell;
|
||||
+
|
||||
+ for (shell = allowed_shells; *shell != NULL; shell++)
|
||||
+ free(*shell);
|
||||
+ free(allowed_shells);
|
||||
+ allowed_shells = NULL;
|
||||
+ }
|
||||
+ current_shell = NULL;
|
||||
+
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
+char *
|
||||
+sudo_getusershell(void)
|
||||
+{
|
||||
+ debug_decl(getusershell, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if (current_shell == NULL)
|
||||
+ current_shell = read_shells();
|
||||
+
|
||||
+ debug_return_str(*current_shell++);
|
||||
+}
|
||||
diff --git a/mkdep.pl b/mkdep.pl
|
||||
index 2040320..02b5f41 100755
|
||||
--- a/mkdep.pl
|
||||
+++ b/mkdep.pl
|
||||
@@ -112,7 +112,7 @@ sub mkdep {
|
||||
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
|
||||
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
|
||||
$makefile =~ s:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:;
|
||||
- $makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo pipe2.lo:;
|
||||
+ $makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getline.lo getopt_long.lo getusershell.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo pipe2.lo:;
|
||||
|
||||
# Parse OBJS lines
|
||||
my %objs;
|
||||
diff --git a/plugins/sudoers/check.c b/plugins/sudoers/check.c
|
||||
index 92f859c..31d2615 100644
|
||||
--- a/plugins/sudoers/check.c
|
||||
+++ b/plugins/sudoers/check.c
|
||||
@@ -331,3 +331,28 @@ get_authpw(int mode)
|
||||
|
||||
debug_return_ptr(pw);
|
||||
}
|
||||
+
|
||||
+/*
|
||||
+ * Returns true if the specified shell is allowed by /etc/shells, else false.
|
||||
+ */
|
||||
+bool
|
||||
+check_user_shell(const struct passwd *pw)
|
||||
+{
|
||||
+ const char *shell;
|
||||
+ debug_decl(check_user_shell, SUDOERS_DEBUG_AUTH)
|
||||
+
|
||||
+ if (!def_runas_check_shell)
|
||||
+ debug_return_bool(true);
|
||||
+
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "%s: checking /etc/shells for %s", __func__, pw->pw_shell);
|
||||
+
|
||||
+ setusershell();
|
||||
+ while ((shell = getusershell()) != NULL) {
|
||||
+ if (strcmp(shell, pw->pw_shell) == 0)
|
||||
+ debug_return_bool(true);
|
||||
+ }
|
||||
+ endusershell();
|
||||
+
|
||||
+ debug_return_bool(false);
|
||||
+}
|
||||
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
||||
index 97eaf79..7b111f8 100644
|
||||
--- a/plugins/sudoers/def_data.c
|
||||
+++ b/plugins/sudoers/def_data.c
|
||||
@@ -498,6 +498,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
N_("Allow the use of unknown runas user and/or group ID"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "runas_check_shell", T_FLAG,
|
||||
+ N_("Only permit running commands as a user with a valid shell"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
||||
index 55878c9..50725e6 100644
|
||||
--- a/plugins/sudoers/def_data.h
|
||||
+++ b/plugins/sudoers/def_data.h
|
||||
@@ -228,6 +228,8 @@
|
||||
#define def_case_insensitive_group (sudo_defs_table[I_CASE_INSENSITIVE_GROUP].sd_un.flag)
|
||||
#define I_RUNAS_ALLOW_UNKNOWN_ID 114
|
||||
#define def_runas_allow_unknown_id (sudo_defs_table[I_RUNAS_ALLOW_UNKNOWN_ID].sd_un.flag)
|
||||
+#define I_RUNAS_CHECK_SHELL 115
|
||||
+#define def_runas_check_shell (sudo_defs_table[I_RUNAS_CHECK_SHELL].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
||||
index cf0eead..bb81d8b 100644
|
||||
--- a/plugins/sudoers/def_data.in
|
||||
+++ b/plugins/sudoers/def_data.in
|
||||
@@ -360,3 +360,6 @@ case_insensitive_group
|
||||
runas_allow_unknown_id
|
||||
T_FLAG
|
||||
"Allow the use of unknown runas user and/or group ID"
|
||||
+runas_check_shell
|
||||
+ T_FLAG
|
||||
+ "Only permit running commands as a user with a valid shell"
|
||||
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
|
||||
index b393d70..a791942 100644
|
||||
--- a/plugins/sudoers/sudoers.c
|
||||
+++ b/plugins/sudoers/sudoers.c
|
||||
@@ -390,6 +390,13 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
||||
goto bad;
|
||||
}
|
||||
|
||||
+ /* Check runas user's shell. */
|
||||
+ if (!check_user_shell(runas_pw)) {
|
||||
+ log_warningx(SLOG_RAW_MSG, N_("invalid shell for user %s: %s"),
|
||||
+ runas_pw->pw_name, runas_pw->pw_shell);
|
||||
+ goto bad;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* We don't reset the environment for sudoedit or if the user
|
||||
* specified the -E command line flag and they have setenv privs.
|
||||
diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
|
||||
index 28dbbb3..d33c4ef 100644
|
||||
--- a/plugins/sudoers/sudoers.h
|
||||
+++ b/plugins/sudoers/sudoers.h
|
||||
@@ -250,6 +250,7 @@ int find_path(const char *infile, char **outfile, struct stat *sbp,
|
||||
|
||||
/* check.c */
|
||||
int check_user(int validate, int mode);
|
||||
+bool check_user_shell(const struct passwd *pw);
|
||||
bool user_is_exempt(void);
|
||||
|
||||
/* prompt.c */
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
@ -1,96 +0,0 @@
|
||||
diff -r fcd7a6d8330e lib/util/regress/atofoo/atofoo_test.c
|
||||
--- a/lib/util/regress/atofoo/atofoo_test.c Fri Jan 11 13:31:15 2019 -0700
|
||||
+++ b/lib/util/regress/atofoo/atofoo_test.c Thu Oct 10 14:02:30 2019 -0600
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2014 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
+ * Copyright (c) 2014-2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -24,6 +24,7 @@
|
||||
#else
|
||||
# include "compat/stdbool.h"
|
||||
#endif
|
||||
+#include <errno.h>
|
||||
|
||||
#include "sudo_compat.h"
|
||||
#include "sudo_util.h"
|
||||
@@ -78,15 +79,20 @@ static struct strtoid_data {
|
||||
id_t id;
|
||||
const char *sep;
|
||||
const char *ep;
|
||||
+ int errnum;
|
||||
} strtoid_data[] = {
|
||||
- { "0,1", 0, ",", "," },
|
||||
- { "10", 10, NULL, NULL },
|
||||
- { "-2", -2, NULL, NULL },
|
||||
+ { "0,1", 0, ",", ",", 0 },
|
||||
+ { "10", 10, NULL, NULL, 0 },
|
||||
+ { "-1", 0, NULL, NULL, EINVAL },
|
||||
+ { "4294967295", 0, NULL, NULL, EINVAL },
|
||||
+ { "4294967296", 0, NULL, NULL, ERANGE },
|
||||
+ { "-2147483649", 0, NULL, NULL, ERANGE },
|
||||
+ { "-2", -2, NULL, NULL, 0 },
|
||||
#if SIZEOF_ID_T != SIZEOF_LONG_LONG
|
||||
- { "-2", (id_t)4294967294U, NULL, NULL },
|
||||
+ { "-2", (id_t)4294967294U, NULL, NULL, 0 },
|
||||
#endif
|
||||
- { "4294967294", (id_t)4294967294U, NULL, NULL },
|
||||
- { NULL, 0, NULL, NULL }
|
||||
+ { "4294967294", (id_t)4294967294U, NULL, NULL, 0 },
|
||||
+ { NULL, 0, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -102,11 +108,23 @@ test_strtoid(int *ntests)
|
||||
(*ntests)++;
|
||||
errstr = "some error";
|
||||
value = sudo_strtoid(d->idstr, d->sep, &ep, &errstr);
|
||||
- if (errstr != NULL) {
|
||||
- if (d->id != (id_t)-1) {
|
||||
- sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
|
||||
+ if (d->errnum != 0) {
|
||||
+ if (errstr == NULL) {
|
||||
+ sudo_warnx_nodebug("FAIL: %s: missing errstr for errno %d",
|
||||
+ d->idstr, d->errnum);
|
||||
+ errors++;
|
||||
+ } else if (value != 0) {
|
||||
+ sudo_warnx_nodebug("FAIL: %s should return 0 on error",
|
||||
+ d->idstr);
|
||||
+ errors++;
|
||||
+ } else if (errno != d->errnum) {
|
||||
+ sudo_warnx_nodebug("FAIL: %s: errno mismatch, %d != %d",
|
||||
+ d->idstr, errno, d->errnum);
|
||||
errors++;
|
||||
}
|
||||
+ } else if (errstr != NULL) {
|
||||
+ sudo_warnx_nodebug("FAIL: %s: %s", d->idstr, errstr);
|
||||
+ errors++;
|
||||
} else if (value != d->id) {
|
||||
sudo_warnx_nodebug("FAIL: %s != %u", d->idstr, (unsigned int)d->id);
|
||||
errors++;
|
||||
diff -r fcd7a6d8330e plugins/sudoers/regress/testsudoers/test5.out.ok
|
||||
--- a/plugins/sudoers/regress/testsudoers/test5.out.ok Fri Jan 11 13:31:15 2019 -0700
|
||||
+++ b/plugins/sudoers/regress/testsudoers/test5.out.ok Thu Oct 10 14:02:30 2019 -0600
|
||||
@@ -4,7 +4,7 @@ Parse error in sudoers near line 1.
|
||||
Entries for user root:
|
||||
|
||||
Command unmatched
|
||||
-testsudoers: test5.inc should be owned by gid 4294967295
|
||||
+testsudoers: test5.inc should be owned by gid 4294967294
|
||||
Parse error in sudoers near line 1.
|
||||
|
||||
Entries for user root:
|
||||
diff -r fcd7a6d8330e plugins/sudoers/regress/testsudoers/test5.sh
|
||||
--- a/plugins/sudoers/regress/testsudoers/test5.sh Fri Jan 11 13:31:15 2019 -0700
|
||||
+++ b/plugins/sudoers/regress/testsudoers/test5.sh Thu Oct 10 14:02:30 2019 -0600
|
||||
@@ -24,7 +24,7 @@ EOF
|
||||
|
||||
# Test group writable
|
||||
chmod 664 $TESTFILE
|
||||
-./testsudoers -U $MYUID -G -1 root id <<EOF
|
||||
+./testsudoers -U $MYUID -G -2 root id <<EOF
|
||||
#include $TESTFILE
|
||||
EOF
|
||||
|
||||
Binary file not shown.
BIN
sudo-1.9.2.tar.gz
Normal file
BIN
sudo-1.9.2.tar.gz
Normal file
Binary file not shown.
17
sudo.spec
17
sudo.spec
@ -1,6 +1,6 @@
|
||||
Name: sudo
|
||||
Version: 1.8.27
|
||||
Release: 5
|
||||
Version: 1.9.2
|
||||
Release: 1
|
||||
Summary: Allows restricted root access for specified users
|
||||
License: ISC
|
||||
URL: http://www.courtesan.com/sudo/
|
||||
@ -10,11 +10,6 @@ Source1: sudoers
|
||||
Source2: sudo
|
||||
Source3: sudo-i
|
||||
|
||||
Patch6000: sudo_minus_1_uid.patch
|
||||
Patch6001: strtoid_minus_1_test_fix.patch
|
||||
Patch6002: Fix-CVE-2019-19232-control-matching-of-unknown-IDs.patch
|
||||
Patch6003: Fix-CVE-2019-19234-add-runas_check_shell-flag.patch
|
||||
|
||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
Requires: pam
|
||||
Recommends: vim-minimal
|
||||
@ -51,6 +46,8 @@ export CFLAGS="$RPM_OPT_FLAGS -fpie" LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now"
|
||||
--libdir=%{_libdir} \
|
||||
--docdir=%{_pkgdocdir} \
|
||||
--disable-root-mailer \
|
||||
--disable-log-server \
|
||||
--disable-log-client \
|
||||
--with-logging=syslog \
|
||||
--with-logfac=authpriv \
|
||||
--with-pam \
|
||||
@ -117,6 +114,7 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i
|
||||
%attr(0750,root,root) %dir /etc/sudoers.d/
|
||||
%attr(0644,root,root) %{_tmpfilesdir}/sudo.conf
|
||||
%attr(0644,root,root) /etc/dnf/protected.d/sudo.conf
|
||||
%attr(0640,root,root) /etc/sudo.conf
|
||||
%attr(4111,root,root) %{_bindir}/sudo
|
||||
%attr(0111,root,root) %{_bindir}/sudoreplay
|
||||
%{_bindir}/sudoedit
|
||||
@ -127,6 +125,8 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i
|
||||
%attr(0644,root,root) %{_libexecdir}/sudo/sudoers.so
|
||||
%attr(0644,root,root) %{_libexecdir}/sudo/group_file.so
|
||||
%attr(0644,root,root) %{_libexecdir}/sudo/system_group.so
|
||||
%attr(0644,root,root) %{_libexecdir}/sudo/audit_json.so
|
||||
%attr(0644,root,root) %{_libexecdir}/sudo/sample_approval.so
|
||||
%attr(0644,root,root) %{_libexecdir}/sudo/libsudo_util.so*
|
||||
%dir /var/db/sudo
|
||||
%dir /var/db/sudo/lectured
|
||||
@ -149,6 +149,9 @@ install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT/etc/pam.d/sudo-i
|
||||
%exclude %{_pkgdocdir}/ChangeLog
|
||||
|
||||
%changelog
|
||||
* Wed Jul 29 2020 zhangxingliang <zhangxingliang3@huawei.com> - 1.9.2-1
|
||||
- update to 1.9.2
|
||||
|
||||
* Fri Apr 17 2020 Anakin Zhang <nbztx@126.com> - 1.8.27-5
|
||||
- Read drop-in files from /etc/sudoers.d
|
||||
|
||||
|
||||
@ -1,172 +0,0 @@
|
||||
Treat an ID of -1 as invalid since that means "no change".
|
||||
Fixes CVE-2019-14287.
|
||||
Found by Joe Vennix from Apple Information Security.
|
||||
|
||||
diff -r fcd7a6d8330e lib/util/strtoid.c
|
||||
--- a/lib/util/strtoid.c Fri Jan 11 13:31:15 2019 -0700
|
||||
+++ b/lib/util/strtoid.c Thu Oct 10 09:52:12 2019 -0600
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2013-2016 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
+ * Copyright (c) 2013-2019 Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@@ -47,6 +47,27 @@
|
||||
#include "sudo_util.h"
|
||||
|
||||
/*
|
||||
+ * Make sure that the ID ends with a valid separator char.
|
||||
+ */
|
||||
+static bool
|
||||
+valid_separator(const char *p, const char *ep, const char *sep)
|
||||
+{
|
||||
+ bool valid = false;
|
||||
+ debug_decl(valid_separator, SUDO_DEBUG_UTIL)
|
||||
+
|
||||
+ if (ep != p) {
|
||||
+ /* check for valid separator (including '\0') */
|
||||
+ if (sep == NULL)
|
||||
+ sep = "";
|
||||
+ do {
|
||||
+ if (*ep == *sep)
|
||||
+ valid = true;
|
||||
+ } while (*sep++ != '\0');
|
||||
+ }
|
||||
+ debug_return_bool(valid);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Parse a uid/gid in string form.
|
||||
* If sep is non-NULL, it contains valid separator characters (e.g. comma, space)
|
||||
* If endp is non-NULL it is set to the next char after the ID.
|
||||
@@ -60,38 +81,35 @@ sudo_strtoid_v1(const char *p, const cha
|
||||
char *ep;
|
||||
id_t ret = 0;
|
||||
long long llval;
|
||||
- bool valid = false;
|
||||
debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
|
||||
|
||||
/* skip leading space so we can pick up the sign, if any */
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
- if (sep == NULL)
|
||||
- sep = "";
|
||||
+
|
||||
+ /* While id_t may be 64-bit signed, uid_t and gid_t are 32-bit unsigned. */
|
||||
errno = 0;
|
||||
llval = strtoll(p, &ep, 10);
|
||||
- if (ep != p) {
|
||||
- /* check for valid separator (including '\0') */
|
||||
- do {
|
||||
- if (*ep == *sep)
|
||||
- valid = true;
|
||||
- } while (*sep++ != '\0');
|
||||
+ if ((errno == ERANGE && llval == LLONG_MAX) || llval > (id_t)UINT_MAX) {
|
||||
+ errno = ERANGE;
|
||||
+ if (errstr != NULL)
|
||||
+ *errstr = N_("value too large");
|
||||
+ goto done;
|
||||
}
|
||||
- if (!valid) {
|
||||
+ if ((errno == ERANGE && llval == LLONG_MIN) || llval < INT_MIN) {
|
||||
+ errno = ERANGE;
|
||||
+ if (errstr != NULL)
|
||||
+ *errstr = N_("value too small");
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* Disallow id -1, which means "no change". */
|
||||
+ if (!valid_separator(p, ep, sep) || llval == -1 || llval == (id_t)UINT_MAX) {
|
||||
if (errstr != NULL)
|
||||
*errstr = N_("invalid value");
|
||||
errno = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
- if (errno == ERANGE) {
|
||||
- if (errstr != NULL) {
|
||||
- if (llval == LLONG_MAX)
|
||||
- *errstr = N_("value too large");
|
||||
- else
|
||||
- *errstr = N_("value too small");
|
||||
- }
|
||||
- goto done;
|
||||
- }
|
||||
ret = (id_t)llval;
|
||||
if (errstr != NULL)
|
||||
*errstr = NULL;
|
||||
@@ -106,30 +124,15 @@ sudo_strtoid_v1(const char *p, const cha
|
||||
{
|
||||
char *ep;
|
||||
id_t ret = 0;
|
||||
- bool valid = false;
|
||||
debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL)
|
||||
|
||||
/* skip leading space so we can pick up the sign, if any */
|
||||
while (isspace((unsigned char)*p))
|
||||
p++;
|
||||
- if (sep == NULL)
|
||||
- sep = "";
|
||||
+
|
||||
errno = 0;
|
||||
if (*p == '-') {
|
||||
long lval = strtol(p, &ep, 10);
|
||||
- if (ep != p) {
|
||||
- /* check for valid separator (including '\0') */
|
||||
- do {
|
||||
- if (*ep == *sep)
|
||||
- valid = true;
|
||||
- } while (*sep++ != '\0');
|
||||
- }
|
||||
- if (!valid) {
|
||||
- if (errstr != NULL)
|
||||
- *errstr = N_("invalid value");
|
||||
- errno = EINVAL;
|
||||
- goto done;
|
||||
- }
|
||||
if ((errno == ERANGE && lval == LONG_MAX) || lval > INT_MAX) {
|
||||
errno = ERANGE;
|
||||
if (errstr != NULL)
|
||||
@@ -142,28 +145,31 @@ sudo_strtoid_v1(const char *p, const cha
|
||||
*errstr = N_("value too small");
|
||||
goto done;
|
||||
}
|
||||
- ret = (id_t)lval;
|
||||
- } else {
|
||||
- unsigned long ulval = strtoul(p, &ep, 10);
|
||||
- if (ep != p) {
|
||||
- /* check for valid separator (including '\0') */
|
||||
- do {
|
||||
- if (*ep == *sep)
|
||||
- valid = true;
|
||||
- } while (*sep++ != '\0');
|
||||
- }
|
||||
- if (!valid) {
|
||||
+
|
||||
+ /* Disallow id -1, which means "no change". */
|
||||
+ if (!valid_separator(p, ep, sep) || lval == -1) {
|
||||
if (errstr != NULL)
|
||||
*errstr = N_("invalid value");
|
||||
errno = EINVAL;
|
||||
goto done;
|
||||
}
|
||||
+ ret = (id_t)lval;
|
||||
+ } else {
|
||||
+ unsigned long ulval = strtoul(p, &ep, 10);
|
||||
if ((errno == ERANGE && ulval == ULONG_MAX) || ulval > UINT_MAX) {
|
||||
errno = ERANGE;
|
||||
if (errstr != NULL)
|
||||
*errstr = N_("value too large");
|
||||
goto done;
|
||||
}
|
||||
+
|
||||
+ /* Disallow id -1, which means "no change". */
|
||||
+ if (!valid_separator(p, ep, sep) || ulval == UINT_MAX) {
|
||||
+ if (errstr != NULL)
|
||||
+ *errstr = N_("invalid value");
|
||||
+ errno = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
ret = (id_t)ulval;
|
||||
}
|
||||
if (errstr != NULL)
|
||||
77
sudoers
77
sudoers
@ -7,6 +7,45 @@
|
||||
##
|
||||
## This file must be edited with the 'visudo' command.
|
||||
|
||||
## Host Aliases
|
||||
## Groups of machines. You may prefer to use hostnames (perhaps using
|
||||
## wildcards for entire domains) or IP addresses instead.
|
||||
# Host_Alias FILESERVERS = fs1, fs2
|
||||
# Host_Alias MAILSERVERS = smtp, smtp2
|
||||
|
||||
## User Aliases
|
||||
## These aren't often necessary, as you can use regular groups
|
||||
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
|
||||
## rather than USERALIAS
|
||||
# User_Alias ADMINS = jsmith, mikem
|
||||
|
||||
|
||||
## Command Aliases
|
||||
## These are groups of related commands...
|
||||
|
||||
## Networking
|
||||
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
|
||||
|
||||
## Installation and management of software
|
||||
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
|
||||
|
||||
## Services
|
||||
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable
|
||||
|
||||
## Updating the locate database
|
||||
# Cmnd_Alias LOCATE = /usr/bin/updatedb
|
||||
|
||||
## Storage
|
||||
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
|
||||
|
||||
## Delegating permissions
|
||||
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp
|
||||
|
||||
## Processes
|
||||
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
|
||||
|
||||
## Drivers
|
||||
# Cmnd_Alias DRIVERS = /sbin/modprobe
|
||||
|
||||
# Defaults specification
|
||||
|
||||
@ -15,6 +54,24 @@
|
||||
#
|
||||
Defaults !visiblepw
|
||||
|
||||
#
|
||||
# Preserving HOME has security implications since many programs
|
||||
# use it when searching for configuration files. Note that HOME
|
||||
# is already set when the the env_reset option is enabled, so
|
||||
# this option is only effective for configurations where either
|
||||
# env_reset is disabled or HOME is present in the env_keep list.
|
||||
#
|
||||
Defaults always_set_home
|
||||
Defaults match_group_by_gid
|
||||
|
||||
# Prior to version 1.8.15, groups listed in sudoers that were not
|
||||
# found in the system group database were passed to the group
|
||||
# plugin, if any. Starting with 1.8.15, only groups of the form
|
||||
# %:group are resolved via the group plugin by default.
|
||||
# We enable always_query_group_plugin to restore old behavior.
|
||||
# Disable this option for new behavior.
|
||||
Defaults always_query_group_plugin
|
||||
|
||||
Defaults env_reset
|
||||
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE KDEDIR LS_COLORS"
|
||||
Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
|
||||
@ -22,6 +79,12 @@ Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES
|
||||
Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
|
||||
Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
|
||||
|
||||
#
|
||||
# Adding HOME to env_keep may enable a user to run unrestricted
|
||||
# commands via sudo.
|
||||
#
|
||||
# Defaults env_keep += "HOME"
|
||||
|
||||
Defaults secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
|
||||
## Next comes the main part: which users can run what software on
|
||||
@ -36,8 +99,22 @@ Defaults secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbi
|
||||
## Allow root to run any commands anywhere
|
||||
root ALL=(ALL) ALL
|
||||
|
||||
## Allows members of the 'sys' group to run networking, software,
|
||||
## service management apps and more.
|
||||
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
|
||||
|
||||
## Allows people in group wheel to run all commands
|
||||
%wheel ALL=(ALL) ALL
|
||||
|
||||
## Same thing without a password
|
||||
# %wheel ALL=(ALL) NOPASSWD: ALL
|
||||
|
||||
## Allows members of the users group to mount and unmount the
|
||||
## cdrom as root
|
||||
# %users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
|
||||
|
||||
## Allows members of the users group to shutdown this system
|
||||
# %users localhost=/sbin/shutdown -h now
|
||||
|
||||
## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
|
||||
#includedir /etc/sudoers.d
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user