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 /* limit hostname to COMMA */ 404 if ((limit = strchr(current, COMMA)) == NULL) 405 continue; 406 *limit = '\0'; 407 408 /* remove blanks before COMMA */ 409 if ((limit = strpbrk(current, " \t")) != NULL) 410 *limit = '\0'; 411 412 /* compare size of hostname */ 413 if (phlen != strlen(current)) { 414 continue; 415 } 416 417 /* do actual compare */ 418 if (strncasecmp(phost0, current, phlen) == 0) { 419 return (1); 420 } else { 421 continue; 422 } 423 } 424 } else { 425 for (; *attr; attr++) { 426 if (strlcpy(triple, *attr, 427 sizeof (triple)) >= sizeof (triple)) 428 continue; 429 if (split_triple(triple, &thost, &tuser, &tdomain) != 0) 430 continue; 431 if (thost != NULL && *thost != '\0' && nhost != 0) { 432 for (i = 0; i < nhost; i++) 433 if (strcasecmp(thost, phost[i]) == 0) 434 break; 435 if (i == nhost) 436 continue; 437 } 438 if (tuser != NULL && *tuser != '\0' && nusers != 0) { 439 for (i = 0; i < nusers; i++) 440 if (strcmp(tuser, pusers[i]) == 0) 441 break; 442 if (i == nusers) 443 continue; 444 } 445 if (tdomain != NULL && *tdomain != '\0' && 446 ndomains != 0) { 447 for (i = 0; i < ndomains; i++) 448 if (domcmp(tdomain, pdomains[i]) == 0) 449 break; 450 if (i == ndomains) 451 continue; 452 } 453 return (1); 454 } 455 } 456 457 return (0); 458 } 459 460 static int 461 match_triple(struct nss_innetgr_args *ia, ns_ldap_result_t *result) 462 { 463 ns_ldap_entry_t *entry; 464 465 for (entry = result->entry; entry != NULL; entry = entry->next) 466 if (match_triple_entry(ia, entry) == 1) 467 return (1); 468 469 return (0); 470 } 471 472 static int 473 add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab) 474 { 475 char **attrs; 476 char **a; 477 478 attrs = __ns_ldap_getAttr(entry, _N_MEMBER); 479 if (attrs == NULL || *attrs == NULL) 480 return (0); 481 482 for (a = attrs; *a != NULL; a++) {} 483 484 do { 485 a--; 486 if (add_netgroup_name(*a, tab) != 0) 487 return (-1); 488 } while (a > attrs); 489 return (0); 490 } 491 492 static int 493 add_netgroup_member(ns_ldap_result_t *result, netgroup_table_t *tab) 494 { 495 ns_ldap_entry_t *entry; 496 int ret = 0; 497 498 for (entry = result->entry; entry != NULL; entry = entry->next) { 499 ret = add_netgroup_member_entry(entry, tab); 500 if (ret != 0) 501 break; 502 } 503 return (ret); 504 } 505 506 /* 507 * top_down_search checks only checks the netgroup specified in netgrname 508 */ 509 static nss_status_t 510 top_down_search(struct nss_innetgr_args *ia, char *netgrname) 511 { 512 char searchfilter[SEARCHFILTERLEN]; 513 char name[SEARCHFILTERLEN]; 514 char userdata[SEARCHFILTERLEN]; 515 ns_ldap_result_t *result = NULL; 516 ns_ldap_error_t *error = NULL; 517 int rc; 518 void *cookie = NULL; 519 nss_status_t status = NSS_NOTFOUND; 520 netgroup_table_t tab; 521 netgroup_name_t *ng; 522 int ret; 523 524 (void) memset(&tab, 0, sizeof (tab)); 525 526 if (add_netgroup_name(netgrname, &tab) != 0) 527 return ((nss_status_t)NSS_NOTFOUND); 528 529 while ((ng = get_next_netgroup(&tab)) != NULL) { 530 if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0) 531 break; 532 ret = snprintf(searchfilter, sizeof (searchfilter), _F_SETMEMBER, 533 name); 534 if (ret >= sizeof (searchfilter) || ret < 0) 535 break; 536 537 ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD, name); 538 if (ret >= sizeof (userdata) || ret < 0) 539 break; 540 541 rc = __ns_ldap_firstEntry(_NETGROUP, searchfilter, 542 _merge_SSD_filter, netgrent_attrs, NULL, 0, &cookie, &result, 543 &error, userdata); 544 545 (void) __ns_ldap_freeError(&error); 546 while (rc == NS_LDAP_SUCCESS && result != NULL) { 547 if (match_triple(ia, result) == 1) { 548 /* We found a match */ 549 ia->status = NSS_NETGR_FOUND; 550 status = NSS_SUCCESS; 551 break; 552 } 553 554 rc = add_netgroup_member(result, &tab); 555 (void) __ns_ldap_freeResult(&result); 556 557 if (rc != NS_LDAP_SUCCESS) 558 break; 559 rc = __ns_ldap_nextEntry(cookie, &result, &error); 560 (void) __ns_ldap_freeError(&error); 561 } 562 (void) __ns_ldap_freeResult(&result); 563 (void) __ns_ldap_endEntry(&cookie, &error); 564 (void) __ns_ldap_freeError(&error); 565 566 if (status == NSS_SUCCESS || 567 (rc != NS_LDAP_SUCCESS && rc != NS_LDAP_NOTFOUND)) 568 break; 569 } 570 571 (void) __ns_ldap_freeResult(&result); 572 (void) __ns_ldap_endEntry(&cookie, &error); 573 (void) __ns_ldap_freeError(&error); 574 free_netgroup_table(&tab); 575 return (status); 576 } 577 578 /* 579 * __netgr_in checks only checks the netgroup specified in ngroup 580 */ 581 static nss_status_t 582 __netgr_in(void *a, char *netgrname) 583 { 584 struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 585 nss_status_t status = NSS_NOTFOUND; 586 587 #ifdef DEBUG 588 (void) fprintf(stdout, "\n[getnetgrent.c: netgr_in]\n"); 589 (void) fprintf(stdout, "\tmachine: argc[%d]='%s' user: " 590 "argc[%d]='%s',\n\tdomain:argc[%d]='%s' " 591 "netgroup: argc[%d]='%s'\n", 592 NSS_NETGR_MACHINE, 593 PRINT_VAL(ia->arg[NSS_NETGR_MACHINE]), 594 NSS_NETGR_USER, 595 PRINT_VAL(ia->arg[NSS_NETGR_USER]), 596 NSS_NETGR_DOMAIN, 597 PRINT_VAL(ia->arg[NSS_NETGR_DOMAIN]), 598 NSS_NETGR_N, 599 PRINT_VAL(ia->arg[NSS_NETGR_N])); 600 (void) fprintf(stdout, "\tgroups='%s'\n", netgrname); 601 #endif /* DEBUG */ 602 603 ia->status = NSS_NETGR_NO; 604 605 if (netgrname == NULL) 606 return (status); 607 608 return (top_down_search(ia, netgrname)); 609 } 610 611 /*ARGSUSED0*/ 612 static nss_status_t 613 netgr_in(ldap_backend_ptr be, void *a) 614 { 615 struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 616 int i; 617 nss_status_t rc = (nss_status_t)NSS_NOTFOUND; 618 619 ia->status = NSS_NETGR_NO; 620 for (i = 0; i < ia->groups.argc; i++) { 621 rc = __netgr_in(a, ia->groups.argv[i]); 622 if (ia->status == NSS_NETGR_FOUND) 623 return (NSS_SUCCESS); 624 } 625 return (rc); 626 } 627 628 /* 629 * 630 */ 631 632 static nss_status_t 633 getnetgr_ldap_setent(ldap_backend_ptr be, void *a) 634 { 635 const char *netgroup = (const char *) a; 636 getnetgrent_cookie_t *cookie; 637 638 #ifdef DEBUG 639 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_setent]\n"); 640 #endif /* DEBUG */ 641 642 cookie = (getnetgrent_cookie_t *)be->netgroup_cookie; 643 if (cookie != NULL && cookie->netgroup != NULL) { 644 /* is this another set on the same netgroup */ 645 if (strcmp(cookie->netgroup, netgroup) == 0) 646 return ((nss_status_t)NSS_SUCCESS); 647 } 648 649 return (NSS_NOTFOUND); 650 } 651 652 static void 653 free_getnetgrent_cookie(getnetgrent_cookie_t **cookie) 654 { 655 ns_ldap_error_t *error = NULL; 656 getnetgrent_cookie_t *p = *cookie; 657 658 #ifdef DEBUG 659 (void) fprintf(stdout, "\n[getnetgrent.c: free_getnetgrent_cookie]\n"); 660 #endif /* DEBUG */ 661 662 if (p == NULL) 663 return; 664 665 (void) __ns_ldap_freeResult(&p->results); 666 (void) __ns_ldap_endEntry(&p->cookie, &error); 667 (void) __ns_ldap_freeError(&error); 668 free_netgroup_table(&p->tab); 669 free(p->netgroup); 670 free(p); 671 *cookie = NULL; 672 } 673 674 /*ARGSUSED1*/ 675 static nss_status_t 676 getnetgr_ldap_endent(ldap_backend_ptr be, void *a) 677 { 678 679 #ifdef DEBUG 680 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_endent]\n"); 681 #endif /* DEBUG */ 682 683 free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 684 685 return ((nss_status_t)NSS_NOTFOUND); 686 } 687 688 689 /*ARGSUSED1*/ 690 static nss_status_t 691 getnetgr_ldap_destr(ldap_backend_ptr be, void *a) 692 { 693 694 #ifdef DEBUG 695 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_destr]\n"); 696 #endif /* DEBUG */ 697 698 free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 699 free(be); 700 701 return ((nss_status_t)NSS_NOTFOUND); 702 } 703 704 705 static nss_status_t 706 getnetgr_ldap_getent(ldap_backend_ptr be, void *a) 707 { 708 struct nss_getnetgrent_args *args; 709 getnetgrent_cookie_t *p; 710 char searchfilter[SEARCHFILTERLEN]; 711 char userdata[SEARCHFILTERLEN]; 712 char name[SEARCHFILTERLEN]; 713 int rc; 714 void *cookie = NULL; 715 ns_ldap_result_t *result = NULL; 716 ns_ldap_error_t *error = NULL; 717 char **attrs; 718 char *hostname, *username, *domain; 719 char *buffer; 720 nss_status_t status = NSS_SUCCESS; 721 netgroup_name_t *ng; 722 int ret; 723 724 #ifdef DEBUG 725 (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n"); 726 #endif /* DEBUG */ 727 728 args = (struct nss_getnetgrent_args *)a; 729 730 args->status = NSS_NETGR_NO; 731 732 p = (getnetgrent_cookie_t *)be->netgroup_cookie; 733 if (p == NULL) 734 return ((nss_status_t)NSS_SUCCESS); 735 736 for (;;) { 737 while (p->cookie == NULL) { 738 ng = get_next_netgroup(&p->tab); 739 if (ng == NULL) /* no more */ 740 break; 741 742 if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0) 743 break; 744 745 ret = snprintf(searchfilter, sizeof (searchfilter), 746 _F_SETMEMBER, name); 747 if (ret >= sizeof (searchfilter) || ret < 0) 748 break; 749 750 ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD, 751 name); 752 if (ret >= sizeof (userdata) || ret < 0) 753 break; 754 755 result = NULL; 756 rc = __ns_ldap_firstEntry(_NETGROUP, searchfilter, 757 _merge_SSD_filter, netgrent_attrs, NULL, 0, &cookie, 758 &result, &error, userdata); 759 (void) __ns_ldap_freeError(&error); 760 761 if (rc == NS_LDAP_SUCCESS && result != NULL) { 762 p->cookie = cookie; 763 p->results = result; 764 break; 765 } 766 (void) __ns_ldap_freeResult(&result); 767 (void) __ns_ldap_endEntry(&cookie, &error); 768 (void) __ns_ldap_freeError(&error); 769 } 770 if (p->cookie == NULL) 771 break; 772 if (p->results == NULL) { 773 result = NULL; 774 rc = __ns_ldap_nextEntry(p->cookie, &result, &error); 775 (void) __ns_ldap_freeError(&error); 776 if (rc == NS_LDAP_SUCCESS && result != NULL) 777 p->results = result; 778 else { 779 (void) __ns_ldap_freeResult(&result); 780 (void) __ns_ldap_endEntry(&p->cookie, &error); 781 (void) __ns_ldap_freeError(&error); 782 p->cookie = NULL; 783 } 784 } 785 if (p->results == NULL) 786 continue; 787 788 if (p->entry == NULL) 789 p->entry = p->results->entry; 790 791 if (p->entry == NULL) 792 continue; 793 794 if (p->attrs == NULL) { 795 attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE); 796 if (attrs != NULL && *attrs != NULL) 797 p->attrs = attrs; 798 } 799 800 if (p->attrs != NULL) { 801 attrs = p->attrs; 802 buffer = args->buffer; 803 804 if (strlcpy(buffer, *attrs, args->buflen) >= args->buflen) { 805 status = NSS_STR_PARSE_ERANGE; 806 break; 807 } 808 809 rc = split_triple(buffer, &hostname, &username, &domain); 810 attrs++; 811 if (attrs != NULL && *attrs != NULL) 812 p->attrs = attrs; 813 else 814 p->attrs = NULL; 815 if (rc == 0) { 816 args->retp[NSS_NETGR_MACHINE] = hostname; 817 args->retp[NSS_NETGR_USER] = username; 818 args->retp[NSS_NETGR_DOMAIN] = domain; 819 args->status = NSS_NETGR_FOUND; 820 if (p->attrs != NULL) 821 break; 822 } 823 } 824 825 if (p->attrs == NULL) { 826 rc = add_netgroup_member_entry(p->entry, &p->tab); 827 if (rc != 0) { 828 args->status = NSS_NETGR_NO; 829 break; 830 } 831 832 p->entry = p->entry->next; 833 if (p->entry == NULL) 834 (void) __ns_ldap_freeResult(&p->results); 835 if (args->status == NSS_NETGR_FOUND) 836 break; 837 } 838 } 839 840 return (status); 841 } 842 843 static ldap_backend_op_t getnetgroup_ops[] = { 844 getnetgr_ldap_destr, 845 getnetgr_ldap_endent, 846 getnetgr_ldap_setent, 847 getnetgr_ldap_getent, 848 }; 849 850 /* 851 * 852 */ 853 854 static nss_status_t 855 netgr_set(ldap_backend_ptr be, void *a) 856 { 857 struct nss_setnetgrent_args *args = 858 (struct nss_setnetgrent_args *)a; 859 ldap_backend_ptr get_be; 860 getnetgrent_cookie_t *p; 861 862 #ifdef DEBUG 863 (void) fprintf(stdout, "\n[getnetgrent.c: netgr_set]\n"); 864 (void) fprintf(stdout, 865 "\targs->netgroup: %s\n", ISNULL(args->netgroup)); 866 #endif /* DEBUG */ 867 868 if (args->netgroup == NULL) 869 return ((nss_status_t)NSS_NOTFOUND); 870 871 free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 872 p = (getnetgrent_cookie_t *)calloc(1, sizeof (getnetgrent_cookie_t)); 873 if (p == NULL) 874 return ((nss_status_t)NSS_NOTFOUND); 875 p->netgroup = strdup(args->netgroup); 876 if (p->netgroup == NULL) { 877 free(p); 878 return ((nss_status_t)NSS_NOTFOUND); 879 } 880 if (add_netgroup_name(args->netgroup, &p->tab) == -1) { 881 free_getnetgrent_cookie(&p); 882 return ((nss_status_t)NSS_NOTFOUND); 883 } 884 885 /* now allocate and return iteration backend structure */ 886 if ((get_be = (ldap_backend_ptr)malloc(sizeof (*get_be))) == NULL) 887 return (NSS_UNAVAIL); 888 get_be->ops = getnetgroup_ops; 889 get_be->nops = sizeof (getnetgroup_ops) / sizeof (getnetgroup_ops[0]); 890 get_be->tablename = NULL; 891 get_be->attrs = netgrent_attrs; 892 get_be->result = NULL; 893 get_be->ldapobj2ent = NULL; 894 get_be->setcalled = 1; 895 get_be->filter = NULL; 896 get_be->toglue = NULL; 897 get_be->enumcookie = NULL; 898 get_be->netgroup_cookie = p; 899 args->iterator = (nss_backend_t *)get_be; 900 901 (void) __ns_ldap_freeResult(&be->result); 902 903 return (NSS_SUCCESS); 904 } 905 906 907 /*ARGSUSED1*/ 908 static nss_status_t 909 netgr_ldap_destr(ldap_backend_ptr be, void *a) 910 { 911 912 #ifdef DEBUG 913 (void) fprintf(stdout, "\n[getnetgrent.c: netgr_ldap_destr]\n"); 914 #endif /* DEBUG */ 915 916 (void) _clean_ldap_backend(be); 917 918 return ((nss_status_t)NSS_NOTFOUND); 919 } 920 921 922 923 924 static ldap_backend_op_t netgroup_ops[] = { 925 netgr_ldap_destr, 926 0, 927 0, 928 0, 929 netgr_in, /* innetgr() */ 930 netgr_set /* setnetgrent() */ 931 }; 932 933 934 /* 935 * _nss_ldap_netgroup_constr is where life begins. This function calls the 936 * generic ldap constructor function to define and build the abstract data 937 * types required to support ldap operations. 938 */ 939 940 /*ARGSUSED0*/ 941 nss_backend_t * 942 _nss_ldap_netgroup_constr(const char *dummy1, const char *dummy2, 943 const char *dummy3) 944 { 945 946 #ifdef DEBUG 947 (void) fprintf(stdout, 948 "\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n"); 949 #endif /* DEBUG */ 950 951 return ((nss_backend_t *)_nss_ldap_constr(netgroup_ops, 952 sizeof (netgroup_ops)/sizeof (netgroup_ops[0]), _NETGROUP, 953 netgrent_attrs, NULL)); 954 } 955