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