1 |
diff -up sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix sudo-1.8.6p3/plugins/sudoers/sssd.c |
2 |
--- sudo-1.8.6p3/plugins/sudoers/sssd.c.netgrfilterfix 2014-07-30 13:29:47.713823996 +0200 |
3 |
+++ sudo-1.8.6p3/plugins/sudoers/sssd.c 2014-07-30 13:30:08.917436088 +0200 |
4 |
@@ -614,16 +615,13 @@ sudo_sss_check_host(struct sudo_sss_hand |
5 |
} |
6 |
|
7 |
/* |
8 |
- * Look for netgroup specifcations in the sudoUser attribute and |
9 |
- * if found, filter according to netgroup membership. |
10 |
- * returns: |
11 |
- * true -> netgroup spec found && negroup member |
12 |
- * false -> netgroup spec found && not a meber of netgroup |
13 |
- * true -> netgroup spec not found (filtered by SSSD already, netgroups are an exception) |
14 |
+ * SSSD doesn't handle netgroups, we have to ensure they are correctly filtered |
15 |
+ * in sudo. The rules may contain mixed sudoUser specification so we have to check |
16 |
+ * not only for netgroup membership but also for user and group matches. |
17 |
*/ |
18 |
-bool sudo_sss_filter_user_netgroup(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) |
19 |
+bool sudo_sss_filter_sudoUser(struct sudo_sss_handle *handle, struct sss_sudo_rule *rule) |
20 |
{ |
21 |
- bool ret = false, netgroup_spec_found = false; |
22 |
+ bool ret = false; |
23 |
char **val_array, *val; |
24 |
int i; |
25 |
debug_decl(sudo_sss_check_user_netgroup, SUDO_DEBUG_SSSD); |
26 |
@@ -641,21 +639,48 @@ bool sudo_sss_filter_user_netgroup(struc |
27 |
sudo_debug_printf(SUDO_DEBUG_INFO, "handle->fn_get_values(sudoUser): != 0"); |
28 |
debug_return_bool(ret); |
29 |
} |
30 |
- |
31 |
+ /* |
32 |
+ * Scan sudoUser values and look for netgroup specs. |
33 |
+ * Netgroup-only rule specification should be filtered |
34 |
+ * out if the user isn't member of any specified netgroup. |
35 |
+ */ |
36 |
for (i = 0; val_array[i] != NULL && !ret; ++i) { |
37 |
val = val_array[i]; |
38 |
- if (*val == '+') { |
39 |
- netgroup_spec_found = true; |
40 |
- } |
41 |
sudo_debug_printf(SUDO_DEBUG_DEBUG, "val[%d]=%s", i, val); |
42 |
- if (strcmp(val, "ALL") == 0 || netgr_matches(val, NULL, NULL, user_name)) { |
43 |
- ret = true; |
44 |
- sudo_debug_printf(SUDO_DEBUG_DIAG, |
45 |
- "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, user_name); |
46 |
+ if (*val == '+') { |
47 |
+ /* Netgroup spec found, check netgroup membership */ |
48 |
+ if (netgr_matches(val, NULL, NULL, handle->pw->pw_name)) { |
49 |
+ ret = true; |
50 |
+ sudo_debug_printf(SUDO_DEBUG_DIAG, |
51 |
+ "sssd/ldap sudoUser '%s' ... MATCH! (%s)", val, handle->pw->pw_name); |
52 |
+ } |
53 |
+ } else { |
54 |
+ /* |
55 |
+ * Non-netgroup sudoUser value |
56 |
+ */ |
57 |
+ if (strcmp(val, "ALL") == 0) { |
58 |
+ ret = true; |
59 |
+ } else { |
60 |
+ const char *match_val = (*val == '!' ? val + 1 : val); |
61 |
+ const bool negated = (*val == '!' ? true : false); |
62 |
+ const bool group_spec = (*match_val == '%' ? true : false); |
63 |
+ |
64 |
+ if (group_spec) { |
65 |
+ if (usergr_matches(match_val, |
66 |
+ handle->pw->pw_name, handle->pw)) { |
67 |
+ ret = !negated; |
68 |
+ } |
69 |
+ } else { |
70 |
+ if (userpw_matches(match_val, |
71 |
+ handle->pw->pw_name, handle->pw)) { |
72 |
+ ret = !negated; |
73 |
+ } |
74 |
+ } |
75 |
+ } |
76 |
} |
77 |
} |
78 |
handle->fn_free_values(val_array); |
79 |
- debug_return_bool(netgroup_spec_found ? ret : true); |
80 |
+ debug_return_bool(ret); |
81 |
} |
82 |
|
83 |
static int |
84 |
@@ -666,7 +691,7 @@ sudo_sss_result_filterp(struct sudo_sss_ |
85 |
debug_decl(sudo_sss_result_filterp, SUDO_DEBUG_SSSD); |
86 |
|
87 |
if (sudo_sss_check_host(handle, rule) && |
88 |
- sudo_sss_filter_user_netgroup(handle, rule)) |
89 |
+ sudo_sss_filter_sudoUser(handle, rule)) |
90 |
debug_return_int(1); |
91 |
else |
92 |
debug_return_int(0); |