diff -Nru sudo-1.8.16/debian/changelog sudo-1.8.16/debian/changelog --- sudo-1.8.16/debian/changelog 2016-08-15 16:10:33.000000000 +0000 +++ sudo-1.8.16/debian/changelog 2017-01-14 11:41:45.000000000 +0000 @@ -1,3 +1,11 @@ +sudo (1.8.16-0ubuntu1.3) xenial; urgency=medium + + * sssd-doesnt-handle-netgroups.diff, sssd-fix-matching-loop.diff: + Only check username as part of the netgroup when netgroup_tuple is enabled. + (LP: #1607666) + + -- Timo Aaltonen Sat, 14 Jan 2017 01:54:21 +0200 + sudo (1.8.16-0ubuntu1.2) xenial; urgency=medium * debian/sudoers: diff -Nru sudo-1.8.16/debian/patches/series sudo-1.8.16/debian/patches/series --- sudo-1.8.16/debian/patches/series 2016-05-04 11:53:33.000000000 +0000 +++ sudo-1.8.16/debian/patches/series 2017-01-14 00:05:27.000000000 +0000 @@ -3,3 +3,5 @@ keep_home_by_default.patch also_check_sudo_group.diff lp1565567.patch +sssd-doesnt-handle-netgroups.diff +sssd-fix-matching-loop.diff diff -Nru sudo-1.8.16/debian/patches/sssd-doesnt-handle-netgroups.diff sudo-1.8.16/debian/patches/sssd-doesnt-handle-netgroups.diff --- sudo-1.8.16/debian/patches/sssd-doesnt-handle-netgroups.diff 1970-01-01 00:00:00.000000000 +0000 +++ sudo-1.8.16/debian/patches/sssd-doesnt-handle-netgroups.diff 2017-01-14 00:04:06.000000000 +0000 @@ -0,0 +1,129 @@ + +# HG changeset patch +# User Todd C. Miller +# Date 1464886059 21600 +# Node ID 50d8d88bcc28ba9c6236c2a6cc51a593b0c308a1 +# Parent bec7e2ec26ff5837d7225c414f3ac6d2e52b9093 +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. +Adapted from a patch from Daniel Kopecek. + +diff -r bec7e2ec26ff -r 50d8d88bcc28 plugins/sudoers/sssd.c +--- a/plugins/sudoers/sssd.c Wed Jun 01 14:48:31 2016 -0600 ++++ b/plugins/sudoers/sssd.c Thu Jun 02 10:47:39 2016 -0600 +@@ -688,54 +688,71 @@ + } + + /* +- * Look for netgroup specifcations in the sudoUser attribute and +- * if found, filter according to netgroup membership. +- * returns: +- * true -> netgroup spec found && netgroup member +- * false -> netgroup spec found && not a member 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. + */ + static bool +-sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) ++sudo_sss_check_user(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) + { +- bool ret = false, netgroup_spec_found = false; +- char **val_array, *val; ++ int matched = UNSPEC; ++ char **val_array; + int i; +- debug_decl(sudo_sss_filter_user_netgroup, SUDOERS_DEBUG_SSSD); ++ debug_decl(sudo_sss_check_user, SUDOERS_DEBUG_SSSD); + + if (!handle || !rule) +- debug_return_bool(ret); ++ debug_return_bool(false); + + 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); ++ case 0: ++ break; ++ case ENOENT: ++ sudo_debug_printf(SUDO_DEBUG_INFO, "No result."); ++ debug_return_bool(false); ++ default: ++ sudo_debug_printf(SUDO_DEBUG_INFO, ++ "handle->fn_get_values(sudoUser): != 0"); ++ debug_return_bool(false); + } + +- for (i = 0; val_array[i] != NULL && !ret; ++i) { +- val = val_array[i]; +- if (*val == '+') { +- netgroup_spec_found = true; +- } ++ /* Walk through sudoUser values. */ ++ for (i = 0; val_array[i] != NULL && matched != false; ++i) { ++ bool negated = false; ++ const char *val = val_array[i]; ++ + sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val); +- if (strcmp(val, "ALL") == 0 || netgr_matches(val, +- def_netgroup_tuple ? user_runhost : NULL, +- def_netgroup_tuple ? user_srunhost : NULL, handle->pw->pw_name)) { +- ret = true; +- sudo_debug_printf(SUDO_DEBUG_DIAG, +- "sssd/ldap sudoUser '%s' ... MATCH! (%s)", +- val, handle->pw->pw_name); ++ if (*val == '!') { ++ val++; ++ negated = true; ++ } ++ switch (*val) { ++ case '+': ++ /* Netgroup spec found, check membership. */ ++ if (netgr_matches(val, def_netgroup_tuple ? user_runhost : NULL, ++ def_netgroup_tuple ? user_srunhost : NULL, handle->pw->pw_name)) { ++ matched = !negated; ++ } ++ break; ++ case '%': ++ /* User group found, check membership. */ ++ if (usergr_matches(val, handle->pw->pw_name, handle->pw)) { ++ matched = !negated; ++ } ++ break; ++ default: ++ /* Not a netgroup or user group. */ ++ if (strcmp(val, "ALL") == 0 || ++ userpw_matches(val, handle->pw->pw_name, handle->pw)) { ++ matched = !negated; ++ } + break; + } ++ sudo_debug_printf(SUDO_DEBUG_DIAG, ++ "sssd/ldap sudoUser '%s' ... %s (%s)", val_array[i], ++ matched == true ? "MATCH!" : "not", handle->pw->pw_name); + } + handle->fn_free_values(val_array); +- debug_return_bool(netgroup_spec_found ? ret : true); ++ debug_return_bool(matched == true); + } + + static int +@@ -746,7 +763,7 @@ + debug_decl(sudo_sss_result_filterp, SUDOERS_DEBUG_SSSD); + + if (sudo_sss_check_host(handle, rule) && +- sudo_sss_filter_user_netgroup(handle, rule)) ++ sudo_sss_check_user(handle, rule)) + debug_return_int(1); + else + debug_return_int(0); + diff -Nru sudo-1.8.16/debian/patches/sssd-fix-matching-loop.diff sudo-1.8.16/debian/patches/sssd-fix-matching-loop.diff --- sudo-1.8.16/debian/patches/sssd-fix-matching-loop.diff 1970-01-01 00:00:00.000000000 +0000 +++ sudo-1.8.16/debian/patches/sssd-fix-matching-loop.diff 2017-01-13 23:58:26.000000000 +0000 @@ -0,0 +1,29 @@ +# HG changeset patch +# User Todd C. Miller +# Date 1464984460 21600 +# Node ID 2eab4070dcf7119200e46488932b8814e4f8a02b +# Parent f976b3d973e038c161546b6bcc1c8f494857e0be +When matching host, short-circuit the loop when we get a match. +Only check username as part of the netgroup when netgroup_tuple is +enabled. + +--- a/plugins/sudoers/sssd.c ++++ b/plugins/sudoers/sssd.c +@@ -668,13 +668,14 @@ sudo_sss_check_host(struct sudo_sss_hand + } + + /* walk through values */ +- for (i = 0; val_array[i] != NULL; ++i) { ++ for (i = 0; val_array[i] != NULL && !ret; ++i) { + val = val_array[i]; + sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val); + + /* match any or address or netgroup or hostname */ +- if (!strcmp(val, "ALL") || addr_matches(val) || netgr_matches(val, +- user_runhost, user_srunhost, handle->pw->pw_name) || ++ if (!strcmp(val, "ALL") || addr_matches(val) || ++ netgr_matches(val, user_runhost, user_srunhost, ++ def_netgroup_tuple ? handle->pw->pw_name: NULL) || + hostname_matches(user_srunhost, user_runhost, val)) + ret = true; +