17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*e429788eSmj162486 * Common Development and Distribution License (the "License"). 6*e429788eSmj162486 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*e429788eSmj162486 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <syslog.h> 297c478bd9Sstevel@tonic-gate #include "ldap_common.h" 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* netgroup attributes filters */ 327c478bd9Sstevel@tonic-gate #define _N_TRIPLE "nisnetgrouptriple" 337c478bd9Sstevel@tonic-gate #define _N_MEMBER "membernisnetgroup" 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #define PRINT_VAL(a) (((a).argc == 0) || ((a).argv == NULL) || \ 367c478bd9Sstevel@tonic-gate ((a).argv[0] == NULL)) ? "*" : (a).argv[0] 377c478bd9Sstevel@tonic-gate #define ISNULL(a) (a == NULL ? "<NULL>" : a) 387c478bd9Sstevel@tonic-gate #define MAX_DOMAIN_LEN 1024 397c478bd9Sstevel@tonic-gate #define MAX_TRIPLE_LEN (MAXHOSTNAMELEN + LOGNAME_MAX + \ 407c478bd9Sstevel@tonic-gate MAX_DOMAIN_LEN + 5) 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #define _F_SETMEMBER "(&(objectClass=nisNetGroup)(cn=%s))" 437c478bd9Sstevel@tonic-gate #define _F_SETMEMBER_SSD "(&(%%s)(cn=%s))" 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate #define N_HASH 257 46*e429788eSmj162486 #define COMMA ',' 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate static const char *netgrent_attrs[] = { 497c478bd9Sstevel@tonic-gate _N_TRIPLE, 507c478bd9Sstevel@tonic-gate _N_MEMBER, 517c478bd9Sstevel@tonic-gate (char *)NULL 527c478bd9Sstevel@tonic-gate }; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate typedef struct netgroup_name { 557c478bd9Sstevel@tonic-gate char *name; 567c478bd9Sstevel@tonic-gate struct netgroup_name *next; 577c478bd9Sstevel@tonic-gate struct netgroup_name *next_hash; 587c478bd9Sstevel@tonic-gate } netgroup_name_t; 597c478bd9Sstevel@tonic-gate 607c478bd9Sstevel@tonic-gate typedef struct { 617c478bd9Sstevel@tonic-gate netgroup_name_t *hash_list[N_HASH]; 627c478bd9Sstevel@tonic-gate netgroup_name_t *to_do; 637c478bd9Sstevel@tonic-gate netgroup_name_t *done; 647c478bd9Sstevel@tonic-gate } netgroup_table_t; 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate typedef struct { 677c478bd9Sstevel@tonic-gate ns_ldap_result_t *results; 687c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 697c478bd9Sstevel@tonic-gate char **attrs; 707c478bd9Sstevel@tonic-gate void *cookie; 717c478bd9Sstevel@tonic-gate char *netgroup; 727c478bd9Sstevel@tonic-gate netgroup_table_t tab; 737c478bd9Sstevel@tonic-gate } getnetgrent_cookie_t; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate typedef struct { 767c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia; 777c478bd9Sstevel@tonic-gate const char *ssd_filter; 787c478bd9Sstevel@tonic-gate const char *netgrname; 797c478bd9Sstevel@tonic-gate const char *membername; 807c478bd9Sstevel@tonic-gate netgroup_table_t tab; 817c478bd9Sstevel@tonic-gate } innetgr_cookie_t; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate typedef unsigned int hash_t; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate static hash_t 867c478bd9Sstevel@tonic-gate get_hash(const char *s) 877c478bd9Sstevel@tonic-gate { 887c478bd9Sstevel@tonic-gate unsigned int sum = 0; 897c478bd9Sstevel@tonic-gate unsigned int i; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate for (i = 0; s[i] != '\0'; i++) 927c478bd9Sstevel@tonic-gate sum += ((unsigned char *)s)[i]; 937c478bd9Sstevel@tonic-gate 947c478bd9Sstevel@tonic-gate return ((sum + i) % N_HASH); 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate /* 987c478bd9Sstevel@tonic-gate * Adds a name to the netgroup table 997c478bd9Sstevel@tonic-gate * 1007c478bd9Sstevel@tonic-gate * Returns 1017c478bd9Sstevel@tonic-gate * 0 if successfully added or already present 1027c478bd9Sstevel@tonic-gate * -1 if memory allocation error 1037c478bd9Sstevel@tonic-gate */ 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate static int 1067c478bd9Sstevel@tonic-gate add_netgroup_name(const char *name, netgroup_table_t *tab) 1077c478bd9Sstevel@tonic-gate { 1087c478bd9Sstevel@tonic-gate hash_t h; 1097c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 1107c478bd9Sstevel@tonic-gate netgroup_name_t *ng_new; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate if (tab == NULL || name == NULL || *name == '\0') 1137c478bd9Sstevel@tonic-gate return (NULL); 1147c478bd9Sstevel@tonic-gate 1157c478bd9Sstevel@tonic-gate h = get_hash(name); 1167c478bd9Sstevel@tonic-gate ng = tab->hash_list[h]; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate while (ng != NULL) { 1197c478bd9Sstevel@tonic-gate if (strcmp(name, ng->name) == 0) 1207c478bd9Sstevel@tonic-gate break; 1217c478bd9Sstevel@tonic-gate ng = ng->next_hash; 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate if (ng == NULL) { 1257c478bd9Sstevel@tonic-gate ng_new = (netgroup_name_t *) 1267c478bd9Sstevel@tonic-gate calloc(1, sizeof (netgroup_name_t)); 1277c478bd9Sstevel@tonic-gate if (ng_new == NULL) 1287c478bd9Sstevel@tonic-gate return (-1); 1297c478bd9Sstevel@tonic-gate ng_new->name = strdup(name); 1307c478bd9Sstevel@tonic-gate if (ng_new->name == NULL) { 1317c478bd9Sstevel@tonic-gate free(ng_new); 1327c478bd9Sstevel@tonic-gate return (-1); 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate ng_new->next_hash = tab->hash_list[h]; 1357c478bd9Sstevel@tonic-gate tab->hash_list[h] = ng_new; 1367c478bd9Sstevel@tonic-gate ng_new->next = tab->to_do; 1377c478bd9Sstevel@tonic-gate tab->to_do = ng_new; 1387c478bd9Sstevel@tonic-gate } 1397c478bd9Sstevel@tonic-gate return (0); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate static netgroup_name_t * 1437c478bd9Sstevel@tonic-gate get_next_netgroup(netgroup_table_t *tab) 1447c478bd9Sstevel@tonic-gate { 1457c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate if (tab == NULL) 1487c478bd9Sstevel@tonic-gate return (NULL); 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate ng = tab->to_do; 1517c478bd9Sstevel@tonic-gate if (ng != NULL) { 1527c478bd9Sstevel@tonic-gate tab->to_do = ng->next; 1537c478bd9Sstevel@tonic-gate ng->next = tab->done; 1547c478bd9Sstevel@tonic-gate tab->done = ng; 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate return (ng); 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate static void 1607c478bd9Sstevel@tonic-gate free_netgroup_table(netgroup_table_t *tab) 1617c478bd9Sstevel@tonic-gate { 1627c478bd9Sstevel@tonic-gate netgroup_name_t *ng, *next; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate if (tab == NULL) 1657c478bd9Sstevel@tonic-gate return; 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate for (ng = tab->to_do; ng != NULL; ng = next) { 1687c478bd9Sstevel@tonic-gate if (ng->name != NULL) 1697c478bd9Sstevel@tonic-gate free(ng->name); 1707c478bd9Sstevel@tonic-gate next = ng->next; 1717c478bd9Sstevel@tonic-gate free(ng); 1727c478bd9Sstevel@tonic-gate } 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate for (ng = tab->done; ng != NULL; ng = next) { 1757c478bd9Sstevel@tonic-gate if (ng->name != NULL) 1767c478bd9Sstevel@tonic-gate free(ng->name); 1777c478bd9Sstevel@tonic-gate next = ng->next; 1787c478bd9Sstevel@tonic-gate free(ng); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate (void) memset(tab, 0, sizeof (*tab)); 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* 1847c478bd9Sstevel@tonic-gate * domain comparing routine 1857c478bd9Sstevel@tonic-gate * n1: See if n1 is n2 or an ancestor of it 1867c478bd9Sstevel@tonic-gate * n2: (in string terms, n1 is a suffix of n2) 1877c478bd9Sstevel@tonic-gate * Returns ZERO for success, -1 for failure. 1887c478bd9Sstevel@tonic-gate */ 1897c478bd9Sstevel@tonic-gate static int 1907c478bd9Sstevel@tonic-gate domcmp(const char *n1, const char *n2) 1917c478bd9Sstevel@tonic-gate { 1927c478bd9Sstevel@tonic-gate #define PASS 0 1937c478bd9Sstevel@tonic-gate #define FAIL -1 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate size_t l1, l2; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate if ((n1 == NULL) || (n2 == NULL)) 1987c478bd9Sstevel@tonic-gate return (FAIL); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate l1 = strlen(n1); 2017c478bd9Sstevel@tonic-gate l2 = strlen(n2); 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate /* Turn a blind eye to the presence or absence of trailing periods */ 2047c478bd9Sstevel@tonic-gate if (l1 != 0 && n1[l1 - 1] == '.') { 2057c478bd9Sstevel@tonic-gate --l1; 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate if (l2 != 0 && n2[l2 - 1] == '.') { 2087c478bd9Sstevel@tonic-gate --l2; 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate if (l1 > l2) { /* Can't be a suffix */ 2117c478bd9Sstevel@tonic-gate return (FAIL); 2127c478bd9Sstevel@tonic-gate } else if (l1 == 0) { /* Trivially a suffix; */ 2137c478bd9Sstevel@tonic-gate /* (do we want this case?) */ 2147c478bd9Sstevel@tonic-gate return (PASS); 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate /* So 0 < l1 <= l2 */ 2177c478bd9Sstevel@tonic-gate if (l1 < l2 && n2[l2 - l1 - 1] != '.') { 2187c478bd9Sstevel@tonic-gate return (FAIL); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate if (strncasecmp(n1, &n2[l2 - l1], l1) == 0) { 2217c478bd9Sstevel@tonic-gate return (PASS); 2227c478bd9Sstevel@tonic-gate } else { 2237c478bd9Sstevel@tonic-gate return (FAIL); 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate static int 2287c478bd9Sstevel@tonic-gate split_triple(char *triple, char **hostname, char **username, char **domain) 2297c478bd9Sstevel@tonic-gate { 2307c478bd9Sstevel@tonic-gate int i, syntax_err; 2317c478bd9Sstevel@tonic-gate char *splittriple[3]; 2327c478bd9Sstevel@tonic-gate char *p = triple; 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate #ifdef DEBUG 2357c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: split_triple]\n"); 2367c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate if (triple == NULL) 2397c478bd9Sstevel@tonic-gate return (-1); 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate p++; 2427c478bd9Sstevel@tonic-gate syntax_err = 0; 2437c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 2447c478bd9Sstevel@tonic-gate char *start; 2457c478bd9Sstevel@tonic-gate char *limit; 2467c478bd9Sstevel@tonic-gate const char *terminators = ",) \t"; 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate if (i == 2) { 2497c478bd9Sstevel@tonic-gate /* Don't allow comma */ 2507c478bd9Sstevel@tonic-gate terminators++; 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate while (isspace(*p)) { 2537c478bd9Sstevel@tonic-gate p++; 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate start = p; 2567c478bd9Sstevel@tonic-gate limit = strpbrk(start, terminators); 2577c478bd9Sstevel@tonic-gate if (limit == 0) { 2587c478bd9Sstevel@tonic-gate syntax_err++; 2597c478bd9Sstevel@tonic-gate break; 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate p = limit; 2627c478bd9Sstevel@tonic-gate while (isspace(*p)) { 2637c478bd9Sstevel@tonic-gate p++; 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate if (*p == terminators[0]) { 2667c478bd9Sstevel@tonic-gate /* 2677c478bd9Sstevel@tonic-gate * Successfully parsed this name and 2687c478bd9Sstevel@tonic-gate * the separator after it (comma or 2697c478bd9Sstevel@tonic-gate * right paren); leave p ready for 2707c478bd9Sstevel@tonic-gate * next parse. 2717c478bd9Sstevel@tonic-gate */ 2727c478bd9Sstevel@tonic-gate p++; 2737c478bd9Sstevel@tonic-gate if (start == limit) { 2747c478bd9Sstevel@tonic-gate /* Wildcard */ 2757c478bd9Sstevel@tonic-gate splittriple[i] = NULL; 2767c478bd9Sstevel@tonic-gate } else { 2777c478bd9Sstevel@tonic-gate *limit = '\0'; 2787c478bd9Sstevel@tonic-gate splittriple[i] = start; 2797c478bd9Sstevel@tonic-gate } 2807c478bd9Sstevel@tonic-gate } else { 2817c478bd9Sstevel@tonic-gate syntax_err++; 2827c478bd9Sstevel@tonic-gate break; 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate if (syntax_err != 0) 2877c478bd9Sstevel@tonic-gate return (-1); 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate *hostname = splittriple[0]; 2907c478bd9Sstevel@tonic-gate *username = splittriple[1]; 2917c478bd9Sstevel@tonic-gate *domain = splittriple[2]; 2927c478bd9Sstevel@tonic-gate 2937c478bd9Sstevel@tonic-gate return (0); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* 297*e429788eSmj162486 * Test membership in triple 298*e429788eSmj162486 * return 0 = no match 299*e429788eSmj162486 * return 1 = match 3007c478bd9Sstevel@tonic-gate */ 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate static int 3037c478bd9Sstevel@tonic-gate match_triple_entry(struct nss_innetgr_args *ia, const ns_ldap_entry_t *entry) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate int ndomains; 3067c478bd9Sstevel@tonic-gate char **pdomains; 3077c478bd9Sstevel@tonic-gate int nhost; 3087c478bd9Sstevel@tonic-gate char **phost; 3097c478bd9Sstevel@tonic-gate int nusers; 3107c478bd9Sstevel@tonic-gate char **pusers; 3117c478bd9Sstevel@tonic-gate char **attr; 3127c478bd9Sstevel@tonic-gate char triple[MAX_TRIPLE_LEN]; 3137c478bd9Sstevel@tonic-gate char *tuser, *thost, *tdomain; 3147c478bd9Sstevel@tonic-gate int i; 315*e429788eSmj162486 char *current, *limit; 316*e429788eSmj162486 int pulen, phlen; 317*e429788eSmj162486 char *pusers0, *phost0; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate nhost = ia->arg[NSS_NETGR_MACHINE].argc; 3207c478bd9Sstevel@tonic-gate phost = (char **)ia->arg[NSS_NETGR_MACHINE].argv; 321*e429788eSmj162486 if (phost == NULL || *phost == NULL) { 3227c478bd9Sstevel@tonic-gate nhost = 0; 323*e429788eSmj162486 } else { 324*e429788eSmj162486 phost0 = phost[0]; 325*e429788eSmj162486 phlen = strlen(phost0); 326*e429788eSmj162486 } 3277c478bd9Sstevel@tonic-gate nusers = ia->arg[NSS_NETGR_USER].argc; 3287c478bd9Sstevel@tonic-gate pusers = (char **)ia->arg[NSS_NETGR_USER].argv; 329*e429788eSmj162486 if (pusers == NULL || *pusers == NULL) { 3307c478bd9Sstevel@tonic-gate nusers = 0; 331*e429788eSmj162486 } else { 332*e429788eSmj162486 pusers0 = pusers[0]; 333*e429788eSmj162486 pulen = strlen(pusers0); 334*e429788eSmj162486 } 3357c478bd9Sstevel@tonic-gate ndomains = ia->arg[NSS_NETGR_DOMAIN].argc; 3367c478bd9Sstevel@tonic-gate pdomains = (char **)ia->arg[NSS_NETGR_DOMAIN].argv; 3377c478bd9Sstevel@tonic-gate if (pdomains == NULL || *pdomains == NULL) 3387c478bd9Sstevel@tonic-gate ndomains = 0; 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate attr = __ns_ldap_getAttr(entry, _N_TRIPLE); 3417c478bd9Sstevel@tonic-gate if (attr == NULL || *attr == NULL) 3427c478bd9Sstevel@tonic-gate return (0); 3437c478bd9Sstevel@tonic-gate 344*e429788eSmj162486 /* Special cases for speedup */ 345*e429788eSmj162486 if (nusers == 1 && nhost == 0 && ndomains == 0) { 346*e429788eSmj162486 /* Special case for finding a single user in a netgroup */ 3477c478bd9Sstevel@tonic-gate for (; *attr; attr++) { 348*e429788eSmj162486 /* jump to first comma and check next character */ 349*e429788eSmj162486 current = *attr; 350*e429788eSmj162486 if ((current = strchr(current, COMMA)) == NULL) 351*e429788eSmj162486 continue; 352*e429788eSmj162486 current++; 353*e429788eSmj162486 354*e429788eSmj162486 /* skip whitespaces */ 355*e429788eSmj162486 while (isspace(*current)) 356*e429788eSmj162486 current++; 357*e429788eSmj162486 358*e429788eSmj162486 /* if user part is null, then treat as wildcard */ 359*e429788eSmj162486 if (*current == COMMA) 360*e429788eSmj162486 return (1); 361*e429788eSmj162486 362*e429788eSmj162486 /* compare first character */ 363*e429788eSmj162486 if (*pusers0 != *current) 364*e429788eSmj162486 continue; 365*e429788eSmj162486 366*e429788eSmj162486 /* limit username to COMMA */ 367*e429788eSmj162486 if ((limit = strchr(current, COMMA)) == NULL) 368*e429788eSmj162486 continue; 369*e429788eSmj162486 *limit = '\0'; 370*e429788eSmj162486 371*e429788eSmj162486 /* remove blanks before COMMA */ 372*e429788eSmj162486 if ((limit = strpbrk(current, " \t")) != NULL) 373*e429788eSmj162486 *limit = '\0'; 374*e429788eSmj162486 375*e429788eSmj162486 /* compare size of username */ 376*e429788eSmj162486 if (pulen != strlen(current)) { 377*e429788eSmj162486 continue; 378*e429788eSmj162486 } 379*e429788eSmj162486 380*e429788eSmj162486 /* do actual compare */ 381*e429788eSmj162486 if (strncmp(pusers0, current, pulen) == 0) { 382*e429788eSmj162486 return (1); 383*e429788eSmj162486 } else { 384*e429788eSmj162486 continue; 385*e429788eSmj162486 } 386*e429788eSmj162486 } 387*e429788eSmj162486 } else if (nusers == 0 && nhost == 1 && ndomains == 0) { 388*e429788eSmj162486 /* Special case for finding a single host in a netgroup */ 389*e429788eSmj162486 for (; *attr; attr++) { 390*e429788eSmj162486 391*e429788eSmj162486 /* jump to first character and check */ 392*e429788eSmj162486 current = *attr; 393*e429788eSmj162486 current++; 394*e429788eSmj162486 395*e429788eSmj162486 /* skip whitespaces */ 396*e429788eSmj162486 while (isspace(*current)) 397*e429788eSmj162486 current++; 398*e429788eSmj162486 399*e429788eSmj162486 /* if host part is null, then treat as wildcard */ 400*e429788eSmj162486 if (*current == COMMA) 401*e429788eSmj162486 return (1); 402*e429788eSmj162486 403*e429788eSmj162486 /* compare first character */ 404*e429788eSmj162486 if (tolower(*phost0) != tolower(*current)) 405*e429788eSmj162486 continue; 406*e429788eSmj162486 407*e429788eSmj162486 /* limit hostname to COMMA */ 408*e429788eSmj162486 if ((limit = strchr(current, COMMA)) == NULL) 409*e429788eSmj162486 continue; 410*e429788eSmj162486 *limit = '\0'; 411*e429788eSmj162486 412*e429788eSmj162486 /* remove blanks before COMMA */ 413*e429788eSmj162486 if ((limit = strpbrk(current, " \t")) != NULL) 414*e429788eSmj162486 *limit = '\0'; 415*e429788eSmj162486 416*e429788eSmj162486 /* compare size of hostname */ 417*e429788eSmj162486 if (phlen != strlen(current)) { 418*e429788eSmj162486 continue; 419*e429788eSmj162486 } 420*e429788eSmj162486 421*e429788eSmj162486 /* do actual compare */ 422*e429788eSmj162486 if (strncasecmp(phost0, current, phlen) == 0) { 423*e429788eSmj162486 return (1); 424*e429788eSmj162486 } else { 425*e429788eSmj162486 continue; 426*e429788eSmj162486 } 427*e429788eSmj162486 } 428*e429788eSmj162486 } else { 429*e429788eSmj162486 for (; *attr; attr++) { 430*e429788eSmj162486 if (strlcpy(triple, *attr, 431*e429788eSmj162486 sizeof (triple)) >= sizeof (triple)) 4327c478bd9Sstevel@tonic-gate continue; 4337c478bd9Sstevel@tonic-gate if (split_triple(triple, &thost, &tuser, &tdomain) != 0) 4347c478bd9Sstevel@tonic-gate continue; 4357c478bd9Sstevel@tonic-gate if (thost != NULL && *thost != '\0' && nhost != 0) { 4367c478bd9Sstevel@tonic-gate for (i = 0; i < nhost; i++) 4377c478bd9Sstevel@tonic-gate if (strcasecmp(thost, phost[i]) == 0) 4387c478bd9Sstevel@tonic-gate break; 4397c478bd9Sstevel@tonic-gate if (i == nhost) 4407c478bd9Sstevel@tonic-gate continue; 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate if (tuser != NULL && *tuser != '\0' && nusers != 0) { 4437c478bd9Sstevel@tonic-gate for (i = 0; i < nusers; i++) 4447c478bd9Sstevel@tonic-gate if (strcmp(tuser, pusers[i]) == 0) 4457c478bd9Sstevel@tonic-gate break; 4467c478bd9Sstevel@tonic-gate if (i == nusers) 4477c478bd9Sstevel@tonic-gate continue; 4487c478bd9Sstevel@tonic-gate } 449*e429788eSmj162486 if (tdomain != NULL && *tdomain != '\0' && 450*e429788eSmj162486 ndomains != 0) { 4517c478bd9Sstevel@tonic-gate for (i = 0; i < ndomains; i++) 4527c478bd9Sstevel@tonic-gate if (domcmp(tdomain, pdomains[i]) == 0) 4537c478bd9Sstevel@tonic-gate break; 4547c478bd9Sstevel@tonic-gate if (i == ndomains) 4557c478bd9Sstevel@tonic-gate continue; 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate return (1); 4587c478bd9Sstevel@tonic-gate } 459*e429788eSmj162486 } 4607c478bd9Sstevel@tonic-gate 4617c478bd9Sstevel@tonic-gate return (0); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate static int 4657c478bd9Sstevel@tonic-gate match_triple(struct nss_innetgr_args *ia, ns_ldap_result_t *result) 4667c478bd9Sstevel@tonic-gate { 4677c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) 4707c478bd9Sstevel@tonic-gate if (match_triple_entry(ia, entry) == 1) 4717c478bd9Sstevel@tonic-gate return (1); 4727c478bd9Sstevel@tonic-gate 4737c478bd9Sstevel@tonic-gate return (0); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate static int 4777c478bd9Sstevel@tonic-gate add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab) 4787c478bd9Sstevel@tonic-gate { 4797c478bd9Sstevel@tonic-gate char **attrs; 4807c478bd9Sstevel@tonic-gate char **a; 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate attrs = __ns_ldap_getAttr(entry, _N_MEMBER); 4837c478bd9Sstevel@tonic-gate if (attrs == NULL || *attrs == NULL) 4847c478bd9Sstevel@tonic-gate return (0); 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate for (a = attrs; *a != NULL; a++) {} 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate do { 4897c478bd9Sstevel@tonic-gate a--; 4907c478bd9Sstevel@tonic-gate if (add_netgroup_name(*a, tab) != 0) 4917c478bd9Sstevel@tonic-gate return (-1); 4927c478bd9Sstevel@tonic-gate } while (a > attrs); 4937c478bd9Sstevel@tonic-gate return (0); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate static int 4977c478bd9Sstevel@tonic-gate add_netgroup_member(ns_ldap_result_t *result, netgroup_table_t *tab) 4987c478bd9Sstevel@tonic-gate { 4997c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 5007c478bd9Sstevel@tonic-gate int ret = 0; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) { 5037c478bd9Sstevel@tonic-gate ret = add_netgroup_member_entry(entry, tab); 5047c478bd9Sstevel@tonic-gate if (ret != 0) 5057c478bd9Sstevel@tonic-gate break; 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate return (ret); 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate /* 5117c478bd9Sstevel@tonic-gate * top_down_search checks only checks the netgroup specified in netgrname 5127c478bd9Sstevel@tonic-gate */ 5137c478bd9Sstevel@tonic-gate static nss_status_t 5147c478bd9Sstevel@tonic-gate top_down_search(struct nss_innetgr_args *ia, char *netgrname) 5157c478bd9Sstevel@tonic-gate { 5167c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 5177c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 5187c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 5197c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 5207c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 5217c478bd9Sstevel@tonic-gate int rc; 5227c478bd9Sstevel@tonic-gate void *cookie = NULL; 5237c478bd9Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND; 5247c478bd9Sstevel@tonic-gate netgroup_table_t tab; 5257c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 5267c478bd9Sstevel@tonic-gate int ret; 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate (void) memset(&tab, 0, sizeof (tab)); 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate if (add_netgroup_name(netgrname, &tab) != 0) 5317c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate while ((ng = get_next_netgroup(&tab)) != NULL) { 5347c478bd9Sstevel@tonic-gate if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0) 5357c478bd9Sstevel@tonic-gate break; 5367c478bd9Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), _F_SETMEMBER, 5377c478bd9Sstevel@tonic-gate name); 5387c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 5397c478bd9Sstevel@tonic-gate break; 5407c478bd9Sstevel@tonic-gate 5417c478bd9Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD, name); 5427c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 5437c478bd9Sstevel@tonic-gate break; 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate rc = __ns_ldap_firstEntry(_NETGROUP, searchfilter, 5467c478bd9Sstevel@tonic-gate _merge_SSD_filter, netgrent_attrs, NULL, 0, &cookie, &result, 5477c478bd9Sstevel@tonic-gate &error, userdata); 5487c478bd9Sstevel@tonic-gate 5497c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5507c478bd9Sstevel@tonic-gate while (rc == NS_LDAP_SUCCESS && result != NULL) { 5517c478bd9Sstevel@tonic-gate if (match_triple(ia, result) == 1) { 5527c478bd9Sstevel@tonic-gate /* We found a match */ 5537c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_FOUND; 5547c478bd9Sstevel@tonic-gate status = NSS_SUCCESS; 5557c478bd9Sstevel@tonic-gate break; 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate 5587c478bd9Sstevel@tonic-gate rc = add_netgroup_member(result, &tab); 5597c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) 5627c478bd9Sstevel@tonic-gate break; 5637c478bd9Sstevel@tonic-gate rc = __ns_ldap_nextEntry(cookie, &result, &error); 5647c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 5677c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&cookie, &error); 5687c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate if (status == NSS_SUCCESS || 5717c478bd9Sstevel@tonic-gate (rc != NS_LDAP_SUCCESS && rc != NS_LDAP_NOTFOUND)) 5727c478bd9Sstevel@tonic-gate break; 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 5767c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&cookie, &error); 5777c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5787c478bd9Sstevel@tonic-gate free_netgroup_table(&tab); 5797c478bd9Sstevel@tonic-gate return (status); 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate /* 5837c478bd9Sstevel@tonic-gate * __netgr_in checks only checks the netgroup specified in ngroup 5847c478bd9Sstevel@tonic-gate */ 5857c478bd9Sstevel@tonic-gate static nss_status_t 5867c478bd9Sstevel@tonic-gate __netgr_in(void *a, char *netgrname) 5877c478bd9Sstevel@tonic-gate { 5887c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 5897c478bd9Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND; 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate #ifdef DEBUG 5927c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_in]\n"); 5937c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tmachine: argc[%d]='%s' user: " 5947c478bd9Sstevel@tonic-gate "argc[%d]='%s',\n\tdomain:argc[%d]='%s' " 5957c478bd9Sstevel@tonic-gate "netgroup: argc[%d]='%s'\n", 5967c478bd9Sstevel@tonic-gate NSS_NETGR_MACHINE, 5977c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_MACHINE]), 5987c478bd9Sstevel@tonic-gate NSS_NETGR_USER, 5997c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_USER]), 6007c478bd9Sstevel@tonic-gate NSS_NETGR_DOMAIN, 6017c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_DOMAIN]), 6027c478bd9Sstevel@tonic-gate NSS_NETGR_N, 6037c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_N])); 6047c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tgroups='%s'\n", netgrname); 6057c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_NO; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate if (netgrname == NULL) 6107c478bd9Sstevel@tonic-gate return (status); 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate return (top_down_search(ia, netgrname)); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 6167c478bd9Sstevel@tonic-gate static nss_status_t 6177c478bd9Sstevel@tonic-gate netgr_in(ldap_backend_ptr be, void *a) 6187c478bd9Sstevel@tonic-gate { 6197c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 6207c478bd9Sstevel@tonic-gate int i; 6217c478bd9Sstevel@tonic-gate nss_status_t rc = (nss_status_t)NSS_NOTFOUND; 6227c478bd9Sstevel@tonic-gate 6237c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_NO; 6247c478bd9Sstevel@tonic-gate for (i = 0; i < ia->groups.argc; i++) { 6257c478bd9Sstevel@tonic-gate rc = __netgr_in(a, ia->groups.argv[i]); 6267c478bd9Sstevel@tonic-gate if (ia->status == NSS_NETGR_FOUND) 6277c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate return (rc); 6307c478bd9Sstevel@tonic-gate } 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate /* 6337c478bd9Sstevel@tonic-gate * 6347c478bd9Sstevel@tonic-gate */ 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate static nss_status_t 6377c478bd9Sstevel@tonic-gate getnetgr_ldap_setent(ldap_backend_ptr be, void *a) 6387c478bd9Sstevel@tonic-gate { 6397c478bd9Sstevel@tonic-gate const char *netgroup = (const char *) a; 6407c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *cookie; 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate #ifdef DEBUG 6437c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_setent]\n"); 6447c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6457c478bd9Sstevel@tonic-gate 6467c478bd9Sstevel@tonic-gate cookie = (getnetgrent_cookie_t *)be->netgroup_cookie; 6477c478bd9Sstevel@tonic-gate if (cookie != NULL && cookie->netgroup != NULL) { 6487c478bd9Sstevel@tonic-gate /* is this another set on the same netgroup */ 6497c478bd9Sstevel@tonic-gate if (strcmp(cookie->netgroup, netgroup) == 0) 6507c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 6517c478bd9Sstevel@tonic-gate } 6527c478bd9Sstevel@tonic-gate 6537c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate 6567c478bd9Sstevel@tonic-gate static void 6577c478bd9Sstevel@tonic-gate free_getnetgrent_cookie(getnetgrent_cookie_t **cookie) 6587c478bd9Sstevel@tonic-gate { 6597c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 6607c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p = *cookie; 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate #ifdef DEBUG 6637c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: free_getnetgrent_cookie]\n"); 6647c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate if (p == NULL) 6677c478bd9Sstevel@tonic-gate return; 6687c478bd9Sstevel@tonic-gate 6697c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results); 6707c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&p->cookie, &error); 6717c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 6727c478bd9Sstevel@tonic-gate free_netgroup_table(&p->tab); 6737c478bd9Sstevel@tonic-gate free(p->netgroup); 6747c478bd9Sstevel@tonic-gate free(p); 6757c478bd9Sstevel@tonic-gate *cookie = NULL; 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate 6787c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 6797c478bd9Sstevel@tonic-gate static nss_status_t 6807c478bd9Sstevel@tonic-gate getnetgr_ldap_endent(ldap_backend_ptr be, void *a) 6817c478bd9Sstevel@tonic-gate { 6827c478bd9Sstevel@tonic-gate 6837c478bd9Sstevel@tonic-gate #ifdef DEBUG 6847c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_endent]\n"); 6857c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 6887c478bd9Sstevel@tonic-gate 6897c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 6947c478bd9Sstevel@tonic-gate static nss_status_t 6957c478bd9Sstevel@tonic-gate getnetgr_ldap_destr(ldap_backend_ptr be, void *a) 6967c478bd9Sstevel@tonic-gate { 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate #ifdef DEBUG 6997c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_destr]\n"); 7007c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 7037c478bd9Sstevel@tonic-gate free(be); 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate static nss_status_t 7107c478bd9Sstevel@tonic-gate getnetgr_ldap_getent(ldap_backend_ptr be, void *a) 7117c478bd9Sstevel@tonic-gate { 7127c478bd9Sstevel@tonic-gate struct nss_getnetgrent_args *args; 7137c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p; 7147c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 7157c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 7167c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 7177c478bd9Sstevel@tonic-gate int rc; 7187c478bd9Sstevel@tonic-gate void *cookie = NULL; 7197c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 7207c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 7217c478bd9Sstevel@tonic-gate char **attrs; 7227c478bd9Sstevel@tonic-gate char *hostname, *username, *domain; 7237c478bd9Sstevel@tonic-gate char *buffer; 7247c478bd9Sstevel@tonic-gate nss_status_t status = NSS_SUCCESS; 7257c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 7267c478bd9Sstevel@tonic-gate int ret; 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate #ifdef DEBUG 7297c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n"); 7307c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate args = (struct nss_getnetgrent_args *)a; 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_NO; 7357c478bd9Sstevel@tonic-gate 7367c478bd9Sstevel@tonic-gate p = (getnetgrent_cookie_t *)be->netgroup_cookie; 7377c478bd9Sstevel@tonic-gate if (p == NULL) 7387c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate for (;;) { 7417c478bd9Sstevel@tonic-gate while (p->cookie == NULL) { 7427c478bd9Sstevel@tonic-gate ng = get_next_netgroup(&p->tab); 7437c478bd9Sstevel@tonic-gate if (ng == NULL) /* no more */ 7447c478bd9Sstevel@tonic-gate break; 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0) 7477c478bd9Sstevel@tonic-gate break; 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), 7507c478bd9Sstevel@tonic-gate _F_SETMEMBER, name); 7517c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 7527c478bd9Sstevel@tonic-gate break; 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD, 7557c478bd9Sstevel@tonic-gate name); 7567c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 7577c478bd9Sstevel@tonic-gate break; 7587c478bd9Sstevel@tonic-gate 7597c478bd9Sstevel@tonic-gate result = NULL; 7607c478bd9Sstevel@tonic-gate rc = __ns_ldap_firstEntry(_NETGROUP, searchfilter, 7617c478bd9Sstevel@tonic-gate _merge_SSD_filter, netgrent_attrs, NULL, 0, &cookie, 7627c478bd9Sstevel@tonic-gate &result, &error, userdata); 7637c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS && result != NULL) { 7667c478bd9Sstevel@tonic-gate p->cookie = cookie; 7677c478bd9Sstevel@tonic-gate p->results = result; 7687c478bd9Sstevel@tonic-gate break; 7697c478bd9Sstevel@tonic-gate } 7707c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 7717c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&cookie, &error); 7727c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate if (p->cookie == NULL) 7757c478bd9Sstevel@tonic-gate break; 7767c478bd9Sstevel@tonic-gate if (p->results == NULL) { 7777c478bd9Sstevel@tonic-gate result = NULL; 7787c478bd9Sstevel@tonic-gate rc = __ns_ldap_nextEntry(p->cookie, &result, &error); 7797c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 7807c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS && result != NULL) 7817c478bd9Sstevel@tonic-gate p->results = result; 7827c478bd9Sstevel@tonic-gate else { 7837c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 7847c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&p->cookie, &error); 7857c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 7867c478bd9Sstevel@tonic-gate p->cookie = NULL; 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate if (p->results == NULL) 7907c478bd9Sstevel@tonic-gate continue; 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate if (p->entry == NULL) 7937c478bd9Sstevel@tonic-gate p->entry = p->results->entry; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate if (p->entry == NULL) 7967c478bd9Sstevel@tonic-gate continue; 7977c478bd9Sstevel@tonic-gate 7987c478bd9Sstevel@tonic-gate if (p->attrs == NULL) { 7997c478bd9Sstevel@tonic-gate attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE); 8007c478bd9Sstevel@tonic-gate if (attrs != NULL && *attrs != NULL) 8017c478bd9Sstevel@tonic-gate p->attrs = attrs; 8027c478bd9Sstevel@tonic-gate } 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate if (p->attrs != NULL) { 8057c478bd9Sstevel@tonic-gate attrs = p->attrs; 8067c478bd9Sstevel@tonic-gate buffer = args->buffer; 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate if (strlcpy(buffer, *attrs, args->buflen) >= args->buflen) { 8097c478bd9Sstevel@tonic-gate status = NSS_STR_PARSE_ERANGE; 8107c478bd9Sstevel@tonic-gate break; 8117c478bd9Sstevel@tonic-gate } 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate rc = split_triple(buffer, &hostname, &username, &domain); 8147c478bd9Sstevel@tonic-gate attrs++; 8157c478bd9Sstevel@tonic-gate if (attrs != NULL && *attrs != NULL) 8167c478bd9Sstevel@tonic-gate p->attrs = attrs; 8177c478bd9Sstevel@tonic-gate else 8187c478bd9Sstevel@tonic-gate p->attrs = NULL; 8197c478bd9Sstevel@tonic-gate if (rc == 0) { 8207c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_MACHINE] = hostname; 8217c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_USER] = username; 8227c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_DOMAIN] = domain; 8237c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_FOUND; 8247c478bd9Sstevel@tonic-gate if (p->attrs != NULL) 8257c478bd9Sstevel@tonic-gate break; 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate } 8287c478bd9Sstevel@tonic-gate 8297c478bd9Sstevel@tonic-gate if (p->attrs == NULL) { 8307c478bd9Sstevel@tonic-gate rc = add_netgroup_member_entry(p->entry, &p->tab); 8317c478bd9Sstevel@tonic-gate if (rc != 0) { 8327c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_NO; 8337c478bd9Sstevel@tonic-gate break; 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate p->entry = p->entry->next; 8377c478bd9Sstevel@tonic-gate if (p->entry == NULL) 8387c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results); 8397c478bd9Sstevel@tonic-gate if (args->status == NSS_NETGR_FOUND) 8407c478bd9Sstevel@tonic-gate break; 8417c478bd9Sstevel@tonic-gate } 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate return (status); 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate static ldap_backend_op_t getnetgroup_ops[] = { 8487c478bd9Sstevel@tonic-gate getnetgr_ldap_destr, 8497c478bd9Sstevel@tonic-gate getnetgr_ldap_endent, 8507c478bd9Sstevel@tonic-gate getnetgr_ldap_setent, 8517c478bd9Sstevel@tonic-gate getnetgr_ldap_getent, 8527c478bd9Sstevel@tonic-gate }; 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate /* 8557c478bd9Sstevel@tonic-gate * 8567c478bd9Sstevel@tonic-gate */ 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate static nss_status_t 8597c478bd9Sstevel@tonic-gate netgr_set(ldap_backend_ptr be, void *a) 8607c478bd9Sstevel@tonic-gate { 8617c478bd9Sstevel@tonic-gate struct nss_setnetgrent_args *args = 8627c478bd9Sstevel@tonic-gate (struct nss_setnetgrent_args *)a; 8637c478bd9Sstevel@tonic-gate ldap_backend_ptr get_be; 8647c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p; 8657c478bd9Sstevel@tonic-gate 8667c478bd9Sstevel@tonic-gate #ifdef DEBUG 8677c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_set]\n"); 8687c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 8697c478bd9Sstevel@tonic-gate "\targs->netgroup: %s\n", ISNULL(args->netgroup)); 8707c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 8717c478bd9Sstevel@tonic-gate 8727c478bd9Sstevel@tonic-gate if (args->netgroup == NULL) 8737c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 8767c478bd9Sstevel@tonic-gate p = (getnetgrent_cookie_t *)calloc(1, sizeof (getnetgrent_cookie_t)); 8777c478bd9Sstevel@tonic-gate if (p == NULL) 8787c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 8797c478bd9Sstevel@tonic-gate p->netgroup = strdup(args->netgroup); 8807c478bd9Sstevel@tonic-gate if (p->netgroup == NULL) { 8817c478bd9Sstevel@tonic-gate free(p); 8827c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate if (add_netgroup_name(args->netgroup, &p->tab) == -1) { 8857c478bd9Sstevel@tonic-gate free_getnetgrent_cookie(&p); 8867c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 8877c478bd9Sstevel@tonic-gate } 8887c478bd9Sstevel@tonic-gate 8897c478bd9Sstevel@tonic-gate /* now allocate and return iteration backend structure */ 8907c478bd9Sstevel@tonic-gate if ((get_be = (ldap_backend_ptr)malloc(sizeof (*get_be))) == NULL) 8917c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 8927c478bd9Sstevel@tonic-gate get_be->ops = getnetgroup_ops; 8937c478bd9Sstevel@tonic-gate get_be->nops = sizeof (getnetgroup_ops) / sizeof (getnetgroup_ops[0]); 8947c478bd9Sstevel@tonic-gate get_be->tablename = NULL; 8957c478bd9Sstevel@tonic-gate get_be->attrs = netgrent_attrs; 8967c478bd9Sstevel@tonic-gate get_be->result = NULL; 8977c478bd9Sstevel@tonic-gate get_be->ldapobj2ent = NULL; 8987c478bd9Sstevel@tonic-gate get_be->setcalled = 1; 8997c478bd9Sstevel@tonic-gate get_be->filter = NULL; 9007c478bd9Sstevel@tonic-gate get_be->toglue = NULL; 9017c478bd9Sstevel@tonic-gate get_be->enumcookie = NULL; 9027c478bd9Sstevel@tonic-gate get_be->netgroup_cookie = p; 9037c478bd9Sstevel@tonic-gate args->iterator = (nss_backend_t *)get_be; 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 9067c478bd9Sstevel@tonic-gate 9077c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 9127c478bd9Sstevel@tonic-gate static nss_status_t 9137c478bd9Sstevel@tonic-gate netgr_ldap_destr(ldap_backend_ptr be, void *a) 9147c478bd9Sstevel@tonic-gate { 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate #ifdef DEBUG 9177c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_ldap_destr]\n"); 9187c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9197c478bd9Sstevel@tonic-gate 9207c478bd9Sstevel@tonic-gate (void) _clean_ldap_backend(be); 9217c478bd9Sstevel@tonic-gate 9227c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9237c478bd9Sstevel@tonic-gate } 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate 9267c478bd9Sstevel@tonic-gate 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate static ldap_backend_op_t netgroup_ops[] = { 9297c478bd9Sstevel@tonic-gate netgr_ldap_destr, 9307c478bd9Sstevel@tonic-gate 0, 9317c478bd9Sstevel@tonic-gate 0, 9327c478bd9Sstevel@tonic-gate 0, 9337c478bd9Sstevel@tonic-gate netgr_in, /* innetgr() */ 9347c478bd9Sstevel@tonic-gate netgr_set /* setnetgrent() */ 9357c478bd9Sstevel@tonic-gate }; 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate 9387c478bd9Sstevel@tonic-gate /* 9397c478bd9Sstevel@tonic-gate * _nss_ldap_netgroup_constr is where life begins. This function calls the 9407c478bd9Sstevel@tonic-gate * generic ldap constructor function to define and build the abstract data 9417c478bd9Sstevel@tonic-gate * types required to support ldap operations. 9427c478bd9Sstevel@tonic-gate */ 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 9457c478bd9Sstevel@tonic-gate nss_backend_t * 9467c478bd9Sstevel@tonic-gate _nss_ldap_netgroup_constr(const char *dummy1, const char *dummy2, 9477c478bd9Sstevel@tonic-gate const char *dummy3) 9487c478bd9Sstevel@tonic-gate { 9497c478bd9Sstevel@tonic-gate 9507c478bd9Sstevel@tonic-gate #ifdef DEBUG 9517c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 9527c478bd9Sstevel@tonic-gate "\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n"); 9537c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(netgroup_ops, 9567c478bd9Sstevel@tonic-gate sizeof (netgroup_ops)/sizeof (netgroup_ops[0]), _NETGROUP, 9577c478bd9Sstevel@tonic-gate netgrent_attrs, NULL)); 9587c478bd9Sstevel@tonic-gate } 959