Print this page
2989 Eliminate use of LOGNAME_MAX in ON
1166 useradd have warning with name more 8 chars
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/nsswitch/ldap/common/getnetgrent.c
+++ new/usr/src/lib/nsswitch/ldap/common/getnetgrent.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.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
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 + * Copyright (c) 2013 Gary Mills
23 + *
22 24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 25 * Use is subject to license terms.
24 26 */
25 27
26 28
27 29 #include <syslog.h>
28 30 #include "ldap_common.h"
29 31
30 32 /* netgroup attributes filters */
31 33 #define _N_TRIPLE "nisnetgrouptriple"
32 34 #define _N_MEMBER "membernisnetgroup"
33 35
34 36 #define PRINT_VAL(a) (((a).argc == 0) || ((a).argv == NULL) || \
35 37 ((a).argv[0] == NULL)) ? "*" : (a).argv[0]
36 38 #define ISNULL(a) (a == NULL ? "<NULL>" : a)
37 39 #define MAX_DOMAIN_LEN 1024
38 -#define MAX_TRIPLE_LEN (MAXHOSTNAMELEN + LOGNAME_MAX + \
40 +#define MAX_TRIPLE_LEN (MAXHOSTNAMELEN + LOGNAME_MAX_ILLUMOS + \
39 41 MAX_DOMAIN_LEN + 5)
40 42
41 43 #define _F_SETMEMBER "(&(objectClass=nisNetGroup)(cn=%s))"
42 44 #define _F_SETMEMBER_SSD "(&(%%s)(cn=%s))"
43 45
44 46 #define N_HASH 257
45 47 #define COMMA ','
46 48
47 49 static const char *netgrent_attrs[] = {
48 50 _N_TRIPLE,
49 51 _N_MEMBER,
50 52 (char *)NULL
51 53 };
52 54
53 55 typedef struct netgroup_name {
54 56 char *name;
55 57 struct netgroup_name *next;
56 58 struct netgroup_name *next_hash;
57 59 } netgroup_name_t;
58 60
59 61 typedef struct {
60 62 netgroup_name_t *hash_list[N_HASH];
61 63 netgroup_name_t *to_do;
62 64 netgroup_name_t *done;
63 65 } netgroup_table_t;
64 66
65 67 typedef struct {
66 68 ns_ldap_result_t *results;
67 69 ns_ldap_entry_t *entry;
68 70 char **attrs;
69 71 char *netgroup;
70 72 netgroup_table_t tab;
71 73 } getnetgrent_cookie_t;
72 74
73 75 typedef struct {
74 76 struct nss_innetgr_args *ia;
75 77 const char *ssd_filter;
76 78 const char *netgrname;
77 79 const char *membername;
78 80 netgroup_table_t tab;
79 81 } innetgr_cookie_t;
80 82
81 83 typedef unsigned int hash_t;
82 84
83 85 static hash_t
84 86 get_hash(const char *s)
85 87 {
86 88 unsigned int sum = 0;
87 89 unsigned int i;
88 90
89 91 for (i = 0; s[i] != '\0'; i++)
90 92 sum += ((unsigned char *)s)[i];
91 93
92 94 return ((sum + i) % N_HASH);
93 95 }
94 96
95 97 /*
96 98 * Adds a name to the netgroup table
97 99 *
98 100 * Returns
99 101 * 0 if successfully added or already present
100 102 * -1 if memory allocation error or NULL netgroup_table_t
101 103 * from caller.
102 104 */
103 105
104 106 static int
105 107 add_netgroup_name(const char *name, netgroup_table_t *tab)
106 108 {
107 109 hash_t h;
108 110 netgroup_name_t *ng;
109 111 netgroup_name_t *ng_new;
110 112
111 113 if (tab == NULL) {
112 114 /*
113 115 * Should never happen. But if it does,
114 116 * that's an error condition.
115 117 */
116 118 return (-1);
117 119 }
118 120 if (name == NULL || *name == '\0') {
119 121 /* no name to add means success */
120 122 return (0);
121 123 }
122 124
123 125 h = get_hash(name);
124 126 ng = tab->hash_list[h];
125 127
126 128 while (ng != NULL) {
127 129 if (strcmp(name, ng->name) == 0)
128 130 break;
129 131 ng = ng->next_hash;
130 132 }
131 133
132 134 if (ng == NULL) {
133 135 ng_new = (netgroup_name_t *)
134 136 calloc(1, sizeof (netgroup_name_t));
135 137 if (ng_new == NULL)
136 138 return (-1);
137 139 ng_new->name = strdup(name);
138 140 if (ng_new->name == NULL) {
139 141 free(ng_new);
140 142 return (-1);
141 143 }
142 144 ng_new->next_hash = tab->hash_list[h];
143 145 tab->hash_list[h] = ng_new;
144 146 ng_new->next = tab->to_do;
145 147 tab->to_do = ng_new;
146 148 }
147 149 return (0);
148 150 }
149 151
150 152 static netgroup_name_t *
151 153 get_next_netgroup(netgroup_table_t *tab)
152 154 {
153 155 netgroup_name_t *ng;
154 156
155 157 if (tab == NULL)
156 158 return (NULL);
157 159
158 160 ng = tab->to_do;
159 161 if (ng != NULL) {
160 162 tab->to_do = ng->next;
161 163 ng->next = tab->done;
162 164 tab->done = ng;
163 165 }
164 166 return (ng);
165 167 }
166 168
167 169 static void
168 170 free_netgroup_table(netgroup_table_t *tab)
169 171 {
170 172 netgroup_name_t *ng, *next;
171 173
172 174 if (tab == NULL)
173 175 return;
174 176
175 177 for (ng = tab->to_do; ng != NULL; ng = next) {
176 178 if (ng->name != NULL)
177 179 free(ng->name);
178 180 next = ng->next;
179 181 free(ng);
180 182 }
181 183
182 184 for (ng = tab->done; ng != NULL; ng = next) {
183 185 if (ng->name != NULL)
184 186 free(ng->name);
185 187 next = ng->next;
186 188 free(ng);
187 189 }
188 190 (void) memset(tab, 0, sizeof (*tab));
189 191 }
190 192
191 193 /*
192 194 * domain comparing routine
193 195 * n1: See if n1 is n2 or an ancestor of it
194 196 * n2: (in string terms, n1 is a suffix of n2)
195 197 * Returns ZERO for success, -1 for failure.
196 198 */
197 199 static int
198 200 domcmp(const char *n1, const char *n2)
199 201 {
200 202 #define PASS 0
201 203 #define FAIL -1
202 204
203 205 size_t l1, l2;
204 206
205 207 if ((n1 == NULL) || (n2 == NULL))
206 208 return (FAIL);
207 209
208 210 l1 = strlen(n1);
209 211 l2 = strlen(n2);
210 212
211 213 /* Turn a blind eye to the presence or absence of trailing periods */
212 214 if (l1 != 0 && n1[l1 - 1] == '.') {
213 215 --l1;
214 216 }
215 217 if (l2 != 0 && n2[l2 - 1] == '.') {
216 218 --l2;
217 219 }
218 220 if (l1 > l2) { /* Can't be a suffix */
219 221 return (FAIL);
220 222 } else if (l1 == 0) { /* Trivially a suffix; */
221 223 /* (do we want this case?) */
222 224 return (PASS);
223 225 }
224 226 /* So 0 < l1 <= l2 */
225 227 if (l1 < l2 && n2[l2 - l1 - 1] != '.') {
226 228 return (FAIL);
227 229 }
228 230 if (strncasecmp(n1, &n2[l2 - l1], l1) == 0) {
229 231 return (PASS);
230 232 } else {
231 233 return (FAIL);
232 234 }
233 235 }
234 236
235 237 static int
236 238 split_triple(char *triple, char **hostname, char **username, char **domain)
237 239 {
238 240 int i, syntax_err;
239 241 char *splittriple[3];
240 242 char *p = triple;
241 243
242 244 #ifdef DEBUG
243 245 (void) fprintf(stdout, "\n[getnetgrent.c: split_triple]\n");
244 246 #endif /* DEBUG */
245 247
246 248 if (triple == NULL)
247 249 return (-1);
248 250
249 251 p++;
250 252 syntax_err = 0;
251 253 for (i = 0; i < 3; i++) {
252 254 char *start;
253 255 char *limit;
254 256 const char *terminators = ",) \t";
255 257
256 258 if (i == 2) {
257 259 /* Don't allow comma */
258 260 terminators++;
259 261 }
260 262 while (isspace(*p)) {
261 263 p++;
262 264 }
263 265 start = p;
264 266 limit = strpbrk(start, terminators);
265 267 if (limit == 0) {
266 268 syntax_err++;
267 269 break;
268 270 }
269 271 p = limit;
270 272 while (isspace(*p)) {
271 273 p++;
272 274 }
273 275 if (*p == terminators[0]) {
274 276 /*
275 277 * Successfully parsed this name and
276 278 * the separator after it (comma or
277 279 * right paren); leave p ready for
278 280 * next parse.
279 281 */
280 282 p++;
281 283 if (start == limit) {
282 284 /* Wildcard */
283 285 splittriple[i] = NULL;
284 286 } else {
285 287 *limit = '\0';
286 288 splittriple[i] = start;
287 289 }
288 290 } else {
289 291 syntax_err++;
290 292 break;
291 293 }
292 294 }
293 295
294 296 if (syntax_err != 0)
295 297 return (-1);
296 298
297 299 *hostname = splittriple[0];
298 300 *username = splittriple[1];
299 301 *domain = splittriple[2];
300 302
301 303 return (0);
302 304 }
303 305
304 306 /*
305 307 * Test membership in triple
306 308 * return 0 = no match
307 309 * return 1 = match
308 310 */
309 311
310 312 static int
311 313 match_triple_entry(struct nss_innetgr_args *ia, const ns_ldap_entry_t *entry)
312 314 {
313 315 int ndomains;
314 316 char **pdomains;
315 317 int nhost;
316 318 char **phost;
317 319 int nusers;
318 320 char **pusers;
319 321 char **attr;
320 322 char triple[MAX_TRIPLE_LEN];
321 323 char *tuser, *thost, *tdomain;
322 324 int i;
323 325 char *current, *limit;
324 326 int pulen, phlen;
325 327 char *pusers0, *phost0;
326 328
327 329 nhost = ia->arg[NSS_NETGR_MACHINE].argc;
328 330 phost = (char **)ia->arg[NSS_NETGR_MACHINE].argv;
329 331 if (phost == NULL || *phost == NULL) {
330 332 nhost = 0;
331 333 } else {
332 334 phost0 = phost[0];
333 335 phlen = strlen(phost0);
334 336 #ifdef DEBUG
335 337 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
336 338 "entering with host: %s", phost0 ? phost0 : "");
337 339 #endif
338 340 }
339 341 nusers = ia->arg[NSS_NETGR_USER].argc;
340 342 pusers = (char **)ia->arg[NSS_NETGR_USER].argv;
341 343 if (pusers == NULL || *pusers == NULL) {
342 344 nusers = 0;
343 345 } else {
344 346 pusers0 = pusers[0];
345 347 pulen = strlen(pusers0);
346 348 #ifdef DEBUG
347 349 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
348 350 "entering with user: %s", pusers0 ? pusers0 : "");
349 351 #endif
350 352 }
351 353 ndomains = ia->arg[NSS_NETGR_DOMAIN].argc;
352 354 pdomains = (char **)ia->arg[NSS_NETGR_DOMAIN].argv;
353 355 if (pdomains == NULL || *pdomains == NULL)
354 356 ndomains = 0;
355 357 #ifdef DEBUG
356 358 else
357 359 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
358 360 "entering with domain: %s", pdomains[0] ? pdomains[0] : "");
359 361 #endif
360 362
361 363 attr = __ns_ldap_getAttr(entry, _N_TRIPLE);
362 364 if (attr == NULL || *attr == NULL)
363 365 return (0);
364 366
365 367 #ifdef DEBUG
366 368 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
367 369 "(nusers: %d, nhost:%d, ndomains: %d)",
368 370 nusers, nhost, ndomains);
369 371 #endif
370 372
371 373 /* Special cases for speedup */
372 374 if (nusers == 1 && nhost == 0 && ndomains == 0) {
373 375 /* Special case for finding a single user in a netgroup */
374 376 for (; *attr; attr++) {
375 377 /* jump to first comma and check next character */
376 378 current = *attr;
377 379 #ifdef DEBUG
378 380 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
379 381 "current is: %s", current);
380 382 #endif
381 383 if ((current = strchr(current, COMMA)) == NULL)
382 384 continue;
383 385 current++;
384 386
385 387 /* skip whitespaces */
386 388 while (isspace(*current))
387 389 current++;
388 390
389 391 /* if user part is null, then treat as wildcard */
390 392 if (*current == COMMA)
391 393 return (1);
392 394
393 395 /* compare first character */
394 396 if (*pusers0 != *current)
395 397 continue;
396 398
397 399 /* limit username to COMMA */
398 400 if ((limit = strchr(current, COMMA)) == NULL)
399 401 continue;
400 402 *limit = '\0';
401 403
402 404 /* remove blanks before COMMA */
403 405 if ((limit = strpbrk(current, " \t")) != NULL)
404 406 *limit = '\0';
405 407
406 408 /* compare size of username */
407 409 if (pulen != strlen(current)) {
408 410 continue;
409 411 }
410 412
411 413 /* do actual compare */
412 414 if (strncmp(pusers0, current, pulen) == 0) {
413 415 return (1);
414 416 } else {
415 417 continue;
416 418 }
417 419 }
418 420 } else if (nusers == 0 && nhost == 1 && ndomains == 0) {
419 421 /* Special case for finding a single host in a netgroup */
420 422 for (; *attr; attr++) {
421 423
422 424 /* jump to first character and check */
423 425 current = *attr;
424 426 #ifdef DEBUG
425 427 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
426 428 "current is: %s", current);
427 429 #endif
428 430 current++;
429 431
430 432 /* skip whitespaces */
431 433 while (isspace(*current))
432 434 current++;
433 435
434 436 /* if host part is null, then treat as wildcard */
435 437 if (*current == COMMA)
436 438 return (1);
437 439
438 440 /* limit hostname to COMMA */
439 441 if ((limit = strchr(current, COMMA)) == NULL)
440 442 continue;
441 443 *limit = '\0';
442 444
443 445 /* remove blanks before COMMA */
444 446 if ((limit = strpbrk(current, " \t")) != NULL)
445 447 *limit = '\0';
446 448
447 449 /* compare size of hostname */
448 450 if (phlen != strlen(current)) {
449 451 continue;
450 452 }
451 453
452 454 /* do actual compare */
453 455 if (strncasecmp(phost0, current, phlen) == 0) {
454 456 return (1);
455 457 } else {
456 458 continue;
457 459 }
458 460 }
459 461 } else {
460 462 for (; *attr; attr++) {
461 463 if (strlcpy(triple, *attr,
462 464 sizeof (triple)) >= sizeof (triple))
463 465 continue;
464 466 #ifdef DEBUG
465 467 syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
466 468 "triple is: %s", triple);
467 469 #endif
468 470 if (split_triple(triple, &thost, &tuser, &tdomain) != 0)
469 471 continue;
470 472 if (thost != NULL && *thost != '\0' && nhost != 0) {
471 473 for (i = 0; i < nhost; i++)
472 474 if (strcasecmp(thost, phost[i]) == 0)
473 475 break;
474 476 if (i == nhost)
475 477 continue;
476 478 }
477 479 if (tuser != NULL && *tuser != '\0' && nusers != 0) {
478 480 for (i = 0; i < nusers; i++)
479 481 if (strcmp(tuser, pusers[i]) == 0)
480 482 break;
481 483 if (i == nusers)
482 484 continue;
483 485 }
484 486 if (tdomain != NULL && *tdomain != '\0' &&
485 487 ndomains != 0) {
486 488 for (i = 0; i < ndomains; i++)
487 489 if (domcmp(tdomain, pdomains[i]) == 0)
488 490 break;
489 491 if (i == ndomains)
490 492 continue;
491 493 }
492 494 return (1);
493 495 }
494 496 }
495 497
496 498 return (0);
497 499 }
498 500
499 501 static int
500 502 match_triple(struct nss_innetgr_args *ia, ns_ldap_result_t *result)
501 503 {
502 504 ns_ldap_entry_t *entry;
503 505
504 506 for (entry = result->entry; entry != NULL; entry = entry->next)
505 507 if (match_triple_entry(ia, entry) == 1)
506 508 return (1);
507 509
508 510 return (0);
509 511 }
510 512
511 513 static int
512 514 add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab)
513 515 {
514 516 char **attrs;
515 517 char **a;
516 518
517 519 attrs = __ns_ldap_getAttr(entry, _N_MEMBER);
518 520 if (attrs == NULL || *attrs == NULL)
519 521 return (0);
520 522
521 523 for (a = attrs; *a != NULL; a++) {}
522 524
523 525 do {
524 526 a--;
525 527 if (add_netgroup_name(*a, tab) != 0)
526 528 return (-1);
527 529 } while (a > attrs);
528 530 return (0);
529 531 }
530 532
531 533 static int
532 534 add_netgroup_member(ns_ldap_result_t *result, netgroup_table_t *tab)
533 535 {
534 536 ns_ldap_entry_t *entry;
535 537 int ret = 0;
536 538
537 539 for (entry = result->entry; entry != NULL; entry = entry->next) {
538 540 ret = add_netgroup_member_entry(entry, tab);
539 541 if (ret != 0)
540 542 break;
541 543 }
542 544 return (ret);
543 545 }
544 546
545 547 /*
546 548 * top_down_search checks only checks the netgroup specified in netgrname
547 549 */
548 550 static nss_status_t
549 551 top_down_search(struct nss_innetgr_args *ia, char *netgrname)
550 552 {
551 553 char searchfilter[SEARCHFILTERLEN];
552 554 char name[SEARCHFILTERLEN];
553 555 char userdata[SEARCHFILTERLEN];
554 556 ns_ldap_result_t *result = NULL;
555 557 ns_ldap_error_t *error = NULL;
556 558 int rc;
557 559 nss_status_t status = NSS_NOTFOUND;
558 560 nss_status_t status1;
559 561 netgroup_table_t tab;
560 562 netgroup_name_t *ng;
561 563 int ret;
562 564
563 565 (void) memset(&tab, 0, sizeof (tab));
564 566
565 567 if (add_netgroup_name(netgrname, &tab) != 0)
566 568 return ((nss_status_t)NSS_NOTFOUND);
567 569
568 570 while ((ng = get_next_netgroup(&tab)) != NULL) {
569 571 #ifdef DEBUG
570 572 syslog(LOG_DEBUG, "nss_ldap: top_down_search: netgroup loop "
571 573 "(ng->name: %s)", ng->name ? ng->name : "null !");
572 574 #endif
573 575 if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0)
574 576 break;
575 577 ret = snprintf(searchfilter, sizeof (searchfilter),
576 578 _F_SETMEMBER, name);
577 579 if (ret >= sizeof (searchfilter) || ret < 0)
578 580 break;
579 581
580 582 ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD,
581 583 name);
582 584 if (ret >= sizeof (userdata) || ret < 0)
583 585 break;
584 586
585 587 /* searching for current netgroup name entry */
586 588 rc = __ns_ldap_list(_NETGROUP, searchfilter,
587 589 _merge_SSD_filter, netgrent_attrs, NULL, 0, &result,
588 590 &error, NULL, userdata);
589 591
590 592 if (error != NULL) {
591 593 status1 = switch_err(rc, error);
592 594 if (status1 == NSS_TRYAGAIN) {
593 595 (void) __ns_ldap_freeError(&error);
594 596 free_netgroup_table(&tab);
595 597 return (status1);
596 598 }
597 599 }
598 600
599 601 (void) __ns_ldap_freeError(&error);
600 602 if (rc == NS_LDAP_SUCCESS) {
601 603 if (match_triple(ia, result) == 1) {
602 604 /* We found a match */
603 605 ia->status = NSS_NETGR_FOUND;
604 606 status = NSS_SUCCESS;
605 607 #ifdef DEBUG
606 608 syslog(LOG_DEBUG, "nss_ldap: top_down_search: "
607 609 "found match");
608 610 #endif
609 611 break;
610 612 }
611 613
612 614 /*
613 615 * No match found. Check for membernisnetgroup
614 616 * in result and if yes, start again with those.
615 617 */
616 618 rc = add_netgroup_member(result, &tab);
617 619 if (rc != 0)
618 620 break;
619 621 } else if (rc != NS_LDAP_NOTFOUND) {
620 622 break;
621 623 }
622 624 (void) __ns_ldap_freeResult(&result);
623 625 }
624 626
625 627 (void) __ns_ldap_freeResult(&result);
626 628 free_netgroup_table(&tab);
627 629 return (status);
628 630 }
629 631
630 632 /*
631 633 * __netgr_in checks only checks the netgroup specified in ngroup
632 634 */
633 635 static nss_status_t
634 636 __netgr_in(void *a, char *netgrname)
635 637 {
636 638 struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a;
637 639 nss_status_t status = NSS_NOTFOUND;
638 640
639 641 #ifdef DEBUG
640 642 (void) fprintf(stdout, "\n[getnetgrent.c: netgr_in]\n");
641 643 (void) fprintf(stdout, "\tmachine: argc[%d]='%s' user: "
642 644 "argc[%d]='%s',\n\tdomain:argc[%d]='%s' "
643 645 "netgroup: argc[%d]='%s'\n",
644 646 NSS_NETGR_MACHINE,
645 647 PRINT_VAL(ia->arg[NSS_NETGR_MACHINE]),
646 648 NSS_NETGR_USER,
647 649 PRINT_VAL(ia->arg[NSS_NETGR_USER]),
648 650 NSS_NETGR_DOMAIN,
649 651 PRINT_VAL(ia->arg[NSS_NETGR_DOMAIN]),
650 652 NSS_NETGR_N,
651 653 PRINT_VAL(ia->arg[NSS_NETGR_N]));
652 654 (void) fprintf(stdout, "\tgroups='%s'\n", netgrname);
653 655 #endif /* DEBUG */
654 656
655 657 ia->status = NSS_NETGR_NO;
656 658
657 659 if (netgrname == NULL)
658 660 return (status);
659 661
660 662 return (top_down_search(ia, netgrname));
661 663 }
662 664
663 665 /*ARGSUSED0*/
664 666 static nss_status_t
665 667 netgr_in(ldap_backend_ptr be, void *a)
666 668 {
667 669 struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a;
668 670 int i;
669 671 nss_status_t rc = (nss_status_t)NSS_NOTFOUND;
670 672
671 673 ia->status = NSS_NETGR_NO;
672 674 for (i = 0; i < ia->groups.argc; i++) {
673 675 rc = __netgr_in(a, ia->groups.argv[i]);
674 676 if (ia->status == NSS_NETGR_FOUND)
675 677 return (NSS_SUCCESS);
676 678 }
677 679 return (rc);
678 680 }
679 681
680 682 /*
681 683 *
682 684 */
683 685
684 686 static nss_status_t
685 687 getnetgr_ldap_setent(ldap_backend_ptr be, void *a)
686 688 {
687 689 const char *netgroup = (const char *) a;
688 690 getnetgrent_cookie_t *cookie;
689 691
690 692 #ifdef DEBUG
691 693 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_setent]\n");
692 694 #endif /* DEBUG */
693 695
694 696 cookie = (getnetgrent_cookie_t *)be->netgroup_cookie;
695 697 if (cookie != NULL && cookie->netgroup != NULL) {
696 698 /* is this another set on the same netgroup */
697 699 if (strcmp(cookie->netgroup, netgroup) == 0)
698 700 return ((nss_status_t)NSS_SUCCESS);
699 701 }
700 702
701 703 return (NSS_NOTFOUND);
702 704 }
703 705
704 706 static void
705 707 free_getnetgrent_cookie(getnetgrent_cookie_t **cookie)
706 708 {
707 709 getnetgrent_cookie_t *p = *cookie;
708 710
709 711 #ifdef DEBUG
710 712 (void) fprintf(stdout, "\n[getnetgrent.c: free_getnetgrent_cookie]\n");
711 713 #endif /* DEBUG */
712 714
713 715 if (p == NULL)
714 716 return;
715 717
716 718 (void) __ns_ldap_freeResult(&p->results);
717 719 free_netgroup_table(&p->tab);
718 720 free(p->netgroup);
719 721 free(p);
720 722 *cookie = NULL;
721 723 }
722 724
723 725 /*ARGSUSED1*/
724 726 static nss_status_t
725 727 getnetgr_ldap_endent(ldap_backend_ptr be, void *a)
726 728 {
727 729
728 730 #ifdef DEBUG
729 731 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_endent]\n");
730 732 #endif /* DEBUG */
731 733
732 734 free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie);
733 735
734 736 return ((nss_status_t)NSS_NOTFOUND);
735 737 }
736 738
737 739
738 740 /*ARGSUSED1*/
739 741 static nss_status_t
740 742 getnetgr_ldap_destr(ldap_backend_ptr be, void *a)
741 743 {
742 744
743 745 #ifdef DEBUG
744 746 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_destr]\n");
745 747 #endif /* DEBUG */
746 748
747 749 free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie);
748 750 free(be);
749 751
750 752 return ((nss_status_t)NSS_NOTFOUND);
751 753 }
752 754
753 755
754 756 static nss_status_t
755 757 getnetgr_ldap_getent(ldap_backend_ptr be, void *a)
756 758 {
757 759 struct nss_getnetgrent_args *args;
758 760 getnetgrent_cookie_t *p;
759 761 char searchfilter[SEARCHFILTERLEN];
760 762 char userdata[SEARCHFILTERLEN];
761 763 char name[SEARCHFILTERLEN];
762 764 int rc;
763 765 ns_ldap_result_t *result = NULL;
764 766 ns_ldap_error_t *error = NULL;
765 767 char **attrs;
766 768 char *hostname, *username, *domain;
767 769 char *buffer;
768 770 nss_status_t status = NSS_SUCCESS;
769 771 netgroup_name_t *ng;
770 772 int ret;
771 773
772 774 #ifdef DEBUG
773 775 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n");
774 776 #endif /* DEBUG */
775 777
776 778 args = (struct nss_getnetgrent_args *)a;
777 779
778 780 args->status = NSS_NETGR_NO;
779 781
780 782 p = (getnetgrent_cookie_t *)be->netgroup_cookie;
781 783 if (p == NULL)
782 784 return ((nss_status_t)NSS_SUCCESS);
783 785
784 786 for (;;) {
785 787 /*
786 788 * Search through each netgroup consecutively: only search
787 789 * next netgroup when results from previous netgroup are
788 790 * processed.
789 791 * Needed for nested netgroup (memberNisNetgroup attributes).
790 792 */
791 793 if (p->results == NULL) {
792 794 if ((ng = get_next_netgroup(&p->tab)) != NULL) {
793 795 if (_ldap_filter_name(name, ng->name,
794 796 sizeof (name)) != 0)
795 797 break;
796 798
797 799 ret = snprintf(searchfilter,
798 800 sizeof (searchfilter),
799 801 _F_SETMEMBER, name);
800 802 if (ret >= sizeof (searchfilter) || ret < 0)
801 803 break;
802 804
803 805 #ifdef DEBUG
804 806 syslog(LOG_DEBUG, "nss_ldap: "
805 807 "getnetgr_ldap_getent: "
806 808 "netgroup name: %s", name);
807 809 #endif
808 810 ret = snprintf(userdata, sizeof (userdata),
809 811 _F_SETMEMBER_SSD, name);
810 812 if (ret >= sizeof (userdata) || ret < 0)
811 813 break;
812 814
813 815 result = NULL;
814 816 rc = __ns_ldap_list(_NETGROUP, searchfilter,
815 817 _merge_SSD_filter, netgrent_attrs, NULL,
816 818 0, &result, &error, NULL, userdata);
817 819 (void) __ns_ldap_freeError(&error);
818 820
819 821 if (rc == NS_LDAP_SUCCESS && result != NULL) {
820 822 p->results = result;
821 823 } else {
822 824 #ifdef DEBUG
823 825 syslog(LOG_DEBUG, "nss_ldap: "
824 826 "getnetgr_ldap_getent: "
825 827 "__ns_ldap_list() returned %d "
826 828 "(result: 0x%x)", rc, result);
827 829 #endif
828 830 /*
829 831 * Will exit when no more netgroup
830 832 * to search and no more p->results
831 833 * to process.
832 834 */
833 835 (void) __ns_ldap_freeResult(&result);
834 836 }
835 837 } else { /* no more netgroup to process */
836 838 /*
837 839 * If no more results to process, and since
838 840 * there's no more netgroup to process either,
839 841 * then it's time to break and exit the for
840 842 * loop.
841 843 */
842 844 #ifdef DEBUG
843 845 syslog(LOG_DEBUG, "nss_ldap: "
844 846 "getnetgr_ldap_getent: no more netgroup "
845 847 "to process, p->results: 0x%x",
846 848 p->results);
847 849 #endif
848 850 if (p->results == NULL)
849 851 break;
850 852 }
851 853 }
852 854 if (p->results == NULL)
853 855 continue;
854 856
855 857 if (p->entry == NULL)
856 858 p->entry = p->results->entry;
857 859
858 860 if (p->entry == NULL)
859 861 continue;
860 862
861 863 if (p->attrs == NULL) {
862 864 attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE);
863 865 if (attrs != NULL && *attrs != NULL)
864 866 p->attrs = attrs;
865 867 }
866 868
867 869 if (p->attrs != NULL) {
868 870 attrs = p->attrs;
869 871 buffer = args->buffer;
870 872
871 873 if (strlcpy(buffer, *attrs, args->buflen) >=
872 874 args->buflen) {
873 875 status = NSS_STR_PARSE_ERANGE;
874 876 break;
875 877 }
876 878
877 879 rc = split_triple(buffer, &hostname, &username,
878 880 &domain);
879 881 attrs++;
880 882 if (attrs != NULL && *attrs != NULL)
881 883 p->attrs = attrs;
882 884 else
883 885 p->attrs = NULL;
884 886 if (rc == 0) {
885 887 args->retp[NSS_NETGR_MACHINE] = hostname;
886 888 args->retp[NSS_NETGR_USER] = username;
887 889 args->retp[NSS_NETGR_DOMAIN] = domain;
888 890 args->status = NSS_NETGR_FOUND;
889 891 #ifdef DEBUG
890 892 syslog(LOG_DEBUG, "nss_ldap: "
891 893 "getnetgr_ldap_getent: found triple "
892 894 "(%s, %s, %s), 0x%x to process",
893 895 hostname ? hostname : "",
894 896 username ? username : "",
895 897 domain ? domain : "",
896 898 p->attrs);
897 899 #endif
898 900 if (p->attrs != NULL)
899 901 break;
900 902 }
901 903 }
902 904
903 905 if (p->attrs == NULL) {
904 906 rc = add_netgroup_member_entry(p->entry, &p->tab);
905 907 if (rc != 0) {
906 908 args->status = NSS_NETGR_NO;
907 909 break;
908 910 }
909 911
910 912 p->entry = p->entry->next;
911 913 if (p->entry == NULL)
912 914 (void) __ns_ldap_freeResult(&p->results);
913 915 if (args->status == NSS_NETGR_FOUND)
914 916 break;
915 917 }
916 918 }
917 919
918 920 return (status);
919 921 }
920 922
921 923 static ldap_backend_op_t getnetgroup_ops[] = {
922 924 getnetgr_ldap_destr,
923 925 getnetgr_ldap_endent,
924 926 getnetgr_ldap_setent,
925 927 getnetgr_ldap_getent,
926 928 };
927 929
928 930 /*
929 931 *
930 932 */
931 933
932 934 static nss_status_t
933 935 netgr_set(ldap_backend_ptr be, void *a)
934 936 {
935 937 struct nss_setnetgrent_args *args =
936 938 (struct nss_setnetgrent_args *)a;
937 939 ldap_backend_ptr get_be;
938 940 getnetgrent_cookie_t *p;
939 941
940 942 #ifdef DEBUG
941 943 (void) fprintf(stdout, "\n[getnetgrent.c: netgr_set]\n");
942 944 (void) fprintf(stdout,
943 945 "\targs->netgroup: %s\n", ISNULL(args->netgroup));
944 946 #endif /* DEBUG */
945 947
946 948 if (args->netgroup == NULL)
947 949 return ((nss_status_t)NSS_NOTFOUND);
948 950
949 951 free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie);
950 952 p = (getnetgrent_cookie_t *)calloc(1, sizeof (getnetgrent_cookie_t));
951 953 if (p == NULL)
952 954 return ((nss_status_t)NSS_NOTFOUND);
953 955 p->netgroup = strdup(args->netgroup);
954 956 if (p->netgroup == NULL) {
955 957 free(p);
956 958 return ((nss_status_t)NSS_NOTFOUND);
957 959 }
958 960 if (add_netgroup_name(args->netgroup, &p->tab) == -1) {
959 961 free_getnetgrent_cookie(&p);
960 962 return ((nss_status_t)NSS_NOTFOUND);
961 963 }
962 964
963 965 /* now allocate and return iteration backend structure */
964 966 if ((get_be = (ldap_backend_ptr)malloc(sizeof (*get_be))) == NULL)
965 967 return (NSS_UNAVAIL);
966 968 get_be->ops = getnetgroup_ops;
967 969 get_be->nops = sizeof (getnetgroup_ops) / sizeof (getnetgroup_ops[0]);
968 970 get_be->tablename = NULL;
969 971 get_be->attrs = netgrent_attrs;
970 972 get_be->result = NULL;
971 973 get_be->ldapobj2str = NULL;
972 974 get_be->setcalled = 1;
973 975 get_be->filter = NULL;
974 976 get_be->toglue = NULL;
975 977 get_be->enumcookie = NULL;
976 978 get_be->netgroup_cookie = p;
977 979 args->iterator = (nss_backend_t *)get_be;
978 980
979 981 (void) __ns_ldap_freeResult(&be->result);
980 982
981 983 return (NSS_SUCCESS);
982 984 }
983 985
984 986
985 987 /*ARGSUSED1*/
986 988 static nss_status_t
987 989 netgr_ldap_destr(ldap_backend_ptr be, void *a)
988 990 {
989 991
990 992 #ifdef DEBUG
991 993 (void) fprintf(stdout, "\n[getnetgrent.c: netgr_ldap_destr]\n");
992 994 #endif /* DEBUG */
993 995
994 996 (void) _clean_ldap_backend(be);
995 997
996 998 return ((nss_status_t)NSS_NOTFOUND);
997 999 }
998 1000
999 1001
1000 1002
1001 1003
1002 1004 static ldap_backend_op_t netgroup_ops[] = {
1003 1005 netgr_ldap_destr,
1004 1006 0,
1005 1007 0,
1006 1008 0,
1007 1009 netgr_in, /* innetgr() */
1008 1010 netgr_set /* setnetgrent() */
1009 1011 };
1010 1012
1011 1013
1012 1014 /*
1013 1015 * _nss_ldap_netgroup_constr is where life begins. This function calls the
1014 1016 * generic ldap constructor function to define and build the abstract data
1015 1017 * types required to support ldap operations.
1016 1018 */
1017 1019
1018 1020 /*ARGSUSED0*/
1019 1021 nss_backend_t *
1020 1022 _nss_ldap_netgroup_constr(const char *dummy1, const char *dummy2,
1021 1023 const char *dummy3)
1022 1024 {
1023 1025
1024 1026 #ifdef DEBUG
1025 1027 (void) fprintf(stdout,
1026 1028 "\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n");
1027 1029 #endif /* DEBUG */
1028 1030
1029 1031 return ((nss_backend_t *)_nss_ldap_constr(netgroup_ops,
1030 1032 sizeof (netgroup_ops)/sizeof (netgroup_ops[0]), _NETGROUP,
1031 1033 netgrent_attrs, NULL));
1032 1034 }
↓ open down ↓ |
984 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX