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