Print this page
NEX-14547 Get UNIX group info. from AD/LDAP with partial RFC2307 schema
NEX-13132 smbd dumping core in nss_ldap.so.1`getbymember
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-13132 smbd dumping core in nss_ldap.so.1`getbymember disables ALL shares
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/nsswitch/ldap/common/getgrent.c
+++ new/usr/src/lib/nsswitch/ldap/common/getgrent.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 *
25 25 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
26 26 */
27 27
28 28 #include <grp.h>
29 29 #include "ldap_common.h"
|
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
30 30 #include <string.h>
31 31
32 32 /* String which may need to be removed from beginning of group password */
33 33 #define _CRYPT "{CRYPT}"
34 34 #define _NO_PASSWD_VAL ""
35 35
36 36 /* Group attributes filters */
37 37 #define _G_NAME "cn"
38 38 #define _G_GID "gidnumber"
39 39 #define _G_PASSWD "userpassword"
40 -#define _G_MEM "memberuid"
40 +#define _G_MEMUID "memberuid"
41 +#define _G_MEM_DN "member" /* DN */
41 42
42 43 #define _F_GETGRNAM "(&(objectClass=posixGroup)(cn=%s))"
43 44 #define _F_GETGRNAM_SSD "(&(%%s)(cn=%s))"
44 45 #define _F_GETGRGID "(&(objectClass=posixGroup)(gidNumber=%u))"
45 46 #define _F_GETGRGID_SSD "(&(%%s)(gidNumber=%u))"
46 -/*
47 - * Group membership can be defined by either username or DN, so when searching
48 - * for groups by member we need to consider both. The first parameter in the
49 - * filter is replaced by username, the second by DN.
50 - */
51 -#define _F_GETGRMEM \
52 - "(&(objectClass=posixGroup)(|(memberUid=%s)(memberUid=%s)))"
53 -#define _F_GETGRMEM_SSD "(&(%%s)(|(memberUid=%s)(memberUid=%s)))"
54 47
55 48 /*
56 - * Copied from getpwnam.c, needed to look up user DN.
57 - * Would it be better to move to ldap_common.h rather than duplicate?
49 + * When searching for groups in which a specified user is a member,
50 + * there are a few different membership schema that might be in use.
51 + * We'll use a filter that should work with an of the common ones:
52 + * "memberUid=NAME", or "member=DN" (try uniquemember too?)
53 + * The first parameter in the filter string is replaced by username,
54 + * and the remaining ones by the full DN.
58 55 */
59 -#define _F_GETPWNAM "(&(objectClass=posixAccount)(uid=%s))"
60 -#define _F_GETPWNAM_SSD "(&(%%s)(uid=%s))"
56 +#define _F_GETGRMEM "(&(objectClass=posixGroup)" \
57 + "(|(memberUid=%s)(member=%s)))"
58 +#define _F_GETGRMEM_SSD "(&(%%s)" \
59 + "(|(memberUid=%s)(member=%s)))"
61 60
62 61 static const char *gr_attrs[] = {
63 62 _G_NAME,
64 63 _G_GID,
65 64 _G_PASSWD,
66 - _G_MEM,
65 + _G_MEMUID,
66 + _G_MEM_DN,
67 67 (char *)NULL
68 68 };
69 69
70 +static int
71 +getmembers_UID(char **bufpp, int *lenp, ns_ldap_attr_t *members);
72 +static int
73 +getmembers_DN(char **bufpp, int *lenp, ns_ldap_attr_t *members);
70 74
75 +
71 76 /*
72 77 * _nss_ldap_group2str is the data marshaling method for the group getXbyY
73 78 * (e.g., getgrnam(), getgrgid(), getgrent()) backend processes. This method
74 79 * is called after a successful ldap search has been performed. This method
75 80 * will parse the ldap search values into the file format.
76 81 * e.g.
77 82 *
78 83 * adm::4:root,adm,daemon
79 84 *
80 85 */
81 86
82 87 static int
83 88 _nss_ldap_group2str(ldap_backend_ptr be, nss_XbyY_args_t *argp)
84 89 {
85 90 int i;
86 91 int nss_result;
87 92 int buflen = 0, len;
88 - int firstime = 1;
89 93 char *buffer = NULL;
90 94 ns_ldap_result_t *result = be->result;
91 95 char **gname, **passwd, **gid, *password, *end;
92 96 char gid_nobody[NOBODY_STR_LEN];
93 97 char *gid_nobody_v[1];
94 - char *member_str, *strtok_state;
95 98 ns_ldap_attr_t *members;
96 99
97 100 (void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY);
98 101 gid_nobody_v[0] = gid_nobody;
99 102
100 103 if (result == NULL)
101 104 return (NSS_STR_PARSE_PARSE);
102 105 buflen = argp->buf.buflen;
103 106
104 107 if (argp->buf.result != NULL) {
105 108 if ((be->buffer = calloc(1, buflen)) == NULL) {
106 109 nss_result = NSS_STR_PARSE_PARSE;
107 110 goto result_grp2str;
108 111 }
109 112 buffer = be->buffer;
110 113 } else
111 114 buffer = argp->buf.buffer;
112 115
113 116 nss_result = NSS_STR_PARSE_SUCCESS;
114 117 (void) memset(buffer, 0, buflen);
115 118
116 119 gname = __ns_ldap_getAttr(result->entry, _G_NAME);
117 120 if (gname == NULL || gname[0] == NULL || (strlen(gname[0]) < 1)) {
118 121 nss_result = NSS_STR_PARSE_PARSE;
119 122 goto result_grp2str;
120 123 }
121 124 passwd = __ns_ldap_getAttr(result->entry, _G_PASSWD);
122 125 if (passwd == NULL || passwd[0] == NULL || (strlen(passwd[0]) == 0)) {
123 126 /* group password could be NULL, replace it with "" */
124 127 password = _NO_PASSWD_VAL;
125 128 } else {
126 129 /*
127 130 * Preen "{crypt}" if necessary.
128 131 * If the password does not include the {crypt} prefix
129 132 * then the password may be plain text. And thus
130 133 * perhaps crypt(3c) should be used to encrypt it.
131 134 * Currently the password is copied verbatim.
132 135 */
133 136 if (strncasecmp(passwd[0], _CRYPT, strlen(_CRYPT)) == 0)
134 137 password = passwd[0] + strlen(_CRYPT);
135 138 else
136 139 password = passwd[0];
137 140 }
138 141 gid = __ns_ldap_getAttr(result->entry, _G_GID);
|
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
139 142 if (gid == NULL || gid[0] == NULL || (strlen(gid[0]) < 1)) {
140 143 nss_result = NSS_STR_PARSE_PARSE;
141 144 goto result_grp2str;
142 145 }
143 146 /* Validate GID */
144 147 if (strtoul(gid[0], &end, 10) > MAXUID)
145 148 gid = gid_nobody_v;
146 149 len = snprintf(buffer, buflen, "%s:%s:%s:", gname[0], password, gid[0]);
147 150 TEST_AND_ADJUST(len, buffer, buflen, result_grp2str);
148 151
149 - members = __ns_ldap_getAttrStruct(result->entry, _G_MEM);
150 - if (members == NULL || members->attrvalue == NULL) {
151 - /* no member is fine, skip processing the member list */
152 - goto nomember;
152 + members = __ns_ldap_getAttrStruct(result->entry, _G_MEMUID);
153 + if (members != NULL && members->attrvalue != NULL) {
154 + nss_result = getmembers_UID(&buffer, &buflen, members);
155 + if (nss_result != 0)
156 + goto result_grp2str;
153 157 }
154 158
155 - for (i = 0; i < members->value_count; i++) {
156 - if (members->attrvalue[i] == NULL) {
157 - nss_result = NSS_STR_PARSE_PARSE;
159 + members = __ns_ldap_getAttrStruct(result->entry, _G_MEM_DN);
160 + if (members != NULL && members->attrvalue != NULL) {
161 + nss_result = getmembers_DN(&buffer, &buflen, members);
162 + if (nss_result != 0)
158 163 goto result_grp2str;
159 - }
160 - /*
161 - * If we find an '=' in the member attribute value, treat it as
162 - * a DN, otherwise as a username.
163 - */
164 - if (member_str = strchr(members->attrvalue[i], '=')) {
165 - member_str++; /* skip over the '=' */
166 - /* Fail if we can't pull a username out of the RDN */
167 - if (! (member_str = strtok_r(member_str,
168 - ",", &strtok_state))) {
169 - nss_result = NSS_STR_PARSE_PARSE;
170 - goto result_grp2str;
171 - }
172 - } else {
173 - member_str = members->attrvalue[i];
174 - }
175 - if (*member_str != '\0') {
176 - if (firstime) {
177 - len = snprintf(buffer, buflen, "%s",
178 - member_str);
179 - TEST_AND_ADJUST(len, buffer, buflen,
180 - result_grp2str);
181 - firstime = 0;
182 - } else {
183 - len = snprintf(buffer, buflen, ",%s",
184 - member_str);
185 - TEST_AND_ADJUST(len, buffer, buflen,
186 - result_grp2str);
187 - }
188 - }
189 164 }
190 -nomember:
165 +
191 166 /* The front end marshaller doesn't need the trailing nulls */
192 167 if (argp->buf.result != NULL)
193 168 be->buflen = strlen(be->buffer);
194 169 result_grp2str:
195 170 (void) __ns_ldap_freeResult(&be->result);
196 171 return (nss_result);
197 172 }
198 173
199 174 /*
175 + * Process the list values from the "memberUid" attribute of the
176 + * current group. Note that this list is often empty, and we
177 + * get the real list of members via getmember_DN (see below).
178 + */
179 +static int
180 +getmembers_UID(char **bufpp, int *lenp, ns_ldap_attr_t *members)
181 +{
182 + char *member_str, *strtok_state;
183 + char *buffer;
184 + int buflen;
185 + int i, len;
186 + int nss_result = 0;
187 + int firsttime;
188 +
189 + buffer = *bufpp;
190 + buflen = *lenp;
191 + firsttime = (buffer[-1] == ':');
192 +
193 + for (i = 0; i < members->value_count; i++) {
194 + member_str = members->attrvalue[i];
195 + if (member_str == NULL)
196 + goto out;
197 +
198 +#ifdef DEBUG
199 + (void) fprintf(stdout, "getmembers_UID: uid=<%s>\n",
200 + member_str);
201 +#endif
202 + /*
203 + * If not a valid Unix user name, or
204 + * not valid in ldap, just skip.
205 + */
206 + if (member_str[0] == '\0' ||
207 + strpbrk(member_str, " ,:=") != NULL)
208 + continue;
209 +
210 + if (firsttime)
211 + len = snprintf(buffer, buflen, "%s", member_str);
212 + else
213 + len = snprintf(buffer, buflen, ",%s", member_str);
214 + TEST_AND_ADJUST(len, buffer, buflen, out);
215 + }
216 +
217 +out:
218 + *bufpp = buffer;
219 + *lenp = buflen;
220 + return (nss_result);
221 +}
222 +
223 +/*
224 + * Process the list values from the "member" attribute of the
225 + * current group. Note that this list is ONLY one that can be
226 + * assumed to be non-empty. The problem here is that this list
227 + * contains the list of members as "distinguished names" (DN),
228 + * and we want the Unix names (known here as "uid"). We must
229 + * lookup the "uid" for each DN in the member list. Example:
230 + * CN=Doe\, John,OU=Users,DC=contoso,DC=com => john.doe
231 + */
232 +static int
233 +getmembers_DN(char **bufpp, int *lenp, ns_ldap_attr_t *members)
234 +{
235 + ns_ldap_error_t *error = NULL;
236 + char *member_dn, *member_uid;
237 + char *buffer;
238 + int buflen;
239 + int i, len;
240 + int nss_result = 0;
241 + int firsttime;
242 +
243 + buffer = *bufpp;
244 + buflen = *lenp;
245 + firsttime = (buffer[-1] == ':');
246 +
247 + for (i = 0; i < members->value_count; i++) {
248 + member_dn = members->attrvalue[i];
249 + if (member_dn == NULL)
250 + goto out;
251 +
252 + /*
253 + * The attribute name was "member", so these should be
254 + * full distinguisned names (DNs). We need to loookup
255 + * the Unix UID (name) for each.
256 + */
257 +#ifdef DEBUG
258 + (void) fprintf(stdout, "getmembers_DN: dn=%s\n",
259 + member_dn);
260 +#endif
261 + if (member_dn[0] == '\0')
262 + continue;
263 +
264 + nss_result = __ns_ldap_dn2uid(member_dn,
265 + &member_uid, NULL, &error);
266 + if (nss_result != NS_LDAP_SUCCESS) {
267 + (void) __ns_ldap_freeError(&error);
268 + error = NULL;
269 + continue;
270 + }
271 +#ifdef DEBUG
272 + (void) fprintf(stdout, "getmembers_DN: uid=<%s>\n",
273 + member_uid);
274 +#endif
275 + /* Skip invalid names. */
276 + if (member_uid[0] == '\0' ||
277 + strpbrk(member_uid, " ,:=") != NULL) {
278 + free(member_uid);
279 + continue;
280 + }
281 +
282 + if (firsttime)
283 + len = snprintf(buffer, buflen, "%s", member_uid);
284 + else
285 + len = snprintf(buffer, buflen, ",%s", member_uid);
286 + free(member_uid);
287 + TEST_AND_ADJUST(len, buffer, buflen, out);
288 + }
289 +
290 +out:
291 + *bufpp = buffer;
292 + *lenp = buflen;
293 + return (nss_result);
294 +}
295 +
296 +/*
200 297 * getbynam gets a group entry by name. This function constructs an ldap
201 298 * search filter using the name invocation parameter and the getgrnam search
202 299 * filter defined. Once the filter is constructed, we searche for a matching
203 300 * entry and marshal the data results into struct group for the frontend
204 301 * process. The function _nss_ldap_group2ent performs the data marshaling.
205 302 */
206 303
207 304 static nss_status_t
208 305 getbynam(ldap_backend_ptr be, void *a)
209 306 {
210 307 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
211 308 char searchfilter[SEARCHFILTERLEN];
212 309 char userdata[SEARCHFILTERLEN];
213 310 char groupname[SEARCHFILTERLEN];
214 311 int ret;
215 312
216 313 if (_ldap_filter_name(groupname, argp->key.name, sizeof (groupname)) !=
217 314 0)
218 315 return ((nss_status_t)NSS_NOTFOUND);
219 316
220 317 ret = snprintf(searchfilter, sizeof (searchfilter),
221 318 _F_GETGRNAM, groupname);
222 319 if (ret >= sizeof (searchfilter) || ret < 0)
223 320 return ((nss_status_t)NSS_NOTFOUND);
224 321
225 322 ret = snprintf(userdata, sizeof (userdata), _F_GETGRNAM_SSD, groupname);
226 323 if (ret >= sizeof (userdata) || ret < 0)
227 324 return ((nss_status_t)NSS_NOTFOUND);
228 325
229 326 return ((nss_status_t)_nss_ldap_lookup(be, argp,
230 327 _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata));
231 328 }
232 329
233 330
234 331 /*
235 332 * getbygid gets a group entry by number. This function constructs an ldap
236 333 * search filter using the name invocation parameter and the getgrgid search
237 334 * filter defined. Once the filter is constructed, we searche for a matching
238 335 * entry and marshal the data results into struct group for the frontend
239 336 * process. The function _nss_ldap_group2ent performs the data marshaling.
240 337 */
241 338
242 339 static nss_status_t
243 340 getbygid(ldap_backend_ptr be, void *a)
244 341 {
245 342 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
246 343 char searchfilter[SEARCHFILTERLEN];
247 344 char userdata[SEARCHFILTERLEN];
248 345 int ret;
249 346
250 347 if (argp->key.uid > MAXUID)
251 348 return ((nss_status_t)NSS_NOTFOUND);
252 349
253 350 ret = snprintf(searchfilter, sizeof (searchfilter),
254 351 _F_GETGRGID, argp->key.uid);
255 352 if (ret >= sizeof (searchfilter) || ret < 0)
256 353 return ((nss_status_t)NSS_NOTFOUND);
257 354
258 355 ret = snprintf(userdata, sizeof (userdata),
259 356 _F_GETGRGID_SSD, argp->key.uid);
|
↓ open down ↓ |
50 lines elided |
↑ open up ↑ |
260 357 if (ret >= sizeof (userdata) || ret < 0)
261 358 return ((nss_status_t)NSS_NOTFOUND);
262 359
263 360 return ((nss_status_t)_nss_ldap_lookup(be, argp,
264 361 _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata));
265 362
266 363 }
267 364
268 365
269 366 /*
367 + * Use a custom attributes list for getbymember, because the LDAP
368 + * query for this requests a list of groups, and the result can be
369 + * very large if it includes the list of members with each group.
370 + * We don't need or want the list of members in this case.
371 + */
372 +static const char *grbymem_attrs[] = {
373 + _G_NAME, /* cn */
374 + _G_GID, /* gidnumber */
375 + (char *)NULL
376 +};
377 +
378 +/*
270 379 * getbymember returns all groups a user is defined in. This function
271 380 * uses different architectural procedures than the other group backend
272 381 * system calls because it's a private interface. This function constructs
273 382 * an ldap search filter using the name invocation parameter. Once the
274 383 * filter is constructed, we search for all matching groups counting
275 384 * and storing each group name, gid, etc. Data marshaling is used for
276 385 * group processing. The function _nss_ldap_group2ent() performs the
277 386 * data marshaling.
278 387 *
279 388 * (const char *)argp->username; (size_t)strlen(argp->username);
280 389 * (gid_t)argp->gid_array; (int)argp->maxgids;
281 390 * (int)argp->numgids;
282 391 */
283 392
284 393 static nss_status_t
285 394 getbymember(ldap_backend_ptr be, void *a)
286 395 {
396 + ns_ldap_error_t *error = NULL;
287 397 int i, j, k;
288 398 int gcnt = (int)0;
289 - char **groupvalue, **membervalue, *member_str;
290 - char *strtok_state;
399 + char **groupvalue;
291 400 nss_status_t lstat;
292 401 struct nss_groupsbymem *argp = (struct nss_groupsbymem *)a;
293 402 char searchfilter[SEARCHFILTERLEN];
294 403 char userdata[SEARCHFILTERLEN];
295 404 char name[SEARCHFILTERLEN];
405 + char escdn[SEARCHFILTERLEN];
296 406 ns_ldap_result_t *result;
297 407 ns_ldap_entry_t *curEntry;
298 - char *username, **dn_attr, *dn;
408 + char *dn;
299 409 gid_t gid;
300 - int ret;
410 + int ret1, ret2;
301 411
302 412 if (strcmp(argp->username, "") == 0 ||
303 413 strcmp(argp->username, "root") == 0)
304 414 return ((nss_status_t)NSS_NOTFOUND);
305 415
306 416 if (_ldap_filter_name(name, argp->username, sizeof (name)) != 0)
307 417 return ((nss_status_t)NSS_NOTFOUND);
308 418
309 - ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name);
310 - if (ret >= sizeof (searchfilter) || ret < 0)
311 - return ((nss_status_t)NSS_NOTFOUND);
312 -
313 - ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name);
314 - if (ret >= sizeof (userdata) || ret < 0)
315 - return ((nss_status_t)NSS_NOTFOUND);
316 -
317 419 /*
318 420 * Look up the user DN in ldap. If it's not found, search solely by
319 421 * username.
320 422 */
321 - lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL,
322 - _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata);
323 - if (lstat != (nss_status_t)NS_LDAP_SUCCESS)
324 - return ((nss_status_t)lstat);
325 -
326 - if (be->result == NULL ||
327 - !(dn_attr = __ns_ldap_getAttr(be->result->entry, "dn")))
423 + lstat = __ns_ldap_uid2dn(name, &dn, NULL, &error);
424 + if (lstat != (nss_status_t)NS_LDAP_SUCCESS) {
425 + /* Can't get DN. Use bare name */
426 + (void) __ns_ldap_freeError(&error);
328 427 dn = name;
329 - else
330 - dn = dn_attr[0];
428 + }
429 + /* Note: must free dn if != name */
331 430
332 - ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETGRMEM, name,
333 - dn);
334 - if (ret >= sizeof (searchfilter) || ret < 0)
431 + /*
432 + * Compose filter patterns
433 + */
434 + ret1 = snprintf(searchfilter, sizeof (searchfilter),
435 + _F_GETGRMEM, name, dn);
436 + ret2 = snprintf(userdata, sizeof (userdata),
437 + _F_GETGRMEM_SSD, name, dn);
438 + if (dn != name)
439 + free(dn);
440 + if (ret1 >= sizeof (searchfilter) || ret1 < 0)
335 441 return ((nss_status_t)NSS_NOTFOUND);
336 -
337 - ret = snprintf(userdata, sizeof (userdata), _F_GETGRMEM_SSD, name,
338 - dn);
339 - if (ret >= sizeof (userdata) || ret < 0)
442 + if (ret2 >= sizeof (userdata) || ret2 < 0)
340 443 return ((nss_status_t)NSS_NOTFOUND);
341 444
342 445 /*
343 - * Free up resources from user DN search before performing group
344 - * search.
446 + * Query for groups matching the filter.
345 447 */
346 - (void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result);
347 -
348 - gcnt = (int)argp->numgids;
349 448 lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL,
350 - _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata);
449 + _GROUP, searchfilter, grbymem_attrs,
450 + _merge_SSD_filter, userdata);
351 451 if (lstat != (nss_status_t)NS_LDAP_SUCCESS)
352 452 return ((nss_status_t)lstat);
353 453 if (be->result == NULL)
354 454 return (NSS_NOTFOUND);
355 - username = (char *)argp->username;
455 +
456 + /*
457 + * Walk the query result, collecting GIDs.
458 + */
356 459 result = (ns_ldap_result_t *)be->result;
357 460 curEntry = (ns_ldap_entry_t *)result->entry;
358 - for (i = 0; i < result->entries_count && curEntry != NULL; i++) {
359 - membervalue = __ns_ldap_getAttr(curEntry, "memberUid");
360 - if (membervalue == NULL) {
361 - curEntry = curEntry->next;
362 - continue;
461 + gcnt = (int)argp->numgids;
462 + for (i = 0; i < result->entries_count; i++) {
463 +
464 + /*
465 + * Does this group have a gidNumber attr?
466 + */
467 + groupvalue = __ns_ldap_getAttr(curEntry, _G_GID);
468 + if (groupvalue == NULL || groupvalue[0] == NULL) {
469 + /* Drop this group from the list */
470 + goto next_group;
363 471 }
364 - for (j = 0; membervalue[j]; j++) {
365 - /*
366 - * If we find an '=' in the member attribute
367 - * value, treat it as a DN, otherwise as a
368 - * username.
369 - */
370 - if (member_str = strchr(membervalue[j], '=')) {
371 - member_str++; /* skip over the '=' */
372 - member_str = strtok_r(member_str, ",",
373 - &strtok_state);
374 - } else {
375 - member_str = membervalue[j];
376 - }
377 - if (member_str != NULL &&
378 - strcmp(member_str, username) == 0) {
379 - groupvalue = __ns_ldap_getAttr(curEntry,
380 - "gidnumber");
381 - if (groupvalue == NULL ||
382 - groupvalue[0] == NULL) {
383 - /* Drop this group from the list */
384 - break;
385 - }
386 - errno = 0;
387 - gid = (gid_t)strtol(groupvalue[0],
388 - (char **)NULL, 10);
389 472
390 - if (errno == 0 &&
391 - argp->numgids < argp->maxgids) {
392 - for (k = 0; k < argp->numgids; k++) {
393 - if (argp->gid_array[k] == gid)
394 - /* already exists */
395 - break;
396 - }
397 - if (k == argp->numgids)
398 - argp->gid_array[argp->numgids++]
399 - = gid;
473 + /*
474 + * Convert it to a numeric GID
475 + */
476 + errno = 0;
477 + gid = (gid_t)strtol(groupvalue[0], (char **)NULL, 10);
478 + if (errno != 0)
479 + goto next_group;
480 +
481 + /*
482 + * If we don't already have this GID, add it.
483 + */
484 + if (argp->numgids < argp->maxgids) {
485 + for (k = 0; k < argp->numgids; k++) {
486 + if (argp->gid_array[k] == gid) {
487 + /* already have it */
488 + goto next_group;
400 489 }
401 - break;
402 490 }
491 + argp->gid_array[argp->numgids++] = gid;
403 492 }
493 +
494 + next_group:
404 495 curEntry = curEntry->next;
405 496 }
406 497
407 498 (void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result);
408 499 if (gcnt == argp->numgids)
409 500 return ((nss_status_t)NSS_NOTFOUND);
410 501
411 502 /*
412 503 * Return NSS_SUCCESS only if array is full.
413 504 * Explained in <nss_dbdefs.h>.
414 505 */
415 506 return ((nss_status_t)((argp->numgids == argp->maxgids)
416 507 ? NSS_SUCCESS
417 508 : NSS_NOTFOUND));
418 509 }
419 510
420 511 static ldap_backend_op_t gr_ops[] = {
421 512 _nss_ldap_destr,
422 513 _nss_ldap_endent,
423 514 _nss_ldap_setent,
|
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
424 515 _nss_ldap_getent,
425 516 getbynam,
426 517 getbygid,
427 518 getbymember
428 519 };
429 520
430 521
431 522 /*ARGSUSED0*/
432 523 nss_backend_t *
433 524 _nss_ldap_group_constr(const char *dummy1, const char *dummy2,
434 - const char *dummy3)
525 + const char *dummy3)
435 526 {
436 527
437 528 return ((nss_backend_t *)_nss_ldap_constr(gr_ops,
438 529 sizeof (gr_ops)/sizeof (gr_ops[0]), _GROUP, gr_attrs,
439 530 _nss_ldap_group2str));
440 531 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX