1 |
diff -up sudo-1.8.6p3/plugins/sudoers/defaults.c.legacy-group-processing sudo-1.8.6p3/plugins/sudoers/defaults.c |
2 |
--- sudo-1.8.6p3/plugins/sudoers/defaults.c.legacy-group-processing 2012-09-18 15:56:29.000000000 +0200 |
3 |
+++ sudo-1.8.6p3/plugins/sudoers/defaults.c 2015-07-15 09:40:30.600853736 +0200 |
4 |
@@ -362,6 +362,7 @@ init_defaults(void) |
5 |
} |
6 |
|
7 |
/* First initialize the flags. */ |
8 |
+ def_legacy_group_processing = true; |
9 |
#ifdef LONG_OTP_PROMPT |
10 |
def_long_otp_prompt = true; |
11 |
#endif |
12 |
diff -up sudo-1.8.6p3/plugins/sudoers/def_data.c.legacy-group-processing sudo-1.8.6p3/plugins/sudoers/def_data.c |
13 |
--- sudo-1.8.6p3/plugins/sudoers/def_data.c.legacy-group-processing 2015-07-15 09:40:30.561854082 +0200 |
14 |
+++ sudo-1.8.6p3/plugins/sudoers/def_data.c 2015-07-15 09:40:30.600853736 +0200 |
15 |
@@ -355,6 +355,10 @@ struct sudo_defs_types sudo_defs_table[] |
16 |
N_("Don't fork and wait for the command to finish, just exec it"), |
17 |
NULL, |
18 |
}, { |
19 |
+ "legacy_group_processing", T_FLAG, |
20 |
+ N_("Don't pre-resolve all group names"), |
21 |
+ NULL, |
22 |
+ }, { |
23 |
NULL, 0, NULL |
24 |
} |
25 |
}; |
26 |
diff -up sudo-1.8.6p3/plugins/sudoers/def_data.h.legacy-group-processing sudo-1.8.6p3/plugins/sudoers/def_data.h |
27 |
--- sudo-1.8.6p3/plugins/sudoers/def_data.h.legacy-group-processing 2015-07-15 09:40:30.561854082 +0200 |
28 |
+++ sudo-1.8.6p3/plugins/sudoers/def_data.h 2015-07-15 09:40:30.600853736 +0200 |
29 |
@@ -164,6 +164,8 @@ |
30 |
#define I_LIMITPRIVS 81 |
31 |
#define def_cmnd_no_wait (sudo_defs_table[82].sd_un.flag) |
32 |
#define I_CMND_NO_WAIT 82 |
33 |
+#define def_legacy_group_processing (sudo_defs_table[83].sd_un.flag) |
34 |
+#define I_LEGACY_GROUP_PROCESSING 83 |
35 |
|
36 |
enum def_tuple { |
37 |
never, |
38 |
diff -up sudo-1.8.6p3/plugins/sudoers/ldap.c.legacy-group-processing sudo-1.8.6p3/plugins/sudoers/ldap.c |
39 |
--- sudo-1.8.6p3/plugins/sudoers/ldap.c.legacy-group-processing 2015-07-15 09:40:30.596853772 +0200 |
40 |
+++ sudo-1.8.6p3/plugins/sudoers/ldap.c 2015-07-15 09:40:30.601853727 +0200 |
41 |
@@ -1150,6 +1150,15 @@ sudo_ldap_build_pass1(struct passwd *pw) |
42 |
} |
43 |
sz += 13 + MAX_UID_T_LEN; |
44 |
if ((grlist = sudo_get_grlist(pw)) != NULL) { |
45 |
+ if (!grlist->groups_resolved) { |
46 |
+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids, |
47 |
+ grlist->groups, grlist->groups_buffer); |
48 |
+ if (rc < 0) { |
49 |
+ return NULL; |
50 |
+ } |
51 |
+ grlist->ngroups = rc; |
52 |
+ grlist->groups_resolved = true; |
53 |
+ } |
54 |
for (i = 0; i < grlist->ngroups; i++) { |
55 |
if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0) |
56 |
continue; |
57 |
diff -up sudo-1.8.6p3/plugins/sudoers/pwutil.c.legacy-group-processing sudo-1.8.6p3/plugins/sudoers/pwutil.c |
58 |
--- sudo-1.8.6p3/plugins/sudoers/pwutil.c.legacy-group-processing 2015-07-15 09:40:30.589853834 +0200 |
59 |
+++ sudo-1.8.6p3/plugins/sudoers/pwutil.c 2015-07-15 09:48:15.734723742 +0200 |
60 |
@@ -542,10 +542,9 @@ static struct cache_item * |
61 |
make_grlist_item(const char *user, GETGROUPS_T *gids, int ngids) |
62 |
{ |
63 |
char *cp; |
64 |
- size_t i, nsize, ngroups, total, len; |
65 |
+ size_t i, nsize, total; |
66 |
struct cache_item_grlist *grlitem; |
67 |
struct group_list *grlist; |
68 |
- struct group *grp; |
69 |
debug_decl(make_grlist_item, SUDO_DEBUG_NSS) |
70 |
|
71 |
#ifdef HAVE_SETAUTHDB |
72 |
@@ -559,7 +558,6 @@ make_grlist_item(const char *user, GETGR |
73 |
total += sizeof(gid_t *) * ngids; |
74 |
total += GROUPNAME_LEN * ngids; |
75 |
|
76 |
-again: |
77 |
grlitem = ecalloc(1, total); |
78 |
|
79 |
/* |
80 |
@@ -587,27 +585,26 @@ again: |
81 |
for (i = 0; i < ngids; i++) |
82 |
grlist->gids[i] = gids[i]; |
83 |
grlist->ngids = ngids; |
84 |
+ grlist->groups_buffer = cp; |
85 |
|
86 |
/* |
87 |
- * Resolve and store group names by ID. |
88 |
+ * Resolve and store group names by ID if legacy_group_processing is off. |
89 |
*/ |
90 |
- ngroups = 0; |
91 |
- for (i = 0; i < ngids; i++) { |
92 |
- if ((grp = sudo_getgrgid(gids[i])) != NULL) { |
93 |
- len = strlen(grp->gr_name) + 1; |
94 |
- if (cp - (char *)grlitem + len > total) { |
95 |
- total += len + GROUPNAME_LEN; |
96 |
- efree(grlitem); |
97 |
- sudo_gr_delref(grp); |
98 |
- goto again; |
99 |
- } |
100 |
- memcpy(cp, grp->gr_name, len); |
101 |
- grlist->groups[ngroups++] = cp; |
102 |
- cp += len; |
103 |
- sudo_gr_delref(grp); |
104 |
- } |
105 |
+ if (def_legacy_group_processing) { |
106 |
+ for (i = 0; i < ngids; i++) { |
107 |
+ grlist->groups[i] = NULL; |
108 |
+ } |
109 |
+ grlist->ngroups = 0; |
110 |
+ grlist->groups_resolved = false; |
111 |
+ } else { |
112 |
+ int rc = sudo_resolve_gids(gids, ngids, grlist->groups, grlist->groups_buffer); |
113 |
+ if (rc < 0) { |
114 |
+ efree(grlitem); |
115 |
+ return NULL; |
116 |
+ } |
117 |
+ grlist->ngroups = rc; |
118 |
+ grlist->groups_resolved = true; |
119 |
} |
120 |
- grlist->ngroups = ngroups; |
121 |
|
122 |
#ifdef HAVE_SETAUTHDB |
123 |
aix_restoreauthdb(); |
124 |
@@ -616,6 +613,35 @@ again: |
125 |
debug_return_ptr(&grlitem->cache); |
126 |
} |
127 |
|
128 |
+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer) |
129 |
+{ |
130 |
+ struct group *grp; |
131 |
+ int space_left = ngids * GROUPNAME_LEN; |
132 |
+ int ngroups = 0; |
133 |
+ int i; |
134 |
+ char *cp = group_buffer; |
135 |
+ debug_decl(sudo_resolve_gids, SUDO_DEBUG_NSS) |
136 |
+ |
137 |
+ for (i = 0; i < ngids; i++) { |
138 |
+ if ((grp = sudo_getgrgid(gids[i])) != NULL) { |
139 |
+ int len = strlen(grp->gr_name) + 1; |
140 |
+ |
141 |
+ if (space_left < len) { |
142 |
+ sudo_gr_delref(grp); |
143 |
+ debug_return_int(-1); |
144 |
+ } |
145 |
+ |
146 |
+ memcpy(cp, grp->gr_name, len); |
147 |
+ groups[ngroups++] = cp; |
148 |
+ cp += len; |
149 |
+ space_left -= len; |
150 |
+ sudo_gr_delref(grp); |
151 |
+ } |
152 |
+ } |
153 |
+ |
154 |
+ debug_return_int(ngroups); |
155 |
+} |
156 |
+ |
157 |
void |
158 |
sudo_gr_addref(struct group *gr) |
159 |
{ |
160 |
@@ -917,8 +943,22 @@ user_in_group(const struct passwd *pw, c |
161 |
/* |
162 |
* If it could be a sudo-style group ID check gids first. |
163 |
*/ |
164 |
+ bool do_gid_lookup = false; |
165 |
+ gid_t gid; |
166 |
+ |
167 |
if (group[0] == '#') { |
168 |
- gid_t gid = atoi(group + 1); |
169 |
+ gid = atoi(group + 1); |
170 |
+ do_gid_lookup = true; |
171 |
+ } else if (def_legacy_group_processing) { |
172 |
+ struct group *grent = sudo_getgrnam(group); |
173 |
+ if (grent == NULL) { |
174 |
+ goto done; |
175 |
+ } |
176 |
+ gid = grent->gr_gid; |
177 |
+ do_gid_lookup = true; |
178 |
+ } |
179 |
+ |
180 |
+ if (do_gid_lookup) { |
181 |
if (gid == pw->pw_gid) { |
182 |
matched = true; |
183 |
goto done; |
184 |
@@ -931,6 +971,19 @@ user_in_group(const struct passwd *pw, c |
185 |
} |
186 |
} |
187 |
|
188 |
+ if (def_legacy_group_processing) { |
189 |
+ goto done; |
190 |
+ } |
191 |
+ if (!grlist->groups_resolved) { |
192 |
+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids, |
193 |
+ grlist->groups, grlist->groups_buffer); |
194 |
+ if (rc < 0) { |
195 |
+ goto done; |
196 |
+ } |
197 |
+ grlist->ngroups = rc; |
198 |
+ grlist->groups_resolved = true; |
199 |
+ } |
200 |
+ |
201 |
/* |
202 |
* Next check the supplementary group vector. |
203 |
* It usually includes the password db group too. |
204 |
diff -up sudo-1.8.6p3/plugins/sudoers/sudoers.h.legacy-group-processing sudo-1.8.6p3/plugins/sudoers/sudoers.h |
205 |
--- sudo-1.8.6p3/plugins/sudoers/sudoers.h.legacy-group-processing 2015-07-15 09:40:30.589853834 +0200 |
206 |
+++ sudo-1.8.6p3/plugins/sudoers/sudoers.h 2015-07-15 09:40:30.601853727 +0200 |
207 |
@@ -52,6 +52,8 @@ struct group_list { |
208 |
GETGROUPS_T *gids; |
209 |
int ngroups; |
210 |
int ngids; |
211 |
+ int groups_resolved; |
212 |
+ char *groups_buffer; |
213 |
}; |
214 |
|
215 |
/* |
216 |
@@ -290,6 +292,8 @@ __dso_public struct group *sudo_getgrnam |
217 |
__dso_public void sudo_gr_addref(struct group *); |
218 |
__dso_public void sudo_gr_delref(struct group *); |
219 |
bool user_in_group(const struct passwd *, const char *); |
220 |
+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer); |
221 |
+ |
222 |
struct group *sudo_fakegrnam(const char *); |
223 |
struct group_list *sudo_get_grlist(const struct passwd *pw); |
224 |
struct passwd *sudo_fakepwnam(const char *, gid_t); |