sudo package update
Signed-off-by: basebuilder_pel7ppc64bebuilder0 <basebuilder@powerel.org>master
parent
9ece713570
commit
36f654311f
|
@ -0,0 +1,27 @@
|
|||
From 8a045c3880e06f5fcf69a73c4029d6725e17f7bc Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Fri, 19 Aug 2016 13:49:25 +0200
|
||||
Subject: [PATCH 01/10] We do not strip
|
||||
|
||||
rebased from:
|
||||
Patch1: sudo-1.6.7p5-strip.patch
|
||||
---
|
||||
install-sh | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/install-sh b/install-sh
|
||||
index 6944fba..49d383a 100755
|
||||
--- a/install-sh
|
||||
+++ b/install-sh
|
||||
@@ -147,7 +147,7 @@ while ${MORETODO} ; do
|
||||
fi
|
||||
;;
|
||||
X-s)
|
||||
- STRIPIT=true
|
||||
+ #STRIPIT=true
|
||||
;;
|
||||
X--)
|
||||
shift
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
From 44a602b49365969e56c63c9f12eda197e951302f Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Fri, 19 Aug 2016 14:07:35 +0200
|
||||
Subject: [PATCH 02/10] Added "Enviroment debugging" message
|
||||
|
||||
rebased from:
|
||||
Patch2: sudo-1.7.2p1-envdebug.patch
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 9feddfd..39a2d86 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -1390,7 +1390,7 @@ AC_ARG_ENABLE(env_debug,
|
||||
[AS_HELP_STRING([--enable-env-debug], [Whether to enable environment debugging.])],
|
||||
[ case "$enableval" in
|
||||
yes) AC_MSG_RESULT(yes)
|
||||
- AC_DEFINE(ENV_DEBUG)
|
||||
+ AC_DEFINE(ENV_DEBUG, [], [Environment debugging.])
|
||||
;;
|
||||
no) AC_MSG_RESULT(no)
|
||||
;;
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
From ea44d916b9dffe0f33c3c62d1677567bf64a26b8 Mon Sep 17 00:00:00 2001
|
||||
From: Radovan Sroka <rsroka@redhat.com>
|
||||
Date: Tue, 20 Sep 2016 15:07:53 +0200
|
||||
Subject: [PATCH 10/10] Fix upstream testsuite
|
||||
|
||||
---
|
||||
plugins/sudoers/regress/sudoers/test2.in | 60 ---------------------------
|
||||
plugins/sudoers/regress/sudoers/test2.in_ | 60 +++++++++++++++++++++++++++
|
||||
plugins/sudoers/regress/testsudoers/test3.sh | 13 ------
|
||||
plugins/sudoers/regress/testsudoers/test3.sh_ | 13 ++++++
|
||||
4 files changed, 73 insertions(+), 73 deletions(-)
|
||||
delete mode 100644 plugins/sudoers/regress/sudoers/test2.in
|
||||
create mode 100644 plugins/sudoers/regress/sudoers/test2.in_
|
||||
delete mode 100755 plugins/sudoers/regress/testsudoers/test3.sh
|
||||
create mode 100755 plugins/sudoers/regress/testsudoers/test3.sh_
|
||||
|
||||
diff --git a/plugins/sudoers/regress/sudoers/test2.in b/plugins/sudoers/regress/sudoers/test2.in
|
||||
deleted file mode 100644
|
||||
index cfdfaa3..0000000
|
||||
--- a/plugins/sudoers/regress/sudoers/test2.in
|
||||
+++ /dev/null
|
||||
@@ -1,60 +0,0 @@
|
||||
-# Check quoted user name in User_Alias
|
||||
-User_Alias UA1 = "foo"
|
||||
-User_Alias UA2 = "foo.bar"
|
||||
-User_Alias UA3 = "foo\""
|
||||
-User_Alias UA4 = "foo:bar"
|
||||
-User_Alias UA5 = "foo:bar\""
|
||||
-
|
||||
-# Check quoted group name in User_Alias
|
||||
-User_Alias UA6 = "%baz"
|
||||
-User_Alias UA7 = "%baz.biz"
|
||||
-
|
||||
-# Check quoted non-Unix group name in User_Alias
|
||||
-User_Alias UA8 = "%:C/non UNIX 0 c"
|
||||
-User_Alias UA9 = "%:C/non\'UNIX\'1 c"
|
||||
-User_Alias UA10 = "%:C/non\"UNIX\"0 c"
|
||||
-User_Alias UA11 = "%:C/non_UNIX_0 c"
|
||||
-User_Alias UA12 = "%:C/non\'UNIX_3 c"
|
||||
-
|
||||
-# Check quoted user name in Runas_Alias
|
||||
-Runas_Alias RA1 = "foo"
|
||||
-Runas_Alias RA2 = "foo\""
|
||||
-Runas_Alias RA3 = "foo:bar"
|
||||
-Runas_Alias RA4 = "foo:bar\""
|
||||
-
|
||||
-# Check quoted host name in Defaults
|
||||
-Defaults@"somehost" set_home
|
||||
-Defaults@"quoted\"" set_home
|
||||
-
|
||||
-# Check quoted user name in Defaults
|
||||
-Defaults:"you" set_home
|
||||
-Defaults:"us\"" set_home
|
||||
-Defaults:"%them" set_home
|
||||
-Defaults:"%: non UNIX 0 c" set_home
|
||||
-Defaults:"+net" set_home
|
||||
-
|
||||
-# Check quoted runas name in Defaults
|
||||
-Defaults>"someone" set_home
|
||||
-Defaults>"some one" set_home
|
||||
-
|
||||
-# Check quoted command in Defaults
|
||||
-# XXX - not currently supported
|
||||
-#Defaults!"/bin/ls -l" set_home
|
||||
-#Defaults!"/bin/ls -l \"foo\"" set_home
|
||||
-
|
||||
-# Check quoted user, runas and host name in Cmnd_Spec
|
||||
-"foo" "hosta" = ("root") ALL
|
||||
-"foo.bar" "hostb" = ("root") ALL
|
||||
-"foo\"" "hostc" = ("root") ALL
|
||||
-"foo:bar" "hostd" = ("root") ALL
|
||||
-"foo:bar\"" "hoste" = ("root") ALL
|
||||
-
|
||||
-# Check quoted group/netgroup name in Cmnd_Spec
|
||||
-"%baz" "hosta" = ("root") ALL
|
||||
-"%baz.biz" "hostb" = ("root") ALL
|
||||
-"%:C/non UNIX 0 c" "hostc" = ("root") ALL
|
||||
-"%:C/non\'UNIX\'1 c" "hostd" = ("root") ALL
|
||||
-"%:C/non\"UNIX\"0 c" "hoste" = ("root") ALL
|
||||
-"%:C/non_UNIX_0 c" "hostf" = ("root") ALL
|
||||
-"%:C/non\'UNIX_3 c" "hostg" = ("root") ALL
|
||||
-"+netgr" "hosth" = ("root") ALL
|
||||
diff --git a/plugins/sudoers/regress/sudoers/test2.in_ b/plugins/sudoers/regress/sudoers/test2.in_
|
||||
new file mode 100644
|
||||
index 0000000..cfdfaa3
|
||||
--- /dev/null
|
||||
+++ b/plugins/sudoers/regress/sudoers/test2.in_
|
||||
@@ -0,0 +1,60 @@
|
||||
+# Check quoted user name in User_Alias
|
||||
+User_Alias UA1 = "foo"
|
||||
+User_Alias UA2 = "foo.bar"
|
||||
+User_Alias UA3 = "foo\""
|
||||
+User_Alias UA4 = "foo:bar"
|
||||
+User_Alias UA5 = "foo:bar\""
|
||||
+
|
||||
+# Check quoted group name in User_Alias
|
||||
+User_Alias UA6 = "%baz"
|
||||
+User_Alias UA7 = "%baz.biz"
|
||||
+
|
||||
+# Check quoted non-Unix group name in User_Alias
|
||||
+User_Alias UA8 = "%:C/non UNIX 0 c"
|
||||
+User_Alias UA9 = "%:C/non\'UNIX\'1 c"
|
||||
+User_Alias UA10 = "%:C/non\"UNIX\"0 c"
|
||||
+User_Alias UA11 = "%:C/non_UNIX_0 c"
|
||||
+User_Alias UA12 = "%:C/non\'UNIX_3 c"
|
||||
+
|
||||
+# Check quoted user name in Runas_Alias
|
||||
+Runas_Alias RA1 = "foo"
|
||||
+Runas_Alias RA2 = "foo\""
|
||||
+Runas_Alias RA3 = "foo:bar"
|
||||
+Runas_Alias RA4 = "foo:bar\""
|
||||
+
|
||||
+# Check quoted host name in Defaults
|
||||
+Defaults@"somehost" set_home
|
||||
+Defaults@"quoted\"" set_home
|
||||
+
|
||||
+# Check quoted user name in Defaults
|
||||
+Defaults:"you" set_home
|
||||
+Defaults:"us\"" set_home
|
||||
+Defaults:"%them" set_home
|
||||
+Defaults:"%: non UNIX 0 c" set_home
|
||||
+Defaults:"+net" set_home
|
||||
+
|
||||
+# Check quoted runas name in Defaults
|
||||
+Defaults>"someone" set_home
|
||||
+Defaults>"some one" set_home
|
||||
+
|
||||
+# Check quoted command in Defaults
|
||||
+# XXX - not currently supported
|
||||
+#Defaults!"/bin/ls -l" set_home
|
||||
+#Defaults!"/bin/ls -l \"foo\"" set_home
|
||||
+
|
||||
+# Check quoted user, runas and host name in Cmnd_Spec
|
||||
+"foo" "hosta" = ("root") ALL
|
||||
+"foo.bar" "hostb" = ("root") ALL
|
||||
+"foo\"" "hostc" = ("root") ALL
|
||||
+"foo:bar" "hostd" = ("root") ALL
|
||||
+"foo:bar\"" "hoste" = ("root") ALL
|
||||
+
|
||||
+# Check quoted group/netgroup name in Cmnd_Spec
|
||||
+"%baz" "hosta" = ("root") ALL
|
||||
+"%baz.biz" "hostb" = ("root") ALL
|
||||
+"%:C/non UNIX 0 c" "hostc" = ("root") ALL
|
||||
+"%:C/non\'UNIX\'1 c" "hostd" = ("root") ALL
|
||||
+"%:C/non\"UNIX\"0 c" "hoste" = ("root") ALL
|
||||
+"%:C/non_UNIX_0 c" "hostf" = ("root") ALL
|
||||
+"%:C/non\'UNIX_3 c" "hostg" = ("root") ALL
|
||||
+"+netgr" "hosth" = ("root") ALL
|
||||
diff --git a/plugins/sudoers/regress/testsudoers/test3.sh b/plugins/sudoers/regress/testsudoers/test3.sh
|
||||
deleted file mode 100755
|
||||
index c1251b9..0000000
|
||||
--- a/plugins/sudoers/regress/testsudoers/test3.sh
|
||||
+++ /dev/null
|
||||
@@ -1,13 +0,0 @@
|
||||
-#!/bin/sh
|
||||
-#
|
||||
-# Test #include facility
|
||||
-#
|
||||
-
|
||||
-MYUID=`\ls -lnd $TESTDIR/test3.d | awk '{print $3}'`
|
||||
-MYGID=`\ls -lnd $TESTDIR/test3.d | awk '{print $4}'`
|
||||
-exec 2>&1
|
||||
-./testsudoers -U $MYUID -G $MYGID root id <<EOF
|
||||
-#includedir $TESTDIR/test3.d
|
||||
-EOF
|
||||
-
|
||||
-exit 0
|
||||
diff --git a/plugins/sudoers/regress/testsudoers/test3.sh_ b/plugins/sudoers/regress/testsudoers/test3.sh_
|
||||
new file mode 100755
|
||||
index 0000000..c1251b9
|
||||
--- /dev/null
|
||||
+++ b/plugins/sudoers/regress/testsudoers/test3.sh_
|
||||
@@ -0,0 +1,13 @@
|
||||
+#!/bin/sh
|
||||
+#
|
||||
+# Test #include facility
|
||||
+#
|
||||
+
|
||||
+MYUID=`\ls -lnd $TESTDIR/test3.d | awk '{print $3}'`
|
||||
+MYGID=`\ls -lnd $TESTDIR/test3.d | awk '{print $4}'`
|
||||
+exec 2>&1
|
||||
+./testsudoers -U $MYUID -G $MYGID root id <<EOF
|
||||
+#includedir $TESTDIR/test3.d
|
||||
+EOF
|
||||
+
|
||||
+exit 0
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
diff --git a/src/ttyname.c b/src/ttyname.c
|
||||
index ff2cacc..013be95 100644
|
||||
--- a/src/ttyname.c
|
||||
+++ b/src/ttyname.c
|
||||
@@ -477,26 +477,38 @@ done:
|
||||
char *
|
||||
get_process_ttyname(char *name, size_t namelen)
|
||||
{
|
||||
- char path[PATH_MAX], *line = NULL;
|
||||
+ const char path[] = "/proc/self/stat";
|
||||
+ char *cp, buf[1024];
|
||||
char *ret = NULL;
|
||||
- size_t linesize = 0;
|
||||
int serrno = errno;
|
||||
- ssize_t len;
|
||||
- FILE *fp;
|
||||
+ ssize_t nread;
|
||||
+ int fd;
|
||||
debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
|
||||
|
||||
- /* Try to determine the tty from tty_nr in /proc/pid/stat. */
|
||||
- snprintf(path, sizeof(path), "/proc/%u/stat", (unsigned int)getpid());
|
||||
- if ((fp = fopen(path, "r")) != NULL) {
|
||||
- len = getline(&line, &linesize, fp);
|
||||
- fclose(fp);
|
||||
- if (len != -1) {
|
||||
+ /*
|
||||
+ * Try to determine the tty from tty_nr in /proc/self/stat.
|
||||
+ * Ignore /proc/self/stat if it contains embedded NUL bytes.
|
||||
+ */
|
||||
+ if ((fd = open(path, O_RDONLY | O_NOFOLLOW)) != -1) {
|
||||
+ cp = buf;
|
||||
+ while ((nread = read(fd, cp, buf + sizeof(buf) - cp)) != 0) {
|
||||
+ if (nread == -1) {
|
||||
+ if (errno == EAGAIN || errno == EINTR)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ cp += nread;
|
||||
+ if (cp >= buf + sizeof(buf))
|
||||
+ break;
|
||||
+ }
|
||||
+ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) {
|
||||
/*
|
||||
* Field 7 is the tty dev (0 if no tty).
|
||||
- * Since the process name at field 2 "(comm)" may include spaces,
|
||||
- * start at the last ')' found.
|
||||
+ * Since the process name at field 2 "(comm)" may include
|
||||
+ * whitespace (including newlines), start at the last ')' found.
|
||||
*/
|
||||
- char *cp = strrchr(line, ')');
|
||||
+ *cp = '\0';
|
||||
+ cp = strrchr(buf, ')');
|
||||
if (cp != NULL) {
|
||||
char *ep = cp;
|
||||
const char *errstr;
|
||||
@@ -527,7 +539,8 @@ get_process_ttyname(char *name, size_t namelen)
|
||||
errno = ENOENT;
|
||||
|
||||
done:
|
||||
- free(line);
|
||||
+ if (fd != -1)
|
||||
+ close(fd);
|
||||
if (ret == NULL)
|
||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
"unable to resolve tty via %s", path);
|
|
@ -0,0 +1,16 @@
|
|||
diff -up ./plugins/sudoers/sudo_nss.c.display-privs ./plugins/sudoers/sudo_nss.c
|
||||
--- ./plugins/sudoers/sudo_nss.c.display-privs 2017-01-13 23:30:15.000000000 -0500
|
||||
+++ ./plugins/sudoers/sudo_nss.c 2017-08-31 07:41:02.764738698 -0400
|
||||
@@ -348,7 +348,11 @@ display_privs(struct sudo_nss_list *snl,
|
||||
sudo_lbuf_destroy(&defs);
|
||||
sudo_lbuf_destroy(&privs);
|
||||
|
||||
- debug_return_int(count > 0);
|
||||
+/*
|
||||
+ * This is ok, we return 1 which is success in this case
|
||||
+ * and we don't want return failure even when there is nothing to print
|
||||
+ */
|
||||
+ debug_return_int(1);
|
||||
bad:
|
||||
sudo_lbuf_destroy(&defs);
|
||||
sudo_lbuf_destroy(&privs);
|
|
@ -0,0 +1,53 @@
|
|||
From daa728fd889680cf5294fbb0e836cade9fe1a6d8 Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@courtesan.com>
|
||||
Date: Wed, 22 Feb 2017 06:38:33 -0700
|
||||
Subject: [PATCH] Go back to using a Warning/Error prefix in the message
|
||||
printed to stderr for alias problems. Requested by Tomas Sykora.
|
||||
|
||||
---
|
||||
doc/visudo.cat | 10 +++++-----
|
||||
doc/visudo.man.in | 12 ++++++------
|
||||
doc/visudo.mdoc.in | 12 ++++++------
|
||||
plugins/sudoers/regress/visudo/test2.err.ok | 2 +-
|
||||
plugins/sudoers/regress/visudo/test3.err.ok | 4 ++--
|
||||
plugins/sudoers/visudo.c | 14 ++++++++++----
|
||||
6 files changed, 30 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/visudo.c b/plugins/sudoers/visudo.c
|
||||
index 4f192b2..4793d54 100644
|
||||
--- a/plugins/sudoers/visudo.c
|
||||
+++ b/plugins/sudoers/visudo.c
|
||||
@@ -1137,12 +1137,17 @@ check_alias(char *name, int type, char *file, int lineno, bool strict, bool quie
|
||||
} else {
|
||||
if (!quiet) {
|
||||
if (errno == ELOOP) {
|
||||
- sudo_warnx(U_("%s:%d cycle in %s \"%s\""),
|
||||
+ fprintf(stderr, strict ?
|
||||
+ U_("Error: %s:%d cycle in %s \"%s\"") :
|
||||
+ U_("Warning: %s:%d cycle in %s \"%s\""),
|
||||
file, lineno, alias_type_to_string(type), name);
|
||||
} else {
|
||||
- sudo_warnx(U_("%s:%d %s \"%s\" referenced but not defined"),
|
||||
+ fprintf(stderr, strict ?
|
||||
+ U_("Error: %s:%d %s \"%s\" referenced but not defined") :
|
||||
+ U_("Warning: %s:%d %s \"%s\" referenced but not defined"),
|
||||
file, lineno, alias_type_to_string(type), name);
|
||||
}
|
||||
+ fputc('\n', stderr);
|
||||
if (strict && errorfile == NULL) {
|
||||
errorfile = rcstr_addref(file);
|
||||
errorlineno = lineno;
|
||||
@@ -1292,8 +1297,9 @@ print_unused(void *v1, void *v2)
|
||||
{
|
||||
struct alias *a = (struct alias *)v1;
|
||||
|
||||
- sudo_warnx_nodebug(U_("%s:%d unused %s \"%s\""),
|
||||
+ fprintf(stderr, U_("Warning: %s:%d unused %s \"%s\""),
|
||||
a->file, a->lineno, alias_type_to_string(a->type), a->name);
|
||||
+ fputc('\n', stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
diff -up ./plugins/sudoers/sssd.c.fqdnafterfree ./plugins/sudoers/sssd.c
|
||||
--- ./plugins/sudoers/sssd.c.fqdnafterfree 2017-01-14 05:30:15.000000000 +0100
|
||||
+++ ./plugins/sudoers/sssd.c 2017-04-25 14:23:39.655649726 +0200
|
||||
@@ -82,8 +82,8 @@ typedef void (*sss_sudo_free_values_t)(c
|
||||
|
||||
struct sudo_sss_handle {
|
||||
char *domainname;
|
||||
- char *host;
|
||||
- char *shost;
|
||||
+ char *ipa_host;
|
||||
+ char *ipa_shost;
|
||||
struct passwd *pw;
|
||||
void *ssslib;
|
||||
sss_sudo_send_recv_t fn_send_recv;
|
||||
@@ -385,7 +385,7 @@ sudo_sss_open(struct sudo_nss *nss)
|
||||
debug_decl(sudo_sss_open, SUDOERS_DEBUG_SSSD);
|
||||
|
||||
/* Create a handle container. */
|
||||
- handle = malloc(sizeof(struct sudo_sss_handle));
|
||||
+ handle = calloc(1, sizeof(struct sudo_sss_handle));
|
||||
if (handle == NULL) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
debug_return_int(ENOMEM);
|
||||
@@ -447,9 +447,6 @@ sudo_sss_open(struct sudo_nss *nss)
|
||||
debug_return_int(EFAULT);
|
||||
}
|
||||
|
||||
- handle->domainname = NULL;
|
||||
- handle->host = user_runhost;
|
||||
- handle->shost = user_srunhost;
|
||||
handle->pw = sudo_user.pw;
|
||||
nss->handle = handle;
|
||||
|
||||
@@ -458,7 +455,7 @@ sudo_sss_open(struct sudo_nss *nss)
|
||||
* in sssd.conf and use it in preference to user_runhost.
|
||||
*/
|
||||
if (strcmp(user_runhost, user_host) == 0) {
|
||||
- if (get_ipa_hostname(&handle->shost, &handle->host) == -1) {
|
||||
+ if (get_ipa_hostname(&handle->ipa_shost, &handle->ipa_host) == -1) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
free(handle);
|
||||
debug_return_int(ENOMEM);
|
||||
@@ -480,7 +477,10 @@ sudo_sss_close(struct sudo_nss *nss)
|
||||
if (nss && nss->handle) {
|
||||
handle = nss->handle;
|
||||
sudo_dso_unload(handle->ssslib);
|
||||
- free(nss->handle);
|
||||
+ free(handle->ipa_host);
|
||||
+ free(handle->ipa_shost);
|
||||
+ free(handle);
|
||||
+ nss->handle = NULL;
|
||||
}
|
||||
debug_return_int(0);
|
||||
}
|
||||
@@ -585,8 +585,9 @@ sudo_sss_checkpw(struct sudo_nss *nss, s
|
||||
static int
|
||||
sudo_sss_check_runas_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *sss_rule, int group_matched)
|
||||
{
|
||||
- char **val_array = NULL;
|
||||
- char *val;
|
||||
+ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost;
|
||||
+ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost;
|
||||
+ char *val, **val_array = NULL;
|
||||
int ret = false, i;
|
||||
debug_decl(sudo_sss_check_runas_user, SUDOERS_DEBUG_SSSD);
|
||||
|
||||
@@ -656,8 +657,8 @@ sudo_sss_check_runas_user(struct sudo_ss
|
||||
switch (val[0]) {
|
||||
case '+':
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "netgr_");
|
||||
- if (netgr_matches(val, def_netgroup_tuple ? handle->host : NULL,
|
||||
- def_netgroup_tuple ? handle->shost : NULL, runas_pw->pw_name)) {
|
||||
+ if (netgr_matches(val, def_netgroup_tuple ? host : NULL,
|
||||
+ def_netgroup_tuple ? shost : NULL, runas_pw->pw_name)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "=> match");
|
||||
ret = true;
|
||||
}
|
||||
@@ -762,7 +763,9 @@ sudo_sss_check_runas(struct sudo_sss_han
|
||||
static bool
|
||||
sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
{
|
||||
- char **val_array, *val;
|
||||
+ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost;
|
||||
+ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost;
|
||||
+ char *val, **val_array;
|
||||
int matched = UNSPEC;
|
||||
bool negated;
|
||||
int i;
|
||||
@@ -792,9 +795,9 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
|
||||
/* match any or address or netgroup or hostname */
|
||||
if (strcmp(val, "ALL") == 0 || addr_matches(val) ||
|
||||
- netgr_matches(val, handle->host, handle->shost,
|
||||
+ netgr_matches(val, host, shost,
|
||||
def_netgroup_tuple ? handle->pw->pw_name : NULL) ||
|
||||
- hostname_matches(handle->shost, handle->host, val)) {
|
||||
+ hostname_matches(shost, host, val)) {
|
||||
|
||||
matched = negated ? false : true;
|
||||
}
|
||||
@@ -816,9 +819,10 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
static bool
|
||||
sudo_sss_check_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
{
|
||||
- int ret = false;
|
||||
+ const char *host = handle->ipa_host ? handle->ipa_host : user_runhost;
|
||||
+ const char *shost = handle->ipa_shost ? handle->ipa_shost : user_srunhost;
|
||||
char **val_array;
|
||||
- int i;
|
||||
+ int i, ret = false;
|
||||
debug_decl(sudo_sss_check_user, SUDOERS_DEBUG_SSSD);
|
||||
|
||||
if (!handle || !rule)
|
||||
@@ -844,8 +848,8 @@ sudo_sss_check_user(struct sudo_sss_hand
|
||||
switch (*val) {
|
||||
case '+':
|
||||
/* Netgroup spec found, check membership. */
|
||||
- if (netgr_matches(val, def_netgroup_tuple ? handle->host : NULL,
|
||||
- def_netgroup_tuple ? handle->shost : NULL, handle->pw->pw_name)) {
|
||||
+ if (netgr_matches(val, def_netgroup_tuple ? host : NULL,
|
||||
+ def_netgroup_tuple ? shost : NULL, handle->pw->pw_name)) {
|
||||
ret = true;
|
||||
}
|
||||
break;
|
|
@ -0,0 +1,76 @@
|
|||
diff -ru sudo-1.8.20/src/ttyname.c sudo-1.8.20-Q/src/ttyname.c
|
||||
--- sudo-1.8.20/src/ttyname.c 2017-05-10 08:38:44.000000000 -0700
|
||||
+++ sudo-1.8.20-Q/src/ttyname.c 2017-05-19 02:15:48.442705049 -0700
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2012-2016 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
+ * Copyright (c) 2012-2017 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
|
||||
@@ -159,6 +159,8 @@
|
||||
|
||||
static char *ignore_devs[] = {
|
||||
"/dev/fd/",
|
||||
+ "/dev/mqueue/",
|
||||
+ "/dev/shm/",
|
||||
"/dev/stdin",
|
||||
"/dev/stdout",
|
||||
"/dev/stderr",
|
||||
@@ -493,28 +495,35 @@
|
||||
len = getline(&line, &linesize, fp);
|
||||
fclose(fp);
|
||||
if (len != -1) {
|
||||
- /* Field 7 is the tty dev (0 if no tty) */
|
||||
- char *cp = line;
|
||||
- char *ep = line;
|
||||
- const char *errstr;
|
||||
- int field = 0;
|
||||
- while (*++ep != '\0') {
|
||||
- if (*ep == ' ') {
|
||||
- *ep = '\0';
|
||||
- if (++field == 7) {
|
||||
- dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr);
|
||||
- if (errstr) {
|
||||
- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
- "%s: tty device %s: %s", path, cp, errstr);
|
||||
+ /*
|
||||
+ * Field 7 is the tty dev (0 if no tty).
|
||||
+ * Since the process name at field 2 "(comm)" may include spaces,
|
||||
+ * start at the last ')' found.
|
||||
+ */
|
||||
+ char *cp = strrchr(line, ')');
|
||||
+ if (cp != NULL) {
|
||||
+ char *ep = cp;
|
||||
+ const char *errstr;
|
||||
+ int field = 1;
|
||||
+
|
||||
+ while (*++ep != '\0') {
|
||||
+ if (*ep == ' ') {
|
||||
+ *ep = '\0';
|
||||
+ if (++field == 7) {
|
||||
+ dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr);
|
||||
+ if (errstr) {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
+ "%s: tty device %s: %s", path, cp, errstr);
|
||||
+ }
|
||||
+ if (tdev > 0) {
|
||||
+ errno = serrno;
|
||||
+ ret = sudo_ttyname_dev(tdev, name, namelen);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
- if (tdev > 0) {
|
||||
- errno = serrno;
|
||||
- ret = sudo_ttyname_dev(tdev, name, namelen);
|
||||
- goto done;
|
||||
- }
|
||||
- break;
|
||||
+ cp = ep + 1;
|
||||
}
|
||||
- cp = ep + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
From 93cef1efac4e2b4930c23cdc35c0b916365ccabc Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Tue, 21 Feb 2017 14:56:24 +0100
|
||||
Subject: [PATCH] Add ignore_unknown_defaults flag to ignore unknown Defaults
|
||||
entries in sudoers instead of producing a warning.
|
||||
|
||||
Patch: sudo-1.8.19p2-ignore-unknown-defaults.patch
|
||||
Resolves:
|
||||
rhbz#1413160
|
||||
---
|
||||
doc/sudoers.cat | 6 ++++++
|
||||
doc/sudoers.man.in | 11 +++++++++++
|
||||
doc/sudoers.mdoc.in | 10 ++++++++++
|
||||
plugins/sudoers/def_data.c | 4 ++++
|
||||
plugins/sudoers/def_data.h | 2 ++
|
||||
plugins/sudoers/def_data.in | 3 +++
|
||||
plugins/sudoers/defaults.c | 3 ++-
|
||||
7 files changed, 38 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doc/sudoers.cat b/doc/sudoers.cat
|
||||
index 76dbf28..50cf78a 100644
|
||||
--- a/doc/sudoers.cat
|
||||
+++ b/doc/sudoers.cat
|
||||
@@ -1071,6 +1071,12 @@ SSUUDDOOEERRSS OOPPTTIIOONNSS
|
||||
meaningful for the cn=defaults section. This flag is
|
||||
_o_f_f by default.
|
||||
|
||||
+ ignore_unknown_defaults
|
||||
+ If set, ssuuddoo will not produce a warning if it
|
||||
+ encounters an unknown Defaults entry in the _^Hs_^Hu_^Hd_^Ho_^He_^Hr_^Hs
|
||||
+ file or an unknown sudoOption in LDAP. This flag is
|
||||
+ _o_f_f by default.
|
||||
+
|
||||
insults If set, ssuuddoo will insult users when they enter an
|
||||
incorrect password. This flag is _o_f_f by default.
|
||||
|
||||
diff --git a/doc/sudoers.man.in b/doc/sudoers.man.in
|
||||
index 8673da0..4be3760 100644
|
||||
--- a/doc/sudoers.man.in
|
||||
+++ b/doc/sudoers.man.in
|
||||
@@ -2266,6 +2266,17 @@ This flag is
|
||||
\fIoff\fR
|
||||
by default.
|
||||
.TP 18n
|
||||
+ignore_unknown_defaults
|
||||
+If set,
|
||||
+\fBsudo\fR
|
||||
+will not produce a warning if it encounters an unknown Defaults entry
|
||||
+in the
|
||||
+\fIsudoers\fR
|
||||
+file or an unknown sudoOption in LDAP.
|
||||
+This flag is
|
||||
+\fIoff\fR
|
||||
+by default.
|
||||
+.TP 18n
|
||||
insults
|
||||
If set,
|
||||
\fBsudo\fR
|
||||
diff --git a/doc/sudoers.mdoc.in b/doc/sudoers.mdoc.in
|
||||
index 74b6f01..f3fe5e6 100644
|
||||
--- a/doc/sudoers.mdoc.in
|
||||
+++ b/doc/sudoers.mdoc.in
|
||||
@@ -2124,6 +2124,16 @@ section.
|
||||
This flag is
|
||||
.Em off
|
||||
by default.
|
||||
+.It ignore_unknown_defaults
|
||||
+If set,
|
||||
+.Nm sudo
|
||||
+will not produce a warning if it encounters an unknown Defaults entry
|
||||
+in the
|
||||
+.Em sudoers
|
||||
+file or an unknown sudoOption in LDAP.
|
||||
+This flag is
|
||||
+.Em off
|
||||
+by default.
|
||||
.It insults
|
||||
If set,
|
||||
.Nm sudo
|
||||
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
||||
index 3926fed..3d787c2 100644
|
||||
--- a/plugins/sudoers/def_data.c
|
||||
+++ b/plugins/sudoers/def_data.c
|
||||
@@ -443,6 +443,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
N_("Don't pre-resolve all group names"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "ignore_unknown_defaults", T_FLAG,
|
||||
+ N_("Ignore unknown Defaults entries in sudoers instead of producing a warning"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
||||
index b5e61b4..f5773a3 100644
|
||||
--- a/plugins/sudoers/def_data.h
|
||||
+++ b/plugins/sudoers/def_data.h
|
||||
@@ -208,6 +208,8 @@
|
||||
#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||||
#define I_LEGACY_GROUP_PROCESSING 104
|
||||
#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag)
|
||||
+#define I_IGNORE_UNKNOWN_DEFAULTS 105
|
||||
+#define def_ignore_unknown_defaults (sudo_defs_table[I_IGNORE_UNKNOWN_DEFAULTS].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
||||
index f1c9265..8f63d70 100644
|
||||
--- a/plugins/sudoers/def_data.in
|
||||
+++ b/plugins/sudoers/def_data.in
|
||||
@@ -328,3 +328,6 @@ cmnd_no_wait
|
||||
legacy_group_processing
|
||||
T_FLAG
|
||||
"Don't pre-resolve all group names"
|
||||
+ignore_unknown_defaults
|
||||
+ T_FLAG
|
||||
+ "Ignore unknown Defaults entries in sudoers instead of producing a warning"
|
||||
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
|
||||
index 9e60d94..5f93f80 100644
|
||||
--- a/plugins/sudoers/defaults.c
|
||||
+++ b/plugins/sudoers/defaults.c
|
||||
@@ -79,6 +79,7 @@ static struct strmap priorities[] = {
|
||||
};
|
||||
|
||||
static struct early_default early_defaults[] = {
|
||||
+ { I_IGNORE_UNKNOWN_DEFAULTS },
|
||||
#ifdef FQDN
|
||||
{ I_FQDN, true },
|
||||
#else
|
||||
@@ -206,7 +207,7 @@ find_default(const char *name, const char *file, int lineno, bool quiet)
|
||||
if (strcmp(name, sudo_defs_table[i].name) == 0)
|
||||
debug_return_int(i);
|
||||
}
|
||||
- if (!quiet) {
|
||||
+ if (!quiet && !def_ignore_unknown_defaults) {
|
||||
if (lineno > 0) {
|
||||
sudo_warnx(U_("%s:%d unknown defaults entry \"%s\""),
|
||||
file, lineno, name);
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,317 @@
|
|||
diff -up ./doc/sudoers.cat.orig ./doc/sudoers.cat
|
||||
--- ./doc/sudoers.cat.orig 2017-03-21 13:31:00.953951199 +0100
|
||||
+++ ./doc/sudoers.cat 2017-03-21 14:14:18.679116865 +0100
|
||||
@@ -1549,6 +1549,16 @@ SSUUDDOOEERRSS OOPPTTIIOONN
|
||||
will be truncated and overwritten unless _i_o_l_o_g___f_i_l_e
|
||||
ends in six or more Xs.
|
||||
|
||||
+ iolog_flush If set, ssuuddoo will flush I/O log data to disk after each
|
||||
+ write instead of buffering it. This makes it possible
|
||||
+ to view the logs in real-time as the program is
|
||||
+ executing but may significantly reduce the
|
||||
+ effectiveness of I/O log compression. This flag is _o_f_f
|
||||
+ by default.
|
||||
+
|
||||
+ This setting is only supported by version 1.8.20 or
|
||||
+ higher.
|
||||
+
|
||||
iolog_group The group name to look up when setting the group ID on
|
||||
new I/O log files and directories. By default, I/O log
|
||||
files and directories inherit the group ID of the
|
||||
@@ -2141,10 +2151,14 @@ II//OO LLOOGG FFIILLEESS
|
||||
_s_t_d_e_r_r standard error to a pipe or redirected to a file
|
||||
|
||||
All files other than _l_o_g are compressed in gzip format unless the
|
||||
- _c_o_m_p_r_e_s_s___i_o option has been disabled. Due to buffering, the I/O log data
|
||||
- will not be complete until the ssuuddoo command has completed. The output
|
||||
- portion of an I/O log file can be viewed with the sudoreplay(1m) utility,
|
||||
- which can also be used to list or search the available logs.
|
||||
+ _c_o_m_p_r_e_s_s___i_o flag has been disabled. Due to buffering, it is not normally
|
||||
+ possible to display the I/O logs in real-time as the program is executing
|
||||
+ The I/O log data will not be complete until the program run by ssuuddoo has
|
||||
+ exited or has been terminated by a signal. The _i_o_l_o_g___f_l_u_s_h flag can be
|
||||
+ used to disable buffering, in which case I/O log data is written to disk
|
||||
+ as soon as it is available. The output portion of an I/O log file can be
|
||||
+ viewed with the sudoreplay(1m) utility, which can also be used to list or
|
||||
+ search the available logs.
|
||||
|
||||
Note that user input may contain sensitive information such as passwords
|
||||
(even if they are not echoed to the screen), which will be stored in the
|
||||
diff -up ./doc/sudoers.man.in.orig ./doc/sudoers.man.in
|
||||
--- ./doc/sudoers.man.in.orig 2017-03-21 14:22:33.804283190 +0100
|
||||
+++ ./doc/sudoers.man.in 2017-03-21 14:22:21.136664667 +0100
|
||||
@@ -3199,6 +3199,19 @@ ends in six or
|
||||
more
|
||||
\fRX\fRs.
|
||||
.TP 18n
|
||||
+iolog_flush
|
||||
+If set,
|
||||
+\fBsudo\fR
|
||||
+will flush I/O log data to disk after each write instead of buffering it.
|
||||
+This makes it possible to view the logs in real-time as the program
|
||||
+is executing but may significantly reduce the effectiveness of I/O
|
||||
+log compression.
|
||||
+This flag is
|
||||
+\fIoff\fR
|
||||
+by default.
|
||||
+.sp
|
||||
+This setting is only supported by version 1.8.20 or higher.
|
||||
+.TP 18n
|
||||
iolog_group
|
||||
The group name to look up when setting the group ID on new I/O log
|
||||
files and directories.
|
||||
@@ -4298,10 +4311,16 @@ All files other than
|
||||
\fIlog\fR
|
||||
are compressed in gzip format unless the
|
||||
\fIcompress_io\fR
|
||||
-option has been disabled.
|
||||
-Due to buffering, the I/O log data will not be complete until the
|
||||
+flag has been disabled.
|
||||
+Due to buffering, it is not normally possible to display the I/O logs in
|
||||
+real-time as the program is executing
|
||||
+The I/O log data will not be complete until the program run by
|
||||
\fBsudo\fR
|
||||
-command has completed.
|
||||
+has exited or has been terminated by a signal.
|
||||
+The
|
||||
+\fIiolog_flush\fR
|
||||
+flag can be used to disable buffering, in which case I/O log data
|
||||
+is written to disk as soon as it is available.
|
||||
The output portion of an I/O log file can be viewed with the
|
||||
sudoreplay(@mansectsu@)
|
||||
utility, which can also be used to list or search the available logs.
|
||||
diff -up ./doc/sudoers.mdoc.in.orig ./doc/sudoers.mdoc.in
|
||||
--- ./doc/sudoers.mdoc.in.orig 2017-03-21 14:23:46.652089432 +0100
|
||||
+++ ./doc/sudoers.mdoc.in 2017-03-21 14:26:43.686758162 +0100
|
||||
@@ -2998,6 +2998,18 @@ overwritten unless
|
||||
ends in six or
|
||||
more
|
||||
.Li X Ns s .
|
||||
+.It iolog_flush
|
||||
+If set,
|
||||
+.Nm sudo
|
||||
+will flush I/O log data to disk after each write instead of buffering it.
|
||||
+This makes it possible to view the logs in real-time as the program
|
||||
+is executing but may significantly reduce the effectiveness of I/O
|
||||
+log compression.
|
||||
+This flag is
|
||||
+.Em off
|
||||
+by default.
|
||||
+.Pp
|
||||
+This setting is only supported by version 1.8.20 or higher.
|
||||
.It iolog_group
|
||||
The group name to look up when setting the group ID on new I/O log
|
||||
files and directories.
|
||||
@@ -3991,10 +4003,16 @@ All files other than
|
||||
.Pa log
|
||||
are compressed in gzip format unless the
|
||||
.Em compress_io
|
||||
-option has been disabled.
|
||||
-Due to buffering, the I/O log data will not be complete until the
|
||||
-.Nm sudo
|
||||
-command has completed.
|
||||
+flag has been disabled.
|
||||
+Due to buffering, it is not normally possible to display the I/O logs in
|
||||
+real-time as the program is executing
|
||||
+The I/O log data will not be complete until the program run by
|
||||
+.Nm sudo
|
||||
+has exited or has been terminated by a signal.
|
||||
+The
|
||||
+.Em iolog_flush
|
||||
+flag can be used to disable buffering, in which case I/O log data
|
||||
+is written to disk as soon as it is available.
|
||||
The output portion of an I/O log file can be viewed with the
|
||||
.Xr sudoreplay @mansectsu@
|
||||
utility, which can also be used to list or search the available logs.
|
||||
diff -up ./plugins/sudoers/def_data.c.orig ./plugins/sudoers/def_data.c
|
||||
--- ./plugins/sudoers/def_data.c.orig 2017-03-21 13:24:10.682064806 +0100
|
||||
+++ ./plugins/sudoers/def_data.c 2017-03-21 13:25:09.805322057 +0100
|
||||
@@ -447,6 +447,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Ignore unknown Defaults entries in sudoers instead of producing a warning"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "iolog_flush", T_FLAG,
|
||||
+ N_("Flush I/O log data to disk immediately instead of buffering it"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up ./plugins/sudoers/def_data.h.orig ./plugins/sudoers/def_data.h
|
||||
--- ./plugins/sudoers/def_data.h.orig 2017-03-21 13:25:20.489006524 +0100
|
||||
+++ ./plugins/sudoers/def_data.h 2017-03-21 13:28:09.251022290 +0100
|
||||
@@ -210,6 +210,8 @@
|
||||
#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag)
|
||||
#define I_IGNORE_UNKNOWN_DEFAULTS 105
|
||||
#define def_ignore_unknown_defaults (sudo_defs_table[I_IGNORE_UNKNOWN_DEFAULTS].sd_un.flag)
|
||||
+#define I_IOLOG_FLUSH 106
|
||||
+#define def_iolog_flush (sudo_defs_table[I_IOLOG_FLUSH].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up ./plugins/sudoers/def_data.in.orig ./plugins/sudoers/def_data.in
|
||||
--- ./plugins/sudoers/def_data.in.orig 2017-03-21 13:28:35.115258413 +0100
|
||||
+++ ./plugins/sudoers/def_data.in 2017-03-21 13:30:03.239655739 +0100
|
||||
@@ -331,3 +331,6 @@ legacy_group_processing
|
||||
ignore_unknown_defaults
|
||||
T_FLAG
|
||||
"Ignore unknown Defaults entries in sudoers instead of producing a warning"
|
||||
+iolog_flush
|
||||
+ T_FLAG
|
||||
+ "Flush I/O log data to disk immediately instead of buffering it"
|
||||
diff -up ./plugins/sudoers/iolog.c.orig ./plugins/sudoers/iolog.c
|
||||
--- ./plugins/sudoers/iolog.c.orig 2017-03-21 13:12:39.471464160 +0100
|
||||
+++ ./plugins/sudoers/iolog.c 2017-03-21 13:21:49.279230759 +0100
|
||||
@@ -709,6 +709,7 @@ iolog_deserialize_info(struct iolog_deta
|
||||
|
||||
/*
|
||||
* Write the "/log" file that contains the user and command info.
|
||||
+ * This file is not compressed.
|
||||
*/
|
||||
static bool
|
||||
write_info_log(char *pathbuf, size_t len, struct iolog_details *details,
|
||||
@@ -747,6 +748,57 @@ write_info_log(char *pathbuf, size_t len
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
+#ifdef HAVE_ZLIB_H
|
||||
+static const char *
|
||||
+gzstrerror(gzFile file)
|
||||
+{
|
||||
+ int errnum;
|
||||
+
|
||||
+ return gzerror(file, &errnum);
|
||||
+}
|
||||
+#endif /* HAVE_ZLIB_H */
|
||||
+
|
||||
+/*
|
||||
+ * Write to an I/O log, compressing if iolog_compress is enabled.
|
||||
+ * If def_iolog_flush is true, flush the buffer immediately.
|
||||
+ */
|
||||
+static const char *
|
||||
+iolog_write(const void *buf, unsigned int len, int idx)
|
||||
+{
|
||||
+ const char *errstr = NULL;
|
||||
+ debug_decl(iolog_write, SUDOERS_DEBUG_PLUGIN)
|
||||
+
|
||||
+#ifdef HAVE_ZLIB_H
|
||||
+ if (iolog_compress) {
|
||||
+ if (gzwrite(io_log_files[idx].fd.g, buf, len) != (int)len) {
|
||||
+ errstr = gzstrerror(io_log_files[idx].fd.g);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (def_iolog_flush) {
|
||||
+ if (gzflush(io_log_files[idx].fd.g, Z_SYNC_FLUSH) != Z_OK) {
|
||||
+ errstr = gzstrerror(io_log_files[idx].fd.g);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ } else
|
||||
+#endif
|
||||
+ {
|
||||
+ if (fwrite(buf, 1, len, io_log_files[idx].fd.f) != len) {
|
||||
+ errstr = strerror(errno);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (def_iolog_flush) {
|
||||
+ if (fflush(io_log_files[idx].fd.f) != 0) {
|
||||
+ errstr = strerror(errno);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ debug_return_const_str(errstr);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
||||
sudo_printf_t plugin_printf, char * const settings[],
|
||||
@@ -914,13 +966,15 @@ sudoers_io_version(int verbose)
|
||||
|
||||
/*
|
||||
* Generic I/O logging function. Called by the I/O logging entry points.
|
||||
+ * Returns 1 on success and -1 on error.
|
||||
*/
|
||||
static int
|
||||
sudoers_io_log(const char *buf, unsigned int len, int idx)
|
||||
{
|
||||
struct timeval now, delay;
|
||||
+ char tbuf[1024];
|
||||
const char *errstr = NULL;
|
||||
- int ret = true;
|
||||
+ int ret = -1;
|
||||
debug_decl(sudoers_io_version, SUDOERS_DEBUG_PLUGIN)
|
||||
|
||||
if (io_log_files[idx].fd.v == NULL) {
|
||||
@@ -931,41 +985,28 @@ sudoers_io_log(const char *buf, unsigned
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
-#ifdef HAVE_ZLIB_H
|
||||
- if (iolog_compress) {
|
||||
- if (gzwrite(io_log_files[idx].fd.g, (const voidp)buf, len) != (int)len) {
|
||||
- int errnum;
|
||||
+ /* Write I/O log file entry. */
|
||||
+ errstr = iolog_write(buf, len, idx);
|
||||
+ if (errstr != NULL)
|
||||
+ goto done;
|
||||
|
||||
- errstr = gzerror(io_log_files[idx].fd.g, &errnum);
|
||||
- ret = -1;
|
||||
- }
|
||||
- } else
|
||||
-#endif
|
||||
- {
|
||||
- if (fwrite(buf, 1, len, io_log_files[idx].fd.f) != len) {
|
||||
- errstr = strerror(errno);
|
||||
- ret = -1;
|
||||
- }
|
||||
- }
|
||||
+ /* Write timing file entry. */
|
||||
sudo_timevalsub(&now, &last_time, &delay);
|
||||
-#ifdef HAVE_ZLIB_H
|
||||
- if (iolog_compress) {
|
||||
- if (gzprintf(io_log_files[IOFD_TIMING].fd.g, "%d %f %u\n", idx,
|
||||
- delay.tv_sec + ((double)delay.tv_usec / 1000000), len) == 0) {
|
||||
- int errnum;
|
||||
-
|
||||
- errstr = gzerror(io_log_files[IOFD_TIMING].fd.g, &errnum);
|
||||
- ret = -1;
|
||||
- }
|
||||
- } else
|
||||
-#endif
|
||||
- {
|
||||
- if (fprintf(io_log_files[IOFD_TIMING].fd.f, "%d %f %u\n", idx,
|
||||
- delay.tv_sec + ((double)delay.tv_usec / 1000000), len) < 0) {
|
||||
- errstr = strerror(errno);
|
||||
- ret = -1;
|
||||
- }
|
||||
+ len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %f %u\n", idx,
|
||||
+ delay.tv_sec + ((double)delay.tv_usec / 1000000), len);
|
||||
+ if (len >= sizeof(tbuf)) {
|
||||
+ /* Not actually possible due to the size of tbuf[]. */
|
||||
+ errstr = strerror(EOVERFLOW);
|
||||
+ goto done;
|
||||
}
|
||||
+ errstr = iolog_write(tbuf, len, IOFD_TIMING);
|
||||
+ if (errstr != NULL)
|
||||
+ goto done;
|
||||
+
|
||||
+ /* Success. */
|
||||
+ ret = 1;
|
||||
+
|
||||
+done:
|
||||
last_time.tv_sec = now.tv_sec;
|
||||
last_time.tv_usec = now.tv_usec;
|
||||
|
||||
@@ -979,7 +1020,7 @@ sudoers_io_log(const char *buf, unsigned
|
||||
|
||||
/* Ignore errors if they occur if the policy says so. */
|
||||
if (iolog_details.ignore_iolog_errors)
|
||||
- ret = true;
|
||||
+ ret = 1;
|
||||
}
|
||||
|
||||
debug_return_int(ret);
|
|
@ -0,0 +1,171 @@
|
|||
diff --git a/src/exec_pty.c b/src/exec_pty.c
|
||||
index 7403506..56b2899 100644
|
||||
--- a/src/exec_pty.c
|
||||
+++ b/src/exec_pty.c
|
||||
@@ -711,8 +711,10 @@ io_buf_new(int rfd, int wfd,
|
||||
int
|
||||
fork_pty(struct command_details *details, int sv[], sigset_t *omask)
|
||||
{
|
||||
+ struct plugin_container *plugin;
|
||||
struct command_status cstat;
|
||||
- int io_pipe[3][2];
|
||||
+ int io_pipe[3][2] = { { -1, -1 }, { -1, -1 }, { -1, -1 } };
|
||||
+ bool interpose[3] = { false, false, false };
|
||||
sigaction_t sa;
|
||||
sigset_t mask;
|
||||
pid_t child;
|
||||
@@ -738,6 +740,16 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask)
|
||||
sigaddset(&ttyblock, SIGTTIN);
|
||||
sigaddset(&ttyblock, SIGTTOU);
|
||||
|
||||
+ /* Determine whether any of std{in,out,err} should be logged. */
|
||||
+ TAILQ_FOREACH(plugin, &io_plugins, entries) {
|
||||
+ if (plugin->u.io->log_stdin)
|
||||
+ interpose[STDIN_FILENO] = true;
|
||||
+ if (plugin->u.io->log_stdout)
|
||||
+ interpose[STDOUT_FILENO] = true;
|
||||
+ if (plugin->u.io->log_stderr)
|
||||
+ interpose[STDERR_FILENO] = true;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Setup stdin/stdout/stderr for child, to be duped after forking.
|
||||
* In background mode there is no stdin.
|
||||
@@ -763,35 +775,64 @@ fork_pty(struct command_details *details, int sv[], sigset_t *omask)
|
||||
}
|
||||
|
||||
/*
|
||||
- * If either stdin, stdout or stderr is not a tty we use a pipe
|
||||
- * to interpose ourselves instead of duping the pty fd.
|
||||
+ * If stdin, stdout or stderr is not a tty and logging is enabled,
|
||||
+ * use a pipe to interpose ourselves instead of using the pty fd.
|
||||
*/
|
||||
- memset(io_pipe, 0, sizeof(io_pipe));
|
||||
if (io_fds[SFD_STDIN] == -1 || !isatty(STDIN_FILENO)) {
|
||||
- sudo_debug_printf(SUDO_DEBUG_INFO, "stdin not a tty, creating a pipe");
|
||||
- pipeline = true;
|
||||
- if (pipe(io_pipe[STDIN_FILENO]) != 0)
|
||||
- sudo_fatal(U_("unable to create pipe"));
|
||||
- io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
|
||||
- log_stdin, &iobufs);
|
||||
- io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
|
||||
- }
|
||||
- if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
|
||||
- sudo_debug_printf(SUDO_DEBUG_INFO, "stdout not a tty, creating a pipe");
|
||||
- pipeline = true;
|
||||
- if (pipe(io_pipe[STDOUT_FILENO]) != 0)
|
||||
- sudo_fatal(U_("unable to create pipe"));
|
||||
- io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
|
||||
- log_stdout, &iobufs);
|
||||
- io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
|
||||
- }
|
||||
- if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) {
|
||||
- sudo_debug_printf(SUDO_DEBUG_INFO, "stderr not a tty, creating a pipe");
|
||||
- if (pipe(io_pipe[STDERR_FILENO]) != 0)
|
||||
- sudo_fatal(U_("unable to create pipe"));
|
||||
- io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
|
||||
- log_stderr, &iobufs);
|
||||
- io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
|
||||
+ if (!interpose[STDIN_FILENO]) {
|
||||
+ /* Not logging stdin, do not interpose. */
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "stdin not a tty, not logging");
|
||||
+ io_fds[SFD_STDIN] = dup(STDIN_FILENO);
|
||||
+ if (io_fds[SFD_STDIN] == -1)
|
||||
+ sudo_fatal("dup");
|
||||
+ } else {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "stdin not a tty, creating a pipe");
|
||||
+ pipeline = true;
|
||||
+ if (pipe(io_pipe[STDIN_FILENO]) != 0)
|
||||
+ sudo_fatal(U_("unable to create pipe"));
|
||||
+ io_buf_new(STDIN_FILENO, io_pipe[STDIN_FILENO][1],
|
||||
+ log_stdin, &iobufs);
|
||||
+ io_fds[SFD_STDIN] = io_pipe[STDIN_FILENO][0];
|
||||
+ }
|
||||
+ }
|
||||
+ if (io_fds[SFD_STDOUT] == -1 || !isatty(STDOUT_FILENO)) {
|
||||
+ if (!interpose[STDOUT_FILENO]) {
|
||||
+ /* Not logging stdout, do not interpose. */
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "stdout not a tty, not logging");
|
||||
+ io_fds[SFD_STDOUT] = dup(STDOUT_FILENO);
|
||||
+ if (io_fds[SFD_STDOUT] == -1)
|
||||
+ sudo_fatal("dup");
|
||||
+ } else {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "stdout not a tty, creating a pipe");
|
||||
+ pipeline = true;
|
||||
+ if (pipe(io_pipe[STDOUT_FILENO]) != 0)
|
||||
+ sudo_fatal(U_("unable to create pipe"));
|
||||
+ io_buf_new(io_pipe[STDOUT_FILENO][0], STDOUT_FILENO,
|
||||
+ log_stdout, &iobufs);
|
||||
+ io_fds[SFD_STDOUT] = io_pipe[STDOUT_FILENO][1];
|
||||
+ }
|
||||
+ }
|
||||
+ if (io_fds[SFD_STDERR] == -1 || !isatty(STDERR_FILENO)) {
|
||||
+ if (!interpose[STDERR_FILENO]) {
|
||||
+ /* Not logging stderr, do not interpose. */
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "stderr not a tty, not logging");
|
||||
+ io_fds[SFD_STDERR] = dup(STDERR_FILENO);
|
||||
+ if (io_fds[SFD_STDERR] == -1)
|
||||
+ sudo_fatal("dup");
|
||||
+ } else {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO,
|
||||
+ "stderr not a tty, creating a pipe");
|
||||
+ if (pipe(io_pipe[STDERR_FILENO]) != 0)
|
||||
+ sudo_fatal(U_("unable to create pipe"));
|
||||
+ io_buf_new(io_pipe[STDERR_FILENO][0], STDERR_FILENO,
|
||||
+ log_stderr, &iobufs);
|
||||
+ io_fds[SFD_STDERR] = io_pipe[STDERR_FILENO][1];
|
||||
+ }
|
||||
}
|
||||
|
||||
/* We don't want to receive SIGTTIN/SIGTTOU, getting EIO is preferable. */
|
||||
@@ -1549,10 +1590,24 @@ exec_pty(struct command_details *details,
|
||||
setpgid(0, self);
|
||||
|
||||
/* Wire up standard fds, note that stdout/stderr may be pipes. */
|
||||
- if (dup2(io_fds[SFD_STDIN], STDIN_FILENO) == -1 ||
|
||||
- dup2(io_fds[SFD_STDOUT], STDOUT_FILENO) == -1 ||
|
||||
- dup2(io_fds[SFD_STDERR], STDERR_FILENO) == -1)
|
||||
- sudo_fatal("dup2");
|
||||
+ if (io_fds[SFD_STDIN] != STDIN_FILENO) {
|
||||
+ if (dup2(io_fds[SFD_STDIN], STDIN_FILENO) == -1)
|
||||
+ sudo_fatal("dup2");
|
||||
+ if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
|
||||
+ close(io_fds[SFD_STDIN]);
|
||||
+ }
|
||||
+ if (io_fds[SFD_STDOUT] != STDOUT_FILENO) {
|
||||
+ if (dup2(io_fds[SFD_STDOUT], STDOUT_FILENO) == -1)
|
||||
+ sudo_fatal("dup2");
|
||||
+ if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
|
||||
+ close(io_fds[SFD_STDOUT]);
|
||||
+ }
|
||||
+ if (io_fds[SFD_STDERR] != STDERR_FILENO) {
|
||||
+ if (dup2(io_fds[SFD_STDERR], STDERR_FILENO) == -1)
|
||||
+ sudo_fatal("dup2");
|
||||
+ if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
|
||||
+ close(io_fds[SFD_STDERR]);
|
||||
+ }
|
||||
|
||||
/* Wait for parent to grant us the tty if we are foreground. */
|
||||
if (foreground && !ISSET(details->flags, CD_EXEC_BG)) {
|
||||
@@ -1561,15 +1616,9 @@ exec_pty(struct command_details *details,
|
||||
nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
- /* We have guaranteed that the slave fd is > 2 */
|
||||
+ /* Done with the pty slave, don't leak it. */
|
||||
if (io_fds[SFD_SLAVE] != -1)
|
||||
close(io_fds[SFD_SLAVE]);
|
||||
- if (io_fds[SFD_STDIN] != io_fds[SFD_SLAVE])
|
||||
- close(io_fds[SFD_STDIN]);
|
||||
- if (io_fds[SFD_STDOUT] != io_fds[SFD_SLAVE])
|
||||
- close(io_fds[SFD_STDOUT]);
|
||||
- if (io_fds[SFD_STDERR] != io_fds[SFD_SLAVE])
|
||||
- close(io_fds[SFD_STDERR]);
|
||||
|
||||
/* Execute command; only returns on error. */
|
||||
exec_cmnd(details, cstat, errfd);
|
|
@ -0,0 +1,54 @@
|
|||
commit 631d458b6fc7341363a121c390e086cf676ecc83
|
||||
Author: Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
Date: Wed May 3 09:28:36 2017 -0600
|
||||
|
||||
Allow a tuple to be set to boolean true. Regression introduced by
|
||||
refactor of set_default_entry() in sudo 1.8.18.
|
||||
|
||||
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
|
||||
index 89788477..91b47eeb 100644
|
||||
--- a/plugins/sudoers/defaults.c
|
||||
+++ b/plugins/sudoers/defaults.c
|
||||
@@ -238,19 +238,31 @@ parse_default_entry(struct sudo_defs_types *def, const char *val, int op,
|
||||
int rc;
|
||||
debug_decl(parse_default_entry, SUDOERS_DEBUG_DEFAULTS)
|
||||
|
||||
- if (val == NULL && !ISSET(def->type, T_FLAG)) {
|
||||
- /* Check for bogus boolean usage or missing value if non-boolean. */
|
||||
- if (!ISSET(def->type, T_BOOL) || op != false) {
|
||||
- if (!quiet) {
|
||||
- if (lineno > 0) {
|
||||
- sudo_warnx(U_("%s:%d no value specified for \"%s\""),
|
||||
- file, lineno, def->name);
|
||||
- } else {
|
||||
- sudo_warnx(U_("%s: no value specified for \"%s\""),
|
||||
- file, def->name);
|
||||
+ /*
|
||||
+ * If no value specified, the boolean flag must be set for non-flags.
|
||||
+ * Only flags and tuples support boolean "true".
|
||||
+ */
|
||||
+ if (val == NULL) {
|
||||
+ switch (def->type & T_MASK) {
|
||||
+ case T_FLAG:
|
||||
+ break;
|
||||
+ case T_TUPLE:
|
||||
+ if (ISSET(def->type, T_BOOL))
|
||||
+ break;
|
||||
+ /* FALLTHROUGH */
|
||||
+ default:
|
||||
+ if (!ISSET(def->type, T_BOOL) || op != false) {
|
||||
+ if (!quiet) {
|
||||
+ if (lineno > 0) {
|
||||
+ sudo_warnx(U_("%s:%d no value specified for \"%s\""),
|
||||
+ file, lineno, def->name);
|
||||
+ } else {
|
||||
+ sudo_warnx(U_("%s: no value specified for \"%s\""),
|
||||
+ file, def->name);
|
||||
+ }
|
||||
}
|
||||
+ debug_return_bool(false);
|
||||
}
|
||||
- debug_return_bool(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
diff -up ./doc/sudoers.cat.lookup ./doc/sudoers.cat
|
||||
--- ./doc/sudoers.cat.lookup 2017-04-25 13:17:51.073190114 +0200
|
||||
+++ ./doc/sudoers.cat 2017-04-25 13:17:51.081190069 +0200
|
||||
@@ -1140,24 +1140,39 @@ SSUUDDOOEERRSS OOPPTTIIOONN
|
||||
_o_n by default.
|
||||
|
||||
match_group_by_gid
|
||||
- By default, when matching groups, ssuuddooeerrss will first
|
||||
- resolve all the user's group IDs to group names and
|
||||
- then compare those group names to any group names
|
||||
- listed in the _s_u_d_o_e_r_s file. This works well on systems
|
||||
- where the number of groups listed in the _s_u_d_o_e_r_s file
|
||||
- is larger than the number of groups a typical user
|
||||
- belongs to. On systems where group lookups are slow,
|
||||
- where users may belong to a large number of groups, and
|
||||
- where the number of groups listed in the _s_u_d_o_e_r_s file
|
||||
- is relatively small, it may be prohibitively expensive
|
||||
- and running commands via ssuuddoo may take longer than
|
||||
- normal. On such systems it may be faster to use the
|
||||
+ By default, ssuuddooeerrss will look up each group the user is
|
||||
+ a member of by group ID to determine the group name
|
||||
+ (this is only done once). The resulting list of the
|
||||
+ user's group names is used when matching groups listed
|
||||
+ in the _s_u_d_o_e_r_s file. This works well on systems where
|
||||
+ the number of groups listed in the _s_u_d_o_e_r_s file is
|
||||
+ larger than the number of groups a typical user belongs
|
||||
+ to. On systems where group lookups are slow, where
|
||||
+ users may belong to a large number of groups, and where
|
||||
+ the number of groups listed in the _s_u_d_o_e_r_s file is
|
||||
+ relatively small, it may be prohibitively expensive and
|
||||
+ running commands via ssuuddoo may take longer than normal.
|
||||
+ On such systems it may be faster to use the
|
||||
_m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag to avoid resolving the user's
|
||||
- group IDs to group names and instead resolve all group
|
||||
- names listed in the _s_u_d_o_e_r_s file, matching by group ID
|
||||
- instead of by group name. The _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag
|
||||
- has no effect when _s_u_d_o_e_r_s data is stored in LDAP.
|
||||
- This flag is _o_f_f by default.
|
||||
+ group IDs to group names. In this case, ssuuddooeerrss must
|
||||
+ look up any group name listed in the _s_u_d_o_e_r_s file and
|
||||
+ use the group ID instead of the group name when
|
||||
+ determining whether the user is a member of the group.
|
||||
+
|
||||
+ Note that if _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d is enabled, group
|
||||
+ database lookups performed by ssuuddooeerrss will be keyed by
|
||||
+ group name as opposed to group ID. On systems where
|
||||
+ there are multiple sources for the group database, it
|
||||
+ is possible to have conflicting group names or group
|
||||
+ IDs in the local _/_e_t_c_/_g_r_o_u_p file and the remote group
|
||||
+ database. On such systems, enabling or disabling
|
||||
+ _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d can be used to choose whether group
|
||||
+ database queries are performed by name (enabled) or ID
|
||||
+ (disabled), which may aid in working around group entry
|
||||
+ conflicts.
|
||||
+
|
||||
+ The _m_a_t_c_h___g_r_o_u_p___b_y___g_i_d flag has no effect when _s_u_d_o_e_r_s
|
||||
+ data is stored in LDAP. This flag is _o_f_f by default.
|
||||
|
||||
This setting is only supported by version 1.8.18 or
|
||||
higher.
|
||||
diff -up ./doc/sudoers.man.in.lookup ./doc/sudoers.man.in
|
||||
--- ./doc/sudoers.man.in.lookup 2017-04-25 13:17:51.074190108 +0200
|
||||
+++ ./doc/sudoers.man.in 2017-04-25 13:17:51.082190064 +0200
|
||||
@@ -2423,10 +2423,12 @@ This flag is
|
||||
by default.
|
||||
.TP 18n
|
||||
match_group_by_gid
|
||||
-By default, when matching groups,
|
||||
+By default,
|
||||
\fBsudoers\fR
|
||||
-will first resolve all the user's group IDs to group names and then
|
||||
-compare those group names to any group names listed in the
|
||||
+will look up each group the user is a member of by group ID to
|
||||
+determine the group name (this is only done once).
|
||||
+The resulting list of the user's group names is used when matching
|
||||
+groups listed in the
|
||||
\fIsudoers\fR
|
||||
file.
|
||||
This works well on systems where the number of groups listed in the
|
||||
@@ -2442,10 +2444,29 @@ running commands via
|
||||
may take longer than normal.
|
||||
On such systems it may be faster to use the
|
||||
\fImatch_group_by_gid\fR
|
||||
-flag to avoid resolving the user's group IDs to group names and
|
||||
-instead resolve all group names listed in the
|
||||
+flag to avoid resolving the user's group IDs to group names.
|
||||
+In this case,
|
||||
+\fBsudoers\fR
|
||||
+must look up any group name listed in the
|
||||
\fIsudoers\fR
|
||||
-file, matching by group ID instead of by group name.
|
||||
+file and use the group ID instead of the group name when determining
|
||||
+whether the user is a member of the group.
|
||||
+.sp
|
||||
+Note that if
|
||||
+\fImatch_group_by_gid\fR
|
||||
+is enabled, group database lookups performed by
|
||||
+\fBsudoers\fR
|
||||
+will be keyed by group name as opposed to group ID.
|
||||
+On systems where there are multiple sources for the group database,
|
||||
+it is possible to have conflicting group names or group IDs in the local
|
||||
+\fI/etc/group\fR
|
||||
+file and the remote group database.
|
||||
+On such systems, enabling or disabling
|
||||
+\fImatch_group_by_gid\fR
|
||||
+can be used to choose whether group database queries are performed
|
||||
+by name (enabled) or ID (disabled), which may aid in working around
|
||||
+group entry conflicts.
|
||||
+.sp
|
||||
The
|
||||
\fImatch_group_by_gid\fR
|
||||
flag has no effect when
|
||||
diff -up ./doc/sudoers.mdoc.in.lookup ./doc/sudoers.mdoc.in
|
||||
--- ./doc/sudoers.mdoc.in.lookup 2017-04-25 13:17:51.075190102 +0200
|
||||
+++ ./doc/sudoers.mdoc.in 2017-04-25 13:17:51.082190064 +0200
|
||||
@@ -2268,10 +2268,12 @@ This flag is
|
||||
.Em @mail_no_user@
|
||||
by default.
|
||||
.It match_group_by_gid
|
||||
-By default, when matching groups,
|
||||
+By default,
|
||||
.Nm
|
||||
-will first resolve all the user's group IDs to group names and then
|
||||
-compare those group names to any group names listed in the
|
||||
+will look up each group the user is a member of by group ID to
|
||||
+determine the group name (this is only done once).
|
||||
+The resulting list of the user's group names is used when matching
|
||||
+groups listed in the
|
||||
.Em sudoers
|
||||
file.
|
||||
This works well on systems where the number of groups listed in the
|
||||
@@ -2287,10 +2289,29 @@ running commands via
|
||||
may take longer than normal.
|
||||
On such systems it may be faster to use the
|
||||
.Em match_group_by_gid
|
||||
-flag to avoid resolving the user's group IDs to group names and
|
||||
-instead resolve all group names listed in the
|
||||
+flag to avoid resolving the user's group IDs to group names.
|
||||
+In this case,
|
||||
+.Nm
|
||||
+must look up any group name listed in the
|
||||
.Em sudoers
|
||||
-file, matching by group ID instead of by group name.
|
||||
+file and use the group ID instead of the group name when determining
|
||||
+whether the user is a member of the group.
|
||||
+.Pp
|
||||
+Note that if
|
||||
+.Em match_group_by_gid
|
||||
+is enabled, group database lookups performed by
|
||||
+.Nm
|
||||
+will be keyed by group name as opposed to group ID.
|
||||
+On systems where there are multiple sources for the group database,
|
||||
+it is possible to have conflicting group names or group IDs in the local
|
||||
+.Pa /etc/group
|
||||
+file and the remote group database.
|
||||
+On such systems, enabling or disabling
|
||||
+.Em match_group_by_gid
|
||||
+can be used to choose whether group database queries are performed
|
||||
+by name (enabled) or ID (disabled), which may aid in working around
|
||||
+group entry conflicts.
|
||||
+.Pp
|
||||
The
|
||||
.Em match_group_by_gid
|
||||
flag has no effect when
|
|
@ -0,0 +1,206 @@
|
|||
diff -up ./doc/sudoers.cat.manpage ./doc/sudoers.cat
|
||||
--- ./doc/sudoers.cat.manpage 2017-09-11 15:16:47.443869930 +0200
|
||||
+++ ./doc/sudoers.cat 2017-09-11 15:42:15.140500826 +0200
|
||||
@@ -1088,13 +1088,19 @@ SSUUDDOOEERRSS OOPPTTIIOONN
|
||||
connected to the user's tty, due to I/O redirection or
|
||||
because the command is part of a pipeline, that input
|
||||
is also captured and stored in a separate log file.
|
||||
- For more information, see the _I_/_O _L_O_G _F_I_L_E_S section.
|
||||
- This flag is _o_f_f by default.
|
||||
+ Anything sent to the standard input will be consumed,
|
||||
+ regardless of whether or not the command run via ssuuddoo
|
||||
+ is actually reading the standard input. This may have
|
||||
+ unexpected results when using ssuuddoo in a shell script
|
||||
+ that expects to process the standard input. For more
|
||||
+ information about I/O logging, see the _I_/_O _L_O_G _F_I_L_E_S
|
||||
+ section. This flag is _o_f_f by default.
|
||||
|
||||
log_output If set, ssuuddoo will run the command in a pseudo-tty and
|
||||
log all output that is sent to the screen, similar to
|
||||
- the script(1) command. For more information, see the
|
||||
- _I_/_O _L_O_G _F_I_L_E_S section. This flag is _o_f_f by default.
|
||||
+ the script(1) command. For more information about I/O
|
||||
+ logging, see the _I_/_O _L_O_G _F_I_L_E_S section. This flag is
|
||||
+ _o_f_f by default.
|
||||
|
||||
log_year If set, the four-digit year will be logged in the (non-
|
||||
syslog) ssuuddoo log file. This flag is _o_f_f by default.
|
||||
@@ -1396,13 +1402,18 @@ SSUUDDOOEERRSS OOPPTTIIOONN
|
||||
not needed, this option can be disabled to reduce the
|
||||
load on the LDAP server. This flag is _o_n by default.
|
||||
|
||||
- use_pty If set, ssuuddoo will run the command in a pseudo-pty even
|
||||
- if no I/O logging is being gone. A malicious program
|
||||
- run under ssuuddoo could conceivably fork a background
|
||||
- process that retains to the user's terminal device
|
||||
- after the main program has finished executing. Use of
|
||||
- this option will make that impossible. This flag is
|
||||
- _o_f_f by default.
|
||||
+ use_pty If set, and ssuuddoo is running in a terminal, the command
|
||||
+ will be run in a pseudo-pty (even if no I/O logging is
|
||||
+ being done). If the ssuuddoo process is not attached to a
|
||||
+ terminal, _u_s_e___p_t_y has no effect.
|
||||
+
|
||||
+ A malicious program run under ssuuddoo may be capable of
|
||||
+ injecting injecting commands into the user's terminal
|
||||
+ or running a background process that retains access to
|
||||
+ the user's terminal device even after the main program
|
||||
+ has finished executing. By running the command in a
|
||||
+ separate pseudo-pty, this attack is no longer possible.
|
||||
+ This flag is _o_f_f by default.
|
||||
|
||||
utmp_runas If set, ssuuddoo will store the name of the runas user when
|
||||
updating the utmp (or utmpx) file. By default, ssuuddoo
|
||||
@@ -2135,11 +2146,11 @@ LLOOGG FFOORRMMAATT
|
||||
|
||||
II//OO LLOOGG FFIILLEESS
|
||||
When I/O logging is enabled, ssuuddoo will run the command in a pseudo-tty
|
||||
- and log all user input and/or output. I/O is logged to the directory
|
||||
- specified by the _i_o_l_o_g___d_i_r option (_/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o by default) using a
|
||||
- unique session ID that is included in the ssuuddoo log line, prefixed with
|
||||
- ``TSID=''. The _i_o_l_o_g___f_i_l_e option may be used to control the format of
|
||||
- the session ID.
|
||||
+ and log all user input and/or output, depending on which options are
|
||||
+ are enabled. I/O is logged to the directory specified by the _i_o_l_o_g___d_i_r
|
||||
+ option (_/_v_a_r_/_l_o_g_/_s_u_d_o_-_i_o by default) using a unique session ID that is
|
||||
+ included in the ssuuddoo log line, prefixed with "TSID=". The _i_o_l_o_g___f_i_l_e
|
||||
+ option may be used to control the format of the session ID.
|
||||
|
||||
Each I/O log is stored in a separate directory that contains the
|
||||
following files:
|
||||
diff -up ./doc/sudoers.man.in.manpage ./doc/sudoers.man.in
|
||||
--- ./doc/sudoers.man.in.manpage 2017-09-11 15:16:47.444869925 +0200
|
||||
+++ ./doc/sudoers.man.in 2017-09-11 15:16:47.456869864 +0200
|
||||
@@ -2300,7 +2300,14 @@ will run the command in a pseudo-tty and
|
||||
If the standard input is not connected to the user's tty, due to
|
||||
I/O redirection or because the command is part of a pipeline, that
|
||||
input is also captured and stored in a separate log file.
|
||||
-For more information, see the
|
||||
+Anything sent to the standard input will be consumed, regardless of
|
||||
+whether or not the command run via
|
||||
+\fBsudo\fR
|
||||
+is actually reading the standard input.
|
||||
+This may have unexpected results when using
|
||||
+\fBsudo\fR
|
||||
+in a shell script that expects to process the standard input.
|
||||
+For more information about I/O logging, see the
|
||||
\fII/O LOG FILES\fR
|
||||
section.
|
||||
This flag is
|
||||
@@ -2314,7 +2321,7 @@ will run the command in a pseudo-tty and
|
||||
to the screen, similar to the
|
||||
script(1)
|
||||
command.
|
||||
-For more information, see the
|
||||
+For more information about I/O logging, see the
|
||||
\fII/O LOG FILES\fR
|
||||
section.
|
||||
This flag is
|
||||
@@ -2934,14 +2941,24 @@ This flag is
|
||||
by default.
|
||||
.TP 18n
|
||||
use_pty
|
||||
-If set,
|
||||
+If set, and
|
||||
\fBsudo\fR
|
||||
-will run the command in a pseudo-pty even if no I/O logging is being gone.
|
||||
+is running in a terminal, the command will be run in a pseudo-pty
|
||||
+(even if no I/O logging is being done).
|
||||
+If the
|
||||
+\fBsudo\fR
|
||||
+process is not attached to a terminal,
|
||||
+\fIuse_pty\fR
|
||||
+has no effect.
|
||||
+.sp
|
||||
A malicious program run under
|
||||
\fBsudo\fR
|
||||
-could conceivably fork a background process that retains to the user's
|
||||
-terminal device after the main program has finished executing.
|
||||
-Use of this option will make that impossible.
|
||||
+may be capable of injecting injecting commands into the user's
|
||||
+terminal or running a background process that retains access to the
|
||||
+user's terminal device even after the main program has finished
|
||||
+executing.
|
||||
+By running the command in a separate pseudo-pty, this attack is
|
||||
+no longer possible.
|
||||
This flag is
|
||||
\fIoff\fR
|
||||
by default.
|
||||
@@ -4281,7 +4298,8 @@ word wrap will be disabled.
|
||||
.SH "I/O LOG FILES"
|
||||
When I/O logging is enabled,
|
||||
\fBsudo\fR
|
||||
-will run the command in a pseudo-tty and log all user input and/or output.
|
||||
+will run the command in a pseudo-tty and log all user input and/or output,
|
||||
+depending on which options are enabled.
|
||||
I/O is logged to the directory specified by the
|
||||
\fIiolog_dir\fR
|
||||
option
|
||||
diff -up ./doc/sudoers.mdoc.in.manpage ./doc/sudoers.mdoc.in
|
||||
--- ./doc/sudoers.mdoc.in.manpage 2017-09-11 15:16:47.445869920 +0200
|
||||
+++ ./doc/sudoers.mdoc.in 2017-09-11 15:16:47.456869864 +0200
|
||||
@@ -2155,7 +2155,14 @@ will run the command in a pseudo-tty and
|
||||
If the standard input is not connected to the user's tty, due to
|
||||
I/O redirection or because the command is part of a pipeline, that
|
||||
input is also captured and stored in a separate log file.
|
||||
-For more information, see the
|
||||
+Anything sent to the standard input will be consumed, regardless of
|
||||
+whether or not the command run via
|
||||
+.Nm sudo
|
||||
+is actually reading the standard input.
|
||||
+This may have unexpected results when using
|
||||
+.Nm sudo
|
||||
+in a shell script that expects to process the standard input.
|
||||
+For more information about I/O logging, see the
|
||||
.Sx "I/O LOG FILES"
|
||||
section.
|
||||
This flag is
|
||||
@@ -2168,7 +2175,7 @@ will run the command in a pseudo-tty and
|
||||
to the screen, similar to the
|
||||
.Xr script 1
|
||||
command.
|
||||
-For more information, see the
|
||||
+For more information about I/O logging, see the
|
||||
.Sx "I/O LOG FILES"
|
||||
section.
|
||||
This flag is
|
||||
@@ -2752,14 +2759,24 @@ This flag is
|
||||
.Em on
|
||||
by default.
|
||||
.It use_pty
|
||||
-If set,
|
||||
+If set, and
|
||||
.Nm sudo
|
||||
-will run the command in a pseudo-pty even if no I/O logging is being gone.
|
||||
+is running in a terminal, the command will be run in a pseudo-pty
|
||||
+(even if no I/O logging is being done).
|
||||
+If the
|
||||
+.Nm sudo
|
||||
+process is not attached to a terminal,
|
||||
+.Em use_pty
|
||||
+has no effect.
|
||||
+.Pp
|
||||
A malicious program run under
|
||||
.Nm sudo
|
||||
-could conceivably fork a background process that retains to the user's
|
||||
-terminal device after the main program has finished executing.
|
||||
-Use of this option will make that impossible.
|
||||
+may be capable of injecting injecting commands into the user's
|
||||
+terminal or running a background process that retains access to the
|
||||
+user's terminal device even after the main program has finished
|
||||
+executing.
|
||||
+By running the command in a separate pseudo-pty, this attack is
|
||||
+no longer possible.
|
||||
This flag is
|
||||
.Em off
|
||||
by default.
|
||||
@@ -3976,7 +3993,8 @@ word wrap will be disabled.
|
||||
.Sh I/O LOG FILES
|
||||
When I/O logging is enabled,
|
||||
.Nm sudo
|
||||
-will run the command in a pseudo-tty and log all user input and/or output.
|
||||
+will run the command in a pseudo-tty and log all user input and/or output,
|
||||
+depending on which options are enabled.
|
||||
I/O is logged to the directory specified by the
|
||||
.Em iolog_dir
|
||||
option
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
# HG changeset patch
|
||||
# User Todd C. Miller <Todd.Miller@sudo.ws>
|
||||
# Date 1511893724 25200
|
||||
# Node ID 14dacdea331942a38d443a75d1b08f67eafaa5eb
|
||||
# Parent b456101fe5091540e9f6429db7568fa32b6d4da8
|
||||
Avoid a double free when ipa_hostname is set in sssd.conf and it
|
||||
is an unqualified host name. From Daniel Kopecek.
|
||||
|
||||
Also move the "unable to allocate memory" warning into get_ipa_hostname()
|
||||
itself to make it easier to see where the allocation failed in the
|
||||
debug log.
|
||||
|
||||
diff -r b456101fe509 -r 14dacdea3319 plugins/sudoers/sssd.c
|
||||
--- a/plugins/sudoers/sssd.c Tue Nov 28 09:48:43 2017 -0700
|
||||
+++ b/plugins/sudoers/sssd.c Tue Nov 28 11:28:44 2017 -0700
|
||||
@@ -349,6 +349,8 @@
|
||||
*lhostp = lhost;
|
||||
ret = true;
|
||||
} else {
|
||||
+ sudo_warnx(U_("%s: %s"), __func__,
|
||||
+ U_("unable to allocate memory"));
|
||||
free(shost);
|
||||
free(lhost);
|
||||
ret = -1;
|
||||
@@ -456,7 +458,6 @@
|
||||
*/
|
||||
if (strcmp(user_runhost, user_host) == 0) {
|
||||
if (get_ipa_hostname(&handle->ipa_shost, &handle->ipa_host) == -1) {
|
||||
- sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
free(handle);
|
||||
debug_return_int(ENOMEM);
|
||||
}
|
||||
@@ -478,7 +479,8 @@
|
||||
handle = nss->handle;
|
||||
sudo_dso_unload(handle->ssslib);
|
||||
free(handle->ipa_host);
|
||||
- free(handle->ipa_shost);
|
||||
+ if (handle->ipa_host != handle->ipa_shost)
|
||||
+ free(handle->ipa_shost);
|
||||
free(handle);
|
||||
nss->handle = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
From 1f37620953699fe71b09760fe01e33eb6ada771c Mon Sep 17 00:00:00 2001
|
||||
From: "Todd C. Miller" <Todd.Miller@courtesan.com>
|
||||
Date: Wed, 15 Nov 2017 12:27:39 -0700
|
||||
Subject: [PATCH] When checking the results for "sudo -l" and "sudo -v", keep
|
||||
checking even after we get a match since the value of doauth may depend on
|
||||
evaluating all the results. From Radovan Sroka of RedHat.
|
||||
|
||||
In list (-l) or verify (-v) mode, if we have a match but authentication
|
||||
is required, clear FLAG_NOPASSWD so that when listpw/verifypw is
|
||||
set to "all" and there are multiple sudoers sources a password will
|
||||
be required unless none of the entries in all sources require
|
||||
authentication. From Radovan Sroka of RedHat
|
||||
|
||||
Avoid calling cmnd_matches() in list/verify mode if we already have
|
||||
a match.
|
||||
---
|
||||
plugins/sudoers/ldap.c | 5 ++++-
|
||||
plugins/sudoers/parse.c | 10 +++++++---
|
||||
plugins/sudoers/sssd.c | 5 ++++-
|
||||
3 files changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
|
||||
index 46309cba..c5c18360 100644
|
||||
--- a/plugins/sudoers/ldap.c
|
||||
+++ b/plugins/sudoers/ldap.c
|
||||
@@ -3320,12 +3320,13 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
|
||||
(pwcheck == all && doauth != true)) {
|
||||
doauth = !!sudo_ldap_check_bool(ld, entry, "authenticate");
|
||||
}
|
||||
+ if (matched == true)
|
||||
+ continue;
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
sudo_ldap_check_command(ld, entry, NULL) == true) {
|
||||
matched = true;
|
||||
- break;
|
||||
}
|
||||
}
|
||||
if (matched == true || user_uid == 0) {
|
||||
@@ -3339,6 +3340,8 @@ sudo_ldap_lookup(struct sudo_nss *nss, int ret, int pwflag)
|
||||
case any:
|
||||
if (doauth == false)
|
||||
SET(ret, FLAG_NOPASSWD);
|
||||
+ else
|
||||
+ CLR(ret, FLAG_NOPASSWD);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
diff --git a/plugins/sudoers/parse.c b/plugins/sudoers/parse.c
|
||||
index 749a3eb2..a12e88c5 100644
|
||||
--- a/plugins/sudoers/parse.c
|
||||
+++ b/plugins/sudoers/parse.c
|
||||
@@ -182,14 +182,16 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
if (hostlist_matches(sudo_user.pw, &priv->hostlist) != ALLOW)
|
||||
continue;
|
||||
TAILQ_FOREACH(cs, &priv->cmndlist, entries) {
|
||||
+ if ((pwcheck == any && cs->tags.nopasswd == true) ||
|
||||
+ (pwcheck == all && cs->tags.nopasswd != true))
|
||||
+ nopass = cs->tags.nopasswd;
|
||||
+ if (match == ALLOW)
|
||||
+ continue;
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
cmnd_matches(cs->cmnd) == ALLOW)
|
||||
match = ALLOW;
|
||||
- if ((pwcheck == any && cs->tags.nopasswd == true) ||
|
||||
- (pwcheck == all && cs->tags.nopasswd != true))
|
||||
- nopass = cs->tags.nopasswd;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,6 +204,8 @@ sudo_file_lookup(struct sudo_nss *nss, int validated, int pwflag)
|
||||
SET(validated, FLAG_CHECK_USER);
|
||||
else if (nopass == true)
|
||||
SET(validated, FLAG_NOPASSWD);
|
||||
+ else
|
||||
+ CLR(validated, FLAG_NOPASSWD);
|
||||
debug_return_int(validated);
|
||||
}
|
||||
|
||||
diff --git a/plugins/sudoers/sssd.c b/plugins/sudoers/sssd.c
|
||||
index 65b4d875..09ca9fee 100644
|
||||
--- a/plugins/sudoers/sssd.c
|
||||
+++ b/plugins/sudoers/sssd.c
|
||||
@@ -1321,12 +1321,13 @@ sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag)
|
||||
(pwcheck == all && doauth != true)) {
|
||||
doauth = !!sudo_sss_check_bool(handle, rule, "authenticate");
|
||||
}
|
||||
+ if (matched == true)
|
||||
+ continue;
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
sudo_sss_check_command(handle, rule, NULL) == true) {
|
||||
matched = true;
|
||||
- break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1341,6 +1342,8 @@ sudo_sss_lookup(struct sudo_nss *nss, int ret, int pwflag)
|
||||
case any:
|
||||
if (doauth == false)
|
||||
SET(ret, FLAG_NOPASSWD);
|
||||
+ else
|
||||
+ CLR(ret, FLAG_NOPASSWD);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
--
|
||||
2.14.3
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
diff -up ./plugins/sudoers/regress/visudo/test2.err.ok.orig ./plugins/sudoers/regress/visudo/test2.err.ok
|
||||
--- ./plugins/sudoers/regress/visudo/test2.err.ok.orig 2017-04-10 10:12:53.003000000 -0400
|
||||
+++ ./plugins/sudoers/regress/visudo/test2.err.ok 2017-04-10 10:13:36.771000000 -0400
|
||||
@@ -1 +1 @@
|
||||
-visudo: stdin:1 cycle in User_Alias "FOO"
|
||||
+Error: stdin:1 cycle in User_Alias "FOO"
|
||||
diff -up ./plugins/sudoers/regress/visudo/test3.err.ok.orig ./plugins/sudoers/regress/visudo/test3.err.ok
|
||||
--- ./plugins/sudoers/regress/visudo/test3.err.ok.orig 2017-04-10 10:13:12.141000000 -0400
|
||||
+++ ./plugins/sudoers/regress/visudo/test3.err.ok 2017-04-10 10:13:56.842000000 -0400
|
||||
@@ -1,2 +1,2 @@
|
||||
-visudo: stdin:1 unused User_Alias "A"
|
||||
-visudo: stdin:2 unused User_Alias "B"
|
||||
+Warning: stdin:1 unused User_Alias "A"
|
||||
+Warning: stdin:2 unused User_Alias "B"
|
|
@ -0,0 +1,19 @@
|
|||
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
|
||||
index f21a99ee..83202e28 100644
|
||||
--- a/plugins/sudoers/ldap.c
|
||||
+++ b/plugins/sudoers/ldap.c
|
||||
@@ -1847,12 +1847,10 @@ sudo_ldap_build_pass2(void)
|
||||
ldap_conf.timed ? timebuffer : "",
|
||||
(ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
|
||||
} else {
|
||||
- len = asprintf(&filt, "%s%s(sudoUser=*)(sudoUser=%s*)%s%s",
|
||||
- (ldap_conf.timed || ldap_conf.search_filter) ? "(&" : "",
|
||||
+ len = asprintf(&filt, "(&%s(sudoUser=*)(sudoUser=%s*)%s)",
|
||||
ldap_conf.search_filter ? ldap_conf.search_filter : "",
|
||||
query_netgroups ? "+" : "%:",
|
||||
- ldap_conf.timed ? timebuffer : "",
|
||||
- (ldap_conf.timed || ldap_conf.search_filter) ? ")" : "");
|
||||
+ ldap_conf.timed ? timebuffer : "");
|
||||
}
|
||||
if (len == -1)
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
|
@ -0,0 +1,113 @@
|
|||
diff -up sudo-1.8.6p3/doc/sudoers.cat.orig sudo-1.8.6p3/doc/sudoers.cat
|
||||
--- sudo-1.8.6p3/doc/sudoers.cat.orig 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.cat 2013-07-10 14:57:53.791093835 +0200
|
||||
@@ -668,11 +668,24 @@ SSUUDDOOEERRSS FFIILLEE FFO
|
||||
since in a command context, it allows the user to run aannyy command on the
|
||||
system.
|
||||
|
||||
- An exclamation point (`!') can be used as a logical _n_o_t operator both in
|
||||
- an _a_l_i_a_s and in front of a Cmnd. This allows one to exclude certain
|
||||
- values. Note, however, that using a `!' in conjunction with the built-in
|
||||
- AALLLL alias to allow a user to run ``all but a few'' commands rarely works
|
||||
- as intended (see _S_E_C_U_R_I_T_Y _N_O_T_E_S below).
|
||||
+ An exclamation point (`!') can be used as a logical _n_o_t operator in a
|
||||
+ list or _a_l_i_a_s as well as in front of a Cmnd. This allows one to exclude
|
||||
+ certain values. For the `!' operator to be effective, there must be
|
||||
+ something for it to exclude. For example, to match all users except for
|
||||
+ root one would use:
|
||||
+
|
||||
+ ALL,!root
|
||||
+
|
||||
+ If the AALLLL, is omitted, as in:
|
||||
+
|
||||
+ !root
|
||||
+
|
||||
+ it would explicitly deny root but not match any other users. This is
|
||||
+ different from a true ``negation'' operator.
|
||||
+
|
||||
+ Note, however, that using a `!' in conjunction with the built-in AALLLL
|
||||
+ alias to allow a user to run ``all but a few'' commands rarely works as
|
||||
+ intended (see _S_E_C_U_R_I_T_Y _N_O_T_E_S below).
|
||||
|
||||
Long lines can be continued with a backslash (`\') as the last character
|
||||
on the line.
|
||||
diff -up sudo-1.8.6p3/doc/sudoers.man.in.orig sudo-1.8.6p3/doc/sudoers.man.in
|
||||
--- sudo-1.8.6p3/doc/sudoers.man.in.orig 2013-07-10 13:00:20.987336061 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.man.in 2013-07-10 14:57:53.792093837 +0200
|
||||
@@ -1490,11 +1490,37 @@ An exclamation point
|
||||
(`\&!')
|
||||
can be used as a logical
|
||||
\fInot\fR
|
||||
-operator both in an
|
||||
+operator in a list or
|
||||
\fIalias\fR
|
||||
-and in front of a
|
||||
+as well as in front of a
|
||||
\fRCmnd\fR.
|
||||
This allows one to exclude certain values.
|
||||
+For the
|
||||
+`\&!'
|
||||
+operator to be effective, there must be something for it to exclude.
|
||||
+For example, to match all users except for root one would use:
|
||||
+.nf
|
||||
+.sp
|
||||
+.RS 4n
|
||||
+ALL,!root
|
||||
+.RE
|
||||
+.fi
|
||||
+.PP
|
||||
+If the
|
||||
+\fBALL\fR,
|
||||
+is omitted, as in:
|
||||
+.nf
|
||||
+.sp
|
||||
+.RS 4n
|
||||
+!root
|
||||
+.RE
|
||||
+.fi
|
||||
+.PP
|
||||
+it would explicitly deny root but not match any other users.
|
||||
+This is different from a true
|
||||
+``negation''
|
||||
+operator.
|
||||
+.PP
|
||||
Note, however, that using a
|
||||
`\&!'
|
||||
in conjunction with the built-in
|
||||
diff -up sudo-1.8.6p3/doc/sudoers.mdoc.in.orig sudo-1.8.6p3/doc/sudoers.mdoc.in
|
||||
--- sudo-1.8.6p3/doc/sudoers.mdoc.in.orig 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.mdoc.in 2013-07-10 14:57:53.793093839 +0200
|
||||
@@ -1393,11 +1393,31 @@ An exclamation point
|
||||
.Pq Ql \&!
|
||||
can be used as a logical
|
||||
.Em not
|
||||
-operator both in an
|
||||
+operator in a list or
|
||||
.Em alias
|
||||
-and in front of a
|
||||
+as well as in front of a
|
||||
.Li Cmnd .
|
||||
This allows one to exclude certain values.
|
||||
+For the
|
||||
+.Ql \&!
|
||||
+operator to be effective, there must be something for it to exclude.
|
||||
+For example, to match all users except for root one would use:
|
||||
+.Bd -literal -offset 4n
|
||||
+ALL,!root
|
||||
+.Ed
|
||||
+.Pp
|
||||
+If the
|
||||
+.Sy ALL ,
|
||||
+is omitted, as in:
|
||||
+.Bd -literal -offset 4n
|
||||
+!root
|
||||
+.Ed
|
||||
+.Pp
|
||||
+it would explicitly deny root but not match any other users.
|
||||
+This is different from a true
|
||||
+.Dq negation
|
||||
+operator.
|
||||
+.Pp
|
||||
Note, however, that using a
|
||||
.Ql \&!
|
||||
in conjunction with the built-in
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/visudo.c.aliaswarnonly sudo-1.8.6p3/plugins/sudoers/visudo.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/visudo.c.aliaswarnonly 2012-09-25 16:19:04.995831784 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/visudo.c 2012-09-25 16:20:15.768964400 +0200
|
||||
@@ -1238,7 +1238,7 @@ check_aliases(bool strict, bool quiet)
|
||||
|
||||
/* If all aliases were referenced we will have an empty tree. */
|
||||
if (!no_aliases() && !quiet)
|
||||
- alias_apply(print_unused, strict ? "Error" : "Warning");
|
||||
+ alias_apply(print_unused, "Warning");
|
||||
|
||||
debug_return_int(strict ? errors : 0);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/sudoers.c.auditeditor sudo-1.8.6p3/plugins/sudoers/sudoers.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sudoers.c.auditeditor 2012-09-24 16:16:07.577331344 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sudoers.c 2012-09-24 16:30:16.738174293 +0200
|
||||
@@ -709,7 +709,24 @@ sudoers_policy_main(int argc, char * con
|
||||
#endif /* HAVE_SELINUX */
|
||||
|
||||
/* Must audit before uid change. */
|
||||
- audit_success(NewArgv);
|
||||
+ if (ISSET(sudo_mode, MODE_EDIT)) {
|
||||
+ /*
|
||||
+ * Build a new argv, argc for the audit system
|
||||
+ * so that the editor being invoked is visible
|
||||
+ * in audit messages.
|
||||
+ */
|
||||
+ char *editor = NULL;
|
||||
+ char **editor_argv = NULL;
|
||||
+
|
||||
+ editor = find_editor(NewArgc - 1, NewArgv + 1, &editor_argv);
|
||||
+
|
||||
+ if (editor) {
|
||||
+ audit_success(editor_argv);
|
||||
+ efree(editor_argv);
|
||||
+ } else
|
||||
+ errorx(1, _("Can't find an editor"));
|
||||
+ } else
|
||||
+ audit_success(NewArgv);
|
||||
|
||||
*command_infop = command_info;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
diff -up sudo-1.8.6p3/src/selinux.c.auditrolechange sudo-1.8.6p3/src/selinux.c
|
||||
--- sudo-1.8.6p3/src/selinux.c.auditrolechange 2012-09-25 16:29:58.090826474 +0200
|
||||
+++ sudo-1.8.6p3/src/selinux.c 2012-09-25 16:33:53.953084178 +0200
|
||||
@@ -63,7 +63,7 @@ static struct selinux_state {
|
||||
#ifdef HAVE_LINUX_AUDIT
|
||||
static int
|
||||
audit_role_change(const security_context_t old_context,
|
||||
- const security_context_t new_context, const char *ttyn)
|
||||
+ const security_context_t new_context, const char *ttyn, int result)
|
||||
{
|
||||
int au_fd, rc = -1;
|
||||
char *message;
|
||||
@@ -80,7 +80,7 @@ audit_role_change(const security_context
|
||||
easprintf(&message, "newrole: old-context=%s new-context=%s",
|
||||
old_context, new_context);
|
||||
rc = audit_log_user_message(au_fd, AUDIT_USER_ROLE_CHANGE,
|
||||
- message, NULL, NULL, ttyn, 1);
|
||||
+ message, NULL, NULL, ttyn, result);
|
||||
if (rc <= 0)
|
||||
warning(_("unable to send audit message"));
|
||||
efree(message);
|
||||
@@ -335,8 +335,13 @@ selinux_setup(const char *role, const ch
|
||||
warningx("your old context was %s", se_state.old_context);
|
||||
#endif
|
||||
se_state.new_context = get_exec_context(se_state.old_context, role, type);
|
||||
- if (!se_state.new_context)
|
||||
+ if (!se_state.new_context) {
|
||||
+#ifdef HAVE_LINUX_AUDIT
|
||||
+ audit_role_change(se_state.old_context, "?",
|
||||
+ se_state.ttyn, 0);
|
||||
+#endif
|
||||
goto done;
|
||||
+ }
|
||||
|
||||
if (relabel_tty(ttyn, ptyfd) < 0) {
|
||||
warning(_("unable to setup tty context for %s"), se_state.new_context);
|
||||
@@ -352,7 +357,7 @@ selinux_setup(const char *role, const ch
|
||||
|
||||
#ifdef HAVE_LINUX_AUDIT
|
||||
audit_role_change(se_state.old_context, se_state.new_context,
|
||||
- se_state.ttyn);
|
||||
+ se_state.ttyn, 1);
|
||||
#endif
|
||||
|
||||
rval = 0;
|
|
@ -0,0 +1,26 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/auth/pam.c.authinterrupt sudo-1.8.6p3/plugins/sudoers/auth/pam.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/auth/pam.c.authinterrupt 2014-05-22 13:46:31.204706184 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/auth/pam.c 2014-05-22 13:47:06.729830043 +0200
|
||||
@@ -167,13 +167,13 @@ sudo_pam_verify(struct passwd *pw, char
|
||||
/* FALLTHROUGH */
|
||||
case PAM_AUTH_ERR:
|
||||
case PAM_AUTHINFO_UNAVAIL:
|
||||
+ case PAM_PERM_DENIED:
|
||||
if (getpass_error) {
|
||||
/* error or ^C from tgetpass() */
|
||||
debug_return_int(AUTH_INTR);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case PAM_MAXTRIES:
|
||||
- case PAM_PERM_DENIED:
|
||||
debug_return_int(AUTH_FAILURE);
|
||||
default:
|
||||
if ((s = pam_strerror(pamh, *pam_status)))
|
||||
@@ -343,6 +343,7 @@ converse(int num_msg, PAM_CONST struct p
|
||||
if (pass == NULL) {
|
||||
/* Error (or ^C) reading password, don't try again. */
|
||||
getpass_error = 1;
|
||||
+ ret = PAM_CONV_ERR;
|
||||
#if (defined(__darwin__) || defined(__APPLE__)) && !defined(OPENPAM_VERSION)
|
||||
pass = "";
|
||||
#else
|
|
@ -0,0 +1,477 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/alias.c.cycledetect sudo-1.8.6p3/plugins/sudoers/alias.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/alias.c.cycledetect 2012-09-18 15:56:29.000000000 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/alias.c 2013-08-09 10:52:04.785860905 +0200
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2004-2005, 2007-2011
|
||||
+ * Copyright (c) 2004-2005, 2007-2013
|
||||
* Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@@ -50,7 +50,6 @@
|
||||
* Globals
|
||||
*/
|
||||
struct rbtree *aliases;
|
||||
-unsigned int alias_seqno;
|
||||
|
||||
/*
|
||||
* Comparison function for the red-black tree.
|
||||
@@ -76,29 +75,31 @@ alias_compare(const void *v1, const void
|
||||
/*
|
||||
* Search the tree for an alias with the specified name and type.
|
||||
* Returns a pointer to the alias structure or NULL if not found.
|
||||
+ * Caller is responsible for calling alias_put() on the returned
|
||||
+ * alias to mark it as unused.
|
||||
*/
|
||||
struct alias *
|
||||
-alias_find(char *name, int type)
|
||||
+alias_get(char *name, int type)
|
||||
{
|
||||
struct alias key;
|
||||
struct rbnode *node;
|
||||
struct alias *a = NULL;
|
||||
- debug_decl(alias_find, SUDO_DEBUG_ALIAS)
|
||||
+ debug_decl(alias_get, SUDO_DEBUG_ALIAS)
|
||||
|
||||
key.name = name;
|
||||
key.type = type;
|
||||
if ((node = rbfind(aliases, &key)) != NULL) {
|
||||
/*
|
||||
- * Compare the global sequence number with the one stored
|
||||
- * in the alias. If they match then we've seen this alias
|
||||
- * before and found a loop.
|
||||
+ * Check whether this alias is already in use.
|
||||
+ * If so, we've detected a loop. If not, set the flag,
|
||||
+ * which the caller should clear with a call to alias_put().
|
||||
*/
|
||||
a = node->data;
|
||||
- if (a->seqno == alias_seqno) {
|
||||
+ if (a->used) {
|
||||
errno = ELOOP;
|
||||
debug_return_ptr(NULL);
|
||||
}
|
||||
- a->seqno = alias_seqno;
|
||||
+ a->used = true;
|
||||
} else {
|
||||
errno = ENOENT;
|
||||
}
|
||||
@@ -106,6 +107,17 @@ alias_find(char *name, int type)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Clear the "used" flag in an alias once the caller is done with it.
|
||||
+ */
|
||||
+void
|
||||
+alias_put(struct alias *a)
|
||||
+{
|
||||
+ debug_decl(alias_put, SUDO_DEBUG_ALIAS)
|
||||
+ a->used = false;
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Add an alias to the aliases redblack tree.
|
||||
* Returns NULL on success and an error string on failure.
|
||||
*/
|
||||
@@ -119,7 +131,7 @@ alias_add(char *name, int type, struct m
|
||||
a = ecalloc(1, sizeof(*a));
|
||||
a->name = name;
|
||||
a->type = type;
|
||||
- /* a->seqno = 0; */
|
||||
+ /* a->used = false; */
|
||||
list2tq(&a->members, members);
|
||||
if (rbinsert(aliases, a)) {
|
||||
snprintf(errbuf, sizeof(errbuf), _("Alias `%s' already defined"), name);
|
||||
diff -up sudo-1.8.6p3/plugins/sudoers/match.c.cycledetect sudo-1.8.6p3/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/match.c.cycledetect 2013-08-09 10:52:04.783860895 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/match.c 2013-08-09 10:52:04.785860905 +0200
|
||||
@@ -101,13 +101,13 @@ static bool command_matches_normal(char
|
||||
* Check for user described by pw in a list of members.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
-static int
|
||||
-_userlist_matches(struct passwd *pw, struct member_list *list)
|
||||
+int
|
||||
+userlist_matches(struct passwd *pw, struct member_list *list)
|
||||
{
|
||||
struct member *m;
|
||||
struct alias *a;
|
||||
int rval, matched = UNSPEC;
|
||||
- debug_decl(_userlist_matches, SUDO_DEBUG_MATCH)
|
||||
+ debug_decl(userlist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
tq_foreach_rev(list, m) {
|
||||
switch (m->type) {
|
||||
@@ -123,10 +123,11 @@ _userlist_matches(struct passwd *pw, str
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
- if ((a = alias_find(m->name, USERALIAS)) != NULL) {
|
||||
- rval = _userlist_matches(pw, &a->members);
|
||||
+ if ((a = alias_get(m->name, USERALIAS)) != NULL) {
|
||||
+ rval = userlist_matches(pw, &a->members);
|
||||
if (rval != UNSPEC)
|
||||
matched = m->negated ? !rval : rval;
|
||||
+ alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@@ -141,20 +142,13 @@ _userlist_matches(struct passwd *pw, str
|
||||
debug_return_bool(matched);
|
||||
}
|
||||
|
||||
-int
|
||||
-userlist_matches(struct passwd *pw, struct member_list *list)
|
||||
-{
|
||||
- alias_seqno++;
|
||||
- return _userlist_matches(pw, list);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Check for user described by pw in a list of members.
|
||||
* If both lists are empty compare against def_runas_default.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
-static int
|
||||
-_runaslist_matches(struct member_list *user_list,
|
||||
+int
|
||||
+runaslist_matches(struct member_list *user_list,
|
||||
struct member_list *group_list, struct member **matching_user,
|
||||
struct member **matching_group)
|
||||
{
|
||||
@@ -163,7 +157,7 @@ _runaslist_matches(struct member_list *u
|
||||
int rval;
|
||||
int user_matched = UNSPEC;
|
||||
int group_matched = UNSPEC;
|
||||
- debug_decl(_runaslist_matches, SUDO_DEBUG_MATCH)
|
||||
+ debug_decl(runaslist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
if (runas_pw != NULL) {
|
||||
/* If no runas user or runas group listed in sudoers, use default. */
|
||||
@@ -184,11 +178,12 @@ _runaslist_matches(struct member_list *u
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
- if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {
|
||||
- rval = _runaslist_matches(&a->members, &empty,
|
||||
+ if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
|
||||
+ rval = runaslist_matches(&a->members, &empty,
|
||||
matching_user, NULL);
|
||||
if (rval != UNSPEC)
|
||||
user_matched = m->negated ? !rval : rval;
|
||||
+ alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@@ -221,11 +216,12 @@ _runaslist_matches(struct member_list *u
|
||||
group_matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
- if ((a = alias_find(m->name, RUNASALIAS)) != NULL) {
|
||||
- rval = _runaslist_matches(&empty, &a->members,
|
||||
+ if ((a = alias_get(m->name, RUNASALIAS)) != NULL) {
|
||||
+ rval = runaslist_matches(&empty, &a->members,
|
||||
NULL, matching_group);
|
||||
if (rval != UNSPEC)
|
||||
group_matched = m->negated ? !rval : rval;
|
||||
+ alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@@ -253,27 +249,17 @@ _runaslist_matches(struct member_list *u
|
||||
debug_return_int(UNSPEC);
|
||||
}
|
||||
|
||||
-int
|
||||
-runaslist_matches(struct member_list *user_list,
|
||||
- struct member_list *group_list, struct member **matching_user,
|
||||
- struct member **matching_group)
|
||||
-{
|
||||
- alias_seqno++;
|
||||
- return _runaslist_matches(user_list ? user_list : &empty,
|
||||
- group_list ? group_list : &empty, matching_user, matching_group);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Check for host and shost in a list of members.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
-static int
|
||||
-_hostlist_matches(struct member_list *list)
|
||||
+int
|
||||
+hostlist_matches(struct member_list *list)
|
||||
{
|
||||
struct member *m;
|
||||
struct alias *a;
|
||||
int rval, matched = UNSPEC;
|
||||
- debug_decl(_hostlist_matches, SUDO_DEBUG_MATCH)
|
||||
+ debug_decl(hostlist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
tq_foreach_rev(list, m) {
|
||||
switch (m->type) {
|
||||
@@ -289,10 +275,11 @@ _hostlist_matches(struct member_list *li
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
- if ((a = alias_find(m->name, HOSTALIAS)) != NULL) {
|
||||
- rval = _hostlist_matches(&a->members);
|
||||
+ if ((a = alias_get(m->name, HOSTALIAS)) != NULL) {
|
||||
+ rval = hostlist_matches(&a->members);
|
||||
if (rval != UNSPEC)
|
||||
matched = m->negated ? !rval : rval;
|
||||
+ alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@@ -307,23 +294,16 @@ _hostlist_matches(struct member_list *li
|
||||
debug_return_bool(matched);
|
||||
}
|
||||
|
||||
-int
|
||||
-hostlist_matches(struct member_list *list)
|
||||
-{
|
||||
- alias_seqno++;
|
||||
- return _hostlist_matches(list);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Check for cmnd and args in a list of members.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
*/
|
||||
-static int
|
||||
-_cmndlist_matches(struct member_list *list)
|
||||
+int
|
||||
+cmndlist_matches(struct member_list *list)
|
||||
{
|
||||
struct member *m;
|
||||
int matched = UNSPEC;
|
||||
- debug_decl(_cmndlist_matches, SUDO_DEBUG_MATCH)
|
||||
+ debug_decl(cmndlist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
tq_foreach_rev(list, m) {
|
||||
matched = cmnd_matches(m);
|
||||
@@ -333,13 +313,6 @@ _cmndlist_matches(struct member_list *li
|
||||
debug_return_bool(matched);
|
||||
}
|
||||
|
||||
-int
|
||||
-cmndlist_matches(struct member_list *list)
|
||||
-{
|
||||
- alias_seqno++;
|
||||
- return _cmndlist_matches(list);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Check cmnd and args.
|
||||
* Returns ALLOW, DENY or UNSPEC.
|
||||
@@ -357,11 +330,11 @@ cmnd_matches(struct member *m)
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case ALIAS:
|
||||
- alias_seqno++;
|
||||
- if ((a = alias_find(m->name, CMNDALIAS)) != NULL) {
|
||||
- rval = _cmndlist_matches(&a->members);
|
||||
+ if ((a = alias_get(m->name, CMNDALIAS)) != NULL) {
|
||||
+ rval = cmndlist_matches(&a->members);
|
||||
if (rval != UNSPEC)
|
||||
matched = m->negated ? !rval : rval;
|
||||
+ alias_put(a);
|
||||
}
|
||||
break;
|
||||
case COMMAND:
|
||||
diff -up sudo-1.8.6p3/plugins/sudoers/parse.c.cycledetect sudo-1.8.6p3/plugins/sudoers/parse.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/parse.c.cycledetect 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/parse.c 2013-08-09 10:52:04.785860905 +0200
|
||||
@@ -676,13 +676,14 @@ _print_member(struct lbuf *lbuf, char *n
|
||||
}
|
||||
break;
|
||||
case ALIAS:
|
||||
- if ((a = alias_find(name, alias_type)) != NULL) {
|
||||
+ if ((a = alias_get(name, alias_type)) != NULL) {
|
||||
tq_foreach_fwd(&a->members, m) {
|
||||
if (m != tq_first(&a->members))
|
||||
lbuf_append(lbuf, ", ");
|
||||
_print_member(lbuf, m->name, m->type,
|
||||
negated ? !m->negated : m->negated, alias_type);
|
||||
}
|
||||
+ alias_put(a);
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
@@ -697,6 +698,5 @@ static void
|
||||
print_member(struct lbuf *lbuf, char *name, int type, int negated,
|
||||
int alias_type)
|
||||
{
|
||||
- alias_seqno++;
|
||||
_print_member(lbuf, name, type, negated, alias_type);
|
||||
}
|
||||
diff -up sudo-1.8.6p3/plugins/sudoers/parse.h.cycledetect sudo-1.8.6p3/plugins/sudoers/parse.h
|
||||
--- sudo-1.8.6p3/plugins/sudoers/parse.h.cycledetect 2012-09-18 15:56:29.000000000 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/parse.h 2013-08-09 10:54:30.984565529 +0200
|
||||
@@ -148,7 +148,7 @@ struct runascontainer {
|
||||
struct alias {
|
||||
char *name; /* alias name */
|
||||
unsigned short type; /* {USER,HOST,RUNAS,CMND}ALIAS */
|
||||
- unsigned short seqno; /* sequence number */
|
||||
+ bool used; /* "used" flag for cycle detection */
|
||||
struct member_list members; /* list of alias members */
|
||||
};
|
||||
|
||||
@@ -170,35 +170,39 @@ struct defaults {
|
||||
extern struct userspec_list userspecs;
|
||||
extern struct defaults_list defaults;
|
||||
|
||||
-/*
|
||||
- * Alias sequence number to avoid loops.
|
||||
- */
|
||||
-extern unsigned int alias_seqno;
|
||||
-
|
||||
-/*
|
||||
- * Prototypes
|
||||
- */
|
||||
-char *alias_add(char *, int, struct member *);
|
||||
-bool addr_matches(char *);
|
||||
-int cmnd_matches(struct member *);
|
||||
-int cmndlist_matches(struct member_list *);
|
||||
-bool command_matches(char *, char *);
|
||||
-int hostlist_matches(struct member_list *);
|
||||
-bool hostname_matches(char *, char *, char *);
|
||||
-bool netgr_matches(char *, char *, char *, char *);
|
||||
+/* alias.c */
|
||||
bool no_aliases(void);
|
||||
-int runaslist_matches(struct member_list *, struct member_list *, struct member **, struct member **);
|
||||
-int userlist_matches(struct passwd *, struct member_list *);
|
||||
-bool usergr_matches(char *, char *, struct passwd *);
|
||||
-bool userpw_matches(char *, char *, struct passwd *);
|
||||
-bool group_matches(char *, struct group *);
|
||||
-struct alias *alias_find(char *, int);
|
||||
-struct alias *alias_remove(char *, int);
|
||||
-void alias_free(void *);
|
||||
-void alias_apply(int (*)(void *, void *), void *);
|
||||
+char *alias_add(char *name, int type, struct member *members);
|
||||
+int alias_compare(const void *a1, const void *a2);
|
||||
+struct alias *alias_get(char *name, int type);
|
||||
+struct alias *alias_remove(char *name, int type);
|
||||
+void alias_apply(int (*func)(void *, void *), void *cookie);
|
||||
+void alias_free(void *a);
|
||||
+void alias_put(struct alias *a);
|
||||
void init_aliases(void);
|
||||
-void init_lexer(void);
|
||||
+/* gram.c */
|
||||
void init_parser(const char *, bool);
|
||||
-int alias_compare(const void *, const void *);
|
||||
+
|
||||
+/* match_addr.c */
|
||||
+bool addr_matches(char *n);
|
||||
+
|
||||
+/* match.c */
|
||||
+bool command_matches(char *sudoers_cmnd, char *sudoers_args);
|
||||
+bool group_matches(char *sudoers_group, struct group *gr);
|
||||
+bool hostname_matches(char *shost, char *lhost, char *pattern);
|
||||
+bool netgr_matches(char *netgr, char *lhost, char *shost, char *user);
|
||||
+bool usergr_matches(char *group, char *user, struct passwd *pw);
|
||||
+bool userpw_matches(char *sudoers_user, char *user, struct passwd *pw);
|
||||
+int cmnd_matches(struct member *m);
|
||||
+int cmndlist_matches(struct member_list *list);
|
||||
+int hostlist_matches(struct member_list *list);
|
||||
+int runaslist_matches(struct member_list *user_list, struct member_list *group_list, struct member **matching_user, struct member **matching_group);
|
||||
+int userlist_matches(struct passwd *pw, struct member_list *list);
|
||||
+
|
||||
+/* toke.c */
|
||||
+ void init_lexer(void);
|
||||
+
|
||||
+/* base64.c */
|
||||
+ size_t base64_decode(const char *str, unsigned char *dst, size_t dsize);
|
||||
|
||||
#endif /* _SUDO_PARSE_H */
|
||||
diff -up sudo-1.8.6p3/plugins/sudoers/visudo.c.cycledetect sudo-1.8.6p3/plugins/sudoers/visudo.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/visudo.c.cycledetect 2013-08-09 10:52:04.759860779 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/visudo.c 2013-08-09 10:52:04.786860910 +0200
|
||||
@@ -1084,7 +1084,6 @@ alias_remove_recursive(char *name, int t
|
||||
}
|
||||
rbinsert(alias_freelist, a);
|
||||
}
|
||||
- alias_seqno++;
|
||||
debug_return_bool(rval);
|
||||
}
|
||||
|
||||
@@ -1096,12 +1095,13 @@ check_alias(char *name, int type, int st
|
||||
int errors = 0;
|
||||
debug_decl(check_alias, SUDO_DEBUG_ALIAS)
|
||||
|
||||
- if ((a = alias_find(name, type)) != NULL) {
|
||||
+ if ((a = alias_get(name, type)) != NULL) {
|
||||
/* check alias contents */
|
||||
tq_foreach_fwd(&a->members, m) {
|
||||
if (m->type == ALIAS)
|
||||
errors += check_alias(m->name, type, strict, quiet);
|
||||
}
|
||||
+ alias_put(a);
|
||||
} else {
|
||||
if (!quiet) {
|
||||
char *fmt;
|
||||
@@ -1146,26 +1146,22 @@ check_aliases(bool strict, bool quiet)
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
tq_foreach_fwd(&us->users, m) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
errors += check_alias(m->name, USERALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
tq_foreach_fwd(&priv->hostlist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
errors += check_alias(m->name, HOSTALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
errors += check_alias(m->name, RUNASALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
if ((m = cs->cmnd)->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
errors += check_alias(m->name, CMNDALIAS, strict, quiet);
|
||||
}
|
||||
}
|
||||
@@ -1176,7 +1172,6 @@ check_aliases(bool strict, bool quiet)
|
||||
tq_foreach_fwd(&userspecs, us) {
|
||||
tq_foreach_fwd(&us->users, m) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
if (!alias_remove_recursive(m->name, USERALIAS))
|
||||
errors++;
|
||||
}
|
||||
@@ -1184,7 +1179,6 @@ check_aliases(bool strict, bool quiet)
|
||||
tq_foreach_fwd(&us->privileges, priv) {
|
||||
tq_foreach_fwd(&priv->hostlist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
if (!alias_remove_recursive(m->name, HOSTALIAS))
|
||||
errors++;
|
||||
}
|
||||
@@ -1192,13 +1186,11 @@ check_aliases(bool strict, bool quiet)
|
||||
tq_foreach_fwd(&priv->cmndlist, cs) {
|
||||
tq_foreach_fwd(&cs->runasuserlist, m) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
if (!alias_remove_recursive(m->name, RUNASALIAS))
|
||||
errors++;
|
||||
}
|
||||
}
|
||||
if ((m = cs->cmnd)->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
if (!alias_remove_recursive(m->name, CMNDALIAS))
|
||||
errors++;
|
||||
}
|
||||
@@ -1225,7 +1217,6 @@ check_aliases(bool strict, bool quiet)
|
||||
tq_foreach_fwd(&d->binding, binding) {
|
||||
for (m = binding; m != NULL; m = m->next) {
|
||||
if (m->type == ALIAS) {
|
||||
- alias_seqno++;
|
||||
if (!alias_remove_recursive(m->name, atype))
|
||||
errors++;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
From 1b16310c7ec5ba23fbe066c7d000016e534b4448 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Tue, 16 Aug 2016 09:54:06 +0200
|
||||
Subject: [PATCH] Double quotes are not accepted in sudoers
|
||||
|
||||
Regression in sudo 1.8.6p3-7 package, double quotes are not accepted in sudoers
|
||||
|
||||
Rebased from:
|
||||
Patch25: sudo-1.8.6p3-doublequotefix.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#1092499
|
||||
---
|
||||
plugins/sudoers/toke.c | 2 +-
|
||||
plugins/sudoers/toke.l | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c
|
||||
index e5b4d97..3b510bb 100644
|
||||
--- a/plugins/sudoers/toke.c
|
||||
+++ b/plugins/sudoers/toke.c
|
||||
@@ -2385,7 +2385,7 @@ YY_RULE_SETUP
|
||||
LEXTRACE("ERROR "); /* empty string */
|
||||
LEXRETURN(ERROR);
|
||||
}
|
||||
- if (prev_state == INITIAL) {
|
||||
+ if (prev_state == INITIAL || prev_state == GOTDEFS) {
|
||||
switch (sudoerslval.string[0]) {
|
||||
case '%':
|
||||
if (sudoerslval.string[1] == '\0' ||
|
||||
diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l
|
||||
index b63edd0..82724aa 100644
|
||||
--- a/plugins/sudoers/toke.l
|
||||
+++ b/plugins/sudoers/toke.l
|
||||
@@ -185,7 +185,7 @@ DEFVAR [a-z_]+
|
||||
LEXTRACE("ERROR "); /* empty string */
|
||||
LEXRETURN(ERROR);
|
||||
}
|
||||
- if (prev_state == INITIAL) {
|
||||
+ if (prev_state == INITIAL || prev_state == GOTDEFS) {
|
||||
switch (sudoerslval.string[0]) {
|
||||
case '%':
|
||||
if (sudoerslval.string[1] == '\0' ||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.emallocfail sudo-1.8.6p3/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.emallocfail 2012-11-23 15:58:20.139417659 +0100
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2012-11-23 15:58:26.732437421 +0100
|
||||
@@ -212,7 +212,12 @@ sudo_sss_filter_result(struct sudo_sss_h
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG,
|
||||
"reallocating result: %p (count: %u -> %u)", out_res->rules,
|
||||
in_res->num_rules, l);
|
||||
- out_res->rules = erealloc3(out_res->rules, l, sizeof(struct sss_sudo_rule));
|
||||
+ if (l > 0)
|
||||
+ out_res->rules = erealloc3(out_res->rules, l, sizeof(struct sss_sudo_rule));
|
||||
+ else {
|
||||
+ efree(out_res->rules);
|
||||
+ out_res->rules = NULL;
|
||||
+ }
|
||||
}
|
||||
|
||||
out_res->num_rules = l;
|
|
@ -0,0 +1,138 @@
|
|||
diff -up sudo-1.8.6p3/common/lbuf.c.lbufexpandcode sudo-1.8.6p3/common/lbuf.c
|
||||
--- sudo-1.8.6p3/common/lbuf.c.lbufexpandcode 2013-08-12 17:28:52.429562473 +0200
|
||||
+++ sudo-1.8.6p3/common/lbuf.c 2013-08-12 17:29:21.486668465 +0200
|
||||
@@ -77,6 +77,17 @@ lbuf_destroy(struct lbuf *lbuf)
|
||||
debug_return;
|
||||
}
|
||||
|
||||
+static void
|
||||
+lbuf_expand(struct lbuf *lbuf, size_t extra)
|
||||
+{
|
||||
+ if (lbuf->len + extra + 1 >= lbuf->size) {
|
||||
+ do {
|
||||
+ lbuf->size += 256;
|
||||
+ } while (lbuf->len + extra + 1 >= lbuf->size);
|
||||
+ lbuf->buf = erealloc(lbuf->buf, lbuf->size);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Parse the format and append strings, only %s and %% escapes are supported.
|
||||
* Any characters in set are quoted with a backslash.
|
||||
@@ -86,47 +97,40 @@ lbuf_append_quoted(struct lbuf *lbuf, co
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
- char *cp, *s = NULL;
|
||||
+ char *cp, *s;
|
||||
debug_decl(lbuf_append_quoted, SUDO_DEBUG_UTIL)
|
||||
|
||||
va_start(ap, fmt);
|
||||
while (*fmt != '\0') {
|
||||
- len = 1;
|
||||
if (fmt[0] == '%' && fmt[1] == 's') {
|
||||
- s = va_arg(ap, char *);
|
||||
- len = strlen(s);
|
||||
- }
|
||||
- /* Assume worst case that all chars must be escaped. */
|
||||
- if (lbuf->len + (len * 2) + 1 >= lbuf->size) {
|
||||
- do {
|
||||
- lbuf->size += 256;
|
||||
- } while (lbuf->len + len + 1 >= lbuf->size);
|
||||
- lbuf->buf = erealloc(lbuf->buf, lbuf->size);
|
||||
- }
|
||||
- if (*fmt == '%') {
|
||||
- if (*(++fmt) == 's') {
|
||||
- while ((cp = strpbrk(s, set)) != NULL) {
|
||||
- len = (int)(cp - s);
|
||||
- memcpy(lbuf->buf + lbuf->len, s, len);
|
||||
- lbuf->len += len;
|
||||
- lbuf->buf[lbuf->len++] = '\\';
|
||||
- lbuf->buf[lbuf->len++] = *cp;
|
||||
- s = cp + 1;
|
||||
- }
|
||||
- if (*s != '\0') {
|
||||
- len = strlen(s);
|
||||
- memcpy(lbuf->buf + lbuf->len, s, len);
|
||||
- lbuf->len += len;
|
||||
- }
|
||||
- fmt++;
|
||||
- continue;
|
||||
+ if ((s = va_arg(ap, char *)) == NULL)
|
||||
+ goto done;
|
||||
+ while ((cp = strpbrk(s, set)) != NULL) {
|
||||
+ len = (int)(cp - s);
|
||||
+ lbuf_expand(lbuf, len + 2);
|
||||
+ memcpy(lbuf->buf + lbuf->len, s, len);
|
||||
+ lbuf->len += len;
|
||||
+ lbuf->buf[lbuf->len++] = '\\';
|
||||
+ lbuf->buf[lbuf->len++] = *cp;
|
||||
+ s = cp + 1;
|
||||
}
|
||||
+ if (*s != '\0') {
|
||||
+ len = strlen(s);
|
||||
+ lbuf_expand(lbuf, len);
|
||||
+ memcpy(lbuf->buf + lbuf->len, s, len);
|
||||
+ lbuf->len += len;
|
||||
+ }
|
||||
+ fmt += 2;
|
||||
+ continue;
|
||||
}
|
||||
+ lbuf_expand(lbuf, 2);
|
||||
if (strchr(set, *fmt) != NULL)
|
||||
lbuf->buf[lbuf->len++] = '\\';
|
||||
lbuf->buf[lbuf->len++] = *fmt++;
|
||||
}
|
||||
- lbuf->buf[lbuf->len] = '\0';
|
||||
+done:
|
||||
+ if (lbuf->size != 0)
|
||||
+ lbuf->buf[lbuf->len] = '\0';
|
||||
va_end(ap);
|
||||
|
||||
debug_return;
|
||||
@@ -140,33 +144,27 @@ lbuf_append(struct lbuf *lbuf, const cha
|
||||
{
|
||||
va_list ap;
|
||||
int len;
|
||||
- char *s = NULL;
|
||||
+ char *s;
|
||||
debug_decl(lbuf_append, SUDO_DEBUG_UTIL)
|
||||
|
||||
va_start(ap, fmt);
|
||||
while (*fmt != '\0') {
|
||||
- len = 1;
|
||||
if (fmt[0] == '%' && fmt[1] == 's') {
|
||||
- s = va_arg(ap, char *);
|
||||
+ if ((s = va_arg(ap, char *)) == NULL)
|
||||
+ goto done;
|
||||
len = strlen(s);
|
||||
+ lbuf_expand(lbuf, len);
|
||||
+ memcpy(lbuf->buf + lbuf->len, s, len);
|
||||
+ lbuf->len += len;
|
||||
+ fmt += 2;
|
||||
+ continue;
|
||||
}
|
||||
- if (lbuf->len + len + 1 >= lbuf->size) {
|
||||
- do {
|
||||
- lbuf->size += 256;
|
||||
- } while (lbuf->len + len + 1 >= lbuf->size);
|
||||
- lbuf->buf = erealloc(lbuf->buf, lbuf->size);
|
||||
- }
|
||||
- if (*fmt == '%') {
|
||||
- if (*(++fmt) == 's') {
|
||||
- memcpy(lbuf->buf + lbuf->len, s, len);
|
||||
- lbuf->len += len;
|
||||
- fmt++;
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
+ lbuf_expand(lbuf, 1);
|
||||
lbuf->buf[lbuf->len++] = *fmt++;
|
||||
}
|
||||
- lbuf->buf[lbuf->len] = '\0';
|
||||
+done:
|
||||
+ if (lbuf->size != 0)
|
||||
+ lbuf->buf[lbuf->len] = '\0';
|
||||
va_end(ap);
|
||||
|
||||
debug_return;
|
|
@ -0,0 +1,24 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/ldap.c.usermatch sudo-1.8.6p3/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/ldap.c.usermatch 2012-11-23 15:57:00.084176086 +0100
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/ldap.c 2012-11-23 15:57:21.491239877 +0100
|
||||
@@ -742,7 +742,7 @@ sudo_ldap_check_runas_user(LDAP *ld, LDA
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
- if (strcasecmp(val, runas_pw->pw_name) == 0)
|
||||
+ if (userpw_matches(val, runas_pw->pw_name, runas_pw))
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.usermatch sudo-1.8.6p3/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.usermatch 2012-11-23 15:57:12.234211662 +0100
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2012-11-23 15:57:21.492239881 +0100
|
||||
@@ -466,7 +466,7 @@ sudo_sss_check_runas_user(struct sudo_ss
|
||||
/* FALLTHROUGH */
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "FALLTHROUGH");
|
||||
default:
|
||||
- if (strcasecmp(val, runas_pw->pw_name) == 0) {
|
||||
+ if (userpw_matches(val, runas_pw->pw_name, runas_pw)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG,
|
||||
"%s == %s (pw_name) => match", val, runas_pw->pw_name);
|
||||
ret = true;
|
|
@ -0,0 +1,45 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/ldap.c.confparse sudo-1.8.6p3/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/ldap.c.confparse 2012-11-23 15:46:41.801008370 +0100
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/ldap.c 2012-11-23 15:46:07.903885738 +0100
|
||||
@@ -1343,6 +1343,32 @@ sudo_ldap_parse_keyword(const char *keyw
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Read a line of input, remove whole line comments and strip off leading
|
||||
+ * and trailing spaces. Returns static storage that is reused.
|
||||
+ */
|
||||
+static char *
|
||||
+sudo_ldap_parseln(FILE *fp)
|
||||
+{
|
||||
+ size_t len;
|
||||
+ char *cp = NULL;
|
||||
+ static char buf[LINE_MAX];
|
||||
+
|
||||
+ if (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
+ /* Remove comments */
|
||||
+ if (*buf == '#')
|
||||
+ *buf = '\0';
|
||||
+
|
||||
+ /* Trim leading and trailing whitespace/newline */
|
||||
+ len = strlen(buf);
|
||||
+ while (len > 0 && isspace((unsigned char)buf[len - 1]))
|
||||
+ buf[--len] = '\0';
|
||||
+ for (cp = buf; isblank(*cp); cp++)
|
||||
+ continue;
|
||||
+ }
|
||||
+ return(cp);
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
sudo_ldap_read_config(void)
|
||||
{
|
||||
@@ -1364,7 +1390,7 @@ sudo_ldap_read_config(void)
|
||||
if ((fp = fopen(_PATH_LDAP_CONF, "r")) == NULL)
|
||||
debug_return_bool(false);
|
||||
|
||||
- while ((cp = sudo_parseln(fp)) != NULL) {
|
||||
+ while ((cp = sudo_ldap_parseln(fp)) != NULL) {
|
||||
if (*cp == '\0')
|
||||
continue; /* skip empty line */
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p3/doc/sudoers.man.in.mantypo sudo-1.8.6p3/doc/sudoers.man.in
|
||||
--- sudo-1.8.6p3/doc/sudoers.man.in.mantypo 2012-09-24 16:38:33.946465411 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.man.in 2012-09-24 16:39:01.400941691 +0200
|
||||
@@ -1408,7 +1408,7 @@ to include the file
|
||||
The
|
||||
\fR#includedir\fR
|
||||
directive can be used to create a
|
||||
-\fIsudo.d\fR
|
||||
+\fIsudoers.d\fR
|
||||
directory that the system package manager can drop
|
||||
\fIsudoers\fR
|
||||
rules
|
|
@ -0,0 +1,74 @@
|
|||
diff -up sudo-1.8.6p3/doc/sudoers.ldap.cat.mantypos-ldap sudo-1.8.6p3/doc/sudoers.ldap.cat
|
||||
--- sudo-1.8.6p3/doc/sudoers.ldap.cat.mantypos-ldap 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.ldap.cat 2015-04-16 11:24:08.277692534 +0200
|
||||
@@ -119,7 +119,7 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
ssuuddooNNoottAAfftteerr
|
||||
A timestamp in the form yyyymmddHHMMSSZ that indicates an
|
||||
expiration date/time, after which the sudoRole will no longer be
|
||||
- valid. If multiple sudoNotBefore entries are present, the last one
|
||||
+ valid. If multiple sudoNotAfter entries are present, the last one
|
||||
is used. Note that timestamps must be in Coordinated Universal
|
||||
Time (UTC), not the local timezone. The minute and seconds
|
||||
portions are optional, but some LDAP servers require that they be
|
||||
@@ -134,8 +134,8 @@ DDEESSCCRRIIPPTTIIOONN
|
||||
inherent order. The sudoOrder attribute is an integer (or floating
|
||||
point value for LDAP servers that support it) that is used to sort
|
||||
the matching entries. This allows LDAP-based sudoers entries to
|
||||
- more closely mimic the behaviour of the sudoers file, where the of
|
||||
- the entries influences the result. If multiple entries match, the
|
||||
+ more closely mimic the behaviour of the sudoers file, where the order
|
||||
+ of the entries influences the result. If multiple entries match, the
|
||||
entry with the highest sudoOrder attribute is chosen. This
|
||||
corresponds to the ``last match'' behavior of the sudoers file. If
|
||||
the sudoOrder attribute is not present, a value of 0 is assumed.
|
||||
diff -up sudo-1.8.6p3/doc/sudoers.ldap.man.in.mantypos-ldap sudo-1.8.6p3/doc/sudoers.ldap.man.in
|
||||
--- sudo-1.8.6p3/doc/sudoers.ldap.man.in.mantypos-ldap 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.ldap.man.in 2015-04-16 11:24:08.277692534 +0200
|
||||
@@ -238,7 +238,7 @@ that indicates an expiration date/time,
|
||||
\fRsudoRole\fR
|
||||
will no longer be valid.
|
||||
If multiple
|
||||
-\fRsudoNotBefore\fR
|
||||
+\fRsudoNotAfter\fR
|
||||
entries are present, the last one is used.
|
||||
Note that timestamps must be in Coordinated Universal Time (UTC),
|
||||
not the local timezone.
|
||||
@@ -264,7 +264,7 @@ The
|
||||
attribute is an integer (or floating point value for LDAP servers
|
||||
that support it) that is used to sort the matching entries.
|
||||
This allows LDAP-based sudoers entries to more closely mimic the behaviour
|
||||
-of the sudoers file, where the of the entries influences the result.
|
||||
+of the sudoers file, where the order of the entries influences the result.
|
||||
If multiple entries match, the entry with the highest
|
||||
\fRsudoOrder\fR
|
||||
attribute is chosen.
|
||||
diff -up sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in.mantypos-ldap sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in
|
||||
--- sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in.mantypos-ldap 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/doc/sudoers.ldap.mdoc.in 2015-04-16 11:32:51.574469447 +0200
|
||||
@@ -15,7 +15,7 @@
|
||||
.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd July 12, 2012
|
||||
-.Dt SUDOERS.LDAP @mansectsu@
|
||||
+.Dt SUDOERS.LDAP @mansectform@
|
||||
.Os Sudo @PACKAGE_VERSION@
|
||||
.Sh NAME
|
||||
.Nm sudoers.ldap
|
||||
@@ -224,7 +224,7 @@ that indicates an expiration date/time,
|
||||
.Li sudoRole
|
||||
will no longer be valid.
|
||||
If multiple
|
||||
-.Li sudoNotBefore
|
||||
+.Li sudoNotAfter
|
||||
entries are present, the last one is used.
|
||||
Note that timestamps must be in Coordinated Universal Time (UTC),
|
||||
not the local timezone.
|
||||
@@ -249,7 +249,7 @@ The
|
||||
attribute is an integer (or floating point value for LDAP servers
|
||||
that support it) that is used to sort the matching entries.
|
||||
This allows LDAP-based sudoers entries to more closely mimic the behaviour
|
||||
-of the sudoers file, where the of the entries influences the result.
|
||||
+of the sudoers file, where the order of the entries influences the result.
|
||||
If multiple entries match, the entry with the highest
|
||||
.Li sudoOrder
|
||||
attribute is chosen.
|
|
@ -0,0 +1,92 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix sudo-1.8.6p3/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix 2014-07-30 13:29:47.713823996 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2014-07-30 13:30:08.917436088 +0200
|
||||
@@ -614,16 +615,13 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
}
|
||||
|
||||
/*
|
||||
- * Look for netgroup specifcations in the sudoUser attribute and
|
||||
- * if found, filter according to netgroup membership.
|
||||
- * returns:
|
||||
- * true -> netgroup spec found && negroup member
|
||||
- * false -> netgroup spec found && not a meber of netgroup
|
||||
- * true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception)
|
||||
+ * SSSD doesn't handle netgroups, we have to ensure they are correctly filtered
|
||||
+ * in sudo. The rules may contain mixed sudoUser specification so we have to check
|
||||
+ * not only for netgroup membership but also for user and group matches.
|
||||
*/
|
||||
-bool sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
+bool sudo_sss_filter_sudoUser(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
{
|
||||
- bool ret = false, netgroup_spec_found = false;
|
||||
+ bool ret = false;
|
||||
char **val_array, *val;
|
||||
int i;
|
||||
debug_decl(sudo_sss_check_user_netgroup, SUDO_DEBUG_SSSD);
|
||||
@@ -641,21 +639,48 @@ bool sudo_sss_filter_user_netgroup(struc
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoUser): != 0");
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
-
|
||||
+ /*
|
||||
+ * Scan sudoUser values and look for netgroup specs.
|
||||
+ * Netgroup-only rule specification should be filtered
|
||||
+ * out if the user isn't member of any specified netgroup.
|
||||
+ */
|
||||
for (i = 0; val_array[i] != NULL && !ret; ++i) {
|
||||
val = val_array[i];
|
||||
- if (*val == '+') {
|
||||
- netgroup_spec_found = true;
|
||||
- }
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
|
||||
- if (strcmp(val, "ALL") == 0 || netgr_matches(val, NULL, NULL, user_name)) {
|
||||
- ret = true;
|
||||
- sudo_debug_printf(SUDO_DEBUG_DIAG,
|
||||
- "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, user_name);
|
||||
+ if (*val == '+') {
|
||||
+ /* Netgroup spec found, check netgroup membership */
|
||||
+ if (netgr_matches(val, NULL, NULL, handle->pw->pw_name)) {
|
||||
+ ret = true;
|
||||
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
|
||||
+ "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, handle->pw->pw_name);
|
||||
+ }
|
||||
+ } else {
|
||||
+ /*
|
||||
+ * Non-netgroup sudoUser value
|
||||
+ */
|
||||
+ if (strcmp(val, "ALL") == 0) {
|
||||
+ ret = true;
|
||||
+ } else {
|
||||
+ const char *match_val = (*val == '!' ? val + 1 : val);
|
||||
+ const bool negated = (*val == '!' ? true : false);
|
||||
+ const bool group_spec = (*match_val == '%' ? true : false);
|
||||
+
|
||||
+ if (group_spec) {
|
||||
+ if (usergr_matches(match_val,
|
||||
+ handle->pw->pw_name, handle->pw)) {
|
||||
+ ret = !negated;
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (userpw_matches(match_val,
|
||||
+ handle->pw->pw_name, handle->pw)) {
|
||||
+ ret = !negated;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
handle->fn_free_values(val_array);
|
||||
- debug_return_bool(netgroup_spec_found ? ret : true);
|
||||
+ debug_return_bool(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -666,7 +691,7 @@ sudo_sss_result_filterp(struct sudo_sss_
|
||||
debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD);
|
||||
|
||||
if (sudo_sss_check_host(handle, rule) &&
|
||||
- sudo_sss_filter_user_netgroup(handle, rule))
|
||||
+ sudo_sss_filter_sudoUser(handle, rule))
|
||||
debug_return_int(1);
|
||||
else
|
||||
debug_return_int(0);
|
|
@ -0,0 +1,56 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/match.c.netgrmatchtrace sudo-1.8.6p3/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/match.c.netgrmatchtrace 2013-08-12 14:42:56.498247674 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/match.c 2013-08-12 14:43:01.009264127 +0200
|
||||
@@ -713,6 +713,10 @@ netgr_matches(char *netgr, char *lhost,
|
||||
#ifdef HAVE_GETDOMAINNAME
|
||||
static int initialized;
|
||||
#endif
|
||||
+#ifdef HAVE_INNETGR
|
||||
+ bool innetgr_lhost = false;
|
||||
+ bool innetgr_shost = false;
|
||||
+#endif
|
||||
debug_decl(netgr_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
/* make sure we have a valid netgroup, sudo style */
|
||||
@@ -733,9 +737,39 @@ netgr_matches(char *netgr, char *lhost,
|
||||
|
||||
#ifdef HAVE_INNETGR
|
||||
if (innetgr(netgr, lhost, user, domain))
|
||||
- debug_return_bool(true);
|
||||
+ innetgr_lhost = true;
|
||||
else if (lhost != shost && innetgr(netgr, shost, user, domain))
|
||||
- debug_return_bool(true);
|
||||
+ innetgr_shost = true;
|
||||
+
|
||||
+ if (innetgr_lhost) {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_TRACE,
|
||||
+ "(%s, %s, %s) found in netgroup %s\n",
|
||||
+ shost ? shost : "*",
|
||||
+ user ? user : "*",
|
||||
+ domain ? domain : "*",
|
||||
+ netgr);
|
||||
+ } else if (innetgr_shost) {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_TRACE,
|
||||
+ "(%s, %s, %s) found in netgroup %s\n",
|
||||
+ lhost ? lhost : "*",
|
||||
+ user ? user : "*",
|
||||
+ domain ? domain : "*",
|
||||
+ netgr);
|
||||
+ } else {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_TRACE,
|
||||
+ "(%s, %s, %s) NOT found in netgroup %s\n",
|
||||
+ shost ? shost : "*",
|
||||
+ user ? user : "*",
|
||||
+ domain ? domain : "*",
|
||||
+ netgr);
|
||||
+ sudo_debug_printf(SUDO_DEBUG_TRACE,
|
||||
+ "(%s, %s, %s) NOT found in netgroup %s\n",
|
||||
+ lhost ? lhost : "*",
|
||||
+ user ? user : "*",
|
||||
+ domain ? domain : "*",
|
||||
+ netgr);
|
||||
+ }
|
||||
+ debug_return_bool(innetgr_lhost || innetgr_shost);
|
||||
#endif /* HAVE_INNETGR */
|
||||
|
||||
debug_return_bool(false);
|
|
@ -0,0 +1,13 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/match.c.nonehostname sudo-1.8.6p3/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/match.c.nonehostname 2014-05-19 12:50:08.412313041 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/match.c 2014-05-19 12:50:17.787348134 +0200
|
||||
@@ -727,7 +727,8 @@ netgr_matches(char *netgr, char *lhost,
|
||||
/* get the domain name (if any) */
|
||||
if (!initialized) {
|
||||
domain = (char *) emalloc(MAXHOSTNAMELEN + 1);
|
||||
- if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0') {
|
||||
+ if (getdomainname(domain, MAXHOSTNAMELEN + 1) == -1 || *domain == '\0'
|
||||
+ || strncmp (domain, "(none)", 7) == 0) {
|
||||
efree(domain);
|
||||
domain = NULL;
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
From 9b1f0f16bfe7552810b4adb6b17ac3674da660f9 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Mon, 15 Aug 2016 15:13:31 +0200
|
||||
Subject: [PATCH] Backport direct exec of command from sudo
|
||||
|
||||
Added cmnd_no_wait option
|
||||
Sudo does not run command in a new child process,
|
||||
when cmnd_no_wait is enabled.
|
||||
|
||||
!!!
|
||||
Upstream can do that too now in 1.8.17 with combination of
|
||||
pam_session, pam_setcred and use_pty option.
|
||||
They must be disabled and I/O logging must not be configured.
|
||||
See "man sudoers".
|
||||
|
||||
rebased from:
|
||||
Patch8: sudo-1.8.6p3-nowaitopt.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#840980
|
||||
---
|
||||
plugins/sudoers/def_data.c | 4 ++++
|
||||
plugins/sudoers/def_data.h | 2 ++
|
||||
plugins/sudoers/def_data.in | 3 +++
|
||||
plugins/sudoers/policy.c | 4 ++++
|
||||
src/exec.c | 34 ++++++++++++++++++++++++++++++++++
|
||||
src/sudo.c | 5 +++++
|
||||
src/sudo.h | 1 +
|
||||
7 files changed, 53 insertions(+)
|
||||
|
||||
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
||||
index 00caa8b..d8b1ada 100644
|
||||
--- a/plugins/sudoers/def_data.c
|
||||
+++ b/plugins/sudoers/def_data.c
|
||||
@@ -435,6 +435,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
N_("File mode to use for the I/O log files: 0%o"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "cmnd_no_wait", T_FLAG,
|
||||
+ N_("Don't fork and wait for the command to finish, just exec it"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
||||
index d83d2c3..1b6be3d 100644
|
||||
--- a/plugins/sudoers/def_data.h
|
||||
+++ b/plugins/sudoers/def_data.h
|
||||
@@ -204,6 +204,8 @@
|
||||
#define def_iolog_group (sudo_defs_table[I_IOLOG_GROUP].sd_un.str)
|
||||
#define I_IOLOG_MODE 102
|
||||
#define def_iolog_mode (sudo_defs_table[I_IOLOG_MODE].sd_un.mode)
|
||||
+#define I_CMND_NO_WAIT 103
|
||||
+#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
||||
index 9f069f1..5200fe3 100644
|
||||
--- a/plugins/sudoers/def_data.in
|
||||
+++ b/plugins/sudoers/def_data.in
|
||||
@@ -322,3 +322,6 @@ iolog_group
|
||||
iolog_mode
|
||||
T_MODE
|
||||
"File mode to use for the I/O log files: 0%o"
|
||||
+cmnd_no_wait
|
||||
+ T_FLAG
|
||||
+ "Don't fork and wait for the command to finish, just exec it"
|
||||
diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c
|
||||
index 4ee1e28..93df1dd 100644
|
||||
--- a/plugins/sudoers/policy.c
|
||||
+++ b/plugins/sudoers/policy.c
|
||||
@@ -564,6 +564,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
|
||||
if ((command_info[info_len++] = strdup("use_pty=true")) == NULL)
|
||||
goto oom;
|
||||
}
|
||||
+ if (def_cmnd_no_wait) {
|
||||
+ if ((command_info[info_len++] = strdup("cmnd_no_wait=true")) == NULL)
|
||||
+ goto oom;
|
||||
+ }
|
||||
if (def_utmp_runas) {
|
||||
if ((command_info[info_len++] = sudo_new_key_val("utmp_user", runas_pw->pw_name)) == NULL)
|
||||
goto oom;
|
||||
diff --git a/src/exec.c b/src/exec.c
|
||||
index 56da013..08bc86d 100644
|
||||
--- a/src/exec.c
|
||||
+++ b/src/exec.c
|
||||
@@ -384,6 +384,41 @@ sudo_execute(struct command_details *details, struct command_status *cstat)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * If we don't want to wait for the command to exit, then just exec it.
|
||||
+ * THIS WILL BREAK SEVERAL THINGS including SELinux, PAM sessions and I/O
|
||||
+ * logging. Implemented because of rhbz#840980 (backwards compatibility).
|
||||
+ * In 1.8.x branch this is even harder to get back, since the nowait code
|
||||
+ * was completely removed.
|
||||
+ */
|
||||
+ if (details->flags & CD_DONTWAIT) {
|
||||
+ if (exec_setup(details, NULL, -1) == true) {
|
||||
+ restore_signals();
|
||||
+ /* headed for execve() */
|
||||
+ sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
|
||||
+ details->argv, details->envp);
|
||||
+ if (details->closefrom >= 0) {
|
||||
+ closefrom(details->closefrom);
|
||||
+ }
|
||||
+#ifdef HAVE_SELINUX
|
||||
+ if (ISSET(details->flags, CD_RBAC_ENABLED)) {
|
||||
+ selinux_execve(-1, details->command, details->argv, details->envp,
|
||||
+ ISSET(details->flags, CD_NOEXEC));
|
||||
+ } else
|
||||
+#endif
|
||||
+ {
|
||||
+ sudo_execve(-1, details->command, details->argv, details->envp,
|
||||
+ ISSET(details->flags, CD_NOEXEC));
|
||||
+ }
|
||||
+ sudo_debug_printf(SUDO_DEBUG_ERROR, "unable to exec %s: %s",
|
||||
+ details->command, strerror(errno));
|
||||
+ }
|
||||
+ cstat->type = CMD_ERRNO;
|
||||
+ cstat->val = errno;
|
||||
+ return 127;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /*
|
||||
* We communicate with the child over a bi-directional pair of sockets.
|
||||
* Parent sends signal info to child and child sends back wait status.
|
||||
*/
|
||||
diff --git a/src/sudo.c b/src/sudo.c
|
||||
index 5dd090d..0606a19 100644
|
||||
--- a/src/sudo.c
|
||||
+++ b/src/sudo.c
|
||||
@@ -670,6 +670,11 @@ command_info_to_details(char * const info[], struct command_details *details)
|
||||
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
|
||||
break;
|
||||
}
|
||||
+ if (strncmp("cmnd_no_wait=", info[i], sizeof("cmnd_no_wait=") - 1) == 0) {
|
||||
+ if (sudo_strtobool(info[i] + sizeof("cmnd_no_wait=") - 1) == true)
|
||||
+ SET(details->flags, CD_DONTWAIT);
|
||||
+ break;
|
||||
+ }
|
||||
break;
|
||||
case 'e':
|
||||
SET_FLAG("exec_background=", CD_EXEC_BG)
|
||||
diff --git a/src/sudo.h b/src/sudo.h
|
||||
index 3ac2c9d..f07ba11 100644
|
||||
--- a/src/sudo.h
|
||||
+++ b/src/sudo.h
|
||||
@@ -130,6 +130,7 @@ struct user_details {
|
||||
#define CD_SUDOEDIT_FOLLOW 0x10000
|
||||
#define CD_SUDOEDIT_CHECKDIR 0x20000
|
||||
#define CD_SET_GROUPS 0x40000
|
||||
+#define CD_DONTWAIT 0x80000
|
||||
|
||||
struct preserved_fd {
|
||||
TAILQ_ENTRY(preserved_fd) entries;
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
diff -up sudo-1.8.6p3/src/exec.c.nprocfix sudo-1.8.6p3/src/exec.c
|
||||
--- sudo-1.8.6p3/src/exec.c.nprocfix 2013-07-11 12:55:10.686308050 +0200
|
||||
+++ sudo-1.8.6p3/src/exec.c 2013-07-11 12:54:21.159160553 +0200
|
||||
@@ -132,6 +132,15 @@ static int fork_cmnd(struct command_deta
|
||||
if (policy_init_session(details) != true)
|
||||
errorx(1, _("policy plugin failed session initialization"));
|
||||
|
||||
+ /*
|
||||
+ * See the comment in unlimit_nproc. It is important to call
|
||||
+ * this function AFTER policy_init_session, because the PAM
|
||||
+ * subsystem, if used, may change the RLIMIT_NPROC limit to
|
||||
+ * unlimited (infinity) and we would not be able to distinguish
|
||||
+ * between our temporary change and the change done by PAM.
|
||||
+ */
|
||||
+ unlimit_nproc();
|
||||
+
|
||||
cmnd_pid = sudo_debug_fork();
|
||||
switch (cmnd_pid) {
|
||||
case -1:
|
||||
diff -up sudo-1.8.6p3/src/exec_pty.c.nprocfix sudo-1.8.6p3/src/exec_pty.c
|
||||
--- sudo-1.8.6p3/src/exec_pty.c.nprocfix 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/src/exec_pty.c 2013-07-11 12:37:41.811202301 +0200
|
||||
@@ -678,6 +678,15 @@ fork_pty(struct command_details *details
|
||||
errorx(1, _("policy plugin failed session initialization"));
|
||||
|
||||
/*
|
||||
+ * See the comment in unlimit_nproc. It is important to call
|
||||
+ * this function AFTER policy_init_session, because the PAM
|
||||
+ * subsystem, if used, may change the RLIMIT_NPROC limit to
|
||||
+ * unlimited (infinity) and we would not be able to distinguish
|
||||
+ * between our temporary change and the change done by PAM.
|
||||
+ */
|
||||
+ unlimit_nproc();
|
||||
+
|
||||
+ /*
|
||||
* Block some signals until cmnd_pid is set in the parent to avoid a
|
||||
* race between exec of the command and receipt of a fatal signal from it.
|
||||
*/
|
||||
diff -up sudo-1.8.6p3/src/sudo.c.nprocfix sudo-1.8.6p3/src/sudo.c
|
||||
--- sudo-1.8.6p3/src/sudo.c.nprocfix 2013-07-11 12:37:41.767202170 +0200
|
||||
+++ sudo-1.8.6p3/src/sudo.c 2013-07-11 12:37:41.811202301 +0200
|
||||
@@ -808,25 +808,11 @@ sudo_check_suid(const char *path)
|
||||
static void
|
||||
disable_coredumps(void)
|
||||
{
|
||||
-#if defined(__linux__) || defined(RLIMIT_CORE)
|
||||
- struct rlimit rl;
|
||||
+#if defined(RLIMIT_CORE)
|
||||
+ struct rlimit rl;
|
||||
#endif
|
||||
debug_decl(disable_coredumps, SUDO_DEBUG_UTIL)
|
||||
|
||||
-#if defined(__linux__)
|
||||
- /*
|
||||
- * Unlimit the number of processes since Linux's setuid() will
|
||||
- * apply resource limits when changing uid and return EAGAIN if
|
||||
- * nproc would be violated by the uid switch.
|
||||
- */
|
||||
- (void) getrlimit(RLIMIT_NPROC, &nproclimit);
|
||||
- rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
|
||||
- if (setrlimit(RLIMIT_NPROC, &rl)) {
|
||||
- memcpy(&rl, &nproclimit, sizeof(struct rlimit));
|
||||
- rl.rlim_cur = rl.rlim_max;
|
||||
- (void)setrlimit(RLIMIT_NPROC, &rl);
|
||||
- }
|
||||
-#endif /* __linux__ */
|
||||
#ifdef RLIMIT_CORE
|
||||
/*
|
||||
* Turn off core dumps?
|
||||
@@ -841,6 +827,28 @@ disable_coredumps(void)
|
||||
debug_return;
|
||||
}
|
||||
|
||||
+void
|
||||
+unlimit_nproc(void)
|
||||
+{
|
||||
+ debug_decl(unlimit_nproc, SUDO_DEBUG_UTIL)
|
||||
+#if defined(__linux__)
|
||||
+ struct rlimit rl;
|
||||
+ /*
|
||||
+ * Unlimit the number of processes since Linux's setuid() will
|
||||
+ * apply resource limits when changing uid and return EAGAIN if
|
||||
+ * nproc would be violated by the uid switch.
|
||||
+ */
|
||||
+ (void) getrlimit(RLIMIT_NPROC, &nproclimit);
|
||||
+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
|
||||
+ if (setrlimit(RLIMIT_NPROC, &rl)) {
|
||||
+ memcpy(&rl, &nproclimit, sizeof(struct rlimit));
|
||||
+ rl.rlim_cur = rl.rlim_max;
|
||||
+ (void)setrlimit(RLIMIT_NPROC, &rl);
|
||||
+ }
|
||||
+#endif /* __linux__ */
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
#ifdef HAVE_PROJECT_H
|
||||
static void
|
||||
set_project(struct passwd *pw)
|
||||
@@ -1082,7 +1090,6 @@ exec_setup(struct command_details *detai
|
||||
errno = 0;
|
||||
l = sysconf(_SC_CHILD_MAX);
|
||||
if (l == -1 && errno == 0 && getrlimit(RLIMIT_NPROC, &rl) == 0) {
|
||||
- if (rl.rlim_cur == RLIM_INFINITY && rl.rlim_max == RLIM_INFINITY)
|
||||
(void) setrlimit(RLIMIT_NPROC, &nproclimit);
|
||||
}
|
||||
}
|
||||
diff -up sudo-1.8.6p3/src/sudo.h.nprocfix sudo-1.8.6p3/src/sudo.h
|
||||
--- sudo-1.8.6p3/src/sudo.h.nprocfix 2013-07-11 12:37:41.768202173 +0200
|
||||
+++ sudo-1.8.6p3/src/sudo.h 2013-07-11 12:37:41.811202301 +0200
|
||||
@@ -219,6 +219,7 @@ int policy_init_session(struct command_d
|
||||
int run_command(struct command_details *details);
|
||||
extern const char *list_user, *runas_user, *runas_group;
|
||||
extern struct user_details user_details;
|
||||
+void unlimit_nproc(void);
|
||||
|
||||
/* sudo_edit.c */
|
||||
int sudo_edit(struct command_details *details);
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p3/src/tgetpass.c.sigpipefix sudo-1.8.6p3/src/tgetpass.c
|
||||
--- sudo-1.8.6p3/src/tgetpass.c.sigpipefix 2015-03-03 10:23:23.219038693 +0100
|
||||
+++ sudo-1.8.6p3/src/tgetpass.c 2015-03-03 10:23:43.089813184 +0100
|
||||
@@ -173,7 +173,7 @@ restore:
|
||||
(void) sigaction(SIGTSTP, &savetstp, NULL);
|
||||
(void) sigaction(SIGTTIN, &savettin, NULL);
|
||||
(void) sigaction(SIGTTOU, &savettou, NULL);
|
||||
- (void) sigaction(SIGTTOU, &savepipe, NULL);
|
||||
+ (void) sigaction(SIGPIPE, &savepipe, NULL);
|
||||
if (input != STDIN_FILENO)
|
||||
(void) close(input);
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.sssd-noise sudo-1.8.6p3/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.sssd-noise 2012-11-29 13:23:43.332760956 +0100
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2012-11-29 13:23:57.548816054 +0100
|
||||
@@ -350,7 +350,7 @@ static int sudo_sss_setdefs(struct sudo_
|
||||
|
||||
if (sss_error == ENOENT) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "The user was not found in SSSD.");
|
||||
- debug_return_int(-1);
|
||||
+ debug_return_int(0);
|
||||
} else if(sss_error != 0) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "sss_error=%u\n", sss_error);
|
||||
debug_return_int(-1);
|
|
@ -0,0 +1,119 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.sssdfixes sudo-1.8.6p3/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.sssdfixes 2013-08-13 15:20:39.558187669 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2013-08-13 16:24:27.209064162 +0200
|
||||
@@ -534,30 +534,31 @@ sudo_sss_check_runas_group(struct sudo_s
|
||||
* Walk through search results and return true if we have a runas match,
|
||||
* else false. RunAs info is optional.
|
||||
*/
|
||||
-static int
|
||||
+static bool
|
||||
sudo_sss_check_runas(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
{
|
||||
- int ret;
|
||||
+ bool ret;
|
||||
debug_decl(sudo_sss_check_runas, SUDO_DEBUG_SSSD);
|
||||
|
||||
if (rule == NULL)
|
||||
- debug_return_int(false);
|
||||
+ debug_return_bool(false);
|
||||
|
||||
ret = sudo_sss_check_runas_user(handle, rule) != false &&
|
||||
sudo_sss_check_runas_group(handle, rule) != false;
|
||||
|
||||
- debug_return_int(ret);
|
||||
+ debug_return_bool(ret);
|
||||
}
|
||||
|
||||
-static int
|
||||
+static bool
|
||||
sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
{
|
||||
char **val_array, *val;
|
||||
- int ret = false, i;
|
||||
+ bool ret = false;
|
||||
+ int i;
|
||||
debug_decl(sudo_sss_check_host, SUDO_DEBUG_SSSD);
|
||||
|
||||
if (rule == NULL)
|
||||
- debug_return_int(ret);
|
||||
+ debug_return_bool(ret);
|
||||
|
||||
/* get the values from the rule */
|
||||
switch (handle->fn_get_values(rule, "sudoHost", &val_array))
|
||||
@@ -566,10 +567,10 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
break;
|
||||
case ENOENT:
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
|
||||
- debug_return_int(false);
|
||||
+ debug_return_bool(false);
|
||||
default:
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoHost): != 0");
|
||||
- debug_return_int(ret);
|
||||
+ debug_return_bool(ret);
|
||||
}
|
||||
|
||||
/* walk through values */
|
||||
@@ -589,7 +590,52 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
|
||||
handle->fn_free_values(val_array);
|
||||
|
||||
- debug_return_int(ret);
|
||||
+ debug_return_bool(ret);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Look for netgroup specifcations in the sudoUser attribute and
|
||||
+ * if found, filter according to netgroup membership.
|
||||
+ * returns:
|
||||
+ * true -> netgroup spec found && negroup member
|
||||
+ * false -> netgroup spec found && not a meber of netgroup
|
||||
+ * true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception)
|
||||
+ */
|
||||
+bool sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
+{
|
||||
+ bool ret = false, netgroup_spec_found = false;
|
||||
+ char **val_array, *val;
|
||||
+ int i;
|
||||
+ debug_decl(sudo_sss_check_user_netgroup, SUDO_DEBUG_SSSD);
|
||||
+
|
||||
+ if (!handle || !rule)
|
||||
+ debug_return_bool(ret);
|
||||
+
|
||||
+ switch (handle->fn_get_values(rule, "sudoUser", &val_array)) {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case ENOENT:
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO, "No result.");
|
||||
+ debug_return_bool(ret);
|
||||
+ default:
|
||||
+ sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoUser): != 0");
|
||||
+ debug_return_bool(ret);
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; val_array[i] != NULL && !ret; ++i) {
|
||||
+ val = val_array[i];
|
||||
+ if (*val == '+') {
|
||||
+ netgroup_spec_found = true;
|
||||
+ }
|
||||
+ sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
|
||||
+ if (strcmp(val, "ALL") == 0 || netgr_matches(val, NULL, NULL, user_name)) {
|
||||
+ ret = true;
|
||||
+ sudo_debug_printf(SUDO_DEBUG_DIAG,
|
||||
+ "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, user_name);
|
||||
+ }
|
||||
+ }
|
||||
+ handle->fn_free_values(val_array);
|
||||
+ debug_return_bool(netgroup_spec_found ? ret : true);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -599,7 +645,8 @@ sudo_sss_result_filterp(struct sudo_sss_
|
||||
(void)unused;
|
||||
debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD);
|
||||
|
||||
- if (sudo_sss_check_host(handle, rule))
|
||||
+ if (sudo_sss_check_host(handle, rule) &&
|
||||
+ sudo_sss_filter_user_netgroup(handle, rule))
|
||||
debug_return_int(1);
|
||||
else
|
||||
debug_return_int(0);
|
|
@ -0,0 +1,22 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.rulenames sudo-1.8.6p3/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.rulenames 2014-05-21 12:33:21.000768420 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2014-05-21 12:38:13.779864718 +0200
|
||||
@@ -1180,6 +1180,18 @@ sudo_sss_display_entry_long(struct sudo_
|
||||
int count = 0, i;
|
||||
debug_decl(sudo_sss_display_entry_long, SUDO_DEBUG_SSSD);
|
||||
|
||||
+ switch(handle->fn_get_values(rule, "cn", &val_array)) {
|
||||
+ case 0:
|
||||
+ if (val_array[0]) {
|
||||
+ lbuf_append(lbuf, _("\nSSSD Role: %s\n"), val_array[0]);
|
||||
+ }
|
||||
+ handle->fn_free_values(val_array);
|
||||
+ val_array = NULL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ lbuf_append(lbuf, _("\nSSSD Role: UNKNOWN\n"));
|
||||
+ }
|
||||
+
|
||||
/* get the RunAsUser Values from the entry */
|
||||
lbuf_append(lbuf, " RunAsUsers: ");
|
||||
switch (handle->fn_get_values(rule, "sudoRunAsUser", &val_array)) {
|
|
@ -0,0 +1,53 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/match.c.strictuidgid sudo-1.8.6p3/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/match.c.strictuidgid 2012-09-18 15:56:29.000000000 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/match.c 2013-08-08 16:22:00.413281960 +0200
|
||||
@@ -650,14 +650,16 @@ hostname_matches(char *shost, char *lhos
|
||||
bool
|
||||
userpw_matches(char *sudoers_user, char *user, struct passwd *pw)
|
||||
{
|
||||
- debug_decl(userpw_matches, SUDO_DEBUG_MATCH)
|
||||
-
|
||||
- if (pw != NULL && *sudoers_user == '#') {
|
||||
- uid_t uid = (uid_t) atoi(sudoers_user + 1);
|
||||
- if (uid == pw->pw_uid)
|
||||
- debug_return_bool(true);
|
||||
- }
|
||||
- debug_return_bool(strcmp(sudoers_user, user) == 0);
|
||||
+ debug_decl(userpw_matches, SUDO_DEBUG_MATCH)
|
||||
+ if (pw != NULL && *sudoers_user == '#') {
|
||||
+ char *end = NULL;
|
||||
+ uid_t uid = (uid_t) strtol(sudoers_user + 1, &end, 10);
|
||||
+ if (end != NULL && (sudoers_user[1] != '\0' && *end == '\0')) {
|
||||
+ if (uid == pw->pw_uid)
|
||||
+ debug_return_bool(true);
|
||||
+ }
|
||||
+ }
|
||||
+ debug_return_bool(strcmp(sudoers_user, user) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -667,14 +669,16 @@ userpw_matches(char *sudoers_user, char
|
||||
bool
|
||||
group_matches(char *sudoers_group, struct group *gr)
|
||||
{
|
||||
- debug_decl(group_matches, SUDO_DEBUG_MATCH)
|
||||
-
|
||||
- if (*sudoers_group == '#') {
|
||||
- gid_t gid = (gid_t) atoi(sudoers_group + 1);
|
||||
- if (gid == gr->gr_gid)
|
||||
- debug_return_bool(true);
|
||||
- }
|
||||
- debug_return_bool(strcmp(gr->gr_name, sudoers_group) == 0);
|
||||
+ debug_decl(group_matches, SUDO_DEBUG_MATCH)
|
||||
+ if (*sudoers_group == '#') {
|
||||
+ char *end = NULL;
|
||||
+ gid_t gid = (gid_t) strtol(sudoers_group + 1, &end, 10);
|
||||
+ if (end != NULL && (sudoers_group[1] != '\0' && *end == '\0')) {
|
||||
+ if (gid == gr->gr_gid)
|
||||
+ debug_return_bool(true);
|
||||
+ }
|
||||
+ }
|
||||
+ debug_return_bool(strcmp(gr->gr_name, sudoers_group) == 0);
|
||||
}
|
||||
|
||||
/*
|
|
@ -0,0 +1,747 @@
|
|||
diff -up sudo-1.8.6p3/src/sesh.c.sudoedit-selinux sudo-1.8.6p3/src/sesh.c
|
||||
--- sudo-1.8.6p3/src/sesh.c.sudoedit-selinux 2012-09-18 15:56:30.000000000 +0200
|
||||
+++ sudo-1.8.6p3/src/sesh.c 2012-09-25 16:06:33.408584649 +0200
|
||||
@@ -34,6 +34,10 @@
|
||||
# include "compat/stdbool.h"
|
||||
#endif /* HAVE_STDBOOL_H */
|
||||
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
#include "missing.h"
|
||||
#include "alloc.h"
|
||||
#include "error.h"
|
||||
@@ -43,6 +47,16 @@
|
||||
#include "sudo_exec.h"
|
||||
#include "sudo_plugin.h"
|
||||
|
||||
+/*
|
||||
+ * Return codes:
|
||||
+ * EXIT_FAILURE ... unspecified error
|
||||
+ * 0 ... everything ok
|
||||
+ * 30 ... invalid -e arg value
|
||||
+ * 31 ... odd number of paths
|
||||
+ * 32 ... copy operation failed, no files copied
|
||||
+ * 33 ... copy operation failed, some files copied
|
||||
+ */
|
||||
+
|
||||
sudo_conv_t sudo_conv; /* NULL in non-plugin */
|
||||
|
||||
/*
|
||||
@@ -77,19 +91,134 @@ main(int argc, char *argv[], char *envp[
|
||||
if ((cp = strrchr(argv[0], '-')) != NULL && cp != argv[0])
|
||||
noexec = strcmp(cp, "-noexec") == 0;
|
||||
|
||||
- /* Shift argv and make a copy of the command to execute. */
|
||||
- argv++;
|
||||
- argc--;
|
||||
- cmnd = estrdup(argv[0]);
|
||||
-
|
||||
- /* If invoked as a login shell, modify argv[0] accordingly. */
|
||||
- if (argv[-1][0] == '-') {
|
||||
- if ((cp = strrchr(argv[0], '/')) == NULL)
|
||||
- cp = argv[0];
|
||||
- *cp = '-';
|
||||
+ /* check the first argument, if it's `-e' then we are in sudoedit mode */
|
||||
+ if (strncmp(argv[1], "-e", 3) == 0) {
|
||||
+ int fd_src, fd_dst, post, n, ret = -1;
|
||||
+ ssize_t nread, nwritten;
|
||||
+ char *path_src, *path_dst, buf[BUFSIZ];
|
||||
+
|
||||
+ if (argc < 3)
|
||||
+ return EXIT_FAILURE;
|
||||
+
|
||||
+ /*
|
||||
+ * We need to know whether we are performing the copy operation
|
||||
+ * before or after the editing. Without this we would not know
|
||||
+ * which files are temporary and which are the originals.
|
||||
+ * post = 0 ... before
|
||||
+ * post = 1 ... after
|
||||
+ */
|
||||
+ if (strncmp(argv[2], "0", 2) == 0)
|
||||
+ post = 0;
|
||||
+ else if (strncmp(argv[2], "1", 2) == 0)
|
||||
+ post = 1;
|
||||
+ else /* invalid value */
|
||||
+ return 30;
|
||||
+
|
||||
+ /* align argv & argc to the beggining of the file list */
|
||||
+ argv += 3;
|
||||
+ argc -= 3;
|
||||
+
|
||||
+ /* no files specified, nothing to do */
|
||||
+ if (argc == 0)
|
||||
+ return 0;
|
||||
+ /* odd number of paths specified */
|
||||
+ if (argc % 2 == 1)
|
||||
+ return 31;
|
||||
+
|
||||
+ for (n = 0; n < argc - 1; n += 2) {
|
||||
+ path_src = argv[n];
|
||||
+ path_dst = argv[n+1];
|
||||
+ /*
|
||||
+ * Try to open the source file for reading. If it
|
||||
+ * doesn't exist, it's ok, we'll create an empty
|
||||
+ * destination file.
|
||||
+ */
|
||||
+ if ((fd_src = open(path_src, O_RDONLY, 0600)) < 0) {
|
||||
+ if (errno == ENOENT) {
|
||||
+ /* new file */
|
||||
+ } else {
|
||||
+ warning(_("open(%s)"), path_src);
|
||||
+ if (post) {
|
||||
+ ret = 33;
|
||||
+ goto nocleanup;
|
||||
+ } else
|
||||
+ goto cleanup_0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Use O_EXCL if we are not in the post editing stage
|
||||
+ * so that it's ensured that the temporary files are
|
||||
+ * created by us and that we are not opening any sym-
|
||||
+ * links.
|
||||
+ */
|
||||
+ if ((fd_dst = open(path_dst, (post ? 0 : O_EXCL) |
|
||||
+ O_WRONLY|O_TRUNC|O_CREAT, post ? 0644 : 0600)) < 0)
|
||||
+ {
|
||||
+ /* error - cleanup */
|
||||
+ warning(_("open(%s%s)"), path_dst, post ? "" : ", O_EXCL");
|
||||
+ if (post) {
|
||||
+ ret = 33;
|
||||
+ goto nocleanup;
|
||||
+ } else
|
||||
+ goto cleanup_0;
|
||||
+ }
|
||||
+
|
||||
+ if (fd_src != -1) {
|
||||
+ while ((nread = read(fd_src, buf, sizeof(buf))) > 0) {
|
||||
+ if ((nwritten = write(fd_dst, buf, nread)) != nread) {
|
||||
+ warning(_("write"));
|
||||
+ if (post) {
|
||||
+ ret = 33;
|
||||
+ goto nocleanup;
|
||||
+ } else
|
||||
+ goto cleanup_0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (fd_dst != -1)
|
||||
+ close(fd_dst);
|
||||
+ if (fd_src != -1)
|
||||
+ close(fd_src);
|
||||
+ fd_dst = fd_src = -1;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+ /* remove temporary files (post=1) */
|
||||
+ for (n = 0; n < argc - 1; n += 2)
|
||||
+ unlink(argv[n]);
|
||||
+nocleanup:
|
||||
+ if (fd_dst != -1)
|
||||
+ close(fd_dst);
|
||||
+ if (fd_src != -1)
|
||||
+ close(fd_src);
|
||||
+ _exit(ret);
|
||||
+cleanup_0:
|
||||
+ /* remove temporary files (post=0) */
|
||||
+ for (n = 0; n < argc - 1; n += 2)
|
||||
+ unlink(argv[n+1]);
|
||||
+ if (fd_dst != -1)
|
||||
+ close(fd_dst);
|
||||
+ if (fd_src != -1)
|
||||
+ close(fd_src);
|
||||
+ _exit(32);
|
||||
+ } else {
|
||||
+
|
||||
+ /* Shift argv and make a copy of the command to execute. */
|
||||
+ argv++;
|
||||
+ argc--;
|
||||
+ cmnd = estrdup(argv[0]);
|
||||
+
|
||||
+ /* If invoked as a login shell, modify argv[0] accordingly. */
|
||||
+ if (argv[-1][0] == '-') {
|
||||
+ if ((cp = strrchr(argv[0], '/')) == NULL)
|
||||
+ cp = argv[0];
|
||||
+ *cp = '-';
|
||||
+ }
|
||||
+ sudo_execve(cmnd, argv, envp, noexec);
|
||||
+ warning(_("unable to execute %s"), argv[0]);
|
||||
+ sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, EXIT_FAILURE);
|
||||
}
|
||||
- sudo_execve(cmnd, argv, envp, noexec);
|
||||
- warning(_("unable to execute %s"), argv[0]);
|
||||
- sudo_debug_exit_int(__func__, __FILE__, __LINE__, sudo_debug_subsys, EXIT_FAILURE);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
diff -up sudo-1.8.6p3/src/sudo.c.sudoedit-selinux sudo-1.8.6p3/src/sudo.c
|
||||
--- sudo-1.8.6p3/src/sudo.c.sudoedit-selinux 2012-09-18 15:57:43.000000000 +0200
|
||||
+++ sudo-1.8.6p3/src/sudo.c 2012-09-25 16:04:36.687422997 +0200
|
||||
@@ -915,6 +915,10 @@ exec_setup(struct command_details *detai
|
||||
if (selinux_setup(details->selinux_role, details->selinux_type,
|
||||
ptyname ? ptyname : user_details.tty, ptyfd) == -1)
|
||||
goto done;
|
||||
+ if (details->flags & CD_SUDOEDIT_COPY) {
|
||||
+ rval = true;
|
||||
+ goto done;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1116,6 +1120,8 @@ run_command(struct command_details *deta
|
||||
break;
|
||||
case CMD_WSTATUS:
|
||||
/* Command ran, exited or was killed. */
|
||||
+ if (details->flags & CD_SUDOEDIT_COPY)
|
||||
+ break;
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG,
|
||||
"calling policy close with wait status %d", cstat.val);
|
||||
policy_close(&policy_plugin, cstat.val, 0);
|
||||
diff -up sudo-1.8.6p3/src/sudo_edit.c.sudoedit-selinux sudo-1.8.6p3/src/sudo_edit.c
|
||||
--- sudo-1.8.6p3/src/sudo_edit.c.sudoedit-selinux 2012-09-18 15:56:30.000000000 +0200
|
||||
+++ sudo-1.8.6p3/src/sudo_edit.c 2012-09-25 16:06:19.108564255 +0200
|
||||
@@ -49,11 +49,284 @@
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <time.h>
|
||||
#endif
|
||||
+#ifdef HAVE_SELINUX
|
||||
+# include <selinux/selinux.h>
|
||||
+#endif
|
||||
|
||||
#include "sudo.h"
|
||||
|
||||
#if defined(HAVE_SETRESUID) || defined(HAVE_SETREUID) || defined(HAVE_SETEUID)
|
||||
|
||||
+struct tempfile {
|
||||
+ char *tfile;
|
||||
+ char *ofile;
|
||||
+ struct timeval omtim;
|
||||
+ off_t osize;
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+selinux_edit_copy(struct command_details *command_details, struct tempfile *tf, char **files, int nfiles, const char *tmpdir, int tmplen, int tval_isset)
|
||||
+{
|
||||
+ char **sesh_args;
|
||||
+ int i, sesh_nargs, ret;
|
||||
+ struct command_details sesh_details;
|
||||
+ debug_decl(selinux_edit_copy, SUDO_DEBUG_EDIT);
|
||||
+
|
||||
+ /* Prepare selinux stuff (setexeccon) */
|
||||
+ if (selinux_setup(command_details->selinux_role,
|
||||
+ command_details->selinux_type, NULL, -1) != 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (nfiles < 1)
|
||||
+ return 1;
|
||||
+
|
||||
+ /* Construct common args for sesh */
|
||||
+ memcpy(&sesh_details, command_details, sizeof(sesh_details));
|
||||
+ sesh_details.command = _PATH_SUDO_SESH;
|
||||
+ sesh_details.flags |= CD_SUDOEDIT_COPY;
|
||||
+
|
||||
+ sesh_nargs = (nfiles * 2) + 4 + 1;
|
||||
+ sesh_args = (char **)emalloc2(sesh_nargs, sizeof(char *));
|
||||
+ sesh_args++;
|
||||
+ sesh_args[0] = "sesh";
|
||||
+ sesh_args[1] = "-e";
|
||||
+
|
||||
+ if (files != NULL) {
|
||||
+ sesh_args[2] = "0";
|
||||
+
|
||||
+ for (i = 2; i < nfiles+2; ++i) {
|
||||
+ sesh_args[2*i-1] = files[i-2];
|
||||
+ tf[i-2].ofile = files[i-2];
|
||||
+ /*
|
||||
+ * O_CREAT | O_EXCL is used in the sesh helper, so the
|
||||
+ * usage of the tempnam function here is safe.
|
||||
+ */
|
||||
+ sesh_args[2*i] = tempnam(tmpdir, "sudo.");
|
||||
+ tf[i-2].tfile = sesh_args[2*i];
|
||||
+ //tf[i-2].omtim = 0;
|
||||
+ tf[i-2].osize = 0;
|
||||
+ }
|
||||
+
|
||||
+ sesh_args[2*i-1] = NULL;
|
||||
+
|
||||
+ /* Run sesh -e 0 <o1> <t1> ... <on> <tn> */
|
||||
+ sesh_details.argv = sesh_args;
|
||||
+ switch(run_command(&sesh_details)) {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case 31:
|
||||
+ error(1, _("sesh: internal error: odd number of paths"));
|
||||
+ case 32:
|
||||
+ error(1, _("sesh: unable to create temporary files"));
|
||||
+ }
|
||||
+
|
||||
+ /* Chown to user's UID so he can edit the temporary files */
|
||||
+ for (i = 2; i < nfiles+2; ++i) {
|
||||
+ if (chown(tf[i-2].tfile, user_details.uid, user_details.gid) != 0) {
|
||||
+ warning("Unable to chown(%s) to %d:%d for editing",
|
||||
+ tf[i-2].tfile, user_details.uid, user_details.gid);
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ sesh_args[2] = "1";
|
||||
+
|
||||
+ /* Construct args for sesh -e 1 */
|
||||
+ for (i = 2; i < nfiles+2; ++i) {
|
||||
+ sesh_args[2*i-1] = tf[i-2].tfile;
|
||||
+ sesh_args[2*i] = tf[i-2].ofile;
|
||||
+
|
||||
+ if (chown(tf[i-2].tfile, sesh_details.uid, sesh_details.gid) != 0) {
|
||||
+ warning("Unable to chown(%s) back to %d:%d",
|
||||
+ tf[i-2].tfile, sesh_details.uid, sesh_details.gid);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ sesh_args[2*i-1] = NULL;
|
||||
+
|
||||
+ /* Run sesh -e 1 <t1> <o1> ... <tn> <on> */
|
||||
+ sesh_details.argv = sesh_args;
|
||||
+ switch(run_command(&sesh_details)) {
|
||||
+ case 0:
|
||||
+ break;
|
||||
+ case 32:
|
||||
+ warning(_("Copying the temporary files back to its original place failed. The files were left in %s"), tmpdir);
|
||||
+ break;
|
||||
+ case 33:
|
||||
+ warning(_("Copying of some of the temporary files back to its original place failed and they were left in %s"),
|
||||
+ tmpdir);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return (nfiles);
|
||||
+}
|
||||
+
|
||||
+static void switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups);
|
||||
+
|
||||
+static int sudo_edit_copy(struct command_details *command_details, struct tempfile *tf, char **files, int nfiles, const char *tmpdir, int tmplen, int tval_isset)
|
||||
+{
|
||||
+ int i, j, tfd, ofd, rc;
|
||||
+ char *cp, *suff, buf[BUFSIZ];
|
||||
+ ssize_t nwritten, nread;
|
||||
+ struct stat sb;
|
||||
+ struct timeval tv;
|
||||
+ debug_decl(sudo_edit_copy, SUDO_DEBUG_EDIT);
|
||||
+
|
||||
+ if (files != NULL) {
|
||||
+ /* Create temporary copies */
|
||||
+ for (i = 0, j = 0; i < nfiles; i++) {
|
||||
+ rc = -1;
|
||||
+ switch_user(command_details->euid, command_details->egid,
|
||||
+ command_details->ngroups, command_details->groups);
|
||||
+ if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) {
|
||||
+ if (ofd == -1) {
|
||||
+ zero_bytes(&sb, sizeof(sb)); /* new file */
|
||||
+ rc = 0;
|
||||
+ } else {
|
||||
+ rc = fstat(ofd, &sb);
|
||||
+ }
|
||||
+ }
|
||||
+ switch_user(ROOT_UID, user_details.egid,
|
||||
+ user_details.ngroups, user_details.groups);
|
||||
+ if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) {
|
||||
+ if (rc)
|
||||
+ warning("%s", files[i]);
|
||||
+ else
|
||||
+ warningx(_("%s: not a regular file"), files[i]);
|
||||
+ if (ofd != -1)
|
||||
+ close(ofd);
|
||||
+ continue;
|
||||
+ }
|
||||
+ tf[j].ofile = files[i];
|
||||
+ tf[j].osize = sb.st_size;
|
||||
+ mtim_get(&sb, &tf[j].omtim);
|
||||
+ if ((cp = strrchr(tf[j].ofile, '/')) != NULL)
|
||||
+ cp++;
|
||||
+ else
|
||||
+ cp = tf[j].ofile;
|
||||
+ suff = strrchr(cp, '.');
|
||||
+ if (suff != NULL) {
|
||||
+ easprintf(&tf[j].tfile, "%.*s/%.*sXXXXXXXX%s", tmplen, tmpdir,
|
||||
+ (int)(size_t)(suff - cp), cp, suff);
|
||||
+ } else {
|
||||
+ easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp);
|
||||
+ }
|
||||
+ if (seteuid(user_details.uid) != 0)
|
||||
+ error(1, "seteuid(%d)", (int)user_details.uid);
|
||||
+ tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0);
|
||||
+ if (seteuid(ROOT_UID) != 0)
|
||||
+ error(1, "seteuid(ROOT_UID)");
|
||||
+ if (tfd == -1) {
|
||||
+ warning("mkstemps");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (ofd != -1) {
|
||||
+ while ((nread = read(ofd, buf, sizeof(buf))) != 0) {
|
||||
+ if ((nwritten = write(tfd, buf, nread)) != nread) {
|
||||
+ if (nwritten == -1)
|
||||
+ warning("%s", tf[j].tfile);
|
||||
+ else
|
||||
+ warningx(_("%s: short write"), tf[j].tfile);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+ close(ofd);
|
||||
+ }
|
||||
+ /*
|
||||
+ * We always update the stashed mtime because the time
|
||||
+ * resolution of the filesystem the temporary file is on may
|
||||
+ * not match that of the filesystem where the file to be edited
|
||||
+ * resides. It is OK if touch() fails since we only use the info
|
||||
+ * to determine whether or not a file has been modified.
|
||||
+ */
|
||||
+ (void) touch(tfd, NULL, &tf[j].omtim);
|
||||
+ rc = fstat(tfd, &sb);
|
||||
+ if (!rc)
|
||||
+ mtim_get(&sb, &tf[j].omtim);
|
||||
+ close(tfd);
|
||||
+ j++;
|
||||
+ }
|
||||
+ if ((nfiles = j) == 0)
|
||||
+ goto cleanup; /* no files readable, you lose */
|
||||
+ } else {
|
||||
+ /* Copy contents of temp files to real ones */
|
||||
+ for (i = 0; i < nfiles; i++) {
|
||||
+ rc = -1;
|
||||
+ if (seteuid(user_details.uid) != 0)
|
||||
+ error(1, "seteuid(%d)", (int)user_details.uid);
|
||||
+ if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) {
|
||||
+ rc = fstat(tfd, &sb);
|
||||
+ }
|
||||
+ if (seteuid(ROOT_UID) != 0)
|
||||
+ error(1, "seteuid(ROOT_UID)");
|
||||
+ if (rc || !S_ISREG(sb.st_mode)) {
|
||||
+ if (rc)
|
||||
+ warning("%s", tf[i].tfile);
|
||||
+ else
|
||||
+ warningx(_("%s: not a regular file"), tf[i].tfile);
|
||||
+ warningx(_("%s left unmodified"), tf[i].ofile);
|
||||
+ if (tfd != -1)
|
||||
+ close(tfd);
|
||||
+ continue;
|
||||
+ }
|
||||
+ mtim_get(&sb, &tv);
|
||||
+ if (tf[i].osize == sb.st_size && timevalcmp(&tf[i].omtim, &tv, ==)) {
|
||||
+ /*
|
||||
+ * If mtime and size match but the user spent no measurable
|
||||
+ * time in the editor we can't tell if the file was changed.
|
||||
+ */
|
||||
+ if (tval_isset) {
|
||||
+ warningx(_("%s unchanged"), tf[i].ofile);
|
||||
+ unlink(tf[i].tfile);
|
||||
+ close(tfd);
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ switch_user(command_details->euid, command_details->egid,
|
||||
+ command_details->ngroups, command_details->groups);
|
||||
+ ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644);
|
||||
+ switch_user(ROOT_UID, user_details.egid,
|
||||
+ user_details.ngroups, user_details.groups);
|
||||
+ if (ofd == -1) {
|
||||
+ warning(_("unable to write to %s"), tf[i].ofile);
|
||||
+ warningx(_("contents of edit session left in %s"), tf[i].tfile);
|
||||
+ close(tfd);
|
||||
+ continue;
|
||||
+ }
|
||||
+ while ((nread = read(tfd, buf, sizeof(buf))) > 0) {
|
||||
+ if ((nwritten = write(ofd, buf, nread)) != nread) {
|
||||
+ if (nwritten == -1)
|
||||
+ warning("%s", tf[i].ofile);
|
||||
+ else
|
||||
+ warningx(_("%s: short write"), tf[i].ofile);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (nread == 0) {
|
||||
+ /* success, got EOF */
|
||||
+ unlink(tf[i].tfile);
|
||||
+ } else if (nread < 0) {
|
||||
+ warning(_("unable to read temporary file"));
|
||||
+ warningx(_("contents of edit session left in %s"), tf[i].tfile);
|
||||
+ } else {
|
||||
+ warning(_("unable to write to %s"), tf[i].ofile);
|
||||
+ warningx(_("contents of edit session left in %s"), tf[i].tfile);
|
||||
+ }
|
||||
+ close(ofd);
|
||||
+ }
|
||||
+ j = 0;
|
||||
+ }
|
||||
+
|
||||
+ debug_return_int(j);
|
||||
+cleanup:
|
||||
+ for (i = 0; i < nfiles; i++) {
|
||||
+ if (tf[i].tfile != NULL)
|
||||
+ unlink(tf[i].tfile);
|
||||
+ }
|
||||
+
|
||||
+ debug_return_int(-1);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
switch_user(uid_t euid, gid_t egid, int ngroups, GETGROUPS_T *groups)
|
||||
{
|
||||
@@ -87,20 +360,17 @@ int
|
||||
sudo_edit(struct command_details *command_details)
|
||||
{
|
||||
struct command_details editor_details;
|
||||
- ssize_t nread, nwritten;
|
||||
const char *tmpdir;
|
||||
- char *cp, *suff, **nargv, **ap, **files = NULL;
|
||||
- char buf[BUFSIZ];
|
||||
- int rc, i, j, ac, ofd, tfd, nargc, rval, tmplen;
|
||||
- int editor_argc = 0, nfiles = 0;
|
||||
+ char **ap;
|
||||
+ char **nargv, **files = NULL;
|
||||
+ int editor_argc = 0;
|
||||
+ int i, ac, nargc, rval, nfiles = 0, tmplen;
|
||||
struct stat sb;
|
||||
- struct timeval tv, tv1, tv2;
|
||||
- struct tempfile {
|
||||
- char *tfile;
|
||||
- char *ofile;
|
||||
- struct timeval omtim;
|
||||
- off_t osize;
|
||||
- } *tf = NULL;
|
||||
+ struct timeval tv1, tv2;
|
||||
+ struct tempfile *tf;
|
||||
+#ifdef HAVE_SELINUX
|
||||
+ int rbac_enabled;
|
||||
+#endif
|
||||
debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
|
||||
|
||||
/*
|
||||
@@ -109,7 +379,7 @@ sudo_edit(struct command_details *comman
|
||||
*/
|
||||
if (setuid(ROOT_UID) != 0) {
|
||||
warning(_("unable to change uid to root (%u)"), ROOT_UID);
|
||||
- goto cleanup;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -127,6 +397,9 @@ sudo_edit(struct command_details *comman
|
||||
while (tmplen > 0 && tmpdir[tmplen - 1] == '/')
|
||||
tmplen--;
|
||||
|
||||
+#ifdef HAVE_SELINUX
|
||||
+ rbac_enabled = is_selinux_enabled() > 0 && command_details->selinux_role != NULL;
|
||||
+#endif
|
||||
/*
|
||||
* The user's editor must be separated from the files to be
|
||||
* edited by a "--" option.
|
||||
@@ -141,7 +414,7 @@ sudo_edit(struct command_details *comman
|
||||
}
|
||||
if (nfiles == 0) {
|
||||
warningx(_("plugin error: missing file list for sudoedit"));
|
||||
- goto cleanup;
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,81 +423,18 @@ sudo_edit(struct command_details *comman
|
||||
*/
|
||||
tf = emalloc2(nfiles, sizeof(*tf));
|
||||
zero_bytes(tf, nfiles * sizeof(*tf));
|
||||
- for (i = 0, j = 0; i < nfiles; i++) {
|
||||
- rc = -1;
|
||||
- switch_user(command_details->euid, command_details->egid,
|
||||
- command_details->ngroups, command_details->groups);
|
||||
- if ((ofd = open(files[i], O_RDONLY, 0644)) != -1 || errno == ENOENT) {
|
||||
- if (ofd == -1) {
|
||||
- zero_bytes(&sb, sizeof(sb)); /* new file */
|
||||
- rc = 0;
|
||||
- } else {
|
||||
- rc = fstat(ofd, &sb);
|
||||
- }
|
||||
- }
|
||||
- switch_user(ROOT_UID, user_details.egid,
|
||||
- user_details.ngroups, user_details.groups);
|
||||
- if (rc || (ofd != -1 && !S_ISREG(sb.st_mode))) {
|
||||
- if (rc)
|
||||
- warning("%s", files[i]);
|
||||
- else
|
||||
- warningx(_("%s: not a regular file"), files[i]);
|
||||
- if (ofd != -1)
|
||||
- close(ofd);
|
||||
- continue;
|
||||
- }
|
||||
- tf[j].ofile = files[i];
|
||||
- tf[j].osize = sb.st_size;
|
||||
- mtim_get(&sb, &tf[j].omtim);
|
||||
- if ((cp = strrchr(tf[j].ofile, '/')) != NULL)
|
||||
- cp++;
|
||||
- else
|
||||
- cp = tf[j].ofile;
|
||||
- suff = strrchr(cp, '.');
|
||||
- if (suff != NULL) {
|
||||
- easprintf(&tf[j].tfile, "%.*s/%.*sXXXXXXXX%s", tmplen, tmpdir,
|
||||
- (int)(size_t)(suff - cp), cp, suff);
|
||||
- } else {
|
||||
- easprintf(&tf[j].tfile, "%.*s/%s.XXXXXXXX", tmplen, tmpdir, cp);
|
||||
- }
|
||||
- if (seteuid(user_details.uid) != 0)
|
||||
- error(1, "seteuid(%d)", (int)user_details.uid);
|
||||
- tfd = mkstemps(tf[j].tfile, suff ? strlen(suff) : 0);
|
||||
- if (seteuid(ROOT_UID) != 0)
|
||||
- error(1, "seteuid(ROOT_UID)");
|
||||
- if (tfd == -1) {
|
||||
- warning("mkstemps");
|
||||
- goto cleanup;
|
||||
- }
|
||||
- if (ofd != -1) {
|
||||
- while ((nread = read(ofd, buf, sizeof(buf))) != 0) {
|
||||
- if ((nwritten = write(tfd, buf, nread)) != nread) {
|
||||
- if (nwritten == -1)
|
||||
- warning("%s", tf[j].tfile);
|
||||
- else
|
||||
- warningx(_("%s: short write"), tf[j].tfile);
|
||||
- goto cleanup;
|
||||
- }
|
||||
- }
|
||||
- close(ofd);
|
||||
- }
|
||||
- /*
|
||||
- * We always update the stashed mtime because the time
|
||||
- * resolution of the filesystem the temporary file is on may
|
||||
- * not match that of the filesystem where the file to be edited
|
||||
- * resides. It is OK if touch() fails since we only use the info
|
||||
- * to determine whether or not a file has been modified.
|
||||
- */
|
||||
- (void) touch(tfd, NULL, &tf[j].omtim);
|
||||
- rc = fstat(tfd, &sb);
|
||||
- if (!rc)
|
||||
- mtim_get(&sb, &tf[j].omtim);
|
||||
- close(tfd);
|
||||
- j++;
|
||||
- }
|
||||
- if ((nfiles = j) == 0)
|
||||
- goto cleanup; /* no files readable, you lose */
|
||||
+
|
||||
+ /* Make temporary copies of the original files */
|
||||
+ if (!rbac_enabled)
|
||||
+ nfiles = sudo_edit_copy(command_details, tf, files, nfiles, tmpdir, tmplen, 0);
|
||||
+ else
|
||||
+ nfiles = selinux_edit_copy(command_details, tf, files, nfiles, tmpdir, tmplen, 0);
|
||||
|
||||
+ if (nfiles <= 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ switch_user(ROOT_UID, user_details.egid,
|
||||
+ user_details.ngroups, user_details.groups);
|
||||
/*
|
||||
* Allocate space for the new argument vector and fill it in.
|
||||
* We concatenate the editor with its args and the file list
|
||||
@@ -253,84 +463,18 @@ sudo_edit(struct command_details *comman
|
||||
editor_details.argv = nargv;
|
||||
rval = run_command(&editor_details);
|
||||
gettimeofday(&tv2, NULL);
|
||||
+ timevalsub(&tv1, &tv2);
|
||||
|
||||
- /* Copy contents of temp files to real ones */
|
||||
- for (i = 0; i < nfiles; i++) {
|
||||
- rc = -1;
|
||||
- if (seteuid(user_details.uid) != 0)
|
||||
- error(1, "seteuid(%d)", (int)user_details.uid);
|
||||
- if ((tfd = open(tf[i].tfile, O_RDONLY, 0644)) != -1) {
|
||||
- rc = fstat(tfd, &sb);
|
||||
- }
|
||||
- if (seteuid(ROOT_UID) != 0)
|
||||
- error(1, "seteuid(ROOT_UID)");
|
||||
- if (rc || !S_ISREG(sb.st_mode)) {
|
||||
- if (rc)
|
||||
- warning("%s", tf[i].tfile);
|
||||
- else
|
||||
- warningx(_("%s: not a regular file"), tf[i].tfile);
|
||||
- warningx(_("%s left unmodified"), tf[i].ofile);
|
||||
- if (tfd != -1)
|
||||
- close(tfd);
|
||||
- continue;
|
||||
- }
|
||||
- mtim_get(&sb, &tv);
|
||||
- if (tf[i].osize == sb.st_size && timevalcmp(&tf[i].omtim, &tv, ==)) {
|
||||
- /*
|
||||
- * If mtime and size match but the user spent no measurable
|
||||
- * time in the editor we can't tell if the file was changed.
|
||||
- */
|
||||
- timevalsub(&tv1, &tv2);
|
||||
- if (timevalisset(&tv2)) {
|
||||
- warningx(_("%s unchanged"), tf[i].ofile);
|
||||
- unlink(tf[i].tfile);
|
||||
- close(tfd);
|
||||
- continue;
|
||||
- }
|
||||
- }
|
||||
- switch_user(command_details->euid, command_details->egid,
|
||||
- command_details->ngroups, command_details->groups);
|
||||
- ofd = open(tf[i].ofile, O_WRONLY|O_TRUNC|O_CREAT, 0644);
|
||||
- switch_user(ROOT_UID, user_details.egid,
|
||||
- user_details.ngroups, user_details.groups);
|
||||
- if (ofd == -1) {
|
||||
- warning(_("unable to write to %s"), tf[i].ofile);
|
||||
- warningx(_("contents of edit session left in %s"), tf[i].tfile);
|
||||
- close(tfd);
|
||||
- continue;
|
||||
- }
|
||||
- while ((nread = read(tfd, buf, sizeof(buf))) > 0) {
|
||||
- if ((nwritten = write(ofd, buf, nread)) != nread) {
|
||||
- if (nwritten == -1)
|
||||
- warning("%s", tf[i].ofile);
|
||||
- else
|
||||
- warningx(_("%s: short write"), tf[i].ofile);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- if (nread == 0) {
|
||||
- /* success, got EOF */
|
||||
- unlink(tf[i].tfile);
|
||||
- } else if (nread < 0) {
|
||||
- warning(_("unable to read temporary file"));
|
||||
- warningx(_("contents of edit session left in %s"), tf[i].tfile);
|
||||
- } else {
|
||||
- warning(_("unable to write to %s"), tf[i].ofile);
|
||||
- warningx(_("contents of edit session left in %s"), tf[i].tfile);
|
||||
- }
|
||||
- close(ofd);
|
||||
- }
|
||||
+ switch_user(ROOT_UID, user_details.egid,
|
||||
+ user_details.ngroups, user_details.groups);
|
||||
+
|
||||
+ /* Copy the temporary files back to originals */
|
||||
+ if (!rbac_enabled)
|
||||
+ nfiles = sudo_edit_copy(command_details, tf, NULL, nfiles, NULL, 0, timevalisset(&tv2));
|
||||
+ else
|
||||
+ nfiles = selinux_edit_copy(command_details, tf, NULL, nfiles, NULL, 0, timevalisset(&tv2));
|
||||
+
|
||||
debug_return_int(rval);
|
||||
-
|
||||
-cleanup:
|
||||
- /* Clean up temp files and return. */
|
||||
- if (tf != NULL) {
|
||||
- for (i = 0; i < nfiles; i++) {
|
||||
- if (tf[i].tfile != NULL)
|
||||
- unlink(tf[i].tfile);
|
||||
- }
|
||||
- }
|
||||
- debug_return_int(1);
|
||||
}
|
||||
|
||||
#else /* HAVE_SETRESUID || HAVE_SETREUID || HAVE_SETEUID */
|
||||
diff -up sudo-1.8.6p3/src/sudo.h.sudoedit-selinux sudo-1.8.6p3/src/sudo.h
|
||||
--- sudo-1.8.6p3/src/sudo.h.sudoedit-selinux 2012-09-18 15:56:30.000000000 +0200
|
||||
+++ sudo-1.8.6p3/src/sudo.h 2012-09-25 16:04:36.690423001 +0200
|
||||
@@ -130,6 +130,7 @@ struct user_details {
|
||||
#define CD_RBAC_ENABLED 0x0800
|
||||
#define CD_USE_PTY 0x1000
|
||||
#define CD_SET_UTMP 0x2000
|
||||
+#define CD_SUDOEDIT_COPY 0x4000
|
||||
|
||||
struct command_details {
|
||||
uid_t uid;
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p3/plugins/sudoers/visudo.c.fix sudo-1.8.6p3/plugins/sudoers/visudo.c
|
||||
--- sudo-1.8.6p3/plugins/sudoers/visudo.c.fix 2015-07-22 11:29:03.899122767 +0200
|
||||
+++ sudo-1.8.6p3/plugins/sudoers/visudo.c 2015-07-22 11:29:33.001826535 +0200
|
||||
@@ -201,7 +201,7 @@ main(int argc, char *argv[])
|
||||
strict = true; /* strict mode */
|
||||
break;
|
||||
case 'q':
|
||||
- quiet = false; /* quiet mode */
|
||||
+ quiet = true; /* quiet mode */
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
|
@ -0,0 +1,333 @@
|
|||
diff -up sudo-1.8.6p7/aclocal.m4.CVE-2014-9680 sudo-1.8.6p7/aclocal.m4
|
||||
--- sudo-1.8.6p7/aclocal.m4.CVE-2014-9680 2013-02-25 20:42:44.000000000 +0100
|
||||
+++ sudo-1.8.6p7/aclocal.m4 2015-07-05 13:44:11.610596042 +0200
|
||||
@@ -156,6 +156,25 @@ AC_DEFUN([SUDO_IO_LOGDIR], [
|
||||
AC_MSG_RESULT($iolog_dir)
|
||||
])dnl
|
||||
|
||||
+dnl Detect time zone file directory, if any.
|
||||
+dnl
|
||||
+AC_DEFUN([SUDO_TZDIR], [AC_MSG_CHECKING(time zone data directory)
|
||||
+tzdir="$with_tzdir"
|
||||
+if test -z "$tzdir"; then
|
||||
+ tzdir=no
|
||||
+ for d in /usr/share /usr/share/lib /usr/lib /etc; do
|
||||
+ if test -d "$d/zoneinfo"; then
|
||||
+ tzdir="$d/zoneinfo"
|
||||
+ break
|
||||
+ fi
|
||||
+ done
|
||||
+fi
|
||||
+AC_MSG_RESULT([$tzdir])
|
||||
+if test "${tzdir}" != "no"; then
|
||||
+ SUDO_DEFINE_UNQUOTED(_PATH_ZONEINFO, "$tzdir")
|
||||
+fi
|
||||
+])dnl
|
||||
+
|
||||
dnl
|
||||
dnl check for working fnmatch(3)
|
||||
dnl
|
||||
diff -up sudo-1.8.6p7/configure.in.CVE-2014-9680 sudo-1.8.6p7/configure.in
|
||||
--- sudo-1.8.6p7/configure.in.CVE-2014-9680 2015-07-05 13:44:11.598596222 +0200
|
||||
+++ sudo-1.8.6p7/configure.in 2015-07-05 13:44:11.610596042 +0200
|
||||
@@ -776,6 +776,12 @@ AC_ARG_WITH(iologdir, [AS_HELP_STRING([-
|
||||
;;
|
||||
esac])
|
||||
|
||||
+AC_ARG_WITH(tzdir, [AS_HELP_STRING([--with-tzdir=DIR], [path to the time zone data directory])],
|
||||
+[case $with_tzdir in
|
||||
+ yes) AC_MSG_ERROR(["must give --with-tzdir an argument."])
|
||||
+ ;;
|
||||
+esac])
|
||||
+
|
||||
AC_ARG_WITH(sendmail, [AS_HELP_STRING([--with-sendmail], [set path to sendmail])
|
||||
AS_HELP_STRING([--without-sendmail], [do not send mail at all])],
|
||||
[case $with_sendmail in
|
||||
@@ -3250,6 +3256,7 @@ fi
|
||||
SUDO_LOGFILE
|
||||
SUDO_TIMEDIR
|
||||
SUDO_IO_LOGDIR
|
||||
+SUDO_TZDIR
|
||||
|
||||
dnl
|
||||
dnl Turn warnings into errors.
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.cat.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.cat
|
||||
--- sudo-1.8.6p7/doc/sudoers.cat.CVE-2014-9680 2015-07-05 13:44:11.586596402 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.cat 2015-07-05 13:44:11.610596042 +0200
|
||||
@@ -1421,20 +1421,36 @@ SSUUDDOOEERRSS OOPPTTIIOONN
|
||||
|
||||
LLiissttss tthhaatt ccaann bbee uusseedd iinn aa bboooolleeaann ccoonntteexxtt:
|
||||
|
||||
- env_check Environment variables to be removed from the user's
|
||||
- environment if the variable's value contains `%' or `/'
|
||||
+ env_check Environment variables to be removed from the user's
|
||||
+ environment if unless they are considered ``safe''.
|
||||
+ For all variables except TZ, ``safe'' means that the
|
||||
+ variable's value does not contain any `%' or `/'
|
||||
characters. This can be used to guard against printf-
|
||||
style format vulnerabilities in poorly-written
|
||||
- programs. The argument may be a double-quoted, space-
|
||||
- separated list or a single value without double-quotes.
|
||||
- The list can be replaced, added to, deleted from, or
|
||||
- disabled by using the =, +=, -=, and ! operators
|
||||
- respectively. Regardless of whether the env_reset
|
||||
- option is enabled or disabled, variables specified by
|
||||
- env_check will be preserved in the environment if they
|
||||
- pass the aforementioned check. The default list of
|
||||
- environment variables to check is displayed when ssuuddoo
|
||||
- is run by root with the --VV option.
|
||||
+ programs. The TZ variable is considerd unsafe if any
|
||||
+ of the following are true:
|
||||
+
|
||||
+ ++oo It consists of a fully-qualified path name,
|
||||
+ optionally prefixed with a colon (`:'), that does
|
||||
+ not match the location of the _z_o_n_e_i_n_f_o directory.
|
||||
+
|
||||
+ ++oo It contains a _._. path element.
|
||||
+
|
||||
+ ++oo It contains white space or non-printable
|
||||
+ characters.
|
||||
+
|
||||
+ ++oo It is longer than the value of PATH_MAX.
|
||||
+
|
||||
+ The argument may be a double-quoted, space-separated
|
||||
+ list or a single value without double-quotes. The list
|
||||
+ can be replaced, added to, deleted from, or disabled by
|
||||
+ using the =, +=, -=, and ! operators respectively.
|
||||
+ Regardless of whether the env_reset option is enabled
|
||||
+ or disabled, variables specified by env_check will be
|
||||
+ preserved in the environment if they pass the
|
||||
+ aforementioned check. The default list of environment
|
||||
+ variables to check is displayed when ssuuddoo is run by
|
||||
+ root with the --VV option.
|
||||
|
||||
env_delete Environment variables to be removed from the user's
|
||||
environment when the _e_n_v___r_e_s_e_t option is not in effect.
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.man.in.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.man.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.man.in.CVE-2014-9680 2015-07-05 13:44:11.586596402 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.man.in 2015-07-05 13:44:11.611596027 +0200
|
||||
@@ -3002,14 +3002,47 @@ The default value is
|
||||
\fBLists that can be used in a boolean context\fR:
|
||||
.TP 18n
|
||||
env_check
|
||||
-Environment variables to be removed from the user's environment if
|
||||
-the variable's value contains
|
||||
-`%'
|
||||
+ Environment variables to be removed from the user's environment if
|
||||
+unless they are considered
|
||||
+\(lqsafe\(rq.
|
||||
+For all variables except
|
||||
+\fRTZ\fR,
|
||||
+\(lqsafe\(rq
|
||||
+means that the variable's value does not contain any
|
||||
+\(oq%\(cq
|
||||
or
|
||||
-`/'
|
||||
+\(oq/\(cq
|
||||
characters.
|
||||
This can be used to guard against printf-style format vulnerabilities
|
||||
in poorly-written programs.
|
||||
+The
|
||||
+\fRTZ\fR
|
||||
+variable is considerd unsafe if any of the following are true:
|
||||
+.PP
|
||||
+.RS 18n
|
||||
+.PD 0
|
||||
+.TP 4n
|
||||
+\fB\(bu\fR
|
||||
+It consists of a fully-qualified path name,
|
||||
+optionally prefixed with a colon
|
||||
+(\(oq:\&\(cq),
|
||||
+that does not match the location of the
|
||||
+\fIzoneinfo\fR
|
||||
+directory.
|
||||
+.PD
|
||||
+.TP 4n
|
||||
+\fB\(bu\fR
|
||||
+It contains a
|
||||
+\fI..\fR
|
||||
+path element.
|
||||
+.TP 4n
|
||||
+\fB\(bu\fR
|
||||
+It contains white space or non-printable characters.
|
||||
+.TP 4n
|
||||
+\fB\(bu\fR
|
||||
+It is longer than the value of
|
||||
+\fRPATH_MAX\fR.
|
||||
+.PP
|
||||
The argument may be a double-quoted, space-separated list or a
|
||||
single value without double-quotes.
|
||||
The list can be replaced, added to, deleted from, or disabled by using
|
||||
@@ -3031,6 +3064,7 @@ is run by root with
|
||||
the
|
||||
\fB\-V\fR
|
||||
option.
|
||||
+.RE
|
||||
.TP 18n
|
||||
env_delete
|
||||
Environment variables to be removed from the user's environment when the
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.CVE-2014-9680 sudo-1.8.6p7/doc/sudoers.mdoc.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.mdoc.in.CVE-2014-9680 2015-07-05 13:44:11.586596402 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2015-07-05 13:44:11.611596027 +0200
|
||||
@@ -2791,13 +2791,40 @@ The default value is
|
||||
.Bl -tag -width 16n
|
||||
.It env_check
|
||||
Environment variables to be removed from the user's environment if
|
||||
-the variable's value contains
|
||||
+unless they are considered
|
||||
+.Dq safe .
|
||||
+For all variables except
|
||||
+.Li TZ ,
|
||||
+.Dq safe
|
||||
+means that the variable's value does not contain any
|
||||
.Ql %
|
||||
or
|
||||
.Ql /
|
||||
characters.
|
||||
This can be used to guard against printf-style format vulnerabilities
|
||||
in poorly-written programs.
|
||||
+The
|
||||
+.Li TZ
|
||||
+variable is considerd unsafe if any of the following are true:
|
||||
+.Bl -bullet
|
||||
+.It
|
||||
+It consists of a fully-qualified path name,
|
||||
+optionally prefixed with a colon
|
||||
+.Pq Ql :\& ,
|
||||
+that does not match the location of the
|
||||
+.Pa zoneinfo
|
||||
+directory.
|
||||
+.It
|
||||
+It contains a
|
||||
+.Pa ..
|
||||
+path element.
|
||||
+.It
|
||||
+It contains white space or non-printable characters.
|
||||
+.It
|
||||
+It is longer than the value of
|
||||
+.Li PATH_MAX .
|
||||
+.El
|
||||
+.Pp
|
||||
The argument may be a double-quoted, space-separated list or a
|
||||
single value without double-quotes.
|
||||
The list can be replaced, added to, deleted from, or disabled by using
|
||||
diff -up sudo-1.8.6p7/INSTALL.CVE-2014-9680 sudo-1.8.6p7/INSTALL
|
||||
--- sudo-1.8.6p7/INSTALL.CVE-2014-9680 2013-02-25 20:42:43.000000000 +0100
|
||||
+++ sudo-1.8.6p7/INSTALL 2015-07-05 13:44:11.611596027 +0200
|
||||
@@ -461,6 +461,16 @@ The following options are also configura
|
||||
Override the default location of the sudo timestamp directory and
|
||||
use "path" instead.
|
||||
|
||||
+ --with-tzdir=DIR
|
||||
+ Set the directory to the system's time zone data files. This
|
||||
+ is only used when sanitizing the TZ environment variable to
|
||||
+ allow for fully-qualified paths in TZ.
|
||||
+ By default, configure will look for an existing "zoneinfo"
|
||||
+ directory in the following locations:
|
||||
+ /usr/share /usr/share/lib /usr/lib /etc
|
||||
+ If no zoneinfo directory is found, the TZ variable may not
|
||||
+ contain a fully-qualified path.
|
||||
+
|
||||
--with-sendmail=PATH
|
||||
Override configure's guess as to the location of sendmail.
|
||||
|
||||
diff -up sudo-1.8.6p7/pathnames.h.in.CVE-2014-9680 sudo-1.8.6p7/pathnames.h.in
|
||||
--- sudo-1.8.6p7/pathnames.h.in.CVE-2014-9680 2012-09-18 15:56:28.000000000 +0200
|
||||
+++ sudo-1.8.6p7/pathnames.h.in 2015-07-05 13:44:11.612596011 +0200
|
||||
@@ -168,3 +168,7 @@
|
||||
#ifndef _PATH_NETSVC_CONF
|
||||
#undef _PATH_NETSVC_CONF
|
||||
#endif /* _PATH_NETSVC_CONF */
|
||||
+
|
||||
+#ifndef _PATH_ZONEINFO
|
||||
+# undef _PATH_ZONEINFO
|
||||
+#endif /* _PATH_ZONEINFO */
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/env.c.CVE-2014-9680 sudo-1.8.6p7/plugins/sudoers/env.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/env.c.CVE-2014-9680 2013-02-25 20:42:44.000000000 +0100
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/env.c 2015-07-05 13:44:11.612596011 +0200
|
||||
@@ -198,6 +198,7 @@ static const char *initial_checkenv_tabl
|
||||
"LC_*",
|
||||
"LINGUAS",
|
||||
"TERM",
|
||||
+ "TZ",
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -213,7 +214,6 @@ static const char *initial_keepenv_table
|
||||
"PATH",
|
||||
"PS1",
|
||||
"PS2",
|
||||
- "TZ",
|
||||
"XAUTHORITY",
|
||||
"XAUTHORIZATION",
|
||||
NULL
|
||||
@@ -584,6 +584,54 @@ matches_env_delete(const char *var)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * Sanity-check the TZ environment variable.
|
||||
+ * On many systems it is possible to set this to a pathname.
|
||||
+ */
|
||||
+static bool
|
||||
+tz_is_sane(const char *tzval)
|
||||
+{
|
||||
+ const char *cp;
|
||||
+ char lastch;
|
||||
+ debug_decl(tz_is_sane, SUDO_DEBUG_ENV)
|
||||
+
|
||||
+ /* tzcode treats a value beginning with a ':' as a path. */
|
||||
+ if (tzval[0] == ':')
|
||||
+ tzval++;
|
||||
+
|
||||
+ /* Reject fully-qualified TZ that doesn't being with the zoneinfo dir. */
|
||||
+ if (tzval[0] == '/') {
|
||||
+#ifdef _PATH_ZONEINFO
|
||||
+ if (strncmp(tzval, _PATH_ZONEINFO, sizeof(_PATH_ZONEINFO) - 1) != 0 ||
|
||||
+ tzval[sizeof(_PATH_ZONEINFO) - 1] != '/')
|
||||
+ debug_return_bool(false);
|
||||
+#else
|
||||
+ /* Assume the worst. */
|
||||
+ debug_return_bool(false);
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure TZ only contains printable non-space characters
|
||||
+ * and does not contain a '..' path element.
|
||||
+ */
|
||||
+ lastch = '/';
|
||||
+ for (cp = tzval; *cp != '\0'; cp++) {
|
||||
+ if (isspace((unsigned char)*cp) || !isprint((unsigned char)*cp))
|
||||
+ debug_return_bool(false);
|
||||
+ if (lastch == '/' && cp[0] == '.' && cp[1] == '.' &&
|
||||
+ (cp[2] == '/' || cp[2] == '\0'))
|
||||
+ debug_return_bool(false);
|
||||
+ lastch = *cp;
|
||||
+ }
|
||||
+
|
||||
+ /* Reject extra long TZ values (even if not a path). */
|
||||
+ if ((size_t)(cp - tzval) >= PATH_MAX)
|
||||
+ debug_return_bool(false);
|
||||
+
|
||||
+ debug_return_bool(true);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* Apply the env_check list.
|
||||
* Returns true if the variable is allowed, false if denied
|
||||
* or -1 if no match.
|
||||
@@ -607,8 +655,13 @@ matches_env_check(const char *var)
|
||||
iswild = false;
|
||||
if (strncmp(cur->value, var, len) == 0 &&
|
||||
(iswild || var[len] == '=')) {
|
||||
+ if (strncmp(var, "TZ=", 3) == 0 ) {
|
||||
+ /* Sperial case for TZ */
|
||||
+ keepit = tz_is_sane(var + 3);
|
||||
+ } else {
|
||||
keepit = !strpbrk(var, "/%");
|
||||
- break;
|
||||
+ }
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
debug_return_bool(keepit);
|
|
@ -0,0 +1,117 @@
|
|||
diff --git a/src/ttyname.c b/src/ttyname.c
|
||||
index 32f093c..d8858f7 100644
|
||||
--- a/src/ttyname.c
|
||||
+++ b/src/ttyname.c
|
||||
@@ -414,53 +414,80 @@ get_process_ttyname(void)
|
||||
}
|
||||
#elif defined(__linux__)
|
||||
/*
|
||||
- * Return a string from ttyname() containing the tty to which the process is
|
||||
- * attached or NULL if there is no tty associated with the process (or its
|
||||
- * parent). First tries field 7 in /proc/pid/stat, then /proc/ppid/stat.
|
||||
- * Falls back on ttyname of std{in,out,err} if that fails.
|
||||
+ * Store the name of the tty to which the process is attached in name.
|
||||
+ * Returns name on success and NULL on failure, setting errno.
|
||||
*/
|
||||
char *
|
||||
get_process_ttyname(void)
|
||||
{
|
||||
- char *line = NULL, *tty = NULL;
|
||||
- size_t linesize = 0;
|
||||
- ssize_t len;
|
||||
- int i;
|
||||
+ const char path[] = "/proc/self/stat";
|
||||
+ char *cp, buf[1024];
|
||||
+ char *ret = NULL;
|
||||
+ int serrno = errno;
|
||||
+ ssize_t nread;
|
||||
+ int fd;
|
||||
debug_decl(get_process_ttyname, SUDO_DEBUG_UTIL)
|
||||
|
||||
- /* Try to determine the tty from tty_nr in /proc/pid/stat. */
|
||||
- for (i = 0; tty == NULL && i < 2; i++) {
|
||||
- FILE *fp;
|
||||
- char path[PATH_MAX];
|
||||
- (void)snprintf(path, sizeof(path), "/proc/%u/stat",
|
||||
- i ? (unsigned int)getppid() : (unsigned int)getpid());
|
||||
- if ((fp = fopen(path, "r")) == NULL)
|
||||
- continue;
|
||||
- len = getline(&line, &linesize, fp);
|
||||
- fclose(fp);
|
||||
- if (len != -1) {
|
||||
+ /*
|
||||
+ * Try to determine the tty from tty_nr in /proc/self/stat.
|
||||
+ * Ignore /proc/self/stat if it contains embedded NUL bytes.
|
||||
+ */
|
||||
+ if ((fd = open(path, O_RDONLY | O_NOFOLLOW)) != -1) {
|
||||
+ cp = buf;
|
||||
+ while ((nread = read(fd, cp, buf + sizeof(buf) - cp)) != 0) {
|
||||
+ if (nread == -1) {
|
||||
+ if (errno == EAGAIN || errno == EINTR)
|
||||
+ continue;
|
||||
+ break;
|
||||
+ }
|
||||
+ cp += nread;
|
||||
+ if (cp >= buf + sizeof(buf))
|
||||
+ break;
|
||||
+ }
|
||||
+ if (nread == 0 && memchr(buf, '\0', cp - buf) == NULL) {
|
||||
/*
|
||||
* Field 7 is the tty dev (0 if no tty).
|
||||
- * Since the process name at field 2 "(comm)" may include spaces,
|
||||
- * start at the last ')' found.
|
||||
+ * Since the process name at field 2 "(comm)" may include
|
||||
+ * whitespace (including newlines), start at the last ')' found.
|
||||
*/
|
||||
- char *cp = strrchr(line, ')');
|
||||
- int field = 2;
|
||||
- while (*cp != '\0') {
|
||||
- if (*cp++ == ' ') {
|
||||
- if (++field == 7) {
|
||||
- dev_t tdev = (dev_t)atoi(cp);
|
||||
- if (tdev > 0)
|
||||
- tty = sudo_ttyname_dev(tdev);
|
||||
- break;
|
||||
+ *cp = '\0';
|
||||
+ cp = strrchr(buf, ')');
|
||||
+ if (cp != NULL) {
|
||||
+ char *ep = cp;
|
||||
+ int field = 1;
|
||||
+
|
||||
+ while (*++ep != '\0') {
|
||||
+ if (*ep == ' ') {
|
||||
+ *ep = '\0';
|
||||
+ if (++field == 7) {
|
||||
+ dev_t tdev = (dev_t)strtol(cp, NULL, 10);
|
||||
+ if (tdev == 0 || errno == ERANGE || errno == EINVAL) {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
+ "%s: tty device %s: %s", path, cp, strerror(errno));
|
||||
+ }
|
||||
+ if (tdev > 0) {
|
||||
+ errno = serrno;
|
||||
+ ret = sudo_ttyname_dev(tdev);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ cp = ep + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
- efree(line);
|
||||
+ errno = ENOENT;
|
||||
|
||||
- debug_return_str(tty);
|
||||
+done:
|
||||
+ if (fd != -1)
|
||||
+ close(fd);
|
||||
+ if (ret == NULL)
|
||||
+ sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||
+ "unable to resolve tty via %s", path);
|
||||
+
|
||||
+ debug_return_str(ret);
|
||||
}
|
||||
#else
|
||||
/*
|
|
@ -0,0 +1,38 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.authlogicfix sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.authlogicfix 2015-07-05 13:40:15.389145839 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-07-05 13:40:15.413145478 +0200
|
||||
@@ -2392,9 +2392,13 @@ sudo_ldap_lookup(struct sudo_nss *nss, i
|
||||
for (i = 0; i < lres->nentries; i++) {
|
||||
entry = lres->entries[i].entry;
|
||||
if ((pwcheck == any && doauth != false) ||
|
||||
- (pwcheck == all && doauth == false)) {
|
||||
- doauth = sudo_ldap_check_bool(ld, entry, "authenticate");
|
||||
+ (pwcheck == all && doauth != true)) {
|
||||
+ doauth = !!sudo_ldap_check_bool(ld, entry, "authenticate");
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < lres->nentries; i++) {
|
||||
+ entry = lres->entries[i].entry;
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.authlogicfix sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.authlogicfix 2015-07-05 13:40:15.412145494 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2015-07-05 13:40:15.414145463 +0200
|
||||
@@ -970,9 +970,13 @@ sudo_sss_lookup(struct sudo_nss *nss, in
|
||||
for (i = 0; i < sss_result->num_rules; i++) {
|
||||
rule = sss_result->rules + i;
|
||||
if ((pwcheck == any && doauth != false) ||
|
||||
- (pwcheck == all && doauth == false)) {
|
||||
- doauth = sudo_sss_check_bool(handle, rule, "authenticate");
|
||||
+ (pwcheck == all && doauth != true)) {
|
||||
+ doauth = !!sudo_sss_check_bool(handle, rule, "authenticate");
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < sss_result->num_rules; i++) {
|
||||
+ rule = sss_result->rules + i;
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
|
@ -0,0 +1,46 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.clangfixes sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.clangfixes 2014-09-30 10:31:43.920885432 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2014-09-30 10:32:39.413228871 +0200
|
||||
@@ -313,9 +313,9 @@ static int sudo_sss_close(struct sudo_ns
|
||||
if (nss && nss->handle) {
|
||||
handle = nss->handle;
|
||||
dlclose(handle->ssslib);
|
||||
+ efree(nss->handle);
|
||||
}
|
||||
|
||||
- efree(nss->handle);
|
||||
debug_return_int(0);
|
||||
}
|
||||
|
||||
@@ -755,12 +755,15 @@ sudo_sss_result_get(struct sudo_nss *nss
|
||||
*state |= _SUDO_SSS_STATE_HOSTMATCH;
|
||||
}
|
||||
}
|
||||
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
|
||||
+ "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result,
|
||||
+ u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules);
|
||||
+ } else {
|
||||
+ sudo_debug_printf(SUDO_DEBUG_DEBUG,
|
||||
+ "u_sss_result=(%p, %u) => f_sss_result=NULL", u_sss_result,
|
||||
+ u_sss_result->num_rules);
|
||||
}
|
||||
|
||||
- sudo_debug_printf(SUDO_DEBUG_DEBUG,
|
||||
- "u_sss_result=(%p, %u) => f_sss_result=(%p, %u)", u_sss_result,
|
||||
- u_sss_result->num_rules, f_sss_result, f_sss_result->num_rules);
|
||||
-
|
||||
handle->fn_free_result(u_sss_result);
|
||||
|
||||
debug_return_ptr(f_sss_result);
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/visudo.c.clangfixes sudo-1.8.6p7/plugins/sudoers/visudo.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/visudo.c.clangfixes 2014-09-30 10:34:08.689174020 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/visudo.c 2014-09-30 11:00:15.215654285 +0200
|
||||
@@ -544,7 +544,7 @@ reparse_sudoers(char *editor, char *args
|
||||
continue;
|
||||
edit_sudoers(sp, editor, args, errorlineno);
|
||||
}
|
||||
- } while (parse_error);
|
||||
+ } while (parse_error && sp != NULL);
|
||||
|
||||
debug_return;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.c.closefrom-override-fix sudo-1.8.6p7/plugins/sudoers/sudoers.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sudoers.c.closefrom-override-fix 2016-02-15 10:31:11.694164366 +0100
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sudoers.c 2016-02-15 10:33:47.711362062 +0100
|
||||
@@ -336,15 +336,6 @@ sudoers_policy_main(int argc, char * con
|
||||
goto bad;
|
||||
}
|
||||
|
||||
- /* Check for -C overriding def_closefrom. */
|
||||
- if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
|
||||
- if (!def_closefrom_override) {
|
||||
- warningx(_("you are not permitted to use the -C option"));
|
||||
- goto bad;
|
||||
- }
|
||||
- def_closefrom = user_closefrom;
|
||||
- }
|
||||
-
|
||||
set_perms(PERM_INITIAL);
|
||||
|
||||
/* Environment variables specified on the command line. */
|
||||
@@ -374,8 +365,17 @@ sudoers_policy_main(int argc, char * con
|
||||
if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
|
||||
def_preserve_groups = true;
|
||||
|
||||
- /* Find command in path */
|
||||
+ /* Find command in path and apply per-command Defaults. */
|
||||
cmnd_status = set_cmnd();
|
||||
+
|
||||
+ /* Check for -C overriding def_closefrom. */
|
||||
+ if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
|
||||
+ if (!def_closefrom_override) {
|
||||
+ warningx(_("you are not permitted to use the -C option"));
|
||||
+ goto bad;
|
||||
+ }
|
||||
+ def_closefrom = user_closefrom;
|
||||
+ }
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
if (!setlocale(LC_ALL, def_sudoers_locale)) {
|
|
@ -0,0 +1,104 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/match.c.constwarnfix sudo-1.8.6p7/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/match.c.constwarnfix 2014-09-29 15:55:50.996485025 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/match.c 2014-09-29 15:55:51.002484954 +0200
|
||||
@@ -599,7 +599,7 @@ command_matches_dir(char *sudoers_dir, s
|
||||
* Returns true if the hostname matches the pattern, else false
|
||||
*/
|
||||
bool
|
||||
-hostname_matches(char *shost, char *lhost, char *pattern)
|
||||
+hostname_matches(const char *shost, const char *lhost, const char *pattern)
|
||||
{
|
||||
debug_decl(hostname_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
@@ -621,7 +621,7 @@ hostname_matches(char *shost, char *lhos
|
||||
* else returns false.
|
||||
*/
|
||||
bool
|
||||
-userpw_matches(char *sudoers_user, char *user, struct passwd *pw)
|
||||
+userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw)
|
||||
{
|
||||
debug_decl(userpw_matches, SUDO_DEBUG_MATCH)
|
||||
if (pw != NULL && *sudoers_user == '#') {
|
||||
@@ -640,7 +640,7 @@ userpw_matches(char *sudoers_user, char
|
||||
* else returns false.
|
||||
*/
|
||||
bool
|
||||
-group_matches(char *sudoers_group, struct group *gr)
|
||||
+group_matches(const char *sudoers_group, const struct group *gr)
|
||||
{
|
||||
debug_decl(group_matches, SUDO_DEBUG_MATCH)
|
||||
if (*sudoers_group == '#') {
|
||||
@@ -659,7 +659,7 @@ group_matches(char *sudoers_group, struc
|
||||
* else returns false.
|
||||
*/
|
||||
bool
|
||||
-usergr_matches(char *group, char *user, struct passwd *pw)
|
||||
+usergr_matches(const char *group, const char *user, const struct passwd *pw)
|
||||
{
|
||||
int matched = false;
|
||||
struct passwd *pw0 = NULL;
|
||||
@@ -707,7 +707,7 @@ done:
|
||||
* XXX - swap order of host & shost
|
||||
*/
|
||||
bool
|
||||
-netgr_matches(char *netgr, char *lhost, char *shost, char *user)
|
||||
+netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user)
|
||||
{
|
||||
static char *domain;
|
||||
#ifdef HAVE_GETDOMAINNAME
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/parse.h.constwarnfix sudo-1.8.6p7/plugins/sudoers/parse.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/parse.h.constwarnfix 2014-09-29 15:55:50.992485072 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/parse.h 2014-09-29 15:55:51.002484954 +0200
|
||||
@@ -188,11 +188,11 @@ bool addr_matches(char *n);
|
||||
|
||||
/* match.c */
|
||||
bool command_matches(char *sudoers_cmnd, char *sudoers_args);
|
||||
-bool group_matches(char *sudoers_group, struct group *gr);
|
||||
-bool hostname_matches(char *shost, char *lhost, char *pattern);
|
||||
-bool netgr_matches(char *netgr, char *lhost, char *shost, char *user);
|
||||
-bool usergr_matches(char *group, char *user, struct passwd *pw);
|
||||
-bool userpw_matches(char *sudoers_user, char *user, struct passwd *pw);
|
||||
+bool group_matches(const char *sudoers_group, const struct group *gr);
|
||||
+bool hostname_matches(const char *shost, const char *lhost, const char *pattern);
|
||||
+bool netgr_matches(const char *netgr, const char *lhost, const char *shost, const char *user);
|
||||
+bool usergr_matches(const char *group, const char *user, const struct passwd *pw);
|
||||
+bool userpw_matches(const char *sudoers_user, const char *user, const struct passwd *pw);
|
||||
int cmnd_matches(struct member *m);
|
||||
int cmndlist_matches(struct member_list *list);
|
||||
int hostlist_matches(struct member_list *list);
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/pwutil.c.constwarnfix sudo-1.8.6p7/plugins/sudoers/pwutil.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/pwutil.c.constwarnfix 2013-02-25 20:42:44.000000000 +0100
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/pwutil.c 2014-09-29 15:55:51.003484942 +0200
|
||||
@@ -841,7 +841,7 @@ sudo_endgrent(void)
|
||||
}
|
||||
|
||||
struct group_list *
|
||||
-sudo_get_grlist(struct passwd *pw)
|
||||
+sudo_get_grlist(const struct passwd *pw)
|
||||
{
|
||||
struct cache_item key, *item;
|
||||
struct rbnode *node;
|
||||
@@ -905,7 +905,7 @@ done:
|
||||
}
|
||||
|
||||
bool
|
||||
-user_in_group(struct passwd *pw, const char *group)
|
||||
+user_in_group(const struct passwd *pw, const char *group)
|
||||
{
|
||||
struct group_list *grlist;
|
||||
struct group *grp = NULL;
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.constwarnfix sudo-1.8.6p7/plugins/sudoers/sudoers.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sudoers.h.constwarnfix 2013-02-25 20:49:09.000000000 +0100
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2014-09-29 15:55:51.003484942 +0200
|
||||
@@ -288,9 +288,9 @@ __dso_public struct group *sudo_getgrgid
|
||||
__dso_public struct group *sudo_getgrnam(const char *);
|
||||
__dso_public void sudo_gr_addref(struct group *);
|
||||
__dso_public void sudo_gr_delref(struct group *);
|
||||
-bool user_in_group(struct passwd *, const char *);
|
||||
+bool user_in_group(const struct passwd *, const char *);
|
||||
struct group *sudo_fakegrnam(const char *);
|
||||
-struct group_list *sudo_get_grlist(struct passwd *pw);
|
||||
+struct group_list *sudo_get_grlist(const struct passwd *pw);
|
||||
struct passwd *sudo_fakepwnam(const char *, gid_t);
|
||||
struct passwd *sudo_fakepwnamid(const char *user, uid_t uid, gid_t gid);
|
||||
struct passwd *sudo_getpwnam(const char *);
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/Makefile.in.digest-backport-checklinkfix sudo-1.8.6p7/plugins/sudoers/Makefile.in
|
||||
--- sudo-1.8.6p7/plugins/sudoers/Makefile.in.digest-backport-checklinkfix 2015-08-25 14:31:24.889199953 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/Makefile.in 2015-08-25 14:32:34.817198098 +0200
|
||||
@@ -146,7 +146,7 @@ TEST_OBJS = interfaces.o testsudoers.o t
|
||||
|
||||
CHECK_ADDR_OBJS = check_addr.o match_addr.o interfaces.o error.o
|
||||
|
||||
-CHECK_FILL_OBJS = check_fill.o toke_util.o error.o
|
||||
+CHECK_FILL_OBJS = check_fill.o toke_util.o error.o hexchar.o
|
||||
|
||||
CHECK_IOLOG_PATH_OBJS = check_iolog_path.o error.o iolog_path.o pwutil.o \
|
||||
redblack.o
|
|
@ -0,0 +1,260 @@
|
|||
diff -up sudo-1.8.6p7/doc/sudoers.cat.digest-backport-docs sudo-1.8.6p7/doc/sudoers.cat
|
||||
--- sudo-1.8.6p7/doc/sudoers.cat.digest-backport-docs 2015-07-07 13:06:11.078653045 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.cat 2015-07-07 13:12:05.170955417 +0200
|
||||
@@ -260,6 +260,14 @@ SSUUDDOOEERRSS FFIILLEE FFO
|
||||
``localhost'' will only match if that is the actual host name, which is
|
||||
usually only the case for non-networked systems.
|
||||
|
||||
+ digest ::= [A-Fa-f0-9]+ |
|
||||
+ [[A-Za-z0-9+/=]+
|
||||
+
|
||||
+ Digest_Spec ::= "sha224" ':' digest |
|
||||
+ "sha256" ':' digest |
|
||||
+ "sha384" ':' digest |
|
||||
+ "sha512" ':' digest
|
||||
+
|
||||
Cmnd_List ::= Cmnd |
|
||||
Cmnd ',' Cmnd_List
|
||||
|
||||
@@ -267,7 +275,7 @@ SSUUDDOOEERRSS FFIILLEE FFO
|
||||
file name args |
|
||||
file name '""'
|
||||
|
||||
- Cmnd ::= '!'* command name |
|
||||
+ Cmnd ::= Digest_Spec? '!'* command name |
|
||||
'!'* directory |
|
||||
'!'* "sudoedit" |
|
||||
'!'* Cmnd_Alias
|
||||
@@ -291,6 +299,26 @@ SSUUDDOOEERRSS FFIILLEE FFO
|
||||
to permit a user to run ssuuddoo with the --ee option (or as ssuuddooeeddiitt). It may
|
||||
take command line arguments just as a normal command does.
|
||||
|
||||
+ If a command name is prefixed with a Digest_Spec, the command will only
|
||||
+ match successfully if it can be verified using the specified SHA-2
|
||||
+ digest. This may be useful in situations where the user invoking ssuuddoo
|
||||
+ has write access to the command or its parent directory. The following
|
||||
+ digest formats are supported: sha224, sha256, sha384 and sha512. The
|
||||
+ string may be specified in either hex or base64 format (base64 is more
|
||||
+ compact). There are several utilities capable of generating SHA-2
|
||||
+ digests in hex format such as openssl, shasum, sha224sum, sha256sum,
|
||||
+ sha384sum, sha512sum.
|
||||
+
|
||||
+ For example, using openssl:
|
||||
+
|
||||
+ $ openssl dgst -sha224 /bin/ls
|
||||
+ SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25
|
||||
+
|
||||
+ It is also possible to use openssl to generate base64 output:
|
||||
+
|
||||
+ $ openssl dgst -binary -sha224 /bin/ls | openssl base64
|
||||
+ EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
|
||||
+
|
||||
DDeeffaauullttss
|
||||
Certain configuration options may be changed from their default values at
|
||||
run-time via one or more Default_Entry lines. These may affect all users
|
||||
@@ -1797,7 +1825,9 @@ EEXXAAMMPPLLEESS
|
||||
|
||||
# Cmnd alias specification
|
||||
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
|
||||
- /usr/sbin/restore, /usr/sbin/rrestore
|
||||
+ /usr/sbin/restore, /usr/sbin/rrestore\
|
||||
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \
|
||||
+ /home/operator/bin/start_backups
|
||||
Cmnd_Alias KILL = /usr/bin/kill
|
||||
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
|
||||
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
|
||||
@@ -1867,7 +1897,11 @@ EEXXAAMMPPLLEESS
|
||||
The ooppeerraattoorr user may run commands limited to simple maintenance. Here,
|
||||
those are commands related to backups, killing processes, the printing
|
||||
system, shutting down the system, and any commands in the directory
|
||||
- _/_u_s_r_/_o_p_e_r_/_b_i_n_/.
|
||||
+ _/_u_s_r_/_o_p_e_r_/_b_i_n_/. Note that one command in the DUMPS Cmnd_Alias includes a
|
||||
+ sha224 digest, _/_h_o_m_e_/_o_p_e_r_a_t_o_r_/_b_i_n_/_s_t_a_r_t___b_a_c_k_u_p_s. This is because the
|
||||
+ directory containing the script is writable by the operator user. If the
|
||||
+ script is modified (resulting in a digest mismatch) it will no longer be
|
||||
+ possible to run it via ssuuddoo.
|
||||
|
||||
joe ALL = /usr/bin/su operator
|
||||
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.man.in.digest-backport-docs sudo-1.8.6p7/doc/sudoers.man.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.man.in.digest-backport-docs 2015-07-07 13:06:28.363472547 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.man.in 2015-07-07 13:16:05.250448374 +0200
|
||||
@@ -602,6 +602,14 @@ only the case for non-networked systems.
|
||||
.nf
|
||||
.sp
|
||||
.RS 0n
|
||||
+digest ::= [A-Fa-f0-9]+ |
|
||||
+ [[A-Za-z0-9\+/=]+
|
||||
+
|
||||
+Digest_Spec ::= "sha224" ':' digest |
|
||||
+ "sha256" ':' digest |
|
||||
+ "sha384" ':' digest |
|
||||
+ "sha512" ':' digest
|
||||
+
|
||||
Cmnd_List ::= Cmnd |
|
||||
Cmnd ',' Cmnd_List
|
||||
|
||||
@@ -609,7 +617,7 @@ command name ::= file name |
|
||||
file name args |
|
||||
file name '""'
|
||||
|
||||
-Cmnd ::= '!'* command name |
|
||||
+Cmnd ::= Digest_Spec? '!'* command name |
|
||||
'!'* directory |
|
||||
'!'* "sudoedit" |
|
||||
'!'* Cmnd_Alias
|
||||
@@ -664,6 +672,39 @@ with the
|
||||
option (or as
|
||||
\fBsudoedit\fR).
|
||||
It may take command line arguments just as a normal command does.
|
||||
+.PP
|
||||
+If a
|
||||
+\fRcommand name\fR
|
||||
+is prefixed with a
|
||||
+\fRDigest_Spec\fR,
|
||||
+the command will only match successfully if it can be verified
|
||||
+using the specified SHA-2 digest.
|
||||
+This may be useful in situations where the user invoking
|
||||
+\fBsudo\fR
|
||||
+has write access to the command or its parent directory.
|
||||
+The following digest formats are supported: sha224, sha256, sha384 and sha512.
|
||||
+The string may be specified in either hex or base64 format
|
||||
+(base64 is more compact).
|
||||
+There are several utilities capable of generating SHA-2 digests in hex
|
||||
+format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.
|
||||
+.PP
|
||||
+For example, using openssl:
|
||||
+.nf
|
||||
+.sp
|
||||
+.RS 0n
|
||||
+$ openssl dgst -sha224 /bin/ls
|
||||
+SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25
|
||||
+.RE
|
||||
+.fi
|
||||
+.PP
|
||||
+It is also possible to use openssl to generate base64 output:
|
||||
+.nf
|
||||
+.sp
|
||||
+.RS 0n
|
||||
+$ openssl dgst -binary -sha224 /bin/ls | openssl base64
|
||||
+EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
|
||||
+.RE
|
||||
+.fi
|
||||
.SS "Defaults"
|
||||
Certain configuration options may be changed from their default
|
||||
values at run-time via one or more
|
||||
@@ -3684,7 +3725,9 @@ Host_Alias CDROM = orion, perseus, hercu
|
||||
|
||||
# Cmnd alias specification
|
||||
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e
|
||||
- /usr/sbin/restore, /usr/sbin/rrestore
|
||||
+ /usr/sbin/restore, /usr/sbin/rrestore\e
|
||||
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e
|
||||
+ /home/operator/bin/start_backups
|
||||
Cmnd_Alias KILL = /usr/bin/kill
|
||||
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
|
||||
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
|
||||
@@ -3836,6 +3879,15 @@ Here, those are commands related to back
|
||||
printing system, shutting down the system, and any commands in the
|
||||
directory
|
||||
\fI/usr/oper/bin/\fR.
|
||||
+Note that one command in the
|
||||
+\fRDUMPS\fR
|
||||
+Cmnd_Alias includes a sha224 digest,
|
||||
+\fI/home/operator/bin/start_backups\fR.
|
||||
+This is because the directory containing the script is writable by the
|
||||
+operator user.
|
||||
+If the script is modified (resulting in a digest mismatch) it will no longer
|
||||
+be possible to run it via
|
||||
+\fBsudo\fR.
|
||||
.nf
|
||||
.sp
|
||||
.RS 0n
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.digest-backport-docs sudo-1.8.6p7/doc/sudoers.mdoc.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.mdoc.in.digest-backport-docs 2015-07-07 13:06:18.919571166 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2015-07-07 13:23:45.072854748 +0200
|
||||
@@ -579,6 +579,14 @@ Also, the host name
|
||||
will only match if that is the actual host name, which is usually
|
||||
only the case for non-networked systems.
|
||||
.Bd -literal
|
||||
+digest ::= [A-Fa-f0-9]+ |
|
||||
+ [[A-Za-z0-9\+/=]+
|
||||
+
|
||||
+Digest_Spec ::= "sha224" ':' digest |
|
||||
+ "sha256" ':' digest |
|
||||
+ "sha384" ':' digest |
|
||||
+ "sha512" ':' digest
|
||||
+
|
||||
Cmnd_List ::= Cmnd |
|
||||
Cmnd ',' Cmnd_List
|
||||
|
||||
@@ -586,7 +594,7 @@ command name ::= file name |
|
||||
file name args |
|
||||
file name '""'
|
||||
|
||||
-Cmnd ::= '!'* command name |
|
||||
+Cmnd ::= Digest_Spec? '!'* command name |
|
||||
'!'* directory |
|
||||
'!'* "sudoedit" |
|
||||
'!'* Cmnd_Alias
|
||||
@@ -640,6 +648,33 @@ with the
|
||||
option (or as
|
||||
.Nm sudoedit ) .
|
||||
It may take command line arguments just as a normal command does.
|
||||
+.Pp
|
||||
+If a
|
||||
+.Li command name
|
||||
+is prefixed with a
|
||||
+.Li Digest_Spec ,
|
||||
+the command will only match successfully if it can be verified
|
||||
+using the specified SHA-2 digest.
|
||||
+This may be useful in situations where the user invoking
|
||||
+.Nm sudo
|
||||
+has write access to the command or its parent directory.
|
||||
+The following digest formats are supported: sha224, sha256, sha384 and sha512.
|
||||
+The string may be specified in either hex or base64 format
|
||||
+(base64 is more compact).
|
||||
+There are several utilities capable of generating SHA-2 digests in hex
|
||||
+format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.
|
||||
+.Pp
|
||||
+For example, using openssl:
|
||||
+.Bd -literal
|
||||
+$ openssl dgst -sha224 /bin/ls
|
||||
+SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25
|
||||
+.Ed
|
||||
+.Pp
|
||||
+It is also possible to use openssl to generate base64 output:
|
||||
+.Bd -literal
|
||||
+$ openssl dgst -binary -sha224 /bin/ls | openssl base64
|
||||
+EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
|
||||
+.Ed
|
||||
.Ss Defaults
|
||||
Certain configuration options may be changed from their default
|
||||
values at run-time via one or more
|
||||
@@ -3407,7 +3442,9 @@ Host_Alias CDROM = orion, perseus, hercu
|
||||
|
||||
# Cmnd alias specification
|
||||
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\e
|
||||
- /usr/sbin/restore, /usr/sbin/rrestore
|
||||
+ /usr/sbin/restore, /usr/sbin/rrestore\e
|
||||
+ sha224:0GomF8mNN3wlDt1HD9XldjJ3SNgpFdbjO1+NsQ== \e
|
||||
+ /home/operator/bin/start_backups
|
||||
Cmnd_Alias KILL = /usr/bin/kill
|
||||
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
|
||||
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
|
||||
@@ -3540,6 +3577,15 @@ Here, those are commands related to back
|
||||
printing system, shutting down the system, and any commands in the
|
||||
directory
|
||||
.Pa /usr/oper/bin/ .
|
||||
+Note that one command in the
|
||||
+.Li DUMPS
|
||||
+Cmnd_Alias includes a sha224 digest,
|
||||
+.Pa /home/operator/bin/start_backups .
|
||||
+This is because the directory containing the script is writable by the
|
||||
+operator user.
|
||||
+If the script is modified (resulting in a digest mismatch) it will no longer
|
||||
+be possible to run it via
|
||||
+.Nm sudo .
|
||||
.Bd -literal
|
||||
joe ALL = /usr/bin/su operator
|
||||
.Ed
|
|
@ -0,0 +1,435 @@
|
|||
From c8a6eecf768d8102a9a77f5fdb5b516e571d462e Mon Sep 17 00:00:00 2001
|
||||
From: Radovan Sroka <rsroka@redhat.com>
|
||||
Date: Tue, 23 Aug 2016 13:43:08 +0200
|
||||
Subject: [PATCH] Using libgcrypt
|
||||
|
||||
Using libgcrypt and not sudo implementation of SHA...
|
||||
|
||||
Rebased patch of digest backport.
|
||||
Added option --with-gcrypt
|
||||
|
||||
Rebased from:
|
||||
Patch35: sudo-1.8.6p7-digest-backport.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#1183818
|
||||
---
|
||||
configure.ac | 16 +++++++
|
||||
plugins/sudoers/Makefile.in | 9 +++-
|
||||
plugins/sudoers/filedigest.c | 104 +++++++++++++++++++++++++++++++++++++++++++
|
||||
plugins/sudoers/filedigest.h | 17 +++++++
|
||||
plugins/sudoers/match.c | 94 ++++++++++++++++++++++++++++++--------
|
||||
5 files changed, 219 insertions(+), 21 deletions(-)
|
||||
create mode 100644 plugins/sudoers/filedigest.c
|
||||
create mode 100644 plugins/sudoers/filedigest.h
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 13c3c1b..54929b2 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -35,6 +35,7 @@ AC_SUBST([SUDO_OBJS])
|
||||
AC_SUBST([LIBS])
|
||||
AC_SUBST([SUDO_LIBS])
|
||||
AC_SUBST([SUDOERS_LIBS])
|
||||
+AC_SUBST([LIBPARSESUDOERS_LIBS])
|
||||
AC_SUBST([STATIC_SUDOERS])
|
||||
AC_SUBST([NET_LIBS])
|
||||
AC_SUBST([AFS_LIBS])
|
||||
@@ -1517,6 +1518,19 @@ AC_ARG_WITH(selinux, [AS_HELP_STRING([--with-selinux], [enable SELinux support])
|
||||
;;
|
||||
esac], [with_selinux=no])
|
||||
|
||||
+AC_ARG_WITH(gcrypt, [AS_HELP_STRING([--with-gcrypt], [enable libgcrypt support])],
|
||||
+[case $with_gcrypt in
|
||||
+ yes)
|
||||
+ AC_DEFINE(HAVE_LIBGCRYPT)
|
||||
+ LIBPARSESUDOERS_LIBS="${LIBPARSESUDOERS_LIBS} -lgcrypt"
|
||||
+ AC_CHECK_LIB([gcrypt], [gcry_md_open],
|
||||
+ [AC_DEFINE(HAVE_GCRY_MD_OPEN)])
|
||||
+ ;;
|
||||
+ no) ;;
|
||||
+ *) AC_MSG_ERROR(["--with-gcrypt does not take an argument."])
|
||||
+ ;;
|
||||
+esac])
|
||||
+
|
||||
dnl
|
||||
dnl gss_krb5_ccache_name() may not work on Heimdal so we don't use it by default
|
||||
dnl
|
||||
@@ -4344,6 +4358,8 @@ AH_TEMPLATE(HAVE_PROJECT_H, [Define to 1 if you have the <project.h> header file
|
||||
AH_TEMPLATE(HAVE_SECURID, [Define to 1 if you use SecurID for authentication.])
|
||||
AH_TEMPLATE(HAVE_SELINUX, [Define to 1 to enable SELinux RBAC support.])
|
||||
AH_TEMPLATE(HAVE_SETKEYCREATECON, [Define to 1 if you have the `setkeycreatecon' function.])
|
||||
+AH_TEMPLATE(HAVE_LIBGCRYPT, [Define to 1 to enable libgcrypt support.])
|
||||
+AH_TEMPLATE(HAVE_GCRY_MD_OPEN, [Define to 1 if you have the `gcry_md_open' function.])
|
||||
AH_TEMPLATE(HAVE_SHL_LOAD, [Define to 1 if you have the `shl_load' function.])
|
||||
AH_TEMPLATE(HAVE_SKEY, [Define to 1 if you use S/Key.])
|
||||
AH_TEMPLATE(HAVE_SKEYACCESS, [Define to 1 if your S/Key library has skeyaccess().])
|
||||
diff --git a/plugins/sudoers/Makefile.in b/plugins/sudoers/Makefile.in
|
||||
index f36f9ef..32c0ed0 100644
|
||||
--- a/plugins/sudoers/Makefile.in
|
||||
+++ b/plugins/sudoers/Makefile.in
|
||||
@@ -55,6 +55,7 @@ LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la
|
||||
LIBS = $(LT_LIBS)
|
||||
NET_LIBS = @NET_LIBS@
|
||||
SUDOERS_LIBS = @SUDOERS_LIBS@ @AFS_LIBS@ @GETGROUPS_LIB@ $(LIBS) $(NET_LIBS) @ZLIB@ @LIBMD@
|
||||
+LIBPARSESUDOERS_LIBS = @LIBPARSESUDOERS_LIBS@
|
||||
REPLAY_LIBS = @REPLAY_LIBS@ @ZLIB@
|
||||
VISUDO_LIBS = $(NET_LIBS) @LIBMD@
|
||||
TESTSUDOERS_LIBS = $(NET_LIBS) @LIBMD@
|
||||
@@ -153,7 +154,7 @@ AUTH_OBJS = sudo_auth.lo @AUTH_OBJS@
|
||||
LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo hexchar.lo \
|
||||
gram.lo match.lo match_addr.lo pwutil.lo pwutil_impl.lo \
|
||||
rcstr.lo redblack.lo sudoers_debug.lo timestr.lo \
|
||||
- toke.lo toke_util.lo
|
||||
+ toke.lo toke_util.lo filedigest.lo
|
||||
|
||||
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo editor.lo env.lo find_path.lo \
|
||||
gc.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
|
||||
@@ -217,7 +218,7 @@ Makefile: $(srcdir)/Makefile.in
|
||||
(cd $(top_builddir) && ./config.status --file plugins/sudoers/Makefile)
|
||||
|
||||
libparsesudoers.la: $(LIBPARSESUDOERS_OBJS)
|
||||
- $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) -no-install
|
||||
+ $(LIBTOOL) --mode=link $(CC) -o $@ $(LIBPARSESUDOERS_OBJS) $(LIBPARSESUDOERS_LIBS) -no-install
|
||||
|
||||
sudoers.la: $(SUDOERS_OBJS) $(LT_LIBS) libparsesudoers.la @LT_LDDEP@
|
||||
case "$(LT_LDFLAGS)" in \
|
||||
@@ -656,6 +657,10 @@ env.lo: $(srcdir)/env.c $(devdir)/def_data.h $(incdir)/compat/stdbool.h \
|
||||
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h $(top_builddir)/config.h \
|
||||
$(top_builddir)/pathnames.h
|
||||
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/env.c
|
||||
+filedigest.lo: $(srcdir)/filedigest.c $(top_builddir)/config.h \
|
||||
+ $(incdir)/sudo_debug.h
|
||||
+ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/filedigest.c
|
||||
+filedigest.o: filedigest.lo
|
||||
find_path.lo: $(srcdir)/find_path.c $(devdir)/def_data.h \
|
||||
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
|
||||
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
|
||||
diff --git a/plugins/sudoers/filedigest.c b/plugins/sudoers/filedigest.c
|
||||
new file mode 100644
|
||||
index 0000000..c173741
|
||||
--- /dev/null
|
||||
+++ b/plugins/sudoers/filedigest.c
|
||||
@@ -0,0 +1,104 @@
|
||||
+#include <config.h>
|
||||
+#include <errno.h>
|
||||
+#include <stddef.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <unistd.h>
|
||||
+#include "filedigest.h"
|
||||
+#include "sudo_compat.h"
|
||||
+#include "sudo_debug.h"
|
||||
+
|
||||
+#if defined(HAVE_LIBGCRYPT)
|
||||
+#include <gcrypt.h>
|
||||
+
|
||||
+static int sudo_filedigest_gcrypt(int fd, int algo, unsigned char **dvalue, size_t *dvalue_size)
|
||||
+{
|
||||
+ char buffer[4096];
|
||||
+ gcry_md_hd_t ctx;
|
||||
+ int gcry_algo;
|
||||
+ debug_decl(sudo_filedigest_gcrypt, SUDO_DEBUG_UTIL);
|
||||
+
|
||||
+ switch(algo) {
|
||||
+ case SUDO_DIGEST_SHA224:
|
||||
+ gcry_algo = GCRY_MD_SHA224; break;
|
||||
+ case SUDO_DIGEST_SHA256:
|
||||
+ gcry_algo = GCRY_MD_SHA256; break;
|
||||
+ case SUDO_DIGEST_SHA384:
|
||||
+ gcry_algo = GCRY_MD_SHA384; break;
|
||||
+ case SUDO_DIGEST_SHA512:
|
||||
+ gcry_algo = GCRY_MD_SHA512; break;
|
||||
+ default:
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
+
|
||||
+ gcry_md_open(&ctx, gcry_algo, 0);
|
||||
+
|
||||
+ /* Read block of data from fd and digest them */
|
||||
+ while (1) {
|
||||
+ const ssize_t read_bytes = read(fd, buffer, sizeof buffer);
|
||||
+
|
||||
+ if (read_bytes < 0) {
|
||||
+ /* Error */
|
||||
+ gcry_md_close(ctx);
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
+ else if (read_bytes > 0) {
|
||||
+ /* Some data read -- update the digest */
|
||||
+ gcry_md_write(ctx, buffer, (size_t)read_bytes);
|
||||
+ }
|
||||
+ else {
|
||||
+ /* EOF */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * All data digested. Finalize the digest value.
|
||||
+ */
|
||||
+ const unsigned char *value = gcry_md_read(ctx, gcry_algo);
|
||||
+
|
||||
+ if (value == NULL) {
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Make a copy of the digest value. The pointer
|
||||
+ * returned from gcry_md_read cannot be used after
|
||||
+ * gcry_md_close was called
|
||||
+ */
|
||||
+ (*dvalue_size) = gcry_md_get_algo_dlen(gcry_algo);
|
||||
+ (*dvalue) = malloc(*dvalue_size);
|
||||
+
|
||||
+ if (*dvalue == NULL) {
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
+
|
||||
+ memcpy(*dvalue, value, *dvalue_size);
|
||||
+ gcry_md_close(ctx);
|
||||
+
|
||||
+ debug_return_int(0);
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+int sudo_filedigest(const char *path, int algo, unsigned char **dvalue, size_t *dvalue_size)
|
||||
+{
|
||||
+ int rc = -1;
|
||||
+ int fd = -1;
|
||||
+ debug_decl(sudo_filedigest, SUDO_DEBUG_UTIL);
|
||||
+
|
||||
+ if ((fd = open(path, O_RDONLY)) < 0) {
|
||||
+ debug_return_int(rc);
|
||||
+ }
|
||||
+
|
||||
+#if defined(HAVE_LIBGCRYPT)
|
||||
+ rc = sudo_filedigest_gcrypt(fd, algo, dvalue, dvalue_size);
|
||||
+ close(fd);
|
||||
+#else
|
||||
+ rc = -1;
|
||||
+ errno = ENOTSUP;
|
||||
+#endif
|
||||
+ debug_return_int(rc);
|
||||
+}
|
||||
diff --git a/plugins/sudoers/filedigest.h b/plugins/sudoers/filedigest.h
|
||||
new file mode 100644
|
||||
index 0000000..437f02f
|
||||
--- /dev/null
|
||||
+++ b/plugins/sudoers/filedigest.h
|
||||
@@ -0,0 +1,17 @@
|
||||
+#include <stddef.h>
|
||||
+
|
||||
+#define SUDO_DIGEST_SHA224 0
|
||||
+#define SUDO_DIGEST_SHA256 1
|
||||
+#define SUDO_DIGEST_SHA384 2
|
||||
+#define SUDO_DIGEST_SHA512 3
|
||||
+#define SUDO_DIGEST_INVALID 4
|
||||
+
|
||||
+#define SUDO_SHA224_DIGEST_LENGTH 28
|
||||
+#define SUDO_SHA256_DIGEST_LENGTH 32
|
||||
+#define SUDO_SHA384_DIGEST_LENGTH 48
|
||||
+#define SUDO_SHA512_DIGEST_LENGTH 64
|
||||
+
|
||||
+/*
|
||||
+ * Compute a digest of a given file. Returns 0 on success, -1 otherwise.
|
||||
+ */
|
||||
+int sudo_filedigest(const char *path, int algo, unsigned char **dvalue, size_t *dvalue_size);
|
||||
diff --git a/plugins/sudoers/match.c b/plugins/sudoers/match.c
|
||||
index 1916bde..2a9ea4b 100644
|
||||
--- a/plugins/sudoers/match.c
|
||||
+++ b/plugins/sudoers/match.c
|
||||
@@ -62,6 +62,7 @@
|
||||
|
||||
#include "sudoers.h"
|
||||
#include "parse.h"
|
||||
+#include "filedigest.h"
|
||||
#include <gram.h>
|
||||
|
||||
#ifdef HAVE_FNMATCH
|
||||
@@ -576,6 +577,7 @@ command_matches_normal(const char *sudoers_cmnd, const char *sudoers_args, const
|
||||
}
|
||||
#else /* !SUDOERS_NAME_MATCH */
|
||||
|
||||
+#ifndef HAVE_LIBGCRYPT /* !!! */
|
||||
static struct digest_function {
|
||||
const char *digest_name;
|
||||
const unsigned int digest_len;
|
||||
@@ -616,24 +618,43 @@ static struct digest_function {
|
||||
NULL
|
||||
}
|
||||
};
|
||||
+#endif /* !HAVE_LIBGCRYPT */
|
||||
+
|
||||
+static const char *digesttype2str(int digest_type)
|
||||
+{
|
||||
+ switch(digest_type) {
|
||||
+ case SUDO_DIGEST_SHA224:
|
||||
+ return "SHA224";
|
||||
+ case SUDO_DIGEST_SHA256:
|
||||
+ return "SHA256";
|
||||
+ case SUDO_DIGEST_SHA384:
|
||||
+ return "SHA384";
|
||||
+ case SUDO_DIGEST_SHA512:
|
||||
+ return "SHA512";
|
||||
+ }
|
||||
+ return "<INVALID>";
|
||||
+}
|
||||
|
||||
static bool
|
||||
digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
{
|
||||
- unsigned char file_digest[SHA512_DIGEST_LENGTH];
|
||||
- unsigned char sudoers_digest[SHA512_DIGEST_LENGTH];
|
||||
+ unsigned char * file_digest = NULL;
|
||||
+ unsigned char * sudoers_digest = NULL;
|
||||
+ size_t digest_size;
|
||||
unsigned char buf[32 * 1024];
|
||||
- struct digest_function *func = NULL;
|
||||
#ifdef HAVE_FEXECVE
|
||||
bool first = true;
|
||||
bool is_script = false;
|
||||
#endif /* HAVE_FEXECVE */
|
||||
size_t nread;
|
||||
- SHA2_CTX ctx;
|
||||
FILE *fp;
|
||||
unsigned int i;
|
||||
debug_decl(digest_matches, SUDOERS_DEBUG_MATCH)
|
||||
|
||||
+#ifndef HAVE_LIBGCRYPT /* !!! */
|
||||
+
|
||||
+ SHA2_CTX ctx;
|
||||
+ struct digest_function *func = NULL;
|
||||
for (i = 0; digest_functions[i].digest_name != NULL; i++) {
|
||||
if (sd->digest_type == i) {
|
||||
func = &digest_functions[i];
|
||||
@@ -644,9 +665,33 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
sudo_warnx(U_("unsupported digest type %d for %s"), sd->digest_type, file);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
- if (strlen(sd->digest_str) == func->digest_len * 2) {
|
||||
+
|
||||
+ digest_size = func->digest_len;
|
||||
+
|
||||
+ file_digest = malloc(digest_size);
|
||||
+ if (file_digest == NULL) {
|
||||
+ debug_return_bool(false);
|
||||
+ }
|
||||
+
|
||||
+#elif HAVE_LIBGCRYPT
|
||||
+
|
||||
+ if (sudo_filedigest(file, sd->digest_type,
|
||||
+ &file_digest, &digest_size) != 0) {
|
||||
+ sudo_warnx(U_("Cannot compute digest type %d for %s"), sd->digest_type, file);
|
||||
+ goto clean_up;
|
||||
+ }
|
||||
+
|
||||
+#endif /* !HAVE_LIBGCRYPT */
|
||||
+
|
||||
+ sudoers_digest = malloc(digest_size);
|
||||
+ if (sudoers_digest == NULL) {
|
||||
+ free(file_digest);
|
||||
+ debug_return_bool(false);
|
||||
+ }
|
||||
+
|
||||
+ if (strlen(sd->digest_str) == digest_size * 2) {
|
||||
/* Convert the command digest from ascii hex to binary. */
|
||||
- for (i = 0; i < func->digest_len; i++) {
|
||||
+ for (i = 0; i < digest_size ; i++) {
|
||||
const int h = hexchar(&sd->digest_str[i + i]);
|
||||
if (h == -1)
|
||||
goto bad_format;
|
||||
@@ -654,11 +699,11 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
}
|
||||
} else {
|
||||
size_t len = base64_decode(sd->digest_str, sudoers_digest,
|
||||
- sizeof(sudoers_digest));
|
||||
- if (len != func->digest_len) {
|
||||
+ digest_size);
|
||||
+ if (len != digest_size) {
|
||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||
- "incorrect length for digest, expected %u, got %zu",
|
||||
- func->digest_len, len);
|
||||
+ "incorrect length for digest, expected %zu, got %zu",
|
||||
+ digest_size, len);
|
||||
goto bad_format;
|
||||
}
|
||||
}
|
||||
@@ -666,10 +711,11 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
if ((fp = fopen(file, "r")) == NULL) {
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "unable to open %s: %s",
|
||||
file, strerror(errno));
|
||||
- debug_return_bool(false);
|
||||
+ goto clean_up;
|
||||
}
|
||||
-
|
||||
+#ifndef HAVE_LIBGCRYPT
|
||||
func->init(&ctx);
|
||||
+#endif /* !HAVE_LIBGCRYPT */
|
||||
while ((nread = fread(buf, 1, sizeof(buf), fp)) != 0) {
|
||||
#ifdef HAVE_FEXECVE
|
||||
/* Check for #! cookie and set is_script. */
|
||||
@@ -679,21 +725,24 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
is_script = true;
|
||||
}
|
||||
#endif /* HAVE_FEXECVE */
|
||||
+#ifndef HAVE_LIBGCRYPT
|
||||
func->update(&ctx, buf, nread);
|
||||
+#endif /* !HAVE_LIBGCRYPT */
|
||||
}
|
||||
if (ferror(fp)) {
|
||||
sudo_warnx(U_("%s: read error"), file);
|
||||
fclose(fp);
|
||||
- debug_return_bool(false);
|
||||
+ goto clean_up;
|
||||
}
|
||||
+#ifndef HAVE_LIBGCRYPT
|
||||
func->final(file_digest, &ctx);
|
||||
-
|
||||
- if (memcmp(file_digest, sudoers_digest, func->digest_len) != 0) {
|
||||
+#endif /* !HAVE_LIBGCRYPT */
|
||||
+ if (memcmp(file_digest, sudoers_digest, digest_size) != 0) {
|
||||
fclose(fp);
|
||||
sudo_debug_printf(SUDO_DEBUG_DIAG|SUDO_DEBUG_LINENO,
|
||||
"%s digest mismatch for %s, expecting %s",
|
||||
- func->digest_name, file, sd->digest_str);
|
||||
- debug_return_bool(false);
|
||||
+ digesttype2str(sd->digest_type), file, sd->digest_str);
|
||||
+ goto clean_up;
|
||||
}
|
||||
|
||||
#ifdef HAVE_FEXECVE
|
||||
@@ -705,7 +754,7 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
sudo_debug_printf(SUDO_DEBUG_INFO, "unable to dup %s: %s",
|
||||
file, strerror(errno));
|
||||
fclose(fp);
|
||||
- debug_return_bool(false);
|
||||
+ goto clean_up;
|
||||
}
|
||||
/*
|
||||
* Shell scripts go through namei twice and so we can't set the close
|
||||
@@ -715,10 +764,17 @@ digest_matches(const char *file, const struct sudo_digest *sd, int *fd)
|
||||
(void)fcntl(*fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif /* HAVE_FEXECVE */
|
||||
fclose(fp);
|
||||
+ free(file_digest);
|
||||
+ free(sudoers_digest);
|
||||
debug_return_bool(true);
|
||||
bad_format:
|
||||
sudo_warnx(U_("digest for %s (%s) is not in %s form"), file,
|
||||
- sd->digest_str, func->digest_name);
|
||||
+ sd->digest_str, digesttype2str(sd->digest_type));
|
||||
+clean_up:
|
||||
+ if (file_digest)
|
||||
+ free(file_digest);
|
||||
+ if (sudoers_digest)
|
||||
+ free(sudoers_digest);
|
||||
debug_return_bool(false);
|
||||
}
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
diff -up sudo-1.8.6p7/doc/sudoers.cat.digest_race_doc sudo-1.8.6p7/doc/sudoers.cat
|
||||
--- sudo-1.8.6p7/doc/sudoers.cat.digest_race_doc 2016-05-11 13:53:51.125141217 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.cat 2016-05-11 13:56:10.678178899 +0200
|
||||
@@ -301,13 +301,11 @@ SSUUDDOOEERRSS FFIILLEE FFO
|
||||
|
||||
If a command name is prefixed with a Digest_Spec, the command will only
|
||||
match successfully if it can be verified using the specified SHA-2
|
||||
- digest. This may be useful in situations where the user invoking ssuuddoo
|
||||
- has write access to the command or its parent directory. The following
|
||||
- digest formats are supported: sha224, sha256, sha384 and sha512. The
|
||||
- string may be specified in either hex or base64 format (base64 is more
|
||||
- compact). There are several utilities capable of generating SHA-2
|
||||
- digests in hex format such as openssl, shasum, sha224sum, sha256sum,
|
||||
- sha384sum, sha512sum.
|
||||
+ digest. The following digest formats are supported: sha224, sha256,
|
||||
+ sha384 and sha512. The string may be specified in either hex or base64
|
||||
+ format (base64 is more compact). There are several utilities capable of
|
||||
+ generating SHA-2 digests in hex format such as openssl, shasum,
|
||||
+ sha224sum, sha256sum, sha384sum, sha512sum.
|
||||
|
||||
For example, using openssl:
|
||||
|
||||
@@ -319,6 +317,11 @@ SSUUDDOOEERRSS FFIILLEE FFO
|
||||
$ openssl dgst -binary -sha224 /bin/ls | openssl base64
|
||||
EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
|
||||
|
||||
+ If the user has write access to either the command itself or the
|
||||
+ directory in which the command is located (directly or via a ssuuddoo
|
||||
+ command) it may be possible for the user to replace the command after the
|
||||
+ digest check has been performed but before the command is executed.
|
||||
+
|
||||
DDeeffaauullttss
|
||||
Certain configuration options may be changed from their default values at
|
||||
run-time via one or more Default_Entry lines. These may affect all users
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.man.in.digest_race_doc sudo-1.8.6p7/doc/sudoers.man.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.man.in.digest_race_doc 2016-05-11 13:54:01.005002291 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.man.in 2016-05-11 13:58:28.541240345 +0200
|
||||
@@ -679,9 +679,6 @@ is prefixed with a
|
||||
\fRDigest_Spec\fR,
|
||||
the command will only match successfully if it can be verified
|
||||
using the specified SHA-2 digest.
|
||||
-This may be useful in situations where the user invoking
|
||||
-\fBsudo\fR
|
||||
-has write access to the command or its parent directory.
|
||||
The following digest formats are supported: sha224, sha256, sha384 and sha512.
|
||||
The string may be specified in either hex or base64 format
|
||||
(base64 is more compact).
|
||||
@@ -705,6 +702,13 @@ $ openssl dgst -binary -sha224 /bin/ls |
|
||||
EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
|
||||
.RE
|
||||
.fi
|
||||
+.PP
|
||||
+If the user has write access to either the command itself or the
|
||||
+directory in which the command is located (directly or via a
|
||||
+\fBsudo\fR
|
||||
+command) it may be possible for the user to replace the command
|
||||
+after the digest check has been performed but before the command
|
||||
+is executed.
|
||||
.SS "Defaults"
|
||||
Certain configuration options may be changed from their default
|
||||
values at run-time via one or more
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.digest_race_doc sudo-1.8.6p7/doc/sudoers.mdoc.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.mdoc.in.digest_race_doc 2016-05-11 13:54:07.749907447 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2016-05-11 13:59:22.263484933 +0200
|
||||
@@ -655,9 +655,6 @@ is prefixed with a
|
||||
.Li Digest_Spec ,
|
||||
the command will only match successfully if it can be verified
|
||||
using the specified SHA-2 digest.
|
||||
-This may be useful in situations where the user invoking
|
||||
-.Nm sudo
|
||||
-has write access to the command or its parent directory.
|
||||
The following digest formats are supported: sha224, sha256, sha384 and sha512.
|
||||
The string may be specified in either hex or base64 format
|
||||
(base64 is more compact).
|
||||
@@ -675,6 +672,13 @@ It is also possible to use openssl to ge
|
||||
$ openssl dgst -binary -sha224 /bin/ls | openssl base64
|
||||
EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==
|
||||
.Ed
|
||||
+.Pp
|
||||
+If the user has write access to either the command itself or the
|
||||
+directory in which the command is located (directly or via a
|
||||
+.Nm sudo
|
||||
+command) it may be possible for the user to replace the command
|
||||
+after the digest check has been performed but before the command
|
||||
+is executed.
|
||||
.Ss Defaults
|
||||
Certain configuration options may be changed from their default
|
||||
values at run-time via one or more
|
|
@ -0,0 +1,43 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/match.c.digestmessagesfix sudo-1.8.6p7/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/match.c.digestmessagesfix 2015-09-01 15:33:27.493054381 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/match.c 2015-09-01 15:33:31.327054279 +0200
|
||||
@@ -566,6 +566,21 @@ base64_decode(const char *in, unsigned c
|
||||
return io;
|
||||
}
|
||||
|
||||
+static const char *digesttype2str(int digest_type)
|
||||
+{
|
||||
+ switch(digest_type) {
|
||||
+ case SUDO_DIGEST_SHA224:
|
||||
+ return "SHA224";
|
||||
+ case SUDO_DIGEST_SHA256:
|
||||
+ return "SHA256";
|
||||
+ case SUDO_DIGEST_SHA384:
|
||||
+ return "SHA384";
|
||||
+ case SUDO_DIGEST_SHA512:
|
||||
+ return "SHA512";
|
||||
+ }
|
||||
+ return "<INVALID>";
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
digest_matches(char *file, struct sudo_digest *sd)
|
||||
{
|
||||
@@ -597,7 +612,7 @@ digest_matches(char *file, struct sudo_d
|
||||
if (!isxdigit((unsigned char)sd->digest_str[i + i]) ||
|
||||
!isxdigit((unsigned char)sd->digest_str[i + i + 1])) {
|
||||
warningx(_("digest for %s (%s) is not in %s form"), file,
|
||||
- sd->digest_str, sd->digest_str);
|
||||
+ sd->digest_str, digesttype2str(sd->digest_type));
|
||||
goto bad_format;
|
||||
}
|
||||
sudoers_digest[i] = hexchar(&sd->digest_str[i + i]);
|
||||
@@ -619,7 +634,7 @@ digest_matches(char *file, struct sudo_d
|
||||
debug_return_bool(match);
|
||||
bad_format:
|
||||
warningx(_("digest for %s (%s) is not in %s form"), file,
|
||||
- sd->digest_str, sd->digest_str);
|
||||
+ sd->digest_str, digesttype2str(sd->digest_type));
|
||||
if (sudoers_digest)
|
||||
efree(sudoers_digest);
|
||||
if (file_digest)
|
|
@ -0,0 +1,47 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/sudo_nss.c.duplicatenssfix sudo-1.8.6p7/plugins/sudoers/sudo_nss.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sudo_nss.c.duplicatenssfix 2014-09-29 15:30:35.243303099 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sudo_nss.c 2014-09-29 15:33:13.669439300 +0200
|
||||
@@ -88,16 +88,16 @@ sudo_read_nss(void)
|
||||
for ((cp = strtok(cp + 8, " \t")); cp != NULL; (cp = strtok(NULL, " \t"))) {
|
||||
if (strcasecmp(cp, "files") == 0 && !saw_files) {
|
||||
tq_append(&snl, &sudo_nss_file);
|
||||
- got_match = true;
|
||||
+ got_match = saw_files = true;
|
||||
#ifdef HAVE_LDAP
|
||||
} else if (strcasecmp(cp, "ldap") == 0 && !saw_ldap) {
|
||||
tq_append(&snl, &sudo_nss_ldap);
|
||||
- got_match = true;
|
||||
+ got_match = saw_ldap = true;
|
||||
#endif
|
||||
#ifdef HAVE_SSSD
|
||||
} else if (strcasecmp(cp, "sss") == 0 && !saw_sss) {
|
||||
tq_append(&snl, &sudo_nss_sss);
|
||||
- got_match = true;
|
||||
+ got_match = saw_sss = true;
|
||||
#endif
|
||||
} else if (strcasecmp(cp, "[NOTFOUND=return]") == 0 && got_match) {
|
||||
/* NOTFOUND affects the most recent entry */
|
||||
@@ -171,20 +171,20 @@ sudo_read_nss(void)
|
||||
if (!saw_files && strncasecmp(cp, "files", 5) == 0 &&
|
||||
(isspace((unsigned char)cp[5]) || cp[5] == '\0')) {
|
||||
tq_append(&snl, &sudo_nss_file);
|
||||
- got_match = true;
|
||||
+ got_match = saw_files = true;
|
||||
ep = &cp[5];
|
||||
#ifdef HAVE_LDAP
|
||||
} else if (!saw_ldap && strncasecmp(cp, "ldap", 4) == 0 &&
|
||||
(isspace((unsigned char)cp[4]) || cp[4] == '\0')) {
|
||||
tq_append(&snl, &sudo_nss_ldap);
|
||||
- got_match = true;
|
||||
+ got_match = saw_ldap = true;
|
||||
ep = &cp[4];
|
||||
#endif
|
||||
#ifdef HAVE_SSSD
|
||||
} else if (!saw_sss && strncasecmp(cp, "sss", 3) == 0 &&
|
||||
(isspace((unsigned char)cp[3]) || cp[3] == '\0')) {
|
||||
tq_append(&snl, &sudo_nss_sss);
|
||||
- got_match = true;
|
||||
+ got_match = saw_sss = true;
|
||||
ep = &cp[3];
|
||||
#endif
|
||||
} else {
|
|
@ -0,0 +1,192 @@
|
|||
diff -up sudo-1.8.6p7/configure.in.ipahostname sudo-1.8.6p7/configure.in
|
||||
--- sudo-1.8.6p7/configure.in.ipahostname 2014-09-29 11:14:38.393846226 +0200
|
||||
+++ sudo-1.8.6p7/configure.in 2014-09-29 11:14:38.428845807 +0200
|
||||
@@ -309,7 +309,7 @@ dnl Handle SSSD support.
|
||||
dnl
|
||||
AC_ARG_WITH(sssd, [AS_HELP_STRING([--with-sssd], [enable SSSD support])],
|
||||
[case $with_sssd in
|
||||
- yes) SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo"
|
||||
+ yes) SUDOERS_OBJS="${SUDOERS_OBJS} sssd.lo ipa_hostname.lo"
|
||||
AC_DEFINE(HAVE_SSSD)
|
||||
;;
|
||||
no) ;;
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c.ipahostname sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c.ipahostname 2014-09-29 11:14:38.429845795 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ipa_hostname.c 2014-09-29 11:14:38.429845795 +0200
|
||||
@@ -0,0 +1,88 @@
|
||||
+/*
|
||||
+ * Copyright 2013 Red Hat Inc., Durham, North Carolina.
|
||||
+ * All Rights Reserved.
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Daniel Kopecek <dkopecek@redhat.com>
|
||||
+ */
|
||||
+#define _GNU_SOURCE
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <resolv.h>
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+
|
||||
+static const char *sssd_conf_path = "/etc/sssd/sssd.conf";
|
||||
+
|
||||
+char *ipa_hostname(void)
|
||||
+{
|
||||
+ static char hname[MAXHOSTNAMELEN+1];
|
||||
+ size_t hname_len = 0;
|
||||
+ char *line = NULL;
|
||||
+ ssize_t line_len = 0;
|
||||
+ size_t line_buflen = 0;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ if ((fp = fopen(sssd_conf_path, "r")) == NULL)
|
||||
+ return NULL;
|
||||
+ while ((line_len = getline(&line, &line_buflen, fp)) > 0) {
|
||||
+ char *keyword_loc;
|
||||
+ if ((keyword_loc = strstr(line, "ipa_hostname")) != NULL) {
|
||||
+ size_t i;
|
||||
+ char *value_loc;
|
||||
+ size_t value_len;
|
||||
+
|
||||
+ value_loc = keyword_loc + strlen("ipa_hostname") + 1;
|
||||
+ value_len = line_len - (size_t)(value_loc - line);
|
||||
+
|
||||
+ /* Skip spaces and the assignment operator */
|
||||
+ for (i = 0; i < value_len; ++i) {
|
||||
+ if (isspace(value_loc[i]) || value_loc[i] == '=') {
|
||||
+ continue;
|
||||
+ } else {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ value_loc += i;
|
||||
+ value_len -= i;
|
||||
+
|
||||
+ if (value_len <= MAXHOSTNAMELEN) {
|
||||
+ memcpy(hname, value_loc, value_len * sizeof(char));
|
||||
+ free(line);
|
||||
+ fclose(fp);
|
||||
+ hname_len = value_len;
|
||||
+ hname[hname_len] = '\0';
|
||||
+ /* Remove spaces from the end of the string */
|
||||
+ for (i = hname_len - 1; i > 0; --i) {
|
||||
+ if (isspace(hname[i])) {
|
||||
+ hname[i] = '\0';
|
||||
+ --hname_len;
|
||||
+ } else {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return hname;
|
||||
+ }
|
||||
+ }
|
||||
+ free(line);
|
||||
+ line = NULL;
|
||||
+ }
|
||||
+
|
||||
+ fclose(fp);
|
||||
+ return NULL;
|
||||
+}
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h.ipahostname sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h.ipahostname 2014-09-29 11:14:38.429845795 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ipa_hostname.h 2014-09-29 11:14:38.429845795 +0200
|
||||
@@ -0,0 +1,27 @@
|
||||
+/*
|
||||
+ * Copyright 2013 Red Hat Inc., Durham, North Carolina.
|
||||
+ * All Rights Reserved.
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
+ *
|
||||
+ * Authors:
|
||||
+ * Daniel Kopecek <dkopecek@redhat.com>
|
||||
+ */
|
||||
+#ifndef _IPA_HOSTNAME_H_
|
||||
+#define _IPA_HOSTNAME_H_
|
||||
+
|
||||
+char *ipa_hostname(void);
|
||||
+
|
||||
+#endif /* _IPA_HOSTNAME_H_ */
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/Makefile.in.ipahostname sudo-1.8.6p7/plugins/sudoers/Makefile.in
|
||||
--- sudo-1.8.6p7/plugins/sudoers/Makefile.in.ipahostname 2014-09-29 11:14:38.429845795 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/Makefile.in 2014-09-29 11:16:54.923210160 +0200
|
||||
@@ -728,6 +728,9 @@ sia.lo: $(authdir)/sia.c $(top_builddir)
|
||||
$(devdir)/def_data.h $(srcdir)/logging.h $(srcdir)/sudo_nss.h \
|
||||
$(incdir)/sudo_plugin.h $(incdir)/sudo_debug.h $(incdir)/gettext.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(authdir)/sia.c
|
||||
+ipa_hostname.lo: $(srcdir)/ipa_hostname.c $(srcdir)/ipa_hostname.h
|
||||
+ $(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ipa_hostname.c
|
||||
+
|
||||
sssd.lo: $(srcdir)/sssd.c $(top_builddir)/config.h \
|
||||
$(top_srcdir)/compat/dlfcn.h $(srcdir)/sudoers.h \
|
||||
$(top_srcdir)/compat/stdbool.h $(top_builddir)/pathnames.h \
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.ipahostname sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.ipahostname 2014-09-29 11:14:38.424845855 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2014-09-29 11:14:38.429845795 +0200
|
||||
@@ -60,6 +60,7 @@
|
||||
#include "parse.h"
|
||||
#include "lbuf.h"
|
||||
#include "sudo_debug.h"
|
||||
+#include "ipa_hostname.h"
|
||||
|
||||
/* SSSD <--> SUDO interface - do not change */
|
||||
struct sss_sudo_attr {
|
||||
@@ -549,6 +550,24 @@ sudo_sss_check_runas(struct sudo_sss_han
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
+static bool sudo_sss_ipa_hostname_matches(const char *hostname_val)
|
||||
+{
|
||||
+ bool ret = false;
|
||||
+ char *ipa_hostname_val;
|
||||
+ debug_decl(sudo_sss_ipa_hostname_matches, SUDO_DEBUG_SSSD)
|
||||
+
|
||||
+ if ((ipa_hostname_val = ipa_hostname()) != NULL) {
|
||||
+ ret = hostname_matches(ipa_hostname_val, ipa_hostname_val, hostname_val) || \
|
||||
+ netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, NULL);
|
||||
+ }
|
||||
+
|
||||
+ sudo_debug_printf(SUDO_DEBUG_TRACE, "IPA hostname (%s) matches %s => %s",
|
||||
+ ipa_hostname_val ? ipa_hostname_val : "<none>", hostname_val,
|
||||
+ ret ? "true" : "false");
|
||||
+
|
||||
+ debug_return_bool(ret);
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
sudo_sss_check_host(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule)
|
||||
{
|
||||
@@ -580,6 +599,7 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
|
||||
/* match any or address or netgroup or hostname */
|
||||
if (!strcmp(val, "ALL") || addr_matches(val) ||
|
||||
+ sudo_sss_ipa_hostname_matches(val) ||
|
||||
netgr_matches(val, user_host, user_shost, NULL) ||
|
||||
hostname_matches(user_shost, user_host, val))
|
||||
ret = true;
|
|
@ -0,0 +1,91 @@
|
|||
diff -up sudo-1.8.6p7/common/fmt_string.c.ldap_sssd_parse_whitespaces sudo-1.8.6p7/common/fmt_string.c
|
||||
--- sudo-1.8.6p7/common/fmt_string.c.ldap_sssd_parse_whitespaces 2013-02-25 20:42:44.000000000 +0100
|
||||
+++ sudo-1.8.6p7/common/fmt_string.c 2016-05-11 10:31:30.206090322 +0200
|
||||
@@ -38,6 +38,8 @@
|
||||
# include <strings.h>
|
||||
#endif /* HAVE_STRINGS_H */
|
||||
|
||||
+#include <ctype.h>
|
||||
+
|
||||
#include "missing.h"
|
||||
#include "sudo_debug.h"
|
||||
|
||||
@@ -64,3 +66,17 @@ fmt_string(const char *var, const char *
|
||||
|
||||
debug_return_str(str);
|
||||
}
|
||||
+
|
||||
+char * rm_whitespaces(char * str){
|
||||
+ int state = 1;
|
||||
+ char * c;
|
||||
+ for (c = str ; *c != '\0' ; c++){
|
||||
+ if (state && isspace(*c))str++;
|
||||
+ else if (!isspace(*c))state = 0;
|
||||
+ else if (!state && isspace(*c)){
|
||||
+ *c = '\0';
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return str;
|
||||
+}
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldap_sssd_parse_whitespaces sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.ldap_sssd_parse_whitespaces 2016-05-11 10:31:30.202090379 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-11 10:31:30.207090307 +0200
|
||||
@@ -1012,17 +1012,17 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMe
|
||||
if (op == '+' || op == '-') {
|
||||
*(val - 2) = '\0'; /* found, remove extra char */
|
||||
/* case var+=val or var-=val */
|
||||
- set_default(var, strunquote(val), (int) op);
|
||||
+ set_default(rm_whitespaces(var), strunquote(val), (int) op);
|
||||
} else {
|
||||
/* case var=val */
|
||||
- set_default(var, strunquote(val), true);
|
||||
+ set_default(rm_whitespaces(var), strunquote(val), true);
|
||||
}
|
||||
} else if (*var == '!') {
|
||||
/* case !var Boolean False */
|
||||
- set_default(var + 1, NULL, false);
|
||||
+ set_default(rm_whitespaces(var + 1), NULL, false);
|
||||
} else {
|
||||
/* case var Boolean True */
|
||||
- set_default(var, NULL, true);
|
||||
+ set_default(rm_whitespaces(var), NULL, true);
|
||||
}
|
||||
efree(var);
|
||||
}
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.ldap_sssd_parse_whitespaces sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.ldap_sssd_parse_whitespaces 2016-05-11 10:31:30.202090379 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2016-05-11 10:31:30.207090307 +0200
|
||||
@@ -1004,17 +1004,17 @@ sudo_sss_parse_options(struct sudo_sss_h
|
||||
if (op == '+' || op == '-') {
|
||||
*(val - 2) = '\0'; /* found, remove extra char */
|
||||
/* case var+=val or var-=val */
|
||||
- set_default(v, strunquote(val), (int) op);
|
||||
+ set_default(rm_whitespaces(v), strunquote(val), (int) op);
|
||||
} else {
|
||||
/* case var=val */
|
||||
- set_default(v, strunquote(val), true);
|
||||
+ set_default(rm_whitespaces(v), strunquote(val), true);
|
||||
}
|
||||
} else if (*v == '!') {
|
||||
/* case !var Boolean False */
|
||||
- set_default(v + 1, NULL, false);
|
||||
+ set_default(rm_whitespaces(v + 1), NULL, false);
|
||||
} else {
|
||||
/* case var Boolean True */
|
||||
- set_default(v, NULL, true);
|
||||
+ set_default(rm_whitespaces(v), NULL, true);
|
||||
}
|
||||
efree(v);
|
||||
}
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.ldap_sssd_parse_whitespaces sudo-1.8.6p7/plugins/sudoers/sudoers.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sudoers.h.ldap_sssd_parse_whitespaces 2016-05-11 10:31:30.204090350 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2016-05-11 10:31:30.207090307 +0200
|
||||
@@ -346,6 +346,7 @@ int sudoers_hook_unsetenv(const char *na
|
||||
|
||||
/* fmt_string.c */
|
||||
char *fmt_string(const char *, const char *);
|
||||
+char *rm_whitespaces(char * str);
|
||||
|
||||
/* sudoers.c */
|
||||
void plugin_cleanup(int);
|
|
@ -0,0 +1,119 @@
|
|||
From b1f3fcf8d6e9a8e5326771a12fac8e08ed81f766 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Fri, 19 Aug 2016 10:21:27 +0200
|
||||
Subject: [PATCH] Sudo with ldap doesn't work with 'user id'
|
||||
|
||||
in sudoUser option.
|
||||
|
||||
Rebased from:
|
||||
Patch39: sudo-1.8.6p7-ldapsearchuidfix.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#1135539
|
||||
---
|
||||
plugins/sudoers/def_data.c | 4 ++++
|
||||
plugins/sudoers/def_data.h | 2 ++
|
||||
plugins/sudoers/def_data.in | 3 +++
|
||||
plugins/sudoers/defaults.c | 2 ++
|
||||
plugins/sudoers/ldap.c | 10 ++++++++--
|
||||
plugins/sudoers/sudoers.c | 4 ++++
|
||||
6 files changed, 23 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/def_data.c b/plugins/sudoers/def_data.c
|
||||
index d8b1ada..3926fed 100644
|
||||
--- a/plugins/sudoers/def_data.c
|
||||
+++ b/plugins/sudoers/def_data.c
|
||||
@@ -439,6 +439,10 @@ struct sudo_defs_types sudo_defs_table[] = {
|
||||
N_("Don't fork and wait for the command to finish, just exec it"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "legacy_group_processing", T_FLAG,
|
||||
+ N_("Don't pre-resolve all group names"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff --git a/plugins/sudoers/def_data.h b/plugins/sudoers/def_data.h
|
||||
index 1b6be3d..5246e41 100644
|
||||
--- a/plugins/sudoers/def_data.h
|
||||
+++ b/plugins/sudoers/def_data.h
|
||||
@@ -206,6 +206,8 @@
|
||||
#define def_iolog_mode (sudo_defs_table[I_IOLOG_MODE].sd_un.mode)
|
||||
#define I_CMND_NO_WAIT 103
|
||||
#define def_cmnd_no_wait (sudo_defs_table[I_CMND_NO_WAIT].sd_un.flag)
|
||||
+#define I_LEGACY_GROUP_PROCESSING 104
|
||||
+#define def_legacy_group_processing (sudo_defs_table[I_LEGACY_GROUP_PROCESSING].sd_un.flag)
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff --git a/plugins/sudoers/def_data.in b/plugins/sudoers/def_data.in
|
||||
index 5200fe3..f1c9265 100644
|
||||
--- a/plugins/sudoers/def_data.in
|
||||
+++ b/plugins/sudoers/def_data.in
|
||||
@@ -325,3 +325,6 @@ iolog_mode
|
||||
cmnd_no_wait
|
||||
T_FLAG
|
||||
"Don't fork and wait for the command to finish, just exec it"
|
||||
+legacy_group_processing
|
||||
+ T_FLAG
|
||||
+ "Don't pre-resolve all group names"
|
||||
diff --git a/plugins/sudoers/defaults.c b/plugins/sudoers/defaults.c
|
||||
index 5eaf8ea..9e60d94 100644
|
||||
--- a/plugins/sudoers/defaults.c
|
||||
+++ b/plugins/sudoers/defaults.c
|
||||
@@ -450,6 +450,8 @@ init_defaults(void)
|
||||
}
|
||||
|
||||
/* First initialize the flags. */
|
||||
+ def_legacy_group_processing = true;
|
||||
+ def_match_group_by_gid = true;
|
||||
#ifdef LONG_OTP_PROMPT
|
||||
def_long_otp_prompt = true;
|
||||
#endif
|
||||
diff --git a/plugins/sudoers/ldap.c b/plugins/sudoers/ldap.c
|
||||
index 3fe27c7..96a0709 100644
|
||||
--- a/plugins/sudoers/ldap.c
|
||||
+++ b/plugins/sudoers/ldap.c
|
||||
@@ -1666,8 +1666,8 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||
if (ldap_conf.search_filter)
|
||||
sz += strlen(ldap_conf.search_filter);
|
||||
|
||||
- /* Then add (|(sudoUser=USERNAME)(sudoUser=ALL)) + NUL */
|
||||
- sz += 29 + sudo_ldap_value_len(pw->pw_name);
|
||||
+ /* Then add (|(sudoUser=USERNAME)(sudoUser=#uid)(sudoUser=ALL)) + NUL */
|
||||
+ sz += 29 + (12 + MAX_UID_T_LEN) + sudo_ldap_value_len(pw->pw_name);
|
||||
|
||||
/* Add space for primary and supplementary groups and gids */
|
||||
if ((grp = sudo_getgrgid(pw->pw_gid)) != NULL) {
|
||||
@@ -1730,6 +1730,12 @@ sudo_ldap_build_pass1(LDAP *ld, struct passwd *pw)
|
||||
CHECK_LDAP_VCAT(buf, pw->pw_name, sz);
|
||||
CHECK_STRLCAT(buf, ")", sz);
|
||||
|
||||
+ /* Append user uid */
|
||||
+ (void) snprintf(gidbuf, sizeof(gidbuf), "%u", (unsigned int)pw->pw_uid);
|
||||
+ (void) strlcat(buf, "(sudoUser=#", sz);
|
||||
+ (void) strlcat(buf, gidbuf, sz);
|
||||
+ (void) strlcat(buf, ")", sz);
|
||||
+
|
||||
/* Append primary group and gid */
|
||||
if (grp != NULL) {
|
||||
CHECK_STRLCAT(buf, "(sudoUser=%", sz);
|
||||
diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c
|
||||
index 539177a..673ee5d 100644
|
||||
--- a/plugins/sudoers/sudoers.c
|
||||
+++ b/plugins/sudoers/sudoers.c
|
||||
@@ -208,6 +208,10 @@ sudoers_policy_init(void *info, char * const envp[])
|
||||
if (set_loginclass(runas_pw ? runas_pw : sudo_user.pw))
|
||||
ret = true;
|
||||
|
||||
+ if (!def_match_group_by_gid || !def_legacy_group_processing) {
|
||||
+ def_match_group_by_gid = false;
|
||||
+ def_legacy_group_processing = false;
|
||||
+ }
|
||||
cleanup:
|
||||
if (!restore_perms())
|
||||
ret = -1;
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapusermatchfix sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.ldapusermatchfix 2016-05-09 15:33:10.933510674 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-09 15:33:10.937510618 +0200
|
||||
@@ -2735,22 +2735,37 @@ sudo_ldap_result_get(struct sudo_nss *ns
|
||||
result = NULL;
|
||||
rc = ldap_search_ext_s(ld, base->val, LDAP_SCOPE_SUBTREE, filt,
|
||||
NULL, 0, NULL, NULL, tvp, 0, &result);
|
||||
- if (rc != LDAP_SUCCESS) {
|
||||
+ if (rc != LDAP_SUCCESS || result == NULL) {
|
||||
DPRINTF(("nothing found for '%s'", filt), 1);
|
||||
continue;
|
||||
}
|
||||
- lres->user_matches = true;
|
||||
+
|
||||
+ DPRINTF(("search result has %d entries (do_netgr=%s)",
|
||||
+ ldap_count_entries(ld, result), do_netgr ? "true" : "false"), 1);
|
||||
+ /*
|
||||
+ * Only set user_matches if we got some results back and if we are
|
||||
+ * NOT searching for netgroup entries. For the netgroup case, user_maches
|
||||
+ * will be set only if a netgroup match was found.
|
||||
+ */
|
||||
+ lres->user_matches = lres->user_matches ? true : ldap_count_entries(ld, result) > 0 && !do_netgr;
|
||||
|
||||
/* Add the seach result to list of search results. */
|
||||
DPRINTF(("adding search result"), 1);
|
||||
sudo_ldap_result_add_search(lres, ld, result);
|
||||
LDAP_FOREACH(entry, ld, result) {
|
||||
- if ((!do_netgr ||
|
||||
- sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name)) &&
|
||||
+ if (do_netgr) {
|
||||
+ if (sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name) &&
|
||||
sudo_ldap_check_host(ld, entry)) {
|
||||
- lres->host_matches = true;
|
||||
- sudo_ldap_result_add_entry(lres, entry);
|
||||
+ lres->host_matches = true;
|
||||
+ lres->user_matches = true;
|
||||
+ sudo_ldap_result_add_entry(lres, entry);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (sudo_ldap_check_host(ld, entry)) {
|
||||
+ lres->host_matches = true;
|
||||
+ sudo_ldap_result_add_entry(lres, entry);
|
||||
}
|
||||
+ }
|
||||
}
|
||||
DPRINTF(("result now has %d entries", lres->nentries), 1);
|
||||
}
|
|
@ -0,0 +1,224 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/defaults.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/defaults.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/defaults.c.legacy-group-processing 2013-02-25 20:42:44.000000000 +0100
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/defaults.c 2015-08-28 10:52:13.658671686 +0200
|
||||
@@ -362,6 +362,7 @@ init_defaults(void)
|
||||
}
|
||||
|
||||
/* First initialize the flags. */
|
||||
+ def_legacy_group_processing = true;
|
||||
#ifdef LONG_OTP_PROMPT
|
||||
def_long_otp_prompt = true;
|
||||
#endif
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/def_data.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.c.legacy-group-processing 2015-08-28 10:52:13.604671687 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.c 2015-08-28 10:52:13.658671686 +0200
|
||||
@@ -355,6 +355,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Don't fork and wait for the command to finish, just exec it"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "legacy_group_processing", T_FLAG,
|
||||
+ N_("Don't pre-resolve all group names"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.h.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/def_data.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.h.legacy-group-processing 2015-08-28 10:52:13.604671687 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.h 2015-08-28 10:52:13.658671686 +0200
|
||||
@@ -164,6 +164,8 @@
|
||||
#define I_LIMITPRIVS 81
|
||||
#define def_cmnd_no_wait (sudo_defs_table[82].sd_un.flag)
|
||||
#define I_CMND_NO_WAIT 82
|
||||
+#define def_legacy_group_processing (sudo_defs_table[83].sd_un.flag)
|
||||
+#define I_LEGACY_GROUP_PROCESSING 83
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.legacy-group-processing 2015-08-28 10:52:13.656671686 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-08-28 10:52:13.659671686 +0200
|
||||
@@ -1220,6 +1220,15 @@ sudo_ldap_build_pass1(struct passwd *pw)
|
||||
}
|
||||
sz += 13 + MAX_UID_T_LEN;
|
||||
if ((grlist = sudo_get_grlist(pw)) != NULL) {
|
||||
+ if (!grlist->groups_resolved) {
|
||||
+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids,
|
||||
+ grlist->groups, grlist->groups_buffer);
|
||||
+ if (rc < 0) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ grlist->ngroups = rc;
|
||||
+ grlist->groups_resolved = true;
|
||||
+ }
|
||||
for (i = 0; i < grlist->ngroups; i++) {
|
||||
if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
|
||||
continue;
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/pwutil.c.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/pwutil.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/pwutil.c.legacy-group-processing 2015-08-28 10:52:13.633671686 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/pwutil.c 2015-08-28 10:52:13.659671686 +0200
|
||||
@@ -542,10 +542,9 @@ static struct cache_item *
|
||||
make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids)
|
||||
{
|
||||
char *cp;
|
||||
- size_t i, nsize, ngroups, total, len;
|
||||
+ size_t i, nsize, total;
|
||||
struct cache_item_grlist *grlitem;
|
||||
struct group_list *grlist;
|
||||
- struct group *grp;
|
||||
debug_decl(make_grlist_item, SUDO_DEBUG_NSS)
|
||||
|
||||
#ifdef HAVE_SETAUTHDB
|
||||
@@ -559,7 +558,6 @@ make_grlist_item(const char *user, GETGR
|
||||
total += sizeof(gid_t *) * ngids;
|
||||
total += GROUPNAME_LEN * ngids;
|
||||
|
||||
-again:
|
||||
grlitem = ecalloc(1, total);
|
||||
|
||||
/*
|
||||
@@ -587,27 +585,26 @@ again:
|
||||
for (i = 0; i < ngids; i++)
|
||||
grlist->gids[i] = gids[i];
|
||||
grlist->ngids = ngids;
|
||||
+ grlist->groups_buffer = cp;
|
||||
|
||||
/*
|
||||
- * Resolve and store group names by ID.
|
||||
+ * Resolve and store group names by ID if legacy_group_processing is off.
|
||||
*/
|
||||
- ngroups = 0;
|
||||
- for (i = 0; i < ngids; i++) {
|
||||
- if ((grp = sudo_getgrgid(gids[i])) != NULL) {
|
||||
- len = strlen(grp->gr_name) + 1;
|
||||
- if (cp - (char *)grlitem + len > total) {
|
||||
- total += len + GROUPNAME_LEN;
|
||||
- efree(grlitem);
|
||||
- sudo_gr_delref(grp);
|
||||
- goto again;
|
||||
- }
|
||||
- memcpy(cp, grp->gr_name, len);
|
||||
- grlist->groups[ngroups++] = cp;
|
||||
- cp += len;
|
||||
- sudo_gr_delref(grp);
|
||||
- }
|
||||
+ if (def_legacy_group_processing) {
|
||||
+ for (i = 0; i < ngids; i++) {
|
||||
+ grlist->groups[i] = NULL;
|
||||
+ }
|
||||
+ grlist->ngroups = 0;
|
||||
+ grlist->groups_resolved = false;
|
||||
+ } else {
|
||||
+ int rc = sudo_resolve_gids(gids, ngids, grlist->groups, grlist->groups_buffer);
|
||||
+ if (rc < 0) {
|
||||
+ efree(grlitem);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ grlist->ngroups = rc;
|
||||
+ grlist->groups_resolved = true;
|
||||
}
|
||||
- grlist->ngroups = ngroups;
|
||||
|
||||
#ifdef HAVE_SETAUTHDB
|
||||
aix_restoreauthdb();
|
||||
@@ -616,6 +613,35 @@ again:
|
||||
debug_return_ptr(&grlitem->cache);
|
||||
}
|
||||
|
||||
+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer)
|
||||
+{
|
||||
+ struct group *grp;
|
||||
+ int space_left = ngids * GROUPNAME_LEN;
|
||||
+ int ngroups = 0;
|
||||
+ int i;
|
||||
+ char *cp = group_buffer;
|
||||
+ debug_decl(sudo_resolve_gids, SUDO_DEBUG_NSS)
|
||||
+
|
||||
+ for (i = 0; i < ngids; i++) {
|
||||
+ if ((grp = sudo_getgrgid(gids[i])) != NULL) {
|
||||
+ int len = strlen(grp->gr_name) + 1;
|
||||
+
|
||||
+ if (space_left < len) {
|
||||
+ sudo_gr_delref(grp);
|
||||
+ debug_return_int(-1);
|
||||
+ }
|
||||
+
|
||||
+ memcpy(cp, grp->gr_name, len);
|
||||
+ groups[ngroups++] = cp;
|
||||
+ cp += len;
|
||||
+ space_left -= len;
|
||||
+ sudo_gr_delref(grp);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ debug_return_int(ngroups);
|
||||
+}
|
||||
+
|
||||
void
|
||||
sudo_gr_addref(struct group *gr)
|
||||
{
|
||||
@@ -917,8 +943,22 @@ user_in_group(const struct passwd *pw, c
|
||||
/*
|
||||
* If it could be a sudo-style group ID check gids first.
|
||||
*/
|
||||
+ bool do_gid_lookup = false;
|
||||
+ gid_t gid;
|
||||
+
|
||||
if (group[0] == '#') {
|
||||
- gid_t gid = atoi(group + 1);
|
||||
+ gid = atoi(group + 1);
|
||||
+ do_gid_lookup = true;
|
||||
+ } else if (def_legacy_group_processing) {
|
||||
+ struct group *grent = sudo_getgrnam(group);
|
||||
+ if (grent == NULL) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ gid = grent->gr_gid;
|
||||
+ do_gid_lookup = true;
|
||||
+ }
|
||||
+
|
||||
+ if (do_gid_lookup) {
|
||||
if (gid == pw->pw_gid) {
|
||||
matched = true;
|
||||
goto done;
|
||||
@@ -931,6 +971,19 @@ user_in_group(const struct passwd *pw, c
|
||||
}
|
||||
}
|
||||
|
||||
+ if (def_legacy_group_processing) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ if (!grlist->groups_resolved) {
|
||||
+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids,
|
||||
+ grlist->groups, grlist->groups_buffer);
|
||||
+ if (rc < 0) {
|
||||
+ goto done;
|
||||
+ }
|
||||
+ grlist->ngroups = rc;
|
||||
+ grlist->groups_resolved = true;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Next check the supplementary group vector.
|
||||
* It usually includes the password db group too.
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sudoers.h.legacy-group-processing sudo-1.8.6p7/plugins/sudoers/sudoers.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sudoers.h.legacy-group-processing 2015-08-28 10:52:13.634671686 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sudoers.h 2015-08-28 10:52:13.659671686 +0200
|
||||
@@ -52,6 +52,8 @@ struct group_list {
|
||||
GETGROUPS_T *gids;
|
||||
int ngroups;
|
||||
int ngids;
|
||||
+ int groups_resolved;
|
||||
+ char *groups_buffer;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -289,6 +291,8 @@ __dso_public struct group *sudo_getgrnam
|
||||
__dso_public void sudo_gr_addref(struct group *);
|
||||
__dso_public void sudo_gr_delref(struct group *);
|
||||
bool user_in_group(const struct passwd *, const char *);
|
||||
+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer);
|
||||
+
|
||||
struct group *sudo_fakegrnam(const char *);
|
||||
struct group_list *sudo_get_grlist(const struct passwd *pw);
|
||||
struct passwd *sudo_fakepwnam(const char *, gid_t);
|
|
@ -0,0 +1,90 @@
|
|||
From 06b46ae226fecd4188af372ac0ccd7aa582e21c8 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Wed, 17 Aug 2016 10:12:11 +0200
|
||||
Subject: [PATCH] Sudo logs username root instead of realuser
|
||||
|
||||
RHEL7 sudo logs username root instead of realuser in /var/log/secure
|
||||
|
||||
Rebased from:
|
||||
Patch50: sudo-1.8.6p7-logsudouser.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#1312486
|
||||
---
|
||||
plugins/sudoers/logging.c | 14 +++++++-------
|
||||
plugins/sudoers/sudoers.h | 1 +
|
||||
2 files changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/plugins/sudoers/logging.c b/plugins/sudoers/logging.c
|
||||
index 45cae67..74b2220 100644
|
||||
--- a/plugins/sudoers/logging.c
|
||||
+++ b/plugins/sudoers/logging.c
|
||||
@@ -104,7 +104,7 @@ do_syslog(int pri, char *msg)
|
||||
* Log the full line, breaking into multiple syslog(3) calls if necessary
|
||||
*/
|
||||
fmt = _("%8s : %s");
|
||||
- maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
|
||||
+ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(sudo_user_name));
|
||||
for (p = msg; *p != '\0'; ) {
|
||||
len = strlen(p);
|
||||
if (len > maxlen) {
|
||||
@@ -120,7 +120,7 @@ do_syslog(int pri, char *msg)
|
||||
save = *tmp;
|
||||
*tmp = '\0';
|
||||
|
||||
- mysyslog(pri, fmt, user_name, p);
|
||||
+ mysyslog(pri, fmt, sudo_user_name, p);
|
||||
|
||||
*tmp = save; /* restore saved character */
|
||||
|
||||
@@ -128,11 +128,11 @@ do_syslog(int pri, char *msg)
|
||||
for (p = tmp; *p == ' '; p++)
|
||||
continue;
|
||||
} else {
|
||||
- mysyslog(pri, fmt, user_name, p);
|
||||
+ mysyslog(pri, fmt, sudo_user_name, p);
|
||||
p += len;
|
||||
}
|
||||
fmt = _("%8s : (command continued) %s");
|
||||
- maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(user_name));
|
||||
+ maxlen = def_syslog_maxlen - (strlen(fmt) - 5 + strlen(sudo_user_name));
|
||||
}
|
||||
|
||||
sudoers_setlocale(oldlocale, NULL);
|
||||
@@ -179,10 +179,10 @@ do_logfile(const char *msg)
|
||||
timestr = "invalid date";
|
||||
if (def_log_host) {
|
||||
len = asprintf(&full_line, "%s : %s : HOST=%s : %s",
|
||||
- timestr, user_name, user_srunhost, msg);
|
||||
+ timestr, sudo_user_name, user_srunhost, msg);
|
||||
} else {
|
||||
len = asprintf(&full_line, "%s : %s : %s",
|
||||
- timestr, user_name, msg);
|
||||
+ timestr, sudo_user_name, msg);
|
||||
}
|
||||
if (len == -1) {
|
||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||
@@ -746,7 +746,7 @@ send_mail(const char *fmt, ...)
|
||||
|
||||
if ((timestr = get_timestr(time(NULL), def_log_year)) == NULL)
|
||||
timestr = "invalid date";
|
||||
- (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, user_name);
|
||||
+ (void) fprintf(mail, "\n\n%s : %s : %s : ", user_host, timestr, sudo_user_name);
|
||||
va_start(ap, fmt);
|
||||
(void) vfprintf(mail, fmt, ap);
|
||||
va_end(ap);
|
||||
diff --git a/plugins/sudoers/sudoers.h b/plugins/sudoers/sudoers.h
|
||||
index cfd5abb..c69a043 100644
|
||||
--- a/plugins/sudoers/sudoers.h
|
||||
+++ b/plugins/sudoers/sudoers.h
|
||||
@@ -180,6 +180,7 @@ struct sudo_user {
|
||||
/*
|
||||
* Shortcuts for sudo_user contents.
|
||||
*/
|
||||
+#define sudo_user_name (sudo_user.pw->pw_name)
|
||||
#define user_name (sudo_user.name)
|
||||
#define user_uid (sudo_user.uid)
|
||||
#define user_gid (sudo_user.gid)
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
diff -up sudo-1.8.6p7/doc/fixmdoc.sh.manfix-usepty sudo-1.8.6p7/doc/fixmdoc.sh
|
||||
--- sudo-1.8.6p7/doc/fixmdoc.sh.manfix-usepty 2015-07-07 09:06:37.893592317 +0200
|
||||
+++ sudo-1.8.6p7/doc/fixmdoc.sh 2015-07-07 09:07:40.575602754 +0200
|
||||
@@ -1,4 +1,19 @@
|
||||
#!/bin/sh
|
||||
+#
|
||||
+# Copyright (c) 2012-2014 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.
|
||||
+#
|
||||
|
||||
OUTFILE="$1"
|
||||
rm -f "$OUTFILE"
|
||||
@@ -18,11 +33,9 @@ case "$OUTFILE" in
|
||||
# BSD auth
|
||||
BA_FLAG=
|
||||
if [ X"$BAMAN" != X"1" ]; then
|
||||
- BA_FLAG='/^.*\n\.Op Fl a Ar auth_type/{;N;/^.*\n\.Ek$/d;};'
|
||||
+ BA_FLAG='/^.*\n\.Op Fl a Ar type/{;N;/^.*\n\.Ek$/d;};'
|
||||
cat >>"$OUTFILE" <<-'EOF'
|
||||
- /^\.It Fl a Ar type/,/BSD authentication\.$/ {
|
||||
- d
|
||||
- }
|
||||
+ /^\.It Fl a Ar type/,/BSD authentication\.$/d
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -31,9 +44,7 @@ case "$OUTFILE" in
|
||||
if [ X"$LCMAN" != X"1" ]; then
|
||||
LC_FLAG='/^.*\n\.Op Fl c Ar class/{;N;/^.*\n\.Ek$/d;};'
|
||||
cat >>"$OUTFILE" <<-'EOF'
|
||||
- /^\.It Fl c Ar class/,/BSD login classes\.$/ {
|
||||
- d
|
||||
- }
|
||||
+ /^\.It Fl c Ar class/,/BSD login classes\.$/d
|
||||
/^\.Xr login_cap 3 ,$/d
|
||||
/^BSD login class$/ {
|
||||
N
|
||||
@@ -47,12 +58,8 @@ case "$OUTFILE" in
|
||||
if [ X"$SEMAN" != X"1" ]; then
|
||||
SE_FLAG='/^.*\n\.Op Fl r Ar role/{;N;/^.*\n\.Ek$/d;};/^.*\n\.Op Fl t Ar type/{;N;/^.*\n\.Ek$/d;};'
|
||||
cat >>"$OUTFILE" <<-'EOF'
|
||||
- /^\.It Fl r Ar role/,/newline character\.$/ {
|
||||
- d
|
||||
- }
|
||||
- /^\.It Fl t Ar type/,/specified role\.$/ {
|
||||
- d
|
||||
- }
|
||||
+ /^\.It Fl r Ar role/,/^\.Ar role \.$/d
|
||||
+ /^\.It Fl t Ar type/,/derived from the role\.$/d
|
||||
/^SELinux role and type$/ {
|
||||
N
|
||||
/^SELinux role and type\n\.It$/d
|
||||
@@ -103,12 +110,8 @@ case "$OUTFILE" in
|
||||
# BSD login class
|
||||
if [ X"$LCMAN" != X"1" ]; then
|
||||
cat >>"$OUTFILE" <<-'EOF'
|
||||
- /^On BSD systems/,/\.$/ {
|
||||
- d
|
||||
- }
|
||||
- /^\.It use_loginclass$/,/^\.It/ {
|
||||
- /^\.It [^u][^s][^e][^_][^l]/!d
|
||||
- }
|
||||
+ /^On BSD systems/,/\.$/d
|
||||
+ /^\.It use_loginclass$/,/^by default\./d
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -120,15 +123,8 @@ case "$OUTFILE" in
|
||||
N
|
||||
d
|
||||
}
|
||||
- /^\.It limitprivs$/,/^\.It/ {
|
||||
- /^\.It [^l][^i][^m][^i][^t]/!d
|
||||
- }
|
||||
- /^\.It privs$/,/^\.It/ {
|
||||
- /^\.It [^p][^r][^i][^v][^s]$/!d
|
||||
- }
|
||||
- /^On Solaris 10/,/^\.Pp/ {
|
||||
- d
|
||||
- }
|
||||
+ /^\.It \(limit\)*privs$/,/is built on Solaris 10 or higher\.$/d
|
||||
+ /^On Solaris 10/,/^\.Pp/d
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -140,9 +136,7 @@ case "$OUTFILE" in
|
||||
N
|
||||
d
|
||||
}
|
||||
- /^\.It [rt][oy][lp]e$/,/^\.It/ {
|
||||
- /^\.It [^rt][^oy][^lp][^e]$/!d
|
||||
- }
|
||||
+ /^\.It [rt][oy][lp]e$/,/is built with SELinux support\.$/d
|
||||
EOF
|
||||
fi
|
||||
;;
|
|
@ -0,0 +1,194 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/defaults.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/defaults.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/defaults.c.netgroup_tuple 2016-05-09 15:34:41.059246583 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/defaults.c 2016-05-09 15:34:41.066246485 +0200
|
||||
@@ -362,6 +362,7 @@ init_defaults(void)
|
||||
}
|
||||
|
||||
/* First initialize the flags. */
|
||||
+ def_netgroup_tuple = false;
|
||||
def_legacy_group_processing = true;
|
||||
#ifdef LONG_OTP_PROMPT
|
||||
def_long_otp_prompt = true;
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/def_data.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.c.netgroup_tuple 2016-05-09 15:34:41.059246583 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.c 2016-05-09 15:34:41.066246485 +0200
|
||||
@@ -359,6 +359,10 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Don't pre-resolve all group names"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "netgroup_tuple", T_FLAG,
|
||||
+ N_("Use both user and host/domain fields when matching netgroups"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.h.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/def_data.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.h.netgroup_tuple 2016-05-09 15:34:41.059246583 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.h 2016-05-09 15:34:41.066246485 +0200
|
||||
@@ -166,6 +166,8 @@
|
||||
#define I_CMND_NO_WAIT 82
|
||||
#define def_legacy_group_processing (sudo_defs_table[83].sd_un.flag)
|
||||
#define I_LEGACY_GROUP_PROCESSING 83
|
||||
+#define def_netgroup_tuple (sudo_defs_table[84].sd_un.flag)
|
||||
+#define I_NETGROUP_TUPLE 84
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.netgroup_tuple 2016-05-09 15:34:41.065246499 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-09 15:34:41.066246485 +0200
|
||||
@@ -636,8 +636,12 @@ sudo_ldap_check_user_netgroup(LDAP *ld,
|
||||
for (p = bv; *p != NULL && !ret; p++) {
|
||||
val = (*p)->bv_val;
|
||||
/* match any */
|
||||
- if (netgr_matches(val, NULL, NULL, user))
|
||||
- ret = true;
|
||||
+ if (netgr_matches(val,
|
||||
+ def_netgroup_tuple ? user_host : NULL,
|
||||
+ def_netgroup_tuple ? user_shost : NULL,
|
||||
+ user)) {
|
||||
+ ret = true;
|
||||
+ }
|
||||
DPRINTF(("ldap sudoUser netgroup '%s' ... %s", val,
|
||||
ret ? "MATCH!" : "not"), 2 + ((ret) ? 0 : 1));
|
||||
}
|
||||
@@ -652,7 +656,7 @@ sudo_ldap_check_user_netgroup(LDAP *ld,
|
||||
* host match, else false.
|
||||
*/
|
||||
static bool
|
||||
-sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry)
|
||||
+sudo_ldap_check_host(LDAP *ld, LDAPMessage *entry, char *user)
|
||||
{
|
||||
struct berval **bv, **p;
|
||||
char *val;
|
||||
@@ -672,7 +676,7 @@ sudo_ldap_check_host(LDAP *ld, LDAPMessa
|
||||
val = (*p)->bv_val;
|
||||
/* match any or address or netgroup or hostname */
|
||||
if (!strcmp(val, "ALL") || addr_matches(val) ||
|
||||
- netgr_matches(val, user_host, user_shost, NULL) ||
|
||||
+ netgr_matches(val, user_host, user_shost, def_netgroup_tuple ? user : NULL) ||
|
||||
hostname_matches(user_shost, user_host, val))
|
||||
ret = true;
|
||||
DPRINTF(("ldap sudoHost '%s' ... %s", val,
|
||||
@@ -729,7 +733,10 @@ sudo_ldap_check_runas_user(LDAP *ld, LDA
|
||||
val = (*p)->bv_val;
|
||||
switch (val[0]) {
|
||||
case '+':
|
||||
- if (netgr_matches(val, NULL, NULL, runas_pw->pw_name))
|
||||
+ if (netgr_matches(val,
|
||||
+ def_netgroup_tuple ? user_host : NULL,
|
||||
+ def_netgroup_tuple ? user_shost : NULL,
|
||||
+ runas_pw->pw_name))
|
||||
ret = true;
|
||||
break;
|
||||
case '%':
|
||||
@@ -2755,13 +2762,13 @@ sudo_ldap_result_get(struct sudo_nss *ns
|
||||
LDAP_FOREACH(entry, ld, result) {
|
||||
if (do_netgr) {
|
||||
if (sudo_ldap_check_user_netgroup(ld, entry, pw->pw_name) &&
|
||||
- sudo_ldap_check_host(ld, entry)) {
|
||||
+ sudo_ldap_check_host(ld, entry, pw->pw_name)) {
|
||||
lres->host_matches = true;
|
||||
lres->user_matches = true;
|
||||
sudo_ldap_result_add_entry(lres, entry);
|
||||
}
|
||||
} else {
|
||||
- if (sudo_ldap_check_host(ld, entry)) {
|
||||
+ if (sudo_ldap_check_host(ld, entry, pw->pw_name)) {
|
||||
lres->host_matches = true;
|
||||
sudo_ldap_result_add_entry(lres, entry);
|
||||
}
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/match.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/match.c.netgroup_tuple 2016-05-09 15:34:41.062246541 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/match.c 2016-05-09 15:34:41.067246471 +0200
|
||||
@@ -117,7 +117,10 @@ userlist_matches(struct passwd *pw, stru
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case NETGROUP:
|
||||
- if (netgr_matches(m->name, NULL, NULL, pw->pw_name))
|
||||
+ if (netgr_matches(m->name,
|
||||
+ def_netgroup_tuple ? user_host : NULL,
|
||||
+ def_netgroup_tuple ? user_shost : NULL,
|
||||
+ pw->pw_name))
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case USERGROUP:
|
||||
@@ -172,7 +175,10 @@ runaslist_matches(struct member_list *us
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case NETGROUP:
|
||||
- if (netgr_matches(m->name, NULL, NULL, runas_pw->pw_name))
|
||||
+ if (netgr_matches(m->name,
|
||||
+ def_netgroup_tuple ? user_host : NULL,
|
||||
+ def_netgroup_tuple ? user_shost : NULL,
|
||||
+ runas_pw->pw_name))
|
||||
user_matched = !m->negated;
|
||||
break;
|
||||
case USERGROUP:
|
||||
@@ -269,7 +275,7 @@ hostlist_matches(struct member_list *lis
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case NETGROUP:
|
||||
- if (netgr_matches(m->name, user_host, user_shost, NULL))
|
||||
+ if (netgr_matches(m->name, user_host, user_shost, def_netgroup_tuple ? user_name : NULL))
|
||||
matched = !m->negated;
|
||||
break;
|
||||
case NTWKADDR:
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.netgroup_tuple sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.netgroup_tuple 2016-05-09 15:34:41.056246625 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2016-05-09 15:34:41.067246471 +0200
|
||||
@@ -452,7 +452,10 @@ sudo_sss_check_runas_user(struct sudo_ss
|
||||
switch (val[0]) {
|
||||
case '+':
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "netgr_");
|
||||
- if (netgr_matches(val, NULL, NULL, runas_pw->pw_name)) {
|
||||
+ if (netgr_matches(val,
|
||||
+ def_netgroup_tuple ? user_host : NULL,
|
||||
+ def_netgroup_tuple ? user_shost : NULL,
|
||||
+ runas_pw->pw_name)) {
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "=> match");
|
||||
ret = true;
|
||||
}
|
||||
@@ -551,7 +554,7 @@ sudo_sss_check_runas(struct sudo_sss_han
|
||||
debug_return_bool(ret);
|
||||
}
|
||||
|
||||
-static bool sudo_sss_ipa_hostname_matches(const char *hostname_val)
|
||||
+static bool sudo_sss_ipa_hostname_matches(const char *hostname_val, char *user)
|
||||
{
|
||||
bool ret = false;
|
||||
char *ipa_hostname_val;
|
||||
@@ -559,7 +562,7 @@ static bool sudo_sss_ipa_hostname_matche
|
||||
|
||||
if ((ipa_hostname_val = ipa_hostname()) != NULL) {
|
||||
ret = hostname_matches(ipa_hostname_val, ipa_hostname_val, hostname_val) || \
|
||||
- netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, NULL);
|
||||
+ netgr_matches(hostname_val, ipa_hostname_val, ipa_hostname_val, def_netgroup_tuple ? user : NULL);
|
||||
}
|
||||
|
||||
sudo_debug_printf(SUDO_DEBUG_TRACE, "IPA hostname (%s) matches %s => %s",
|
||||
@@ -600,8 +603,9 @@ sudo_sss_check_host(struct sudo_sss_hand
|
||||
|
||||
/* match any or address or netgroup or hostname */
|
||||
if (!strcmp(val, "ALL") || addr_matches(val) ||
|
||||
- sudo_sss_ipa_hostname_matches(val) ||
|
||||
- netgr_matches(val, user_host, user_shost, NULL) ||
|
||||
+ sudo_sss_ipa_hostname_matches(val, handle->pw->pw_name) ||
|
||||
+ netgr_matches(val, user_host, user_shost,
|
||||
+ def_netgroup_tuple ? handle->pw->pw_name : NULL) ||
|
||||
hostname_matches(user_shost, user_host, val))
|
||||
ret = true;
|
||||
|
||||
@@ -649,7 +653,10 @@ bool sudo_sss_filter_sudoUser(struct sud
|
||||
sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val);
|
||||
if (*val == '+') {
|
||||
/* Netgroup spec found, check netgroup membership */
|
||||
- if (netgr_matches(val, NULL, NULL, handle->pw->pw_name)) {
|
||||
+ if (netgr_matches(val,
|
||||
+ def_netgroup_tuple ? user_host : NULL,
|
||||
+ def_netgroup_tuple ? user_shost : NULL,
|
||||
+ handle->pw->pw_name)) {
|
||||
ret = true;
|
||||
sudo_debug_printf(SUDO_DEBUG_DIAG,
|
||||
"sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, handle->pw->pw_name);
|
|
@ -0,0 +1,104 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/match.c.newbase64decoder sudo-1.8.6p7/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/match.c.newbase64decoder 2015-09-01 13:35:42.746241825 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/match.c 2015-09-01 13:40:52.360233611 +0200
|
||||
@@ -510,53 +510,60 @@ command_matches_glob(char *sudoers_cmnd,
|
||||
}
|
||||
|
||||
/*
|
||||
+ * base64 decoder
|
||||
+ * PUBLIC DOMAIN - Jon Mayo - November 13, 2003
|
||||
+ */
|
||||
+static const uint8_t base64dec_tab[256]= {
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
|
||||
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255,
|
||||
+ 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
|
||||
+ 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+ 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
* Decode a NUL-terminated string in base64 format and store the
|
||||
* result in dst.
|
||||
*/
|
||||
size_t
|
||||
-base64_decode(const char *str, unsigned char *dst, size_t dsize)
|
||||
+base64_decode(const char *in, unsigned char *out, size_t out_len)
|
||||
{
|
||||
- static const char b64[] =
|
||||
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
- const unsigned char *dst0 = dst;
|
||||
- const unsigned char *dend = dst + dsize;
|
||||
- unsigned char ch[4];
|
||||
- char *pos;
|
||||
- int i;
|
||||
- debug_decl(base64_decode, SUDO_DEBUG_MATCH)
|
||||
+ size_t in_len = strlen(in);
|
||||
+ size_t ii, io;
|
||||
+ uint_least32_t v;
|
||||
+ size_t rem;
|
||||
|
||||
- /*
|
||||
- * Convert from base64 to binary. Each base64 char holds 6 bits of data
|
||||
- * so 4 base64 chars equals 3 chars of data.
|
||||
- * Padding (with the '=' char) may or may not be present.
|
||||
- */
|
||||
- while (*str != '\0') {
|
||||
- for (i = 0; i < 4; i++) {
|
||||
- switch (*str) {
|
||||
- case '=':
|
||||
- str++;
|
||||
- /* FALLTHROUGH */
|
||||
- case '\0':
|
||||
- ch[i] = '=';
|
||||
- break;
|
||||
- default:
|
||||
- if ((pos = strchr(b64, *str++)) == NULL)
|
||||
- debug_return_size_t((size_t)-1);
|
||||
- ch[i] = (unsigned char)(pos - b64);
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- if (ch[0] == '=' || ch[1] == '=' || dst == dend)
|
||||
- break;
|
||||
- *dst++ = (ch[0] << 2) | ((ch[1] & 0x30) >> 4);
|
||||
- if (ch[2] == '=' || dst == dend)
|
||||
- break;
|
||||
- *dst++ = ((ch[1] & 0x0f) << 4) | ((ch[2] & 0x3c) >> 2);
|
||||
- if (ch[3] == '=' || dst == dend)
|
||||
- break;
|
||||
- *dst++ = ((ch[2] & 0x03) << 6) | ch[3];
|
||||
+ for(io=0,ii=0,v=0,rem=0;ii<in_len;ii++) {
|
||||
+ unsigned char ch;
|
||||
+ if(isspace(in[ii])) continue;
|
||||
+ if(in[ii]=='=') break; /* stop at = */
|
||||
+ ch=base64dec_tab[(size_t)in[ii]];
|
||||
+ if(ch==255) break; /* stop at a parse error */
|
||||
+ v=(v<<6)|ch;
|
||||
+ rem+=6;
|
||||
+ if(rem>=8) {
|
||||
+ rem-=8;
|
||||
+ if(io>=out_len) return -1; /* truncation is failure */
|
||||
+ out[io++]=(v>>rem)&255;
|
||||
}
|
||||
- debug_return_size_t((size_t)(dst - dst0));
|
||||
+ }
|
||||
+ if(rem>=8) {
|
||||
+ rem-=8;
|
||||
+ if(io>=out_len) return -1; /* truncation is failure */
|
||||
+ out[io++]=(v>>rem)&255;
|
||||
+ }
|
||||
+ return io;
|
||||
}
|
||||
|
||||
static bool
|
|
@ -0,0 +1,422 @@
|
|||
diff --git a/config.h.in b/config.h.in
|
||||
index 106af3a..30c3928 100644
|
||||
--- a/config.h.in
|
||||
+++ b/config.h.in
|
||||
@@ -87,6 +87,10 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_H_ERRNO
|
||||
|
||||
+/* Define to 1 if you have the declaration of `SECCOMP_SET_MODE_FILTER', and
|
||||
+ to 0 if you don't. */
|
||||
+#undef HAVE_DECL_SECCOMP_SET_MODE_FILTER
|
||||
+
|
||||
/* Define to 1 if you have the declaration of `sys_sigabbrev', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_SYS_SIGABBREV
|
||||
@@ -134,9 +138,21 @@
|
||||
/* Define to 1 if the compiler supports the __visibility__ attribute. */
|
||||
#undef HAVE_DSO_VISIBILITY
|
||||
|
||||
+/* Define to 1 if you have the `exect' function. */
|
||||
+#undef HAVE_EXECT
|
||||
+
|
||||
+/* Define to 1 if you have the `execvp' function. */
|
||||
+#undef HAVE_EXECVP
|
||||
+
|
||||
+/* Define to 1 if you have the `execvpe' function. */
|
||||
+#undef HAVE_EXECVPE
|
||||
+
|
||||
/* Define to 1 if your system has the F_CLOSEM fcntl. */
|
||||
#undef HAVE_FCNTL_CLOSEM
|
||||
|
||||
+/* Define to 1 if you have the `fexecve' function. */
|
||||
+#undef HAVE_FEXECVE
|
||||
+
|
||||
/* Define to 1 if you have the `fgetln' function. */
|
||||
#undef HAVE_FGETLN
|
||||
|
||||
@@ -421,6 +437,12 @@
|
||||
/* Define to 1 if you have the `posix_openpt' function. */
|
||||
#undef HAVE_POSIX_OPENPT
|
||||
|
||||
+/* Define to 1 if you have the `posix_spawn' function. */
|
||||
+#undef HAVE_POSIX_SPAWN
|
||||
+
|
||||
+/* Define to 1 if you have the `posix_spawnp' function. */
|
||||
+#undef HAVE_POSIX_SPAWNP
|
||||
+
|
||||
/* Define to 1 if you have the `priv_set' function. */
|
||||
#undef HAVE_PRIV_SET
|
||||
|
||||
@@ -703,6 +725,12 @@
|
||||
/* Define to 1 if you have the `vsnprintf' function. */
|
||||
#undef HAVE_VSNPRINTF
|
||||
|
||||
+/* Define to 1 if you have the `wordexp' function. */
|
||||
+#undef HAVE_WORDEXP
|
||||
+
|
||||
+/* Define to 1 if you have the <wordexp.h> header file. */
|
||||
+#undef HAVE_WORDEXP_H
|
||||
+
|
||||
/* Define to 1 if you have the <zlib.h> header file. */
|
||||
#undef HAVE_ZLIB_H
|
||||
|
||||
diff --git a/configure.in b/configure.in
|
||||
index 06b4722..945284e 100644
|
||||
--- a/configure.in
|
||||
+++ b/configure.in
|
||||
@@ -1824,6 +1824,14 @@ case "$host" in
|
||||
shadow_funcs="getspnam"
|
||||
shadow_libs_optional="-lshadow"
|
||||
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
|
||||
+ # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h
|
||||
+ AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER], [], [], [
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/prctl.h>
|
||||
+#include <asm/unistd.h>
|
||||
+#include <linux/seccomp.h>
|
||||
+#include <linux/filter.h>
|
||||
+ ])
|
||||
;;
|
||||
*-convex-bsd*)
|
||||
OSDEFS="${OSDEFS} -D_CONVEX_SOURCE"
|
||||
@@ -2091,7 +2099,7 @@ AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_STDBOOL
|
||||
AC_HEADER_MAJOR
|
||||
-AC_CHECK_HEADERS(malloc.h netgroup.h paths.h spawn.h utime.h utmpx.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h)
|
||||
+AC_CHECK_HEADERS(malloc.h netgroup.h paths.h spawn.h utime.h utmpx.h wordexp.h sys/sockio.h sys/bsdtypes.h sys/select.h sys/stropts.h sys/sysmacros.h)
|
||||
AC_CHECK_HEADERS([procfs.h] [sys/procfs.h], [AC_CHECK_MEMBERS(struct psinfo.pr_ttydev, [AC_CHECK_FUNCS(_ttyname_dev)], [], [AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_PROCFS_H
|
||||
#include <procfs.h>
|
||||
@@ -2226,7 +2234,8 @@ dnl
|
||||
AC_FUNC_GETGROUPS
|
||||
AC_CHECK_FUNCS(glob strrchr sysconf tzset strftime setenv \
|
||||
regcomp setlocale nl_langinfo mbr_check_membership \
|
||||
- setrlimit64)
|
||||
+ setrlimit64 \
|
||||
+ wordexp exect execvp execvpe fexecve posix_spawn posix_spawnp)
|
||||
AC_REPLACE_FUNCS(getgrouplist)
|
||||
AC_CHECK_FUNCS(getline, [], [
|
||||
AC_LIBOBJ(getline)
|
||||
diff --git a/include/missing.h b/include/missing.h
|
||||
index fda151b..cac8088 100644
|
||||
--- a/include/missing.h
|
||||
+++ b/include/missing.h
|
||||
@@ -198,6 +198,13 @@ typedef struct sigaction sigaction_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
+ * The nitems macro may be defined in sys/param.h
|
||||
+ */
|
||||
+#ifndef nitems
|
||||
+# define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
* If dirfd() does not exists, hopefully dd_fd does.
|
||||
*/
|
||||
#if !defined(HAVE_DIRFD) && defined(HAVE_DD_FD)
|
||||
diff --git a/src/Makefile.in b/src/Makefile.in
|
||||
index 918cf04..079aa3e 100644
|
||||
--- a/src/Makefile.in
|
||||
+++ b/src/Makefile.in
|
||||
@@ -109,7 +109,7 @@ sudo: $(OBJS) $(LT_LIBS)
|
||||
$(LIBTOOL) --mode=link $(CC) -o $@ $(OBJS) $(LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS)
|
||||
|
||||
libsudo_noexec.la: sudo_noexec.lo
|
||||
- $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir)
|
||||
+ $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) @LIBDL@ -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir)
|
||||
|
||||
sesh: sesh.o error.o exec_common.o @LIBINTL@ $(LT_LIBS)
|
||||
$(LIBTOOL) --mode=link $(CC) -o $@ sesh.o error.o exec_common.o $(LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) @LIBINTL@ $(LIBS)
|
||||
diff --git a/src/sudo_noexec.c b/src/sudo_noexec.c
|
||||
index 2872501..f04b277 100644
|
||||
--- a/src/sudo_noexec.c
|
||||
+++ b/src/sudo_noexec.c
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
- * Copyright (c) 2004-2005, 2010-2011 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
+ * Copyright (c) 2004-2005, 2010-2016 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
|
||||
@@ -18,20 +18,64 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
+#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
|
||||
+# include <sys/prctl.h>
|
||||
+# include <asm/unistd.h>
|
||||
+# include <linux/filter.h>
|
||||
+# include <linux/seccomp.h>
|
||||
+#endif
|
||||
+
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
#ifdef HAVE_SPAWN_H
|
||||
#include <spawn.h>
|
||||
#endif
|
||||
+#ifdef HAVE_STRING_H
|
||||
+# include <string.h>
|
||||
+#endif /* HAVE_STRING_H */
|
||||
+#ifdef HAVE_STRINGS_H
|
||||
+# include <strings.h>
|
||||
+#endif /* HAVE_STRINGS_H */
|
||||
+#ifdef HAVE_WORDEXP_H
|
||||
+#include <wordexp.h>
|
||||
+#endif
|
||||
+#if defined(HAVE_SHL_LOAD)
|
||||
+# include <dl.h>
|
||||
+#elif defined(HAVE_DLOPEN)
|
||||
+# include <dlfcn.h>
|
||||
+#endif
|
||||
|
||||
#include "missing.h"
|
||||
+#include "pathnames.h"
|
||||
|
||||
+#ifdef HAVE___INTERPOSE
|
||||
/*
|
||||
- * Dummy versions of the execve() family of syscalls. We don't need
|
||||
- * to stub out all of them, just the ones that correspond to actual
|
||||
- * system calls (which varies by OS). Note that it is still possible
|
||||
- * to access the real syscalls via the syscall() interface but very
|
||||
- * few programs actually do that.
|
||||
+ * Mac OS X 10.4 and above has support for library symbol interposition.
|
||||
+ * There is a good explanation of this in the Mac OS X Internals book.
|
||||
+ */
|
||||
+typedef struct interpose_s {
|
||||
+ void *new_func;
|
||||
+ void *orig_func;
|
||||
+} interpose_t;
|
||||
+
|
||||
+# define FN_NAME(fn) dummy_ ## fn
|
||||
+# define INTERPOSE(fn) \
|
||||
+ __attribute__((__used__)) static const interpose_t interpose_ ## fn \
|
||||
+ __attribute__((__section__("__DATA,__interpose"))) = \
|
||||
+ { (void *)dummy_ ## fn, (void *)fn };
|
||||
+#else
|
||||
+# define FN_NAME(fn) fn
|
||||
+# define INTERPOSE(fn)
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * Dummy versions of the exec(3) family of syscalls. It is not enough to
|
||||
+ * just dummy out execve(2) since many C libraries do not call the public
|
||||
+ * execve(2) interface. Note that it is still possible to access the real
|
||||
+ * syscalls via the syscall(2) interface, but that is rarely done.
|
||||
*/
|
||||
|
||||
#define DUMMY_BODY \
|
||||
@@ -40,61 +84,172 @@
|
||||
return -1; \
|
||||
}
|
||||
|
||||
+#define DUMMY1(fn, t1) \
|
||||
+__dso_public int \
|
||||
+FN_NAME(fn)(t1 a1) \
|
||||
+DUMMY_BODY \
|
||||
+INTERPOSE(fn)
|
||||
+
|
||||
#define DUMMY2(fn, t1, t2) \
|
||||
__dso_public int \
|
||||
-fn(t1 a1, t2 a2) \
|
||||
-DUMMY_BODY
|
||||
+FN_NAME(fn)(t1 a1, t2 a2) \
|
||||
+DUMMY_BODY \
|
||||
+INTERPOSE(fn)
|
||||
|
||||
#define DUMMY3(fn, t1, t2, t3) \
|
||||
__dso_public int \
|
||||
-fn(t1 a1, t2 a2, t3 a3) \
|
||||
-DUMMY_BODY
|
||||
+FN_NAME(fn)(t1 a1, t2 a2, t3 a3) \
|
||||
+DUMMY_BODY \
|
||||
+INTERPOSE(fn)
|
||||
|
||||
#define DUMMY6(fn, t1, t2, t3, t4, t5, t6) \
|
||||
__dso_public int \
|
||||
-fn(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
|
||||
-DUMMY_BODY
|
||||
+FN_NAME(fn)(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \
|
||||
+DUMMY_BODY \
|
||||
+INTERPOSE(fn)
|
||||
|
||||
#define DUMMY_VA(fn, t1, t2) \
|
||||
__dso_public int \
|
||||
-fn(t1 a1, t2 a2, ...) \
|
||||
-DUMMY_BODY
|
||||
+FN_NAME(fn)(t1 a1, t2 a2, ...) \
|
||||
+DUMMY_BODY \
|
||||
+INTERPOSE(fn)
|
||||
|
||||
+/*
|
||||
+ * Standard exec(3) family of functions.
|
||||
+ */
|
||||
DUMMY_VA(execl, const char *, const char *)
|
||||
-DUMMY_VA(_execl, const char *, const char *)
|
||||
-DUMMY_VA(__execl, const char *, const char *)
|
||||
DUMMY_VA(execle, const char *, const char *)
|
||||
-DUMMY_VA(_execle, const char *, const char *)
|
||||
-DUMMY_VA(__execle, const char *, const char *)
|
||||
DUMMY_VA(execlp, const char *, const char *)
|
||||
-DUMMY_VA(_execlp, const char *, const char *)
|
||||
-DUMMY_VA(__execlp, const char *, const char *)
|
||||
-DUMMY3(exect, const char *, char * const *, char * const *)
|
||||
-DUMMY3(_exect, const char *, char * const *, char * const *)
|
||||
-DUMMY3(__exect, const char *, char * const *, char * const *)
|
||||
DUMMY2(execv, const char *, char * const *)
|
||||
-DUMMY2(_execv, const char *, char * const *)
|
||||
-DUMMY2(__execv, const char *, char * const *)
|
||||
DUMMY2(execvp, const char *, char * const *)
|
||||
-DUMMY2(_execvp, const char *, char * const *)
|
||||
-DUMMY2(__execvp, const char *, char * const *)
|
||||
-DUMMY3(execvP, const char *, const char *, char * const *)
|
||||
-DUMMY3(_execvP, const char *, const char *, char * const *)
|
||||
-DUMMY3(__execvP, const char *, const char *, char * const *)
|
||||
DUMMY3(execve, const char *, char * const *, char * const *)
|
||||
-DUMMY3(_execve, const char *, char * const *, char * const *)
|
||||
-DUMMY3(__execve, const char *, char * const *, char * const *)
|
||||
+
|
||||
+/*
|
||||
+ * Non-standard exec(3) functions and corresponding private versions.
|
||||
+ */
|
||||
+#ifdef HAVE_EXECVP
|
||||
+DUMMY3(execvP, const char *, const char *, char * const *)
|
||||
+#endif
|
||||
+#ifdef HAVE_EXECVPE
|
||||
DUMMY3(execvpe, const char *, char * const *, char * const *)
|
||||
-DUMMY3(_execvpe, const char *, char * const *, char * const *)
|
||||
-DUMMY3(__execvpe, const char *, char * const *, char * const *)
|
||||
+#endif
|
||||
+#ifdef HAVE_EXECT
|
||||
+DUMMY3(exect, const char *, char * const *, char * const *)
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * Not all systems support fexecve(2), posix_spawn(2) and posix_spawnp(2).
|
||||
+ */
|
||||
+#ifdef HAVE_FEXECVE
|
||||
DUMMY3(fexecve, int , char * const *, char * const *)
|
||||
-DUMMY3(_fexecve, int , char * const *, char * const *)
|
||||
-DUMMY3(__fexecve, int , char * const *, char * const *)
|
||||
-#ifdef HAVE_SPAWN_H
|
||||
+#endif
|
||||
+#ifdef HAVE_POSIX_SPAWN
|
||||
DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
|
||||
-DUMMY6(_posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
|
||||
-DUMMY6(__posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
|
||||
+#endif
|
||||
+#ifdef HAVE_POSIX_SPAWNP
|
||||
DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
|
||||
-DUMMY6(_posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
|
||||
-DUMMY6(__posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *)
|
||||
-#endif /* HAVE_SPAWN_H */
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * system(3) and popen(3).
|
||||
+ * We can't use a wrapper for popen since it returns FILE *, not int.
|
||||
+ */
|
||||
+DUMMY1(system, const char *)
|
||||
+
|
||||
+__dso_public FILE *
|
||||
+FN_NAME(popen)(const char *c, const char *t)
|
||||
+{
|
||||
+ errno = EACCES;
|
||||
+ return NULL;
|
||||
+}
|
||||
+INTERPOSE(popen)
|
||||
+
|
||||
+#if defined(HAVE_WORDEXP) && (defined(RTLD_NEXT) || defined(HAVE_SHL_LOAD) || defined(HAVE___INTERPOSE))
|
||||
+/*
|
||||
+ * We can't use a wrapper for wordexp(3) since we still want to call
|
||||
+ * the real wordexp(3) but with WRDE_NOCMD added to the flags argument.
|
||||
+ */
|
||||
+typedef int (*sudo_fn_wordexp_t)(const char *, wordexp_t *, int);
|
||||
+
|
||||
+__dso_public int
|
||||
+FN_NAME(wordexp)(const char *words, wordexp_t *we, int flags)
|
||||
+{
|
||||
+#if defined(HAVE___INTERPOSE)
|
||||
+ return wordexp(words, we, flags | WRDE_NOCMD);
|
||||
+#else
|
||||
+# if defined(HAVE_DLOPEN)
|
||||
+ void *fn = dlsym(RTLD_NEXT, "wordexp");
|
||||
+# elif defined(HAVE_SHL_LOAD)
|
||||
+ const char *name, *myname = _PATH_SUDO_NOEXEC;
|
||||
+ struct shl_descriptor *desc;
|
||||
+ void *fn = NULL;
|
||||
+ int idx = 0;
|
||||
+
|
||||
+ name = strrchr(myname, '/');
|
||||
+ if (name != NULL)
|
||||
+ myname = name + 1;
|
||||
+
|
||||
+ /* Search for wordexp() but skip this shared object. */
|
||||
+ while (shl_get(idx++, &desc) == 0) {
|
||||
+ name = strrchr(desc->filename, '/');
|
||||
+ if (name == NULL)
|
||||
+ name = desc->filename;
|
||||
+ else
|
||||
+ name++;
|
||||
+ if (strcmp(name, myname) == 0)
|
||||
+ continue;
|
||||
+ if (shl_findsym(&desc->handle, "wordexp", TYPE_PROCEDURE, &fn) == 0)
|
||||
+ break;
|
||||
+ }
|
||||
+# else
|
||||
+ void *fn = NULL;
|
||||
+# endif
|
||||
+ if (fn == NULL) {
|
||||
+ errno = EACCES;
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return ((sudo_fn_wordexp_t)fn)(words, we, flags | WRDE_NOCMD);
|
||||
+#endif /* HAVE___INTERPOSE */
|
||||
+}
|
||||
+INTERPOSE(wordexp)
|
||||
+#endif /* HAVE_WORDEXP && (RTLD_NEXT || HAVE_SHL_LOAD || HAVE___INTERPOSE) */
|
||||
+
|
||||
+/*
|
||||
+ * On Linux we can use a seccomp() filter to disable exec.
|
||||
+ */
|
||||
+#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
|
||||
+
|
||||
+/* Older systems may not support execveat(2). */
|
||||
+#ifndef __NR_execveat
|
||||
+# define __NR_execveat -1
|
||||
+#endif
|
||||
+
|
||||
+static void noexec_ctor(void) __attribute__((constructor));
|
||||
+
|
||||
+static void
|
||||
+noexec_ctor(void)
|
||||
+{
|
||||
+ struct sock_filter exec_filter[] = {
|
||||
+ /* Load syscall number into the accumulator */
|
||||
+ BPF_STMT(BPF_LD | BPF_ABS, offsetof(struct seccomp_data, nr)),
|
||||
+ /* Jump to deny for execve/execveat */
|
||||
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execve, 2, 0),
|
||||
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, __NR_execveat, 1, 0),
|
||||
+ /* Allow non-matching syscalls */
|
||||
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW),
|
||||
+ /* Deny execve/execveat syscall */
|
||||
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (EACCES & SECCOMP_RET_DATA))
|
||||
+ };
|
||||
+ const struct sock_fprog exec_fprog = {
|
||||
+ nitems(exec_filter),
|
||||
+ exec_filter
|
||||
+ };
|
||||
+
|
||||
+ /*
|
||||
+ * SECCOMP_MODE_FILTER will fail unless the process has
|
||||
+ * CAP_SYS_ADMIN or the no_new_privs bit is set.
|
||||
+ */
|
||||
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0)
|
||||
+ (void)prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &exec_fprog);
|
||||
+}
|
||||
+#endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */
|
|
@ -0,0 +1,48 @@
|
|||
diff -up sudo-1.8.6p7/src/exec.c.nproc-nowait sudo-1.8.6p7/src/exec.c
|
||||
--- sudo-1.8.6p7/src/exec.c.nproc-nowait 2016-05-11 12:56:58.694022525 +0200
|
||||
+++ sudo-1.8.6p7/src/exec.c 2016-05-11 12:56:58.759021618 +0200
|
||||
@@ -298,6 +298,7 @@ sudo_execute(struct command_details *det
|
||||
*/
|
||||
if (details->flags & CD_DONTWAIT) {
|
||||
if (exec_setup(details, NULL, -1) == true) {
|
||||
+ restore_nproc();
|
||||
/* headed for execve() */
|
||||
sudo_debug_execve(SUDO_DEBUG_INFO, details->command,
|
||||
details->argv, details->envp);
|
||||
diff -up sudo-1.8.6p7/src/sudo.c.nproc-nowait sudo-1.8.6p7/src/sudo.c
|
||||
--- sudo-1.8.6p7/src/sudo.c.nproc-nowait 2016-05-11 12:56:58.758021632 +0200
|
||||
+++ sudo-1.8.6p7/src/sudo.c 2016-05-11 13:12:21.833116202 +0200
|
||||
@@ -145,6 +145,7 @@ static struct rlimit corelimit;
|
||||
#endif /* RLIMIT_CORE */
|
||||
#if defined(__linux__)
|
||||
static struct rlimit nproclimit;
|
||||
+static struct rlimit orig_nproc_limit;
|
||||
#endif
|
||||
|
||||
int
|
||||
@@ -853,6 +854,17 @@ unlimit_nproc(void)
|
||||
debug_return;
|
||||
}
|
||||
|
||||
+void restore_nproc(void)
|
||||
+{
|
||||
+ debug_decl(restore_nproc, SUDO_DEBUG_EXEC);
|
||||
+#if defined(__linux__)
|
||||
+ if (setrlimit(RLIMIT_NPROC, &orig_nproc_limit) != 0) {
|
||||
+ errorx(1, _("Cannot restore nproc rlimit: errno=%d"), errno);
|
||||
+ }
|
||||
+#endif
|
||||
+ debug_return;
|
||||
+}
|
||||
+
|
||||
#ifdef HAVE_PROJECT_H
|
||||
static void
|
||||
set_project(struct passwd *pw)
|
||||
@@ -1089,6 +1101,7 @@ exec_setup(struct command_details *detai
|
||||
*/
|
||||
#if defined(__linux__) && defined(_SC_CHILD_MAX)
|
||||
{
|
||||
+ getrlimit(RLIMIT_NPROC, &orig_nproc_limit);
|
||||
struct rlimit rl;
|
||||
long l;
|
||||
errno = 0;
|
|
@ -0,0 +1,13 @@
|
|||
diff -up sudo-1.8.6p7/src/sudo.c.null_exception sudo-1.8.6p7/src/sudo.c
|
||||
--- sudo-1.8.6p7/src/sudo.c.null_exception 2016-05-11 10:39:56.466888652 +0200
|
||||
+++ sudo-1.8.6p7/src/sudo.c 2016-05-11 10:39:56.530887742 +0200
|
||||
@@ -483,6 +483,9 @@ get_user_info(struct user_details *ud)
|
||||
errorx(1, _("unable to allocate memory"));
|
||||
ud->cwd = user_info[i] + sizeof("cwd=") - 1;
|
||||
}
|
||||
+ else {
|
||||
+ errorx(1, _("unable to resolve current working directory"));
|
||||
+ }
|
||||
|
||||
if ((cp = get_process_ttyname()) != NULL) {
|
||||
user_info[++i] = fmt_string("tty", cp);
|
|
@ -0,0 +1,221 @@
|
|||
diff -up sudo-1.8.6p7/configure.in.pam_servicebackport sudo-1.8.6p7/configure.in
|
||||
--- sudo-1.8.6p7/configure.in.pam_servicebackport 2016-05-09 15:36:30.213715598 +0200
|
||||
+++ sudo-1.8.6p7/configure.in 2016-05-09 15:36:30.237715261 +0200
|
||||
@@ -121,6 +121,7 @@ AC_SUBST([nsswitch_conf])
|
||||
AC_SUBST([netsvc_conf])
|
||||
AC_SUBST([secure_path])
|
||||
AC_SUBST([editor])
|
||||
+AC_SUBST([pam_login_service])
|
||||
#
|
||||
# Begin initial values for man page substitution
|
||||
#
|
||||
@@ -160,6 +161,7 @@ netsvc_conf=/etc/netsvc.conf
|
||||
noexec_file=/usr/local/libexec/sudo_noexec.so
|
||||
nsswitch_conf=/etc/nsswitch.conf
|
||||
secure_path="not set"
|
||||
+pam_login_service=sudo
|
||||
#
|
||||
# End initial values for man page substitution
|
||||
#
|
||||
@@ -2717,6 +2719,7 @@ if test ${with_pam-"no"} != "no"; then
|
||||
yes) AC_DEFINE([HAVE_PAM_LOGIN])
|
||||
AC_MSG_CHECKING(whether to use PAM login)
|
||||
AC_MSG_RESULT(yes)
|
||||
+ pam_login_service="sudo-i"
|
||||
;;
|
||||
no) ;;
|
||||
*) AC_MSG_ERROR(["--with-pam-login does not take an argument."])
|
||||
diff -up sudo-1.8.6p7/configure.pam_servicebackport sudo-1.8.6p7/configure
|
||||
--- sudo-1.8.6p7/configure.pam_servicebackport 2013-02-25 20:48:02.000000000 +0100
|
||||
+++ sudo-1.8.6p7/configure 2016-05-09 15:36:30.238715247 +0200
|
||||
@@ -658,6 +658,7 @@ OBJEXT
|
||||
EXEEXT
|
||||
ac_ct_CC
|
||||
CC
|
||||
+pam_login_service
|
||||
editor
|
||||
secure_path
|
||||
netsvc_conf
|
||||
@@ -2959,6 +2960,7 @@ netsvc_conf=/etc/netsvc.conf
|
||||
noexec_file=/usr/local/libexec/sudo_noexec.so
|
||||
nsswitch_conf=/etc/nsswitch.conf
|
||||
secure_path="not set"
|
||||
+pam_login_service=sudo
|
||||
#
|
||||
# End initial values for man page substitution
|
||||
#
|
||||
@@ -18631,6 +18633,7 @@ if test "${with_pam_login+set}" = set; t
|
||||
$as_echo_n "checking whether to use PAM login... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }
|
||||
+ pam_login_service="sudo-i"
|
||||
;;
|
||||
no) ;;
|
||||
*) as_fn_error $? "\"--with-pam-login does not take an argument.\"" "$LINENO" 5
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.cat.pam_servicebackport sudo-1.8.6p7/doc/sudoers.cat
|
||||
--- sudo-1.8.6p7/doc/sudoers.cat.pam_servicebackport 2016-05-09 15:36:30.222715472 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.cat 2016-05-09 15:36:30.239715233 +0200
|
||||
@@ -1245,6 +1245,18 @@ SSUUDDOOEERRSS OOPPTTIIOONN
|
||||
noexec file should now be set in the _/_e_t_c_/_s_u_d_o_._c_o_n_f
|
||||
file.
|
||||
|
||||
+ pam_login_service
|
||||
+ On systems that use PAM for authentication, this is the
|
||||
+ service name used when the -^H-i^Hi option is specified. The
|
||||
+ default value is ``sudo''. See the description of
|
||||
+ _^Hp_^Ha_^Hm_^H__^Hs_^He_^Hr_^Hv_^Hi_^Hc_^He for more information.
|
||||
+
|
||||
+ pam_service On systems that use PAM for authentication, the service
|
||||
+ name specifies the PAM policy to apply. This usually
|
||||
+ corresponds to an entry in the _^Hp_^Ha_^Hm_^H._^Hc_^Ho_^Hn_^Hf file or a fi
|
||||
+ in the _^H/_^He_^Ht_^Hc_^H/_^Hp_^Ha_^Hm_^H._^Hd directory. The default valu
|
||||
+ ``sudo''.
|
||||
+
|
||||
passprompt The default prompt to use when asking for a password;
|
||||
can be overridden via the --pp option or the SUDO_PROMPT
|
||||
environment variable. The following percent (`%')
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.man.in.pam_servicebackport sudo-1.8.6p7/doc/sudoers.man.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.man.in.pam_servicebackport 2016-05-09 15:36:30.223715458 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.man.in 2016-05-09 15:36:30.239715233 +0200
|
||||
@@ -2628,6 +2628,29 @@ The path to the noexec file should now b
|
||||
\fI@sysconfdir@/sudo.conf\fR
|
||||
file.
|
||||
.TP 18n
|
||||
+pam_login_service
|
||||
+.br
|
||||
+On systems that use PAM for authentication, this is the service
|
||||
+name used when the
|
||||
+\fB\-i\fR
|
||||
+option is specified.
|
||||
+The default value is
|
||||
+``\fR@pam_login_service@\fR''.
|
||||
+See the description of
|
||||
+\fIpam_service\fR
|
||||
+for more information.
|
||||
+.TP 18n
|
||||
+pam_service
|
||||
+On systems that use PAM for authentication, the service name
|
||||
+specifies the PAM policy to apply.
|
||||
+This usually corresponds to an entry in the
|
||||
+\fIpam.conf\fR
|
||||
+file or a file in the
|
||||
+\fI/etc/pam.d\fR
|
||||
+directory.
|
||||
+The default value is
|
||||
+``\fRsudo\fR''.
|
||||
+.TP 18n
|
||||
passprompt
|
||||
The default prompt to use when asking for a password; can be overridden via the
|
||||
\fB\-p\fR
|
||||
diff -up sudo-1.8.6p7/doc/sudoers.mdoc.in.pam_servicebackport sudo-1.8.6p7/doc/sudoers.mdoc.in
|
||||
--- sudo-1.8.6p7/doc/sudoers.mdoc.in.pam_servicebackport 2016-05-09 15:36:30.223715458 +0200
|
||||
+++ sudo-1.8.6p7/doc/sudoers.mdoc.in 2016-05-09 15:36:30.240715219 +0200
|
||||
@@ -2464,6 +2464,26 @@ This option is no longer supported.
|
||||
The path to the noexec file should now be set in the
|
||||
.Pa @sysconfdir@/sudo.conf
|
||||
file.
|
||||
+.It pam_login_service
|
||||
+On systems that use PAM for authentication, this is the service
|
||||
+name used when the
|
||||
+.Fl i
|
||||
+option is specified.
|
||||
+The default value is
|
||||
+.Dq Li @pam_login_service@ .
|
||||
+See the description of
|
||||
+.Em pam_service
|
||||
+for more information.
|
||||
+.It pam_service
|
||||
+On systems that use PAM for authentication, the service name
|
||||
+specifies the PAM policy to apply.
|
||||
+This usually corresponds to an entry in the
|
||||
+.Pa pam.conf
|
||||
+file or a file in the
|
||||
+.Pa /etc/pam.d
|
||||
+directory.
|
||||
+The default value is
|
||||
+.Dq Li sudo .
|
||||
.It passprompt
|
||||
The default prompt to use when asking for a password; can be overridden via the
|
||||
.Fl p
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/auth/pam.c.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/auth/pam.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/auth/pam.c.pam_servicebackport 2016-05-09 15:36:30.202715752 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/auth/pam.c 2016-05-09 15:36:30.240715219 +0200
|
||||
@@ -90,12 +90,8 @@ sudo_pam_init(struct passwd *pw, sudo_au
|
||||
if (auth != NULL)
|
||||
auth->data = (void *) &pam_status;
|
||||
pam_conv.conv = converse;
|
||||
-#ifdef HAVE_PAM_LOGIN
|
||||
- if (ISSET(sudo_mode, MODE_LOGIN_SHELL))
|
||||
- pam_status = pam_start("sudo-i", pw->pw_name, &pam_conv, &pamh);
|
||||
- else
|
||||
-#endif
|
||||
- pam_status = pam_start("sudo", pw->pw_name, &pam_conv, &pamh);
|
||||
+ pam_status = pam_start(ISSET(sudo_mode, MODE_LOGIN_SHELL) ?
|
||||
+ def_pam_login_service : def_pam_service, pw->pw_name, &pam_conv, &pamh);
|
||||
if (pam_status != PAM_SUCCESS) {
|
||||
log_error(USE_ERRNO|NO_MAIL, _("unable to initialize PAM"));
|
||||
debug_return_int(AUTH_FATAL);
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/defaults.c.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/defaults.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/defaults.c.pam_servicebackport 2016-05-09 15:36:30.234715304 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/defaults.c 2016-05-09 15:36:30.240715219 +0200
|
||||
@@ -424,6 +424,13 @@ init_defaults(void)
|
||||
def_env_reset = ENV_RESET;
|
||||
def_set_logname = true;
|
||||
def_closefrom = STDERR_FILENO + 1;
|
||||
+ def_pam_service = estrdup("sudo");
|
||||
+#ifdef HAVE_PAM_LOGIN
|
||||
+ def_pam_login_service = estrdup("sudo-i");
|
||||
+#else
|
||||
+ def_pam_login_service = estrdup("sudo");
|
||||
+#endif
|
||||
+
|
||||
|
||||
/* Syslog options need special care since they both strings and ints */
|
||||
#if (LOGGING & SLOG_SYSLOG)
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.c.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/def_data.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.c.pam_servicebackport 2016-05-09 15:36:30.234715304 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.c 2016-05-09 15:36:30.240715219 +0200
|
||||
@@ -363,6 +363,14 @@ struct sudo_defs_types sudo_defs_table[]
|
||||
N_("Use both user and host/domain fields when matching netgroups"),
|
||||
NULL,
|
||||
}, {
|
||||
+ "pam_service", T_STR,
|
||||
+ N_("PAM service name to use"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
+ "pam_login_service", T_STR,
|
||||
+ N_("PAM service name to use for login shells"),
|
||||
+ NULL,
|
||||
+ }, {
|
||||
NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.h.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/def_data.h
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.h.pam_servicebackport 2016-05-09 15:36:30.235715289 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.h 2016-05-09 15:36:30.240715219 +0200
|
||||
@@ -168,6 +168,11 @@
|
||||
#define I_LEGACY_GROUP_PROCESSING 83
|
||||
#define def_netgroup_tuple (sudo_defs_table[84].sd_un.flag)
|
||||
#define I_NETGROUP_TUPLE 84
|
||||
+#define def_pam_service (sudo_defs_table[85].sd_un.str)
|
||||
+#define I_PAM_SERVICE 85
|
||||
+#define def_pam_login_service (sudo_defs_table[86].sd_un.str)
|
||||
+#define I_PAM_LOGIN_SERVICE 86
|
||||
+
|
||||
|
||||
enum def_tuple {
|
||||
never,
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/def_data.in.pam_servicebackport sudo-1.8.6p7/plugins/sudoers/def_data.in
|
||||
--- sudo-1.8.6p7/plugins/sudoers/def_data.in.pam_servicebackport 2013-02-25 20:42:44.000000000 +0100
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/def_data.in 2016-05-09 15:36:30.240715219 +0200
|
||||
@@ -259,3 +259,10 @@ privs
|
||||
limitprivs
|
||||
T_STR
|
||||
"Set of limit privileges"
|
||||
+pam_service
|
||||
+ T_STR
|
||||
+ "PAM service name to use"
|
||||
+pam_login_service
|
||||
+ T_STR
|
||||
+ "PAM service name to use for login shells"
|
||||
+
|
|
@ -0,0 +1,13 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/match.c.segfault-null-group-list sudo-1.8.6p7/plugins/sudoers/match.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/match.c.segfault-null-group-list 2016-05-11 10:22:29.201786896 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/match.c 2016-05-11 10:22:29.212786739 +0200
|
||||
@@ -164,6 +164,9 @@ runaslist_matches(struct member_list *us
|
||||
int group_matched = UNSPEC;
|
||||
debug_decl(runaslist_matches, SUDO_DEBUG_MATCH)
|
||||
|
||||
+ if (user_list == NULL)user_list = ∅
|
||||
+ if (group_list == NULL)group_list = ∅
|
||||
+
|
||||
if (runas_pw != NULL) {
|
||||
/* If no runas user or runas group listed in sudoers, use default. */
|
||||
if (tq_empty(user_list) && tq_empty(group_list))
|
|
@ -0,0 +1,12 @@
|
|||
diff -up sudo-1.8.6p7/src/sesh.c.sesh_loginshell sudo-1.8.6p7/src/sesh.c
|
||||
--- sudo-1.8.6p7/src/sesh.c.sesh_loginshell 2014-02-26 12:37:59.735214882 +0100
|
||||
+++ sudo-1.8.6p7/src/sesh.c 2014-02-26 12:38:05.535235487 +0100
|
||||
@@ -214,6 +214,8 @@ cleanup_0:
|
||||
if (argv[-1][0] == '-') {
|
||||
if ((cp = strrchr(argv[0], '/')) == NULL)
|
||||
cp = argv[0];
|
||||
+ else
|
||||
+ argv[0] = cp;
|
||||
*cp = '-';
|
||||
}
|
||||
sudo_execve(cmnd, argv, envp, noexec);
|
|
@ -0,0 +1,137 @@
|
|||
diff -up sudo-1.8.6p7/common/Makefile.in.strunquote sudo-1.8.6p7/common/Makefile.in
|
||||
--- sudo-1.8.6p7/common/Makefile.in.strunquote 2013-02-25 20:46:09.000000000 +0100
|
||||
+++ sudo-1.8.6p7/common/Makefile.in 2015-07-07 14:30:09.267181200 +0200
|
||||
@@ -63,7 +63,7 @@ SHELL = @SHELL@
|
||||
|
||||
LTOBJS = alloc.lo atobool.lo fileops.lo fmt_string.lo lbuf.lo list.lo \
|
||||
secure_path.lo setgroups.lo sudo_conf.lo sudo_debug.lo term.lo \
|
||||
- ttysize.lo zero_bytes.lo @COMMON_OBJS@
|
||||
+ ttysize.lo zero_bytes.lo strunquote.lo @COMMON_OBJS@
|
||||
|
||||
all: libcommon.la
|
||||
|
||||
@@ -164,3 +164,6 @@ ttysize.lo: $(srcdir)/ttysize.c $(top_bu
|
||||
zero_bytes.lo: $(srcdir)/zero_bytes.c $(top_builddir)/config.h \
|
||||
$(incdir)/missing.h
|
||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/zero_bytes.c
|
||||
+strunquote.lo: $(srcdir)/strunquote.c $(top_builddir)/config.h \
|
||||
+ $(incdir)/missing.h
|
||||
+ $(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strunquote.c
|
||||
diff -up sudo-1.8.6p7/common/strunquote.c.strunquote sudo-1.8.6p7/common/strunquote.c
|
||||
--- sudo-1.8.6p7/common/strunquote.c.strunquote 2015-07-07 14:30:09.267181200 +0200
|
||||
+++ sudo-1.8.6p7/common/strunquote.c 2015-07-07 14:31:05.403649285 +0200
|
||||
@@ -0,0 +1,45 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Daniel Kopecek <dkopecek@redhat.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.
|
||||
+ */
|
||||
+#include <string.h>
|
||||
+#include <ctype.h>
|
||||
+
|
||||
+char *strunquote(char *arg)
|
||||
+{
|
||||
+ char *str = arg;
|
||||
+ if (str == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ const size_t len = strlen(str);
|
||||
+ char *strend = str + len - 1;
|
||||
+
|
||||
+ /* Remove blanks */
|
||||
+ for (; isblank((unsigned char)*str); str++);
|
||||
+ for (; isblank((unsigned char)*strend) && strend > str; strend--);
|
||||
+ /*
|
||||
+ * Check that the string is double-quoted.
|
||||
+ * If not, we are done.
|
||||
+ */
|
||||
+ if (*str != '"' || *strend != '"' || str == strend) {
|
||||
+ /* Return the original argument if we didn't touch it */
|
||||
+ return arg;
|
||||
+ }
|
||||
+
|
||||
+ /* Remove the double-quotes */
|
||||
+ *strend = '\0';
|
||||
+ ++str;
|
||||
+
|
||||
+ return str;
|
||||
+}
|
||||
diff -up sudo-1.8.6p7/include/strunquote.h.strunquote sudo-1.8.6p7/include/strunquote.h
|
||||
--- sudo-1.8.6p7/include/strunquote.h.strunquote 2015-07-07 14:30:09.267181200 +0200
|
||||
+++ sudo-1.8.6p7/include/strunquote.h 2015-07-07 14:30:09.267181200 +0200
|
||||
@@ -0,0 +1,17 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2015 Daniel Kopecek <dkopecek@redhat.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.
|
||||
+ */
|
||||
+
|
||||
+char *strunquote(char *arg);
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.strunquote sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.strunquote 2015-07-07 14:30:09.259181276 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2015-07-07 14:30:09.267181200 +0200
|
||||
@@ -79,6 +79,7 @@
|
||||
#include "sudoers.h"
|
||||
#include "parse.h"
|
||||
#include "lbuf.h"
|
||||
+#include "strunquote.h"
|
||||
|
||||
/* Older Netscape LDAP SDKs don't prototype ldapssl_set_strength() */
|
||||
#if defined(HAVE_LDAPSSL_SET_STRENGTH) && !defined(HAVE_LDAP_SSL_H) && !defined(HAVE_MPS_LDAP_SSL_H)
|
||||
@@ -1004,10 +1005,10 @@ sudo_ldap_parse_options(LDAP *ld, LDAPMe
|
||||
if (op == '+' || op == '-') {
|
||||
*(val - 2) = '\0'; /* found, remove extra char */
|
||||
/* case var+=val or var-=val */
|
||||
- set_default(var, val, (int) op);
|
||||
+ set_default(var, strunquote(val), (int) op);
|
||||
} else {
|
||||
/* case var=val */
|
||||
- set_default(var, val, true);
|
||||
+ set_default(var, strunquote(val), true);
|
||||
}
|
||||
} else if (*var == '!') {
|
||||
/* case !var Boolean False */
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.strunquote sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.strunquote 2015-07-07 14:30:09.260181267 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2015-07-07 14:30:09.268181191 +0200
|
||||
@@ -61,6 +61,7 @@
|
||||
#include "lbuf.h"
|
||||
#include "sudo_debug.h"
|
||||
#include "ipa_hostname.h"
|
||||
+#include "strunquote.h"
|
||||
|
||||
/* SSSD <--> SUDO interface - do not change */
|
||||
struct sss_sudo_attr {
|
||||
@@ -996,10 +997,10 @@ sudo_sss_parse_options(struct sudo_sss_h
|
||||
if (op == '+' || op == '-') {
|
||||
*(val - 2) = '\0'; /* found, remove extra char */
|
||||
/* case var+=val or var-=val */
|
||||
- set_default(v, val, (int) op);
|
||||
+ set_default(v, strunquote(val), (int) op);
|
||||
} else {
|
||||
/* case var=val */
|
||||
- set_default(v, val, true);
|
||||
+ set_default(v, strunquote(val), true);
|
||||
}
|
||||
} else if (*v == '!') {
|
||||
/* case !var Boolean False */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
From 447b3f0c91f019c1d30b5703c61316b583f5bce1 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Sykora <tosykora@redhat.com>
|
||||
Date: Mon, 15 Aug 2016 15:15:40 +0200
|
||||
Subject: [PATCH] RHEL7 failed RPMdiff testing
|
||||
|
||||
Package sudo-1.8.3p1-7.el7 failed RHEL7 RPMdiff testing
|
||||
|
||||
Rebased from:
|
||||
Patch16: sudo-1.8.6p7-sudoldapconfman.patch
|
||||
|
||||
Resolves:
|
||||
rhbz#881258
|
||||
---
|
||||
doc/Makefile.in | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doc/Makefile.in b/doc/Makefile.in
|
||||
index a6f2ea2..e27c6e0 100644
|
||||
--- a/doc/Makefile.in
|
||||
+++ b/doc/Makefile.in
|
||||
@@ -319,10 +319,16 @@ install-doc: install-dirs
|
||||
rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
|
||||
echo ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
|
||||
ln -s sudo.$(mansectsu)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu)$(MANCOMPRESSEXT); \
|
||||
+ rm -f $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \
|
||||
+ echo ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \
|
||||
+ ln -s sudoers.ldap.$(mansectform)$(MANCOMPRESSEXT) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)$(MANCOMPRESSEXT); \
|
||||
else \
|
||||
rm -f $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
|
||||
echo ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
|
||||
ln -s sudo.$(mansectsu) $(DESTDIR)$(mandirsu)/sudoedit.$(mansectsu); \
|
||||
+ rm -f $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \
|
||||
+ echo ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \
|
||||
+ ln -s sudoers.ldap.$(mansectform) $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform); \
|
||||
fi
|
||||
|
||||
install-plugin:
|
||||
@@ -336,7 +342,8 @@ uninstall:
|
||||
$(DESTDIR)$(mandirsu)/visudo.$(mansectsu) \
|
||||
$(DESTDIR)$(mandirform)/sudo.conf.$(mansectform) \
|
||||
$(DESTDIR)$(mandirform)/sudoers.$(mansectform) \
|
||||
- $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform)
|
||||
+ $(DESTDIR)$(mandirform)/sudoers.ldap.$(mansectform) \
|
||||
+ $(DESTDIR)$(mandirform)/sudo-ldap.conf.$(mansectform)
|
||||
|
||||
splint:
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
diff -up sudo-1.8.6p7/src/ttyname.c.get_process_ttyname sudo-1.8.6p7/src/ttyname.c
|
||||
--- sudo-1.8.6p7/src/ttyname.c.get_process_ttyname 2013-02-25 20:46:09.000000000 +0100
|
||||
+++ sudo-1.8.6p7/src/ttyname.c 2017-05-25 10:23:28.720850944 +0200
|
||||
@@ -171,6 +171,8 @@ static char *search_devs[] = {
|
||||
|
||||
static char *ignore_devs[] = {
|
||||
"/dev/fd/",
|
||||
+ "/dev/mqueue/",
|
||||
+ "/dev/shm/",
|
||||
"/dev/stdin",
|
||||
"/dev/stdout",
|
||||
"/dev/stderr",
|
||||
@@ -437,9 +439,13 @@ get_process_ttyname(void)
|
||||
len = getline(&line, &linesize, fp);
|
||||
fclose(fp);
|
||||
if (len != -1) {
|
||||
- /* Field 7 is the tty dev (0 if no tty) */
|
||||
- char *cp = line;
|
||||
- int field = 1;
|
||||
+ /*
|
||||
+ * Field 7 is the tty dev (0 if no tty).
|
||||
+ * Since the process name at field 2 "(comm)" may include spaces,
|
||||
+ * start at the last ')' found.
|
||||
+ */
|
||||
+ char *cp = strrchr(line, ')');
|
||||
+ int field = 2;
|
||||
while (*cp != '\0') {
|
||||
if (*cp++ == ' ') {
|
||||
if (++field == 7) {
|
|
@ -0,0 +1,37 @@
|
|||
diff -up sudo-1.8.6p7/plugins/sudoers/ldap.c.unprivileged-list-fix sudo-1.8.6p7/plugins/sudoers/ldap.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/ldap.c.unprivileged-list-fix 2016-05-09 15:58:36.581120998 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/ldap.c 2016-05-09 15:58:36.588120900 +0200
|
||||
@@ -2494,12 +2494,12 @@ sudo_ldap_lookup(struct sudo_nss *nss, i
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
- sudo_ldap_check_command(ld, entry, NULL)) {
|
||||
+ sudo_ldap_check_command(ld, entry, NULL) == true) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
- if (matched || user_uid == 0) {
|
||||
+ if (matched == true || user_uid == 0) {
|
||||
SET(ret, VALIDATE_OK);
|
||||
CLR(ret, VALIDATE_NOT_OK);
|
||||
if (def_authenticate) {
|
||||
diff -up sudo-1.8.6p7/plugins/sudoers/sssd.c.unprivileged-list-fix sudo-1.8.6p7/plugins/sudoers/sssd.c
|
||||
--- sudo-1.8.6p7/plugins/sudoers/sssd.c.unprivileged-list-fix 2016-05-09 15:58:36.581120998 +0200
|
||||
+++ sudo-1.8.6p7/plugins/sudoers/sssd.c 2016-05-09 15:58:36.589120886 +0200
|
||||
@@ -1062,13 +1062,13 @@ sudo_sss_lookup(struct sudo_nss *nss, in
|
||||
/* Only check the command when listing another user. */
|
||||
if (user_uid == 0 || list_pw == NULL ||
|
||||
user_uid == list_pw->pw_uid ||
|
||||
- sudo_sss_check_command(handle, rule, NULL)) {
|
||||
+ sudo_sss_check_command(handle, rule, NULL) == true) {
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
- if (matched || user_uid == 0) {
|
||||
+ if (matched == true || user_uid == 0) {
|
||||
SET(ret, VALIDATE_OK);
|
||||
CLR(ret, VALIDATE_NOT_OK);
|
||||
if (def_authenticate) {
|
|
@ -0,0 +1,20 @@
|
|||
diff -up ./plugins/sudoers/visudo.c.fix ./plugins/sudoers/visudo.c
|
||||
--- ./plugins/sudoers/visudo.c.fix 2015-09-15 10:00:25.957642667 +0200
|
||||
+++ ./plugins/sudoers/visudo.c 2015-09-15 12:37:43.478306234 +0200
|
||||
@@ -479,6 +479,7 @@ reparse_sudoers(char *editor, char *args
|
||||
* Parse the edited sudoers files and do sanity checking
|
||||
*/
|
||||
do {
|
||||
+ parse_error = NULL;
|
||||
sp = tq_first(&sudoerslist);
|
||||
last = tq_last(&sudoerslist);
|
||||
fp = fopen(sp->tpath, "r+");
|
||||
@@ -544,7 +545,7 @@ reparse_sudoers(char *editor, char *args
|
||||
continue;
|
||||
edit_sudoers(sp, editor, args, errorlineno);
|
||||
}
|
||||
- } while (parse_error && sp != NULL);
|
||||
+ } while (parse_error);
|
||||
|
||||
debug_return;
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
## BINDDN DN
|
||||
## The BINDDN parameter specifies the identity, in the form of a Dis‐
|
||||
## tinguished Name (DN), to use when performing LDAP operations. If
|
||||
## not specified, LDAP operations are performed with an anonymous
|
||||
## identity. By default, most LDAP servers will allow anonymous
|
||||
## access.
|
||||
##
|
||||
#binddn uid=sudo,cn=sysaccounts,cn=etc,dc=example,dc=com
|
||||
|
||||
## BINDPW secret
|
||||
## The BINDPW parameter specifies the password to use when performing
|
||||
## LDAP operations. This is typically used in conjunction with the
|
||||
## BINDDN parameter.
|
||||
##
|
||||
#bindpw secret
|
||||
|
||||
## SSL start_tls
|
||||
## If the SSL parameter is set to start_tls, the LDAP server connec‐
|
||||
## tion is initiated normally and TLS encryption is begun before the
|
||||
## bind credentials are sent. This has the advantage of not requiring
|
||||
## a dedicated port for encrypted communications. This parameter is
|
||||
## only supported by LDAP servers that honor the start_tls extension,
|
||||
## such as the OpenLDAP and Tivoli Directory servers.
|
||||
##
|
||||
#ssl start_tls
|
||||
|
||||
## TLS_CACERTFILE file name
|
||||
## The path to a certificate authority bundle which contains the cer‐
|
||||
## tificates for all the Certificate Authorities the client knows to
|
||||
## be valid, e.g. /etc/ssl/ca-bundle.pem. This option is only sup‐
|
||||
## ported by the OpenLDAP libraries. Netscape-derived LDAP libraries
|
||||
## use the same certificate database for CA and client certificates
|
||||
## (see TLS_CERT).
|
||||
##
|
||||
#tls_cacertfile /path/to/CA.crt
|
||||
|
||||
## TLS_CHECKPEER on/true/yes/off/false/no
|
||||
## If enabled, TLS_CHECKPEER will cause the LDAP server's TLS certifi‐
|
||||
## cated to be verified. If the server's TLS certificate cannot be
|
||||
## verified (usually because it is signed by an unknown certificate
|
||||
## authority), sudo will be unable to connect to it. If TLS_CHECKPEER
|
||||
## is disabled, no check is made. Note that disabling the check cre‐
|
||||
## ates an opportunity for man-in-the-middle attacks since the
|
||||
## server's identity will not be authenticated. If possible, the CA's
|
||||
## certificate should be installed locally so it can be verified.
|
||||
## This option is not supported by the Tivoli Directory Server LDAP
|
||||
## libraries.
|
||||
#tls_checkpeer yes
|
||||
|
||||
##
|
||||
## URI ldap[s]://[hostname[:port]] ...
|
||||
## Specifies a whitespace-delimited list of one or more
|
||||
## URIs describing the LDAP server(s) to connect to.
|
||||
##
|
||||
#uri ldap://ldapserver
|
||||
|
||||
##
|
||||
## SUDOERS_BASE base
|
||||
## The base DN to use when performing sudo LDAP queries.
|
||||
## Multiple SUDOERS_BASE lines may be specified, in which
|
||||
## case they are queried in the order specified.
|
||||
##
|
||||
#sudoers_base ou=SUDOers,dc=example,dc=com
|
||||
|
||||
##
|
||||
## BIND_TIMELIMIT seconds
|
||||
## The BIND_TIMELIMIT parameter specifies the amount of
|
||||
## time to wait while trying to connect to an LDAP server.
|
||||
##
|
||||
#bind_timelimit 30
|
||||
|
||||
##
|
||||
## TIMELIMIT seconds
|
||||
## The TIMELIMIT parameter specifies the amount of time
|
||||
## to wait for a response to an LDAP query.
|
||||
##
|
||||
#timelimit 30
|
||||
|
||||
##
|
||||
## SUDOERS_DEBUG debug_level
|
||||
## This sets the debug level for sudo LDAP queries. Debugging
|
||||
## information is printed to the standard error. A value of 1
|
||||
## results in a moderate amount of debugging information.
|
||||
## A value of 2 shows the results of the matches themselves.
|
||||
##
|
||||
#sudoers_debug 1
|
|
@ -0,0 +1,57 @@
|
|||
#
|
||||
# Default /etc/sudo.conf file
|
||||
#
|
||||
# Format:
|
||||
# Plugin plugin_name plugin_path plugin_options ...
|
||||
# Path askpass /path/to/askpass
|
||||
# Path noexec /path/to/sudo_noexec.so
|
||||
# Debug sudo /var/log/sudo_debug all@warn
|
||||
# Set disable_coredump true
|
||||
#
|
||||
# Sudo plugins:
|
||||
#
|
||||
# The plugin_path is relative to ${prefix}/libexec unless fully qualified.
|
||||
# The plugin_name corresponds to a global symbol in the plugin
|
||||
# that contains the plugin interface structure.
|
||||
# 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
|
||||
|
||||
#
|
||||
# Sudo askpass:
|
||||
#
|
||||
# An askpass helper program may be specified to provide a graphical
|
||||
# password prompt for "sudo -A" support. Sudo does not ship with its
|
||||
# own passpass program but can use the OpenSSH askpass.
|
||||
#
|
||||
# Use the OpenSSH askpass
|
||||
#Path askpass /usr/X11R6/bin/ssh-askpass
|
||||
#
|
||||
# Use the Gnome OpenSSH askpass
|
||||
#Path askpass /usr/libexec/openssh/gnome-ssh-askpass
|
||||
|
||||
#
|
||||
# Sudo noexec:
|
||||
#
|
||||
# Path to a shared library containing dummy versions of the execv(),
|
||||
# execve() and fexecve() library functions that just return an error.
|
||||
# This is used to implement the "noexec" functionality on systems that
|
||||
# support C<LD_PRELOAD> or its equivalent.
|
||||
# The compiled-in value is usually sufficient and should only be changed
|
||||
# if you rename or move the sudo_noexec.so file.
|
||||
#
|
||||
#Path noexec /usr/libexec/sudo_noexec.so
|
||||
|
||||
#
|
||||
# Core dumps:
|
||||
#
|
||||
# By default, sudo disables core dumps while it is executing (they
|
||||
# are re-enabled for the command that is run).
|
||||
# To aid in debugging sudo problems, you may wish to enable core
|
||||
# dumps by setting "disable_coredump" to false.
|
||||
#
|
||||
# Set to false here so as not to interfere with /proc/sys/fs/suid_dumpable
|
||||
#
|
||||
Set disable_coredump false
|
|
@ -0,0 +1,112 @@
|
|||
## Sudoers allows particular users to run various commands as
|
||||
## the root user, without needing the root password.
|
||||
##
|
||||
## Examples are provided at the bottom of the file for collections
|
||||
## of related commands, which can then be delegated out to particular
|
||||
## users or groups.
|
||||
##
|
||||
## 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
|
||||
|
||||
#
|
||||
# Refuse to run if unable to disable echo on the tty.
|
||||
#
|
||||
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
|
||||
|
||||
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"
|
||||
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 = /sbin:/bin:/usr/sbin:/usr/bin
|
||||
|
||||
## Next comes the main part: which users can run what software on
|
||||
## which machines (the sudoers file can be shared between multiple
|
||||
## systems).
|
||||
## Syntax:
|
||||
##
|
||||
## user MACHINE=COMMANDS
|
||||
##
|
||||
## The COMMANDS section may have other options added to it.
|
||||
##
|
||||
## 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…
Reference in New Issue