basebuilder_pel7ppc64bebuilder0
6 years ago
79 changed files with 9545 additions and 0 deletions
@ -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,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,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,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,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,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,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,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,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