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 5e429788eSmj162486 * Common Development and Distribution License (the "License"). 6e429788eSmj162486 * 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*3d047983Smichen * Copyright 2007 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 46e429788eSmj162486 #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 /* 297e429788eSmj162486 * Test membership in triple 298e429788eSmj162486 * return 0 = no match 299e429788eSmj162486 * 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; 315e429788eSmj162486 char *current, *limit; 316e429788eSmj162486 int pulen, phlen; 317e429788eSmj162486 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; 321e429788eSmj162486 if (phost == NULL || *phost == NULL) { 3227c478bd9Sstevel@tonic-gate nhost = 0; 323e429788eSmj162486 } else { 324e429788eSmj162486 phost0 = phost[0]; 325e429788eSmj162486 phlen = strlen(phost0); 326e429788eSmj162486 } 3277c478bd9Sstevel@tonic-gate nusers = ia->arg[NSS_NETGR_USER].argc; 3287c478bd9Sstevel@tonic-gate pusers = (char **)ia->arg[NSS_NETGR_USER].argv; 329e429788eSmj162486 if (pusers == NULL || *pusers == NULL) { 3307c478bd9Sstevel@tonic-gate nusers = 0; 331e429788eSmj162486 } else { 332e429788eSmj162486 pusers0 = pusers[0]; 333e429788eSmj162486 pulen = strlen(pusers0); 334e429788eSmj162486 } 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 344e429788eSmj162486 /* Special cases for speedup */ 345e429788eSmj162486 if (nusers == 1 && nhost == 0 && ndomains == 0) { 346e429788eSmj162486 /* Special case for finding a single user in a netgroup */ 3477c478bd9Sstevel@tonic-gate for (; *attr; attr++) { 348e429788eSmj162486 /* jump to first comma and check next character */ 349e429788eSmj162486 current = *attr; 350e429788eSmj162486 if ((current = strchr(current, COMMA)) == NULL) 351e429788eSmj162486 continue; 352e429788eSmj162486 current++; 353e429788eSmj162486 354e429788eSmj162486 /* skip whitespaces */ 355e429788eSmj162486 while (isspace(*current)) 356e429788eSmj162486 current++; 357e429788eSmj162486 358e429788eSmj162486 /* if user part is null, then treat as wildcard */ 359e429788eSmj162486 if (*current == COMMA) 360e429788eSmj162486 return (1); 361e429788eSmj162486 362e429788eSmj162486 /* compare first character */ 363e429788eSmj162486 if (*pusers0 != *current) 364e429788eSmj162486 continue; 365e429788eSmj162486 366e429788eSmj162486 /* limit username to COMMA */ 367e429788eSmj162486 if ((limit = strchr(current, COMMA)) == NULL) 368e429788eSmj162486 continue; 369e429788eSmj162486 *limit = '\0'; 370e429788eSmj162486 371e429788eSmj162486 /* remove blanks before COMMA */ 372e429788eSmj162486 if ((limit = strpbrk(current, " \t")) != NULL) 373e429788eSmj162486 *limit = '\0'; 374e429788eSmj162486 375e429788eSmj162486 /* compare size of username */ 376e429788eSmj162486 if (pulen != strlen(current)) { 377e429788eSmj162486 continue; 378e429788eSmj162486 } 379e429788eSmj162486 380e429788eSmj162486 /* do actual compare */ 381e429788eSmj162486 if (strncmp(pusers0, current, pulen) == 0) { 382e429788eSmj162486 return (1); 383e429788eSmj162486 } else { 384e429788eSmj162486 continue; 385e429788eSmj162486 } 386e429788eSmj162486 } 387e429788eSmj162486 } else if (nusers == 0 && nhost == 1 && ndomains == 0) { 388e429788eSmj162486 /* Special case for finding a single host in a netgroup */ 389e429788eSmj162486 for (; *attr; attr++) { 390e429788eSmj162486 391e429788eSmj162486 /* jump to first character and check */ 392e429788eSmj162486 current = *attr; 393e429788eSmj162486 current++; 394e429788eSmj162486 395e429788eSmj162486 /* skip whitespaces */ 396e429788eSmj162486 while (isspace(*current)) 397e429788eSmj162486 current++; 398e429788eSmj162486 399e429788eSmj162486 /* if host part is null, then treat as wildcard */ 400e429788eSmj162486 if (*current == COMMA) 401e429788eSmj162486 return (1); 402e429788eSmj162486 403e429788eSmj162486 /* limit hostname to COMMA */ 404e429788eSmj162486 if ((limit = strchr(current, COMMA)) == NULL) 405e429788eSmj162486 continue; 406e429788eSmj162486 *limit = '\0'; 407e429788eSmj162486 408e429788eSmj162486 /* remove blanks before COMMA */ 409e429788eSmj162486 if ((limit = strpbrk(current, " \t")) != NULL) 410e429788eSmj162486 *limit = '\0'; 411e429788eSmj162486 412e429788eSmj162486 /* compare size of hostname */ 413e429788eSmj162486 if (phlen != strlen(current)) { 414e429788eSmj162486 continue; 415e429788eSmj162486 } 416e429788eSmj162486 417e429788eSmj162486 /* do actual compare */ 418e429788eSmj162486 if (strncasecmp(phost0, current, phlen) == 0) { 419e429788eSmj162486 return (1); 420e429788eSmj162486 } else { 421e429788eSmj162486 continue; 422e429788eSmj162486 } 423e429788eSmj162486 } 424e429788eSmj162486 } else { 425e429788eSmj162486 for (; *attr; attr++) { 426e429788eSmj162486 if (strlcpy(triple, *attr, 427e429788eSmj162486 sizeof (triple)) >= sizeof (triple)) 4287c478bd9Sstevel@tonic-gate continue; 4297c478bd9Sstevel@tonic-gate if (split_triple(triple, &thost, &tuser, &tdomain) != 0) 4307c478bd9Sstevel@tonic-gate continue; 4317c478bd9Sstevel@tonic-gate if (thost != NULL && *thost != '\0' && nhost != 0) { 4327c478bd9Sstevel@tonic-gate for (i = 0; i < nhost; i++) 4337c478bd9Sstevel@tonic-gate if (strcasecmp(thost, phost[i]) == 0) 4347c478bd9Sstevel@tonic-gate break; 4357c478bd9Sstevel@tonic-gate if (i == nhost) 4367c478bd9Sstevel@tonic-gate continue; 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate if (tuser != NULL && *tuser != '\0' && nusers != 0) { 4397c478bd9Sstevel@tonic-gate for (i = 0; i < nusers; i++) 4407c478bd9Sstevel@tonic-gate if (strcmp(tuser, pusers[i]) == 0) 4417c478bd9Sstevel@tonic-gate break; 4427c478bd9Sstevel@tonic-gate if (i == nusers) 4437c478bd9Sstevel@tonic-gate continue; 4447c478bd9Sstevel@tonic-gate } 445e429788eSmj162486 if (tdomain != NULL && *tdomain != '\0' && 446e429788eSmj162486 ndomains != 0) { 4477c478bd9Sstevel@tonic-gate for (i = 0; i < ndomains; i++) 4487c478bd9Sstevel@tonic-gate if (domcmp(tdomain, pdomains[i]) == 0) 4497c478bd9Sstevel@tonic-gate break; 4507c478bd9Sstevel@tonic-gate if (i == ndomains) 4517c478bd9Sstevel@tonic-gate continue; 4527c478bd9Sstevel@tonic-gate } 4537c478bd9Sstevel@tonic-gate return (1); 4547c478bd9Sstevel@tonic-gate } 455e429788eSmj162486 } 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate return (0); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate static int 4617c478bd9Sstevel@tonic-gate match_triple(struct nss_innetgr_args *ia, ns_ldap_result_t *result) 4627c478bd9Sstevel@tonic-gate { 4637c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 4647c478bd9Sstevel@tonic-gate 4657c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) 4667c478bd9Sstevel@tonic-gate if (match_triple_entry(ia, entry) == 1) 4677c478bd9Sstevel@tonic-gate return (1); 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate return (0); 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate static int 4737c478bd9Sstevel@tonic-gate add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab) 4747c478bd9Sstevel@tonic-gate { 4757c478bd9Sstevel@tonic-gate char **attrs; 4767c478bd9Sstevel@tonic-gate char **a; 4777c478bd9Sstevel@tonic-gate 4787c478bd9Sstevel@tonic-gate attrs = __ns_ldap_getAttr(entry, _N_MEMBER); 4797c478bd9Sstevel@tonic-gate if (attrs == NULL || *attrs == NULL) 4807c478bd9Sstevel@tonic-gate return (0); 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate for (a = attrs; *a != NULL; a++) {} 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate do { 4857c478bd9Sstevel@tonic-gate a--; 4867c478bd9Sstevel@tonic-gate if (add_netgroup_name(*a, tab) != 0) 4877c478bd9Sstevel@tonic-gate return (-1); 4887c478bd9Sstevel@tonic-gate } while (a > attrs); 4897c478bd9Sstevel@tonic-gate return (0); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate static int 4937c478bd9Sstevel@tonic-gate add_netgroup_member(ns_ldap_result_t *result, netgroup_table_t *tab) 4947c478bd9Sstevel@tonic-gate { 4957c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 4967c478bd9Sstevel@tonic-gate int ret = 0; 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) { 4997c478bd9Sstevel@tonic-gate ret = add_netgroup_member_entry(entry, tab); 5007c478bd9Sstevel@tonic-gate if (ret != 0) 5017c478bd9Sstevel@tonic-gate break; 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate return (ret); 5047c478bd9Sstevel@tonic-gate } 5057c478bd9Sstevel@tonic-gate 5067c478bd9Sstevel@tonic-gate /* 5077c478bd9Sstevel@tonic-gate * top_down_search checks only checks the netgroup specified in netgrname 5087c478bd9Sstevel@tonic-gate */ 5097c478bd9Sstevel@tonic-gate static nss_status_t 5107c478bd9Sstevel@tonic-gate top_down_search(struct nss_innetgr_args *ia, char *netgrname) 5117c478bd9Sstevel@tonic-gate { 5127c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 5137c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 5147c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 5157c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 5167c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 5177c478bd9Sstevel@tonic-gate int rc; 5187c478bd9Sstevel@tonic-gate void *cookie = NULL; 5197c478bd9Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND; 520*3d047983Smichen nss_status_t status1; 5217c478bd9Sstevel@tonic-gate netgroup_table_t tab; 5227c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 5237c478bd9Sstevel@tonic-gate int ret; 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate (void) memset(&tab, 0, sizeof (tab)); 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate if (add_netgroup_name(netgrname, &tab) != 0) 5287c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate while ((ng = get_next_netgroup(&tab)) != NULL) { 5317c478bd9Sstevel@tonic-gate if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0) 5327c478bd9Sstevel@tonic-gate break; 533*3d047983Smichen ret = snprintf(searchfilter, sizeof (searchfilter), 534*3d047983Smichen _F_SETMEMBER, name); 5357c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 5367c478bd9Sstevel@tonic-gate break; 5377c478bd9Sstevel@tonic-gate 538*3d047983Smichen ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD, 539*3d047983Smichen name); 5407c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 5417c478bd9Sstevel@tonic-gate break; 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate rc = __ns_ldap_firstEntry(_NETGROUP, searchfilter, 544*3d047983Smichen _merge_SSD_filter, netgrent_attrs, NULL, 0, &cookie, 545*3d047983Smichen &result, &error, userdata); 546*3d047983Smichen 547*3d047983Smichen if (error != NULL) { 548*3d047983Smichen status1 = switch_err(rc, error); 549*3d047983Smichen if (status1 == NSS_TRYAGAIN) { 550*3d047983Smichen (void) __ns_ldap_freeError(&error); 551*3d047983Smichen free_netgroup_table(&tab); 552*3d047983Smichen return (status1); 553*3d047983Smichen } 554*3d047983Smichen } 5557c478bd9Sstevel@tonic-gate 5567c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5577c478bd9Sstevel@tonic-gate while (rc == NS_LDAP_SUCCESS && result != NULL) { 5587c478bd9Sstevel@tonic-gate if (match_triple(ia, result) == 1) { 5597c478bd9Sstevel@tonic-gate /* We found a match */ 5607c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_FOUND; 5617c478bd9Sstevel@tonic-gate status = NSS_SUCCESS; 5627c478bd9Sstevel@tonic-gate break; 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate rc = add_netgroup_member(result, &tab); 5667c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate if (rc != NS_LDAP_SUCCESS) 5697c478bd9Sstevel@tonic-gate break; 5707c478bd9Sstevel@tonic-gate rc = __ns_ldap_nextEntry(cookie, &result, &error); 571*3d047983Smichen if (error != NULL) { 572*3d047983Smichen status1 = switch_err(rc, error); 573*3d047983Smichen if (status1 == NSS_TRYAGAIN) { 574*3d047983Smichen free_netgroup_table(&tab); 575*3d047983Smichen (void) __ns_ldap_freeError(&error); 576*3d047983Smichen (void) __ns_ldap_endEntry(&cookie, 577*3d047983Smichen &error); 578*3d047983Smichen (void) __ns_ldap_freeError(&error); 579*3d047983Smichen return (status1); 580*3d047983Smichen } 581*3d047983Smichen } 5827c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5837c478bd9Sstevel@tonic-gate } 5847c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 5857c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&cookie, &error); 5867c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate if (status == NSS_SUCCESS || 5897c478bd9Sstevel@tonic-gate (rc != NS_LDAP_SUCCESS && rc != NS_LDAP_NOTFOUND)) 5907c478bd9Sstevel@tonic-gate break; 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 5947c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&cookie, &error); 5957c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 5967c478bd9Sstevel@tonic-gate free_netgroup_table(&tab); 5977c478bd9Sstevel@tonic-gate return (status); 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate /* 6017c478bd9Sstevel@tonic-gate * __netgr_in checks only checks the netgroup specified in ngroup 6027c478bd9Sstevel@tonic-gate */ 6037c478bd9Sstevel@tonic-gate static nss_status_t 6047c478bd9Sstevel@tonic-gate __netgr_in(void *a, char *netgrname) 6057c478bd9Sstevel@tonic-gate { 6067c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 6077c478bd9Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND; 6087c478bd9Sstevel@tonic-gate 6097c478bd9Sstevel@tonic-gate #ifdef DEBUG 6107c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_in]\n"); 6117c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tmachine: argc[%d]='%s' user: " 6127c478bd9Sstevel@tonic-gate "argc[%d]='%s',\n\tdomain:argc[%d]='%s' " 6137c478bd9Sstevel@tonic-gate "netgroup: argc[%d]='%s'\n", 6147c478bd9Sstevel@tonic-gate NSS_NETGR_MACHINE, 6157c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_MACHINE]), 6167c478bd9Sstevel@tonic-gate NSS_NETGR_USER, 6177c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_USER]), 6187c478bd9Sstevel@tonic-gate NSS_NETGR_DOMAIN, 6197c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_DOMAIN]), 6207c478bd9Sstevel@tonic-gate NSS_NETGR_N, 6217c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_N])); 6227c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tgroups='%s'\n", netgrname); 6237c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_NO; 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate if (netgrname == NULL) 6287c478bd9Sstevel@tonic-gate return (status); 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate return (top_down_search(ia, netgrname)); 6317c478bd9Sstevel@tonic-gate } 6327c478bd9Sstevel@tonic-gate 6337c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 6347c478bd9Sstevel@tonic-gate static nss_status_t 6357c478bd9Sstevel@tonic-gate netgr_in(ldap_backend_ptr be, void *a) 6367c478bd9Sstevel@tonic-gate { 6377c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 6387c478bd9Sstevel@tonic-gate int i; 6397c478bd9Sstevel@tonic-gate nss_status_t rc = (nss_status_t)NSS_NOTFOUND; 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_NO; 6427c478bd9Sstevel@tonic-gate for (i = 0; i < ia->groups.argc; i++) { 6437c478bd9Sstevel@tonic-gate rc = __netgr_in(a, ia->groups.argv[i]); 6447c478bd9Sstevel@tonic-gate if (ia->status == NSS_NETGR_FOUND) 6457c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate return (rc); 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate /* 6517c478bd9Sstevel@tonic-gate * 6527c478bd9Sstevel@tonic-gate */ 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate static nss_status_t 6557c478bd9Sstevel@tonic-gate getnetgr_ldap_setent(ldap_backend_ptr be, void *a) 6567c478bd9Sstevel@tonic-gate { 6577c478bd9Sstevel@tonic-gate const char *netgroup = (const char *) a; 6587c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *cookie; 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate #ifdef DEBUG 6617c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_setent]\n"); 6627c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6637c478bd9Sstevel@tonic-gate 6647c478bd9Sstevel@tonic-gate cookie = (getnetgrent_cookie_t *)be->netgroup_cookie; 6657c478bd9Sstevel@tonic-gate if (cookie != NULL && cookie->netgroup != NULL) { 6667c478bd9Sstevel@tonic-gate /* is this another set on the same netgroup */ 6677c478bd9Sstevel@tonic-gate if (strcmp(cookie->netgroup, netgroup) == 0) 6687c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 6727c478bd9Sstevel@tonic-gate } 6737c478bd9Sstevel@tonic-gate 6747c478bd9Sstevel@tonic-gate static void 6757c478bd9Sstevel@tonic-gate free_getnetgrent_cookie(getnetgrent_cookie_t **cookie) 6767c478bd9Sstevel@tonic-gate { 6777c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 6787c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p = *cookie; 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate #ifdef DEBUG 6817c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: free_getnetgrent_cookie]\n"); 6827c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate if (p == NULL) 6857c478bd9Sstevel@tonic-gate return; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results); 6887c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&p->cookie, &error); 6897c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 6907c478bd9Sstevel@tonic-gate free_netgroup_table(&p->tab); 6917c478bd9Sstevel@tonic-gate free(p->netgroup); 6927c478bd9Sstevel@tonic-gate free(p); 6937c478bd9Sstevel@tonic-gate *cookie = NULL; 6947c478bd9Sstevel@tonic-gate } 6957c478bd9Sstevel@tonic-gate 6967c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 6977c478bd9Sstevel@tonic-gate static nss_status_t 6987c478bd9Sstevel@tonic-gate getnetgr_ldap_endent(ldap_backend_ptr be, void *a) 6997c478bd9Sstevel@tonic-gate { 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate #ifdef DEBUG 7027c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_endent]\n"); 7037c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7047c478bd9Sstevel@tonic-gate 7057c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 7067c478bd9Sstevel@tonic-gate 7077c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 7087c478bd9Sstevel@tonic-gate } 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 7127c478bd9Sstevel@tonic-gate static nss_status_t 7137c478bd9Sstevel@tonic-gate getnetgr_ldap_destr(ldap_backend_ptr be, void *a) 7147c478bd9Sstevel@tonic-gate { 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate #ifdef DEBUG 7177c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_destr]\n"); 7187c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7197c478bd9Sstevel@tonic-gate 7207c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 7217c478bd9Sstevel@tonic-gate free(be); 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate static nss_status_t 7287c478bd9Sstevel@tonic-gate getnetgr_ldap_getent(ldap_backend_ptr be, void *a) 7297c478bd9Sstevel@tonic-gate { 7307c478bd9Sstevel@tonic-gate struct nss_getnetgrent_args *args; 7317c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p; 7327c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 7337c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 7347c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 7357c478bd9Sstevel@tonic-gate int rc; 7367c478bd9Sstevel@tonic-gate void *cookie = NULL; 7377c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 7387c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 7397c478bd9Sstevel@tonic-gate char **attrs; 7407c478bd9Sstevel@tonic-gate char *hostname, *username, *domain; 7417c478bd9Sstevel@tonic-gate char *buffer; 7427c478bd9Sstevel@tonic-gate nss_status_t status = NSS_SUCCESS; 7437c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 7447c478bd9Sstevel@tonic-gate int ret; 7457c478bd9Sstevel@tonic-gate 7467c478bd9Sstevel@tonic-gate #ifdef DEBUG 7477c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n"); 7487c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate args = (struct nss_getnetgrent_args *)a; 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_NO; 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate p = (getnetgrent_cookie_t *)be->netgroup_cookie; 7557c478bd9Sstevel@tonic-gate if (p == NULL) 7567c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 7577c478bd9Sstevel@tonic-gate 7587c478bd9Sstevel@tonic-gate for (;;) { 7597c478bd9Sstevel@tonic-gate while (p->cookie == NULL) { 7607c478bd9Sstevel@tonic-gate ng = get_next_netgroup(&p->tab); 7617c478bd9Sstevel@tonic-gate if (ng == NULL) /* no more */ 7627c478bd9Sstevel@tonic-gate break; 7637c478bd9Sstevel@tonic-gate 764*3d047983Smichen if (_ldap_filter_name(name, ng->name, 765*3d047983Smichen sizeof (name)) != 0) 7667c478bd9Sstevel@tonic-gate break; 7677c478bd9Sstevel@tonic-gate 768*3d047983Smichen ret = snprintf(searchfilter, 769*3d047983Smichen sizeof (searchfilter), 7707c478bd9Sstevel@tonic-gate _F_SETMEMBER, name); 7717c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 7727c478bd9Sstevel@tonic-gate break; 7737c478bd9Sstevel@tonic-gate 774*3d047983Smichen ret = snprintf(userdata, sizeof (userdata), 775*3d047983Smichen _F_SETMEMBER_SSD, name); 7767c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 7777c478bd9Sstevel@tonic-gate break; 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate result = NULL; 780*3d047983Smichen rc = __ns_ldap_firstEntry(_NETGROUP, 781*3d047983Smichen searchfilter, 782*3d047983Smichen _merge_SSD_filter, netgrent_attrs, 783*3d047983Smichen NULL, 0, &cookie, 7847c478bd9Sstevel@tonic-gate &result, &error, userdata); 7857c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 7867c478bd9Sstevel@tonic-gate 7877c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS && result != NULL) { 7887c478bd9Sstevel@tonic-gate p->cookie = cookie; 7897c478bd9Sstevel@tonic-gate p->results = result; 7907c478bd9Sstevel@tonic-gate break; 7917c478bd9Sstevel@tonic-gate } 7927c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 7937c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&cookie, &error); 7947c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate if (p->cookie == NULL) 7977c478bd9Sstevel@tonic-gate break; 7987c478bd9Sstevel@tonic-gate if (p->results == NULL) { 7997c478bd9Sstevel@tonic-gate result = NULL; 800*3d047983Smichen rc = __ns_ldap_nextEntry(p->cookie, &result, 801*3d047983Smichen &error); 8027c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 8037c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS && result != NULL) 8047c478bd9Sstevel@tonic-gate p->results = result; 8057c478bd9Sstevel@tonic-gate else { 8067c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 807*3d047983Smichen (void) __ns_ldap_endEntry(&p->cookie, 808*3d047983Smichen &error); 8097c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 8107c478bd9Sstevel@tonic-gate p->cookie = NULL; 8117c478bd9Sstevel@tonic-gate } 8127c478bd9Sstevel@tonic-gate } 8137c478bd9Sstevel@tonic-gate if (p->results == NULL) 8147c478bd9Sstevel@tonic-gate continue; 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate if (p->entry == NULL) 8177c478bd9Sstevel@tonic-gate p->entry = p->results->entry; 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate if (p->entry == NULL) 8207c478bd9Sstevel@tonic-gate continue; 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate if (p->attrs == NULL) { 8237c478bd9Sstevel@tonic-gate attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE); 8247c478bd9Sstevel@tonic-gate if (attrs != NULL && *attrs != NULL) 8257c478bd9Sstevel@tonic-gate p->attrs = attrs; 8267c478bd9Sstevel@tonic-gate } 8277c478bd9Sstevel@tonic-gate 8287c478bd9Sstevel@tonic-gate if (p->attrs != NULL) { 8297c478bd9Sstevel@tonic-gate attrs = p->attrs; 8307c478bd9Sstevel@tonic-gate buffer = args->buffer; 8317c478bd9Sstevel@tonic-gate 832*3d047983Smichen if (strlcpy(buffer, *attrs, args->buflen) >= 833*3d047983Smichen args->buflen) { 8347c478bd9Sstevel@tonic-gate status = NSS_STR_PARSE_ERANGE; 8357c478bd9Sstevel@tonic-gate break; 8367c478bd9Sstevel@tonic-gate } 8377c478bd9Sstevel@tonic-gate 838*3d047983Smichen rc = split_triple(buffer, &hostname, &username, 839*3d047983Smichen &domain); 8407c478bd9Sstevel@tonic-gate attrs++; 8417c478bd9Sstevel@tonic-gate if (attrs != NULL && *attrs != NULL) 8427c478bd9Sstevel@tonic-gate p->attrs = attrs; 8437c478bd9Sstevel@tonic-gate else 8447c478bd9Sstevel@tonic-gate p->attrs = NULL; 8457c478bd9Sstevel@tonic-gate if (rc == 0) { 8467c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_MACHINE] = hostname; 8477c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_USER] = username; 8487c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_DOMAIN] = domain; 8497c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_FOUND; 8507c478bd9Sstevel@tonic-gate if (p->attrs != NULL) 8517c478bd9Sstevel@tonic-gate break; 8527c478bd9Sstevel@tonic-gate } 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate if (p->attrs == NULL) { 8567c478bd9Sstevel@tonic-gate rc = add_netgroup_member_entry(p->entry, &p->tab); 8577c478bd9Sstevel@tonic-gate if (rc != 0) { 8587c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_NO; 8597c478bd9Sstevel@tonic-gate break; 8607c478bd9Sstevel@tonic-gate } 8617c478bd9Sstevel@tonic-gate 8627c478bd9Sstevel@tonic-gate p->entry = p->entry->next; 8637c478bd9Sstevel@tonic-gate if (p->entry == NULL) 8647c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results); 8657c478bd9Sstevel@tonic-gate if (args->status == NSS_NETGR_FOUND) 8667c478bd9Sstevel@tonic-gate break; 8677c478bd9Sstevel@tonic-gate } 8687c478bd9Sstevel@tonic-gate } 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate return (status); 8717c478bd9Sstevel@tonic-gate } 8727c478bd9Sstevel@tonic-gate 8737c478bd9Sstevel@tonic-gate static ldap_backend_op_t getnetgroup_ops[] = { 8747c478bd9Sstevel@tonic-gate getnetgr_ldap_destr, 8757c478bd9Sstevel@tonic-gate getnetgr_ldap_endent, 8767c478bd9Sstevel@tonic-gate getnetgr_ldap_setent, 8777c478bd9Sstevel@tonic-gate getnetgr_ldap_getent, 8787c478bd9Sstevel@tonic-gate }; 8797c478bd9Sstevel@tonic-gate 8807c478bd9Sstevel@tonic-gate /* 8817c478bd9Sstevel@tonic-gate * 8827c478bd9Sstevel@tonic-gate */ 8837c478bd9Sstevel@tonic-gate 8847c478bd9Sstevel@tonic-gate static nss_status_t 8857c478bd9Sstevel@tonic-gate netgr_set(ldap_backend_ptr be, void *a) 8867c478bd9Sstevel@tonic-gate { 8877c478bd9Sstevel@tonic-gate struct nss_setnetgrent_args *args = 8887c478bd9Sstevel@tonic-gate (struct nss_setnetgrent_args *)a; 8897c478bd9Sstevel@tonic-gate ldap_backend_ptr get_be; 8907c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p; 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate #ifdef DEBUG 8937c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_set]\n"); 8947c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 8957c478bd9Sstevel@tonic-gate "\targs->netgroup: %s\n", ISNULL(args->netgroup)); 8967c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate if (args->netgroup == NULL) 8997c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 9027c478bd9Sstevel@tonic-gate p = (getnetgrent_cookie_t *)calloc(1, sizeof (getnetgrent_cookie_t)); 9037c478bd9Sstevel@tonic-gate if (p == NULL) 9047c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9057c478bd9Sstevel@tonic-gate p->netgroup = strdup(args->netgroup); 9067c478bd9Sstevel@tonic-gate if (p->netgroup == NULL) { 9077c478bd9Sstevel@tonic-gate free(p); 9087c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate if (add_netgroup_name(args->netgroup, &p->tab) == -1) { 9117c478bd9Sstevel@tonic-gate free_getnetgrent_cookie(&p); 9127c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate /* now allocate and return iteration backend structure */ 9167c478bd9Sstevel@tonic-gate if ((get_be = (ldap_backend_ptr)malloc(sizeof (*get_be))) == NULL) 9177c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 9187c478bd9Sstevel@tonic-gate get_be->ops = getnetgroup_ops; 9197c478bd9Sstevel@tonic-gate get_be->nops = sizeof (getnetgroup_ops) / sizeof (getnetgroup_ops[0]); 9207c478bd9Sstevel@tonic-gate get_be->tablename = NULL; 9217c478bd9Sstevel@tonic-gate get_be->attrs = netgrent_attrs; 9227c478bd9Sstevel@tonic-gate get_be->result = NULL; 923cb5caa98Sdjl get_be->ldapobj2str = NULL; 9247c478bd9Sstevel@tonic-gate get_be->setcalled = 1; 9257c478bd9Sstevel@tonic-gate get_be->filter = NULL; 9267c478bd9Sstevel@tonic-gate get_be->toglue = NULL; 9277c478bd9Sstevel@tonic-gate get_be->enumcookie = NULL; 9287c478bd9Sstevel@tonic-gate get_be->netgroup_cookie = p; 9297c478bd9Sstevel@tonic-gate args->iterator = (nss_backend_t *)get_be; 9307c478bd9Sstevel@tonic-gate 9317c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 9327c478bd9Sstevel@tonic-gate 9337c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 9347c478bd9Sstevel@tonic-gate } 9357c478bd9Sstevel@tonic-gate 9367c478bd9Sstevel@tonic-gate 9377c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 9387c478bd9Sstevel@tonic-gate static nss_status_t 9397c478bd9Sstevel@tonic-gate netgr_ldap_destr(ldap_backend_ptr be, void *a) 9407c478bd9Sstevel@tonic-gate { 9417c478bd9Sstevel@tonic-gate 9427c478bd9Sstevel@tonic-gate #ifdef DEBUG 9437c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_ldap_destr]\n"); 9447c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate (void) _clean_ldap_backend(be); 9477c478bd9Sstevel@tonic-gate 9487c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9497c478bd9Sstevel@tonic-gate } 9507c478bd9Sstevel@tonic-gate 9517c478bd9Sstevel@tonic-gate 9527c478bd9Sstevel@tonic-gate 9537c478bd9Sstevel@tonic-gate 9547c478bd9Sstevel@tonic-gate static ldap_backend_op_t netgroup_ops[] = { 9557c478bd9Sstevel@tonic-gate netgr_ldap_destr, 9567c478bd9Sstevel@tonic-gate 0, 9577c478bd9Sstevel@tonic-gate 0, 9587c478bd9Sstevel@tonic-gate 0, 9597c478bd9Sstevel@tonic-gate netgr_in, /* innetgr() */ 9607c478bd9Sstevel@tonic-gate netgr_set /* setnetgrent() */ 9617c478bd9Sstevel@tonic-gate }; 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate /* 9657c478bd9Sstevel@tonic-gate * _nss_ldap_netgroup_constr is where life begins. This function calls the 9667c478bd9Sstevel@tonic-gate * generic ldap constructor function to define and build the abstract data 9677c478bd9Sstevel@tonic-gate * types required to support ldap operations. 9687c478bd9Sstevel@tonic-gate */ 9697c478bd9Sstevel@tonic-gate 9707c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 9717c478bd9Sstevel@tonic-gate nss_backend_t * 9727c478bd9Sstevel@tonic-gate _nss_ldap_netgroup_constr(const char *dummy1, const char *dummy2, 9737c478bd9Sstevel@tonic-gate const char *dummy3) 9747c478bd9Sstevel@tonic-gate { 9757c478bd9Sstevel@tonic-gate 9767c478bd9Sstevel@tonic-gate #ifdef DEBUG 9777c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 9787c478bd9Sstevel@tonic-gate "\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n"); 9797c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(netgroup_ops, 9827c478bd9Sstevel@tonic-gate sizeof (netgroup_ops)/sizeof (netgroup_ops[0]), _NETGROUP, 9837c478bd9Sstevel@tonic-gate netgrent_attrs, NULL)); 9847c478bd9Sstevel@tonic-gate } 985