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*ca883132SSerge Dussud * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #include <syslog.h> 287c478bd9Sstevel@tonic-gate #include "ldap_common.h" 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* netgroup attributes filters */ 317c478bd9Sstevel@tonic-gate #define _N_TRIPLE "nisnetgrouptriple" 327c478bd9Sstevel@tonic-gate #define _N_MEMBER "membernisnetgroup" 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #define PRINT_VAL(a) (((a).argc == 0) || ((a).argv == NULL) || \ 357c478bd9Sstevel@tonic-gate ((a).argv[0] == NULL)) ? "*" : (a).argv[0] 367c478bd9Sstevel@tonic-gate #define ISNULL(a) (a == NULL ? "<NULL>" : a) 377c478bd9Sstevel@tonic-gate #define MAX_DOMAIN_LEN 1024 387c478bd9Sstevel@tonic-gate #define MAX_TRIPLE_LEN (MAXHOSTNAMELEN + LOGNAME_MAX + \ 397c478bd9Sstevel@tonic-gate MAX_DOMAIN_LEN + 5) 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #define _F_SETMEMBER "(&(objectClass=nisNetGroup)(cn=%s))" 427c478bd9Sstevel@tonic-gate #define _F_SETMEMBER_SSD "(&(%%s)(cn=%s))" 437c478bd9Sstevel@tonic-gate 447c478bd9Sstevel@tonic-gate #define N_HASH 257 45e429788eSmj162486 #define COMMA ',' 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate static const char *netgrent_attrs[] = { 487c478bd9Sstevel@tonic-gate _N_TRIPLE, 497c478bd9Sstevel@tonic-gate _N_MEMBER, 507c478bd9Sstevel@tonic-gate (char *)NULL 517c478bd9Sstevel@tonic-gate }; 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate typedef struct netgroup_name { 547c478bd9Sstevel@tonic-gate char *name; 557c478bd9Sstevel@tonic-gate struct netgroup_name *next; 567c478bd9Sstevel@tonic-gate struct netgroup_name *next_hash; 577c478bd9Sstevel@tonic-gate } netgroup_name_t; 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate typedef struct { 607c478bd9Sstevel@tonic-gate netgroup_name_t *hash_list[N_HASH]; 617c478bd9Sstevel@tonic-gate netgroup_name_t *to_do; 627c478bd9Sstevel@tonic-gate netgroup_name_t *done; 637c478bd9Sstevel@tonic-gate } netgroup_table_t; 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate typedef struct { 667c478bd9Sstevel@tonic-gate ns_ldap_result_t *results; 677c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 687c478bd9Sstevel@tonic-gate char **attrs; 697c478bd9Sstevel@tonic-gate char *netgroup; 707c478bd9Sstevel@tonic-gate netgroup_table_t tab; 717c478bd9Sstevel@tonic-gate } getnetgrent_cookie_t; 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate typedef struct { 747c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia; 757c478bd9Sstevel@tonic-gate const char *ssd_filter; 767c478bd9Sstevel@tonic-gate const char *netgrname; 777c478bd9Sstevel@tonic-gate const char *membername; 787c478bd9Sstevel@tonic-gate netgroup_table_t tab; 797c478bd9Sstevel@tonic-gate } innetgr_cookie_t; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate typedef unsigned int hash_t; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static hash_t 847c478bd9Sstevel@tonic-gate get_hash(const char *s) 857c478bd9Sstevel@tonic-gate { 867c478bd9Sstevel@tonic-gate unsigned int sum = 0; 877c478bd9Sstevel@tonic-gate unsigned int i; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate for (i = 0; s[i] != '\0'; i++) 907c478bd9Sstevel@tonic-gate sum += ((unsigned char *)s)[i]; 917c478bd9Sstevel@tonic-gate 927c478bd9Sstevel@tonic-gate return ((sum + i) % N_HASH); 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate /* 967c478bd9Sstevel@tonic-gate * Adds a name to the netgroup table 977c478bd9Sstevel@tonic-gate * 987c478bd9Sstevel@tonic-gate * Returns 997c478bd9Sstevel@tonic-gate * 0 if successfully added or already present 100*ca883132SSerge Dussud * -1 if memory allocation error or NULL netgroup_table_t 101*ca883132SSerge Dussud * from caller. 1027c478bd9Sstevel@tonic-gate */ 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate static int 1057c478bd9Sstevel@tonic-gate add_netgroup_name(const char *name, netgroup_table_t *tab) 1067c478bd9Sstevel@tonic-gate { 1077c478bd9Sstevel@tonic-gate hash_t h; 1087c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 1097c478bd9Sstevel@tonic-gate netgroup_name_t *ng_new; 1107c478bd9Sstevel@tonic-gate 111*ca883132SSerge Dussud if (tab == NULL) { 112*ca883132SSerge Dussud /* 113*ca883132SSerge Dussud * Should never happen. But if it does, 114*ca883132SSerge Dussud * that's an error condition. 115*ca883132SSerge Dussud */ 116*ca883132SSerge Dussud return (-1); 117*ca883132SSerge Dussud } 118*ca883132SSerge Dussud if (name == NULL || *name == '\0') { 119*ca883132SSerge Dussud /* no name to add means success */ 120*ca883132SSerge Dussud return (0); 121*ca883132SSerge Dussud } 1227c478bd9Sstevel@tonic-gate 1237c478bd9Sstevel@tonic-gate h = get_hash(name); 1247c478bd9Sstevel@tonic-gate ng = tab->hash_list[h]; 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate while (ng != NULL) { 1277c478bd9Sstevel@tonic-gate if (strcmp(name, ng->name) == 0) 1287c478bd9Sstevel@tonic-gate break; 1297c478bd9Sstevel@tonic-gate ng = ng->next_hash; 1307c478bd9Sstevel@tonic-gate } 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate if (ng == NULL) { 1337c478bd9Sstevel@tonic-gate ng_new = (netgroup_name_t *) 1347c478bd9Sstevel@tonic-gate calloc(1, sizeof (netgroup_name_t)); 1357c478bd9Sstevel@tonic-gate if (ng_new == NULL) 1367c478bd9Sstevel@tonic-gate return (-1); 1377c478bd9Sstevel@tonic-gate ng_new->name = strdup(name); 1387c478bd9Sstevel@tonic-gate if (ng_new->name == NULL) { 1397c478bd9Sstevel@tonic-gate free(ng_new); 1407c478bd9Sstevel@tonic-gate return (-1); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate ng_new->next_hash = tab->hash_list[h]; 1437c478bd9Sstevel@tonic-gate tab->hash_list[h] = ng_new; 1447c478bd9Sstevel@tonic-gate ng_new->next = tab->to_do; 1457c478bd9Sstevel@tonic-gate tab->to_do = ng_new; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate return (0); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate static netgroup_name_t * 1517c478bd9Sstevel@tonic-gate get_next_netgroup(netgroup_table_t *tab) 1527c478bd9Sstevel@tonic-gate { 1537c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 1547c478bd9Sstevel@tonic-gate 1557c478bd9Sstevel@tonic-gate if (tab == NULL) 1567c478bd9Sstevel@tonic-gate return (NULL); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate ng = tab->to_do; 1597c478bd9Sstevel@tonic-gate if (ng != NULL) { 1607c478bd9Sstevel@tonic-gate tab->to_do = ng->next; 1617c478bd9Sstevel@tonic-gate ng->next = tab->done; 1627c478bd9Sstevel@tonic-gate tab->done = ng; 1637c478bd9Sstevel@tonic-gate } 1647c478bd9Sstevel@tonic-gate return (ng); 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate static void 1687c478bd9Sstevel@tonic-gate free_netgroup_table(netgroup_table_t *tab) 1697c478bd9Sstevel@tonic-gate { 1707c478bd9Sstevel@tonic-gate netgroup_name_t *ng, *next; 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate if (tab == NULL) 1737c478bd9Sstevel@tonic-gate return; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate for (ng = tab->to_do; ng != NULL; ng = next) { 1767c478bd9Sstevel@tonic-gate if (ng->name != NULL) 1777c478bd9Sstevel@tonic-gate free(ng->name); 1787c478bd9Sstevel@tonic-gate next = ng->next; 1797c478bd9Sstevel@tonic-gate free(ng); 1807c478bd9Sstevel@tonic-gate } 1817c478bd9Sstevel@tonic-gate 1827c478bd9Sstevel@tonic-gate for (ng = tab->done; ng != NULL; ng = next) { 1837c478bd9Sstevel@tonic-gate if (ng->name != NULL) 1847c478bd9Sstevel@tonic-gate free(ng->name); 1857c478bd9Sstevel@tonic-gate next = ng->next; 1867c478bd9Sstevel@tonic-gate free(ng); 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate (void) memset(tab, 0, sizeof (*tab)); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate /* 1927c478bd9Sstevel@tonic-gate * domain comparing routine 1937c478bd9Sstevel@tonic-gate * n1: See if n1 is n2 or an ancestor of it 1947c478bd9Sstevel@tonic-gate * n2: (in string terms, n1 is a suffix of n2) 1957c478bd9Sstevel@tonic-gate * Returns ZERO for success, -1 for failure. 1967c478bd9Sstevel@tonic-gate */ 1977c478bd9Sstevel@tonic-gate static int 1987c478bd9Sstevel@tonic-gate domcmp(const char *n1, const char *n2) 1997c478bd9Sstevel@tonic-gate { 2007c478bd9Sstevel@tonic-gate #define PASS 0 2017c478bd9Sstevel@tonic-gate #define FAIL -1 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate size_t l1, l2; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if ((n1 == NULL) || (n2 == NULL)) 2067c478bd9Sstevel@tonic-gate return (FAIL); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate l1 = strlen(n1); 2097c478bd9Sstevel@tonic-gate l2 = strlen(n2); 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate /* Turn a blind eye to the presence or absence of trailing periods */ 2127c478bd9Sstevel@tonic-gate if (l1 != 0 && n1[l1 - 1] == '.') { 2137c478bd9Sstevel@tonic-gate --l1; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate if (l2 != 0 && n2[l2 - 1] == '.') { 2167c478bd9Sstevel@tonic-gate --l2; 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate if (l1 > l2) { /* Can't be a suffix */ 2197c478bd9Sstevel@tonic-gate return (FAIL); 2207c478bd9Sstevel@tonic-gate } else if (l1 == 0) { /* Trivially a suffix; */ 2217c478bd9Sstevel@tonic-gate /* (do we want this case?) */ 2227c478bd9Sstevel@tonic-gate return (PASS); 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate /* So 0 < l1 <= l2 */ 2257c478bd9Sstevel@tonic-gate if (l1 < l2 && n2[l2 - l1 - 1] != '.') { 2267c478bd9Sstevel@tonic-gate return (FAIL); 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate if (strncasecmp(n1, &n2[l2 - l1], l1) == 0) { 2297c478bd9Sstevel@tonic-gate return (PASS); 2307c478bd9Sstevel@tonic-gate } else { 2317c478bd9Sstevel@tonic-gate return (FAIL); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate 2357c478bd9Sstevel@tonic-gate static int 2367c478bd9Sstevel@tonic-gate split_triple(char *triple, char **hostname, char **username, char **domain) 2377c478bd9Sstevel@tonic-gate { 2387c478bd9Sstevel@tonic-gate int i, syntax_err; 2397c478bd9Sstevel@tonic-gate char *splittriple[3]; 2407c478bd9Sstevel@tonic-gate char *p = triple; 2417c478bd9Sstevel@tonic-gate 2427c478bd9Sstevel@tonic-gate #ifdef DEBUG 2437c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: split_triple]\n"); 2447c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate if (triple == NULL) 2477c478bd9Sstevel@tonic-gate return (-1); 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate p++; 2507c478bd9Sstevel@tonic-gate syntax_err = 0; 2517c478bd9Sstevel@tonic-gate for (i = 0; i < 3; i++) { 2527c478bd9Sstevel@tonic-gate char *start; 2537c478bd9Sstevel@tonic-gate char *limit; 2547c478bd9Sstevel@tonic-gate const char *terminators = ",) \t"; 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate if (i == 2) { 2577c478bd9Sstevel@tonic-gate /* Don't allow comma */ 2587c478bd9Sstevel@tonic-gate terminators++; 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate while (isspace(*p)) { 2617c478bd9Sstevel@tonic-gate p++; 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate start = p; 2647c478bd9Sstevel@tonic-gate limit = strpbrk(start, terminators); 2657c478bd9Sstevel@tonic-gate if (limit == 0) { 2667c478bd9Sstevel@tonic-gate syntax_err++; 2677c478bd9Sstevel@tonic-gate break; 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate p = limit; 2707c478bd9Sstevel@tonic-gate while (isspace(*p)) { 2717c478bd9Sstevel@tonic-gate p++; 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate if (*p == terminators[0]) { 2747c478bd9Sstevel@tonic-gate /* 2757c478bd9Sstevel@tonic-gate * Successfully parsed this name and 2767c478bd9Sstevel@tonic-gate * the separator after it (comma or 2777c478bd9Sstevel@tonic-gate * right paren); leave p ready for 2787c478bd9Sstevel@tonic-gate * next parse. 2797c478bd9Sstevel@tonic-gate */ 2807c478bd9Sstevel@tonic-gate p++; 2817c478bd9Sstevel@tonic-gate if (start == limit) { 2827c478bd9Sstevel@tonic-gate /* Wildcard */ 2837c478bd9Sstevel@tonic-gate splittriple[i] = NULL; 2847c478bd9Sstevel@tonic-gate } else { 2857c478bd9Sstevel@tonic-gate *limit = '\0'; 2867c478bd9Sstevel@tonic-gate splittriple[i] = start; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate } else { 2897c478bd9Sstevel@tonic-gate syntax_err++; 2907c478bd9Sstevel@tonic-gate break; 2917c478bd9Sstevel@tonic-gate } 2927c478bd9Sstevel@tonic-gate } 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate if (syntax_err != 0) 2957c478bd9Sstevel@tonic-gate return (-1); 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate *hostname = splittriple[0]; 2987c478bd9Sstevel@tonic-gate *username = splittriple[1]; 2997c478bd9Sstevel@tonic-gate *domain = splittriple[2]; 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate return (0); 3027c478bd9Sstevel@tonic-gate } 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* 305e429788eSmj162486 * Test membership in triple 306e429788eSmj162486 * return 0 = no match 307e429788eSmj162486 * return 1 = match 3087c478bd9Sstevel@tonic-gate */ 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate static int 3117c478bd9Sstevel@tonic-gate match_triple_entry(struct nss_innetgr_args *ia, const ns_ldap_entry_t *entry) 3127c478bd9Sstevel@tonic-gate { 3137c478bd9Sstevel@tonic-gate int ndomains; 3147c478bd9Sstevel@tonic-gate char **pdomains; 3157c478bd9Sstevel@tonic-gate int nhost; 3167c478bd9Sstevel@tonic-gate char **phost; 3177c478bd9Sstevel@tonic-gate int nusers; 3187c478bd9Sstevel@tonic-gate char **pusers; 3197c478bd9Sstevel@tonic-gate char **attr; 3207c478bd9Sstevel@tonic-gate char triple[MAX_TRIPLE_LEN]; 3217c478bd9Sstevel@tonic-gate char *tuser, *thost, *tdomain; 3227c478bd9Sstevel@tonic-gate int i; 323e429788eSmj162486 char *current, *limit; 324e429788eSmj162486 int pulen, phlen; 325e429788eSmj162486 char *pusers0, *phost0; 3267c478bd9Sstevel@tonic-gate 3277c478bd9Sstevel@tonic-gate nhost = ia->arg[NSS_NETGR_MACHINE].argc; 3287c478bd9Sstevel@tonic-gate phost = (char **)ia->arg[NSS_NETGR_MACHINE].argv; 329e429788eSmj162486 if (phost == NULL || *phost == NULL) { 3307c478bd9Sstevel@tonic-gate nhost = 0; 331e429788eSmj162486 } else { 332e429788eSmj162486 phost0 = phost[0]; 333e429788eSmj162486 phlen = strlen(phost0); 334*ca883132SSerge Dussud #ifdef DEBUG 335*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 336*ca883132SSerge Dussud "entering with host: %s", phost0 ? phost0 : ""); 337*ca883132SSerge Dussud #endif 338e429788eSmj162486 } 3397c478bd9Sstevel@tonic-gate nusers = ia->arg[NSS_NETGR_USER].argc; 3407c478bd9Sstevel@tonic-gate pusers = (char **)ia->arg[NSS_NETGR_USER].argv; 341e429788eSmj162486 if (pusers == NULL || *pusers == NULL) { 3427c478bd9Sstevel@tonic-gate nusers = 0; 343e429788eSmj162486 } else { 344e429788eSmj162486 pusers0 = pusers[0]; 345e429788eSmj162486 pulen = strlen(pusers0); 346*ca883132SSerge Dussud #ifdef DEBUG 347*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 348*ca883132SSerge Dussud "entering with user: %s", pusers0 ? pusers0 : ""); 349*ca883132SSerge Dussud #endif 350e429788eSmj162486 } 3517c478bd9Sstevel@tonic-gate ndomains = ia->arg[NSS_NETGR_DOMAIN].argc; 3527c478bd9Sstevel@tonic-gate pdomains = (char **)ia->arg[NSS_NETGR_DOMAIN].argv; 3537c478bd9Sstevel@tonic-gate if (pdomains == NULL || *pdomains == NULL) 3547c478bd9Sstevel@tonic-gate ndomains = 0; 355*ca883132SSerge Dussud #ifdef DEBUG 356*ca883132SSerge Dussud else 357*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 358*ca883132SSerge Dussud "entering with domain: %s", pdomains[0] ? pdomains[0] : ""); 359*ca883132SSerge Dussud #endif 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate attr = __ns_ldap_getAttr(entry, _N_TRIPLE); 3627c478bd9Sstevel@tonic-gate if (attr == NULL || *attr == NULL) 3637c478bd9Sstevel@tonic-gate return (0); 3647c478bd9Sstevel@tonic-gate 365*ca883132SSerge Dussud #ifdef DEBUG 366*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 367*ca883132SSerge Dussud "(nusers: %d, nhost:%d, ndomains: %d)", 368*ca883132SSerge Dussud nusers, nhost, ndomains); 369*ca883132SSerge Dussud #endif 370*ca883132SSerge Dussud 371e429788eSmj162486 /* Special cases for speedup */ 372e429788eSmj162486 if (nusers == 1 && nhost == 0 && ndomains == 0) { 373e429788eSmj162486 /* Special case for finding a single user in a netgroup */ 3747c478bd9Sstevel@tonic-gate for (; *attr; attr++) { 375e429788eSmj162486 /* jump to first comma and check next character */ 376e429788eSmj162486 current = *attr; 377*ca883132SSerge Dussud #ifdef DEBUG 378*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 379*ca883132SSerge Dussud "current is: %s", current); 380*ca883132SSerge Dussud #endif 381e429788eSmj162486 if ((current = strchr(current, COMMA)) == NULL) 382e429788eSmj162486 continue; 383e429788eSmj162486 current++; 384e429788eSmj162486 385e429788eSmj162486 /* skip whitespaces */ 386e429788eSmj162486 while (isspace(*current)) 387e429788eSmj162486 current++; 388e429788eSmj162486 389e429788eSmj162486 /* if user part is null, then treat as wildcard */ 390e429788eSmj162486 if (*current == COMMA) 391e429788eSmj162486 return (1); 392e429788eSmj162486 393e429788eSmj162486 /* compare first character */ 394e429788eSmj162486 if (*pusers0 != *current) 395e429788eSmj162486 continue; 396e429788eSmj162486 397e429788eSmj162486 /* limit username to COMMA */ 398e429788eSmj162486 if ((limit = strchr(current, COMMA)) == NULL) 399e429788eSmj162486 continue; 400e429788eSmj162486 *limit = '\0'; 401e429788eSmj162486 402e429788eSmj162486 /* remove blanks before COMMA */ 403e429788eSmj162486 if ((limit = strpbrk(current, " \t")) != NULL) 404e429788eSmj162486 *limit = '\0'; 405e429788eSmj162486 406e429788eSmj162486 /* compare size of username */ 407e429788eSmj162486 if (pulen != strlen(current)) { 408e429788eSmj162486 continue; 409e429788eSmj162486 } 410e429788eSmj162486 411e429788eSmj162486 /* do actual compare */ 412e429788eSmj162486 if (strncmp(pusers0, current, pulen) == 0) { 413e429788eSmj162486 return (1); 414e429788eSmj162486 } else { 415e429788eSmj162486 continue; 416e429788eSmj162486 } 417e429788eSmj162486 } 418e429788eSmj162486 } else if (nusers == 0 && nhost == 1 && ndomains == 0) { 419e429788eSmj162486 /* Special case for finding a single host in a netgroup */ 420e429788eSmj162486 for (; *attr; attr++) { 421e429788eSmj162486 422e429788eSmj162486 /* jump to first character and check */ 423e429788eSmj162486 current = *attr; 424*ca883132SSerge Dussud #ifdef DEBUG 425*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 426*ca883132SSerge Dussud "current is: %s", current); 427*ca883132SSerge Dussud #endif 428e429788eSmj162486 current++; 429e429788eSmj162486 430e429788eSmj162486 /* skip whitespaces */ 431e429788eSmj162486 while (isspace(*current)) 432e429788eSmj162486 current++; 433e429788eSmj162486 434e429788eSmj162486 /* if host part is null, then treat as wildcard */ 435e429788eSmj162486 if (*current == COMMA) 436e429788eSmj162486 return (1); 437e429788eSmj162486 438e429788eSmj162486 /* limit hostname to COMMA */ 439e429788eSmj162486 if ((limit = strchr(current, COMMA)) == NULL) 440e429788eSmj162486 continue; 441e429788eSmj162486 *limit = '\0'; 442e429788eSmj162486 443e429788eSmj162486 /* remove blanks before COMMA */ 444e429788eSmj162486 if ((limit = strpbrk(current, " \t")) != NULL) 445e429788eSmj162486 *limit = '\0'; 446e429788eSmj162486 447e429788eSmj162486 /* compare size of hostname */ 448e429788eSmj162486 if (phlen != strlen(current)) { 449e429788eSmj162486 continue; 450e429788eSmj162486 } 451e429788eSmj162486 452e429788eSmj162486 /* do actual compare */ 453e429788eSmj162486 if (strncasecmp(phost0, current, phlen) == 0) { 454e429788eSmj162486 return (1); 455e429788eSmj162486 } else { 456e429788eSmj162486 continue; 457e429788eSmj162486 } 458e429788eSmj162486 } 459e429788eSmj162486 } else { 460e429788eSmj162486 for (; *attr; attr++) { 461e429788eSmj162486 if (strlcpy(triple, *attr, 462e429788eSmj162486 sizeof (triple)) >= sizeof (triple)) 4637c478bd9Sstevel@tonic-gate continue; 464*ca883132SSerge Dussud #ifdef DEBUG 465*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: " 466*ca883132SSerge Dussud "triple is: %s", triple); 467*ca883132SSerge Dussud #endif 4687c478bd9Sstevel@tonic-gate if (split_triple(triple, &thost, &tuser, &tdomain) != 0) 4697c478bd9Sstevel@tonic-gate continue; 4707c478bd9Sstevel@tonic-gate if (thost != NULL && *thost != '\0' && nhost != 0) { 4717c478bd9Sstevel@tonic-gate for (i = 0; i < nhost; i++) 4727c478bd9Sstevel@tonic-gate if (strcasecmp(thost, phost[i]) == 0) 4737c478bd9Sstevel@tonic-gate break; 4747c478bd9Sstevel@tonic-gate if (i == nhost) 4757c478bd9Sstevel@tonic-gate continue; 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate if (tuser != NULL && *tuser != '\0' && nusers != 0) { 4787c478bd9Sstevel@tonic-gate for (i = 0; i < nusers; i++) 4797c478bd9Sstevel@tonic-gate if (strcmp(tuser, pusers[i]) == 0) 4807c478bd9Sstevel@tonic-gate break; 4817c478bd9Sstevel@tonic-gate if (i == nusers) 4827c478bd9Sstevel@tonic-gate continue; 4837c478bd9Sstevel@tonic-gate } 484e429788eSmj162486 if (tdomain != NULL && *tdomain != '\0' && 485e429788eSmj162486 ndomains != 0) { 4867c478bd9Sstevel@tonic-gate for (i = 0; i < ndomains; i++) 4877c478bd9Sstevel@tonic-gate if (domcmp(tdomain, pdomains[i]) == 0) 4887c478bd9Sstevel@tonic-gate break; 4897c478bd9Sstevel@tonic-gate if (i == ndomains) 4907c478bd9Sstevel@tonic-gate continue; 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate return (1); 4937c478bd9Sstevel@tonic-gate } 494e429788eSmj162486 } 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate return (0); 4977c478bd9Sstevel@tonic-gate } 4987c478bd9Sstevel@tonic-gate 4997c478bd9Sstevel@tonic-gate static int 5007c478bd9Sstevel@tonic-gate match_triple(struct nss_innetgr_args *ia, ns_ldap_result_t *result) 5017c478bd9Sstevel@tonic-gate { 5027c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) 5057c478bd9Sstevel@tonic-gate if (match_triple_entry(ia, entry) == 1) 5067c478bd9Sstevel@tonic-gate return (1); 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate return (0); 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate static int 5127c478bd9Sstevel@tonic-gate add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab) 5137c478bd9Sstevel@tonic-gate { 5147c478bd9Sstevel@tonic-gate char **attrs; 5157c478bd9Sstevel@tonic-gate char **a; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate attrs = __ns_ldap_getAttr(entry, _N_MEMBER); 5187c478bd9Sstevel@tonic-gate if (attrs == NULL || *attrs == NULL) 5197c478bd9Sstevel@tonic-gate return (0); 5207c478bd9Sstevel@tonic-gate 5217c478bd9Sstevel@tonic-gate for (a = attrs; *a != NULL; a++) {} 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate do { 5247c478bd9Sstevel@tonic-gate a--; 5257c478bd9Sstevel@tonic-gate if (add_netgroup_name(*a, tab) != 0) 5267c478bd9Sstevel@tonic-gate return (-1); 5277c478bd9Sstevel@tonic-gate } while (a > attrs); 5287c478bd9Sstevel@tonic-gate return (0); 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate static int 5327c478bd9Sstevel@tonic-gate add_netgroup_member(ns_ldap_result_t *result, netgroup_table_t *tab) 5337c478bd9Sstevel@tonic-gate { 5347c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 5357c478bd9Sstevel@tonic-gate int ret = 0; 5367c478bd9Sstevel@tonic-gate 5377c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) { 5387c478bd9Sstevel@tonic-gate ret = add_netgroup_member_entry(entry, tab); 5397c478bd9Sstevel@tonic-gate if (ret != 0) 5407c478bd9Sstevel@tonic-gate break; 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate return (ret); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate /* 5467c478bd9Sstevel@tonic-gate * top_down_search checks only checks the netgroup specified in netgrname 5477c478bd9Sstevel@tonic-gate */ 5487c478bd9Sstevel@tonic-gate static nss_status_t 5497c478bd9Sstevel@tonic-gate top_down_search(struct nss_innetgr_args *ia, char *netgrname) 5507c478bd9Sstevel@tonic-gate { 5517c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 5527c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 5537c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 5547c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 5557c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 5567c478bd9Sstevel@tonic-gate int rc; 5577c478bd9Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND; 5583d047983Smichen nss_status_t status1; 5597c478bd9Sstevel@tonic-gate netgroup_table_t tab; 5607c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 5617c478bd9Sstevel@tonic-gate int ret; 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate (void) memset(&tab, 0, sizeof (tab)); 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate if (add_netgroup_name(netgrname, &tab) != 0) 5667c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate while ((ng = get_next_netgroup(&tab)) != NULL) { 569*ca883132SSerge Dussud #ifdef DEBUG 570*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: top_down_search: netgroup loop " 571*ca883132SSerge Dussud "(ng->name: %s)", ng->name ? ng->name : "null !"); 572*ca883132SSerge Dussud #endif 5737c478bd9Sstevel@tonic-gate if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0) 5747c478bd9Sstevel@tonic-gate break; 5753d047983Smichen ret = snprintf(searchfilter, sizeof (searchfilter), 5763d047983Smichen _F_SETMEMBER, name); 5777c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 5787c478bd9Sstevel@tonic-gate break; 5797c478bd9Sstevel@tonic-gate 5803d047983Smichen ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD, 5813d047983Smichen name); 5827c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 5837c478bd9Sstevel@tonic-gate break; 5847c478bd9Sstevel@tonic-gate 585*ca883132SSerge Dussud /* searching for current netgroup name entry */ 586*ca883132SSerge Dussud rc = __ns_ldap_list(_NETGROUP, searchfilter, 587*ca883132SSerge Dussud _merge_SSD_filter, netgrent_attrs, NULL, 0, &result, 588*ca883132SSerge Dussud &error, NULL, userdata); 5893d047983Smichen 5903d047983Smichen if (error != NULL) { 5913d047983Smichen status1 = switch_err(rc, error); 5923d047983Smichen if (status1 == NSS_TRYAGAIN) { 5933d047983Smichen (void) __ns_ldap_freeError(&error); 5943d047983Smichen free_netgroup_table(&tab); 5953d047983Smichen return (status1); 5963d047983Smichen } 5973d047983Smichen } 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 600*ca883132SSerge Dussud if (rc == NS_LDAP_SUCCESS) { 6017c478bd9Sstevel@tonic-gate if (match_triple(ia, result) == 1) { 6027c478bd9Sstevel@tonic-gate /* We found a match */ 6037c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_FOUND; 6047c478bd9Sstevel@tonic-gate status = NSS_SUCCESS; 605*ca883132SSerge Dussud #ifdef DEBUG 606*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: top_down_search: " 607*ca883132SSerge Dussud "found match"); 608*ca883132SSerge Dussud #endif 6097c478bd9Sstevel@tonic-gate break; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 612*ca883132SSerge Dussud /* 613*ca883132SSerge Dussud * No match found. Check for membernisnetgroup 614*ca883132SSerge Dussud * in result and if yes, start again with those. 615*ca883132SSerge Dussud */ 6167c478bd9Sstevel@tonic-gate rc = add_netgroup_member(result, &tab); 617*ca883132SSerge Dussud if (rc != 0) 6187c478bd9Sstevel@tonic-gate break; 619*ca883132SSerge Dussud } else if (rc != NS_LDAP_NOTFOUND) { 6207c478bd9Sstevel@tonic-gate break; 6217c478bd9Sstevel@tonic-gate } 622*ca883132SSerge Dussud (void) __ns_ldap_freeResult(&result); 623*ca883132SSerge Dussud } 6247c478bd9Sstevel@tonic-gate 6257c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 6267c478bd9Sstevel@tonic-gate free_netgroup_table(&tab); 6277c478bd9Sstevel@tonic-gate return (status); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate /* 6317c478bd9Sstevel@tonic-gate * __netgr_in checks only checks the netgroup specified in ngroup 6327c478bd9Sstevel@tonic-gate */ 6337c478bd9Sstevel@tonic-gate static nss_status_t 6347c478bd9Sstevel@tonic-gate __netgr_in(void *a, char *netgrname) 6357c478bd9Sstevel@tonic-gate { 6367c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 6377c478bd9Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND; 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate #ifdef DEBUG 6407c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_in]\n"); 6417c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tmachine: argc[%d]='%s' user: " 6427c478bd9Sstevel@tonic-gate "argc[%d]='%s',\n\tdomain:argc[%d]='%s' " 6437c478bd9Sstevel@tonic-gate "netgroup: argc[%d]='%s'\n", 6447c478bd9Sstevel@tonic-gate NSS_NETGR_MACHINE, 6457c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_MACHINE]), 6467c478bd9Sstevel@tonic-gate NSS_NETGR_USER, 6477c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_USER]), 6487c478bd9Sstevel@tonic-gate NSS_NETGR_DOMAIN, 6497c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_DOMAIN]), 6507c478bd9Sstevel@tonic-gate NSS_NETGR_N, 6517c478bd9Sstevel@tonic-gate PRINT_VAL(ia->arg[NSS_NETGR_N])); 6527c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tgroups='%s'\n", netgrname); 6537c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_NO; 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate if (netgrname == NULL) 6587c478bd9Sstevel@tonic-gate return (status); 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate return (top_down_search(ia, netgrname)); 6617c478bd9Sstevel@tonic-gate } 6627c478bd9Sstevel@tonic-gate 6637c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 6647c478bd9Sstevel@tonic-gate static nss_status_t 6657c478bd9Sstevel@tonic-gate netgr_in(ldap_backend_ptr be, void *a) 6667c478bd9Sstevel@tonic-gate { 6677c478bd9Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; 6687c478bd9Sstevel@tonic-gate int i; 6697c478bd9Sstevel@tonic-gate nss_status_t rc = (nss_status_t)NSS_NOTFOUND; 6707c478bd9Sstevel@tonic-gate 6717c478bd9Sstevel@tonic-gate ia->status = NSS_NETGR_NO; 6727c478bd9Sstevel@tonic-gate for (i = 0; i < ia->groups.argc; i++) { 6737c478bd9Sstevel@tonic-gate rc = __netgr_in(a, ia->groups.argv[i]); 6747c478bd9Sstevel@tonic-gate if (ia->status == NSS_NETGR_FOUND) 6757c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate return (rc); 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate 6807c478bd9Sstevel@tonic-gate /* 6817c478bd9Sstevel@tonic-gate * 6827c478bd9Sstevel@tonic-gate */ 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate static nss_status_t 6857c478bd9Sstevel@tonic-gate getnetgr_ldap_setent(ldap_backend_ptr be, void *a) 6867c478bd9Sstevel@tonic-gate { 6877c478bd9Sstevel@tonic-gate const char *netgroup = (const char *) a; 6887c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *cookie; 6897c478bd9Sstevel@tonic-gate 6907c478bd9Sstevel@tonic-gate #ifdef DEBUG 6917c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_setent]\n"); 6927c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate cookie = (getnetgrent_cookie_t *)be->netgroup_cookie; 6957c478bd9Sstevel@tonic-gate if (cookie != NULL && cookie->netgroup != NULL) { 6967c478bd9Sstevel@tonic-gate /* is this another set on the same netgroup */ 6977c478bd9Sstevel@tonic-gate if (strcmp(cookie->netgroup, netgroup) == 0) 6987c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 7027c478bd9Sstevel@tonic-gate } 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate static void 7057c478bd9Sstevel@tonic-gate free_getnetgrent_cookie(getnetgrent_cookie_t **cookie) 7067c478bd9Sstevel@tonic-gate { 7077c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p = *cookie; 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate #ifdef DEBUG 7107c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: free_getnetgrent_cookie]\n"); 7117c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7127c478bd9Sstevel@tonic-gate 7137c478bd9Sstevel@tonic-gate if (p == NULL) 7147c478bd9Sstevel@tonic-gate return; 7157c478bd9Sstevel@tonic-gate 7167c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results); 7177c478bd9Sstevel@tonic-gate free_netgroup_table(&p->tab); 7187c478bd9Sstevel@tonic-gate free(p->netgroup); 7197c478bd9Sstevel@tonic-gate free(p); 7207c478bd9Sstevel@tonic-gate *cookie = NULL; 7217c478bd9Sstevel@tonic-gate } 7227c478bd9Sstevel@tonic-gate 7237c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 7247c478bd9Sstevel@tonic-gate static nss_status_t 7257c478bd9Sstevel@tonic-gate getnetgr_ldap_endent(ldap_backend_ptr be, void *a) 7267c478bd9Sstevel@tonic-gate { 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate #ifdef DEBUG 7297c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_endent]\n"); 7307c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7317c478bd9Sstevel@tonic-gate 7327c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 7397c478bd9Sstevel@tonic-gate static nss_status_t 7407c478bd9Sstevel@tonic-gate getnetgr_ldap_destr(ldap_backend_ptr be, void *a) 7417c478bd9Sstevel@tonic-gate { 7427c478bd9Sstevel@tonic-gate 7437c478bd9Sstevel@tonic-gate #ifdef DEBUG 7447c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_destr]\n"); 7457c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 7487c478bd9Sstevel@tonic-gate free(be); 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 7517c478bd9Sstevel@tonic-gate } 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate static nss_status_t 7557c478bd9Sstevel@tonic-gate getnetgr_ldap_getent(ldap_backend_ptr be, void *a) 7567c478bd9Sstevel@tonic-gate { 7577c478bd9Sstevel@tonic-gate struct nss_getnetgrent_args *args; 7587c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p; 7597c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 7607c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 7617c478bd9Sstevel@tonic-gate char name[SEARCHFILTERLEN]; 7627c478bd9Sstevel@tonic-gate int rc; 7637c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = NULL; 7647c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 7657c478bd9Sstevel@tonic-gate char **attrs; 7667c478bd9Sstevel@tonic-gate char *hostname, *username, *domain; 7677c478bd9Sstevel@tonic-gate char *buffer; 7687c478bd9Sstevel@tonic-gate nss_status_t status = NSS_SUCCESS; 7697c478bd9Sstevel@tonic-gate netgroup_name_t *ng; 7707c478bd9Sstevel@tonic-gate int ret; 7717c478bd9Sstevel@tonic-gate 7727c478bd9Sstevel@tonic-gate #ifdef DEBUG 7737c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n"); 7747c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 7757c478bd9Sstevel@tonic-gate 7767c478bd9Sstevel@tonic-gate args = (struct nss_getnetgrent_args *)a; 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_NO; 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate p = (getnetgrent_cookie_t *)be->netgroup_cookie; 7817c478bd9Sstevel@tonic-gate if (p == NULL) 7827c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate for (;;) { 785*ca883132SSerge Dussud /* 786*ca883132SSerge Dussud * Search through each netgroup consecutively: only search 787*ca883132SSerge Dussud * next netgroup when results from previous netgroup are 788*ca883132SSerge Dussud * processed. 789*ca883132SSerge Dussud * Needed for nested netgroup (memberNisNetgroup attributes). 790*ca883132SSerge Dussud */ 791*ca883132SSerge Dussud if (p->results == NULL) { 792*ca883132SSerge Dussud if ((ng = get_next_netgroup(&p->tab)) != NULL) { 7933d047983Smichen if (_ldap_filter_name(name, ng->name, 7943d047983Smichen sizeof (name)) != 0) 7957c478bd9Sstevel@tonic-gate break; 7967c478bd9Sstevel@tonic-gate 7973d047983Smichen ret = snprintf(searchfilter, 7983d047983Smichen sizeof (searchfilter), 7997c478bd9Sstevel@tonic-gate _F_SETMEMBER, name); 8007c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 8017c478bd9Sstevel@tonic-gate break; 8027c478bd9Sstevel@tonic-gate 803*ca883132SSerge Dussud #ifdef DEBUG 804*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: " 805*ca883132SSerge Dussud "getnetgr_ldap_getent: " 806*ca883132SSerge Dussud "netgroup name: %s", name); 807*ca883132SSerge Dussud #endif 8083d047983Smichen ret = snprintf(userdata, sizeof (userdata), 8093d047983Smichen _F_SETMEMBER_SSD, name); 8107c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 8117c478bd9Sstevel@tonic-gate break; 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate result = NULL; 814*ca883132SSerge Dussud rc = __ns_ldap_list(_NETGROUP, searchfilter, 815*ca883132SSerge Dussud _merge_SSD_filter, netgrent_attrs, NULL, 816*ca883132SSerge Dussud 0, &result, &error, NULL, userdata); 8177c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate if (rc == NS_LDAP_SUCCESS && result != NULL) { 8207c478bd9Sstevel@tonic-gate p->results = result; 821*ca883132SSerge Dussud } else { 822*ca883132SSerge Dussud #ifdef DEBUG 823*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: " 824*ca883132SSerge Dussud "getnetgr_ldap_getent: " 825*ca883132SSerge Dussud "__ns_ldap_list() returned %d " 826*ca883132SSerge Dussud "(result: 0x%x)", rc, result); 827*ca883132SSerge Dussud #endif 828*ca883132SSerge Dussud /* 829*ca883132SSerge Dussud * Will exit when no more netgroup 830*ca883132SSerge Dussud * to search and no more p->results 831*ca883132SSerge Dussud * to process. 832*ca883132SSerge Dussud */ 8337c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result); 8347c478bd9Sstevel@tonic-gate } 835*ca883132SSerge Dussud } else { /* no more netgroup to process */ 836*ca883132SSerge Dussud /* 837*ca883132SSerge Dussud * If no more results to process, and since 838*ca883132SSerge Dussud * there's no more netgroup to process either, 839*ca883132SSerge Dussud * then it's time to break and exit the for 840*ca883132SSerge Dussud * loop. 841*ca883132SSerge Dussud */ 842*ca883132SSerge Dussud #ifdef DEBUG 843*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: " 844*ca883132SSerge Dussud "getnetgr_ldap_getent: no more netgroup " 845*ca883132SSerge Dussud "to process, p->results: 0x%x", 846*ca883132SSerge Dussud p->results); 847*ca883132SSerge Dussud #endif 848*ca883132SSerge Dussud if (p->results == NULL) 8497c478bd9Sstevel@tonic-gate break; 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate } 8527c478bd9Sstevel@tonic-gate if (p->results == NULL) 8537c478bd9Sstevel@tonic-gate continue; 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate if (p->entry == NULL) 8567c478bd9Sstevel@tonic-gate p->entry = p->results->entry; 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate if (p->entry == NULL) 8597c478bd9Sstevel@tonic-gate continue; 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate if (p->attrs == NULL) { 8627c478bd9Sstevel@tonic-gate attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE); 8637c478bd9Sstevel@tonic-gate if (attrs != NULL && *attrs != NULL) 8647c478bd9Sstevel@tonic-gate p->attrs = attrs; 8657c478bd9Sstevel@tonic-gate } 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate if (p->attrs != NULL) { 8687c478bd9Sstevel@tonic-gate attrs = p->attrs; 8697c478bd9Sstevel@tonic-gate buffer = args->buffer; 8707c478bd9Sstevel@tonic-gate 8713d047983Smichen if (strlcpy(buffer, *attrs, args->buflen) >= 8723d047983Smichen args->buflen) { 8737c478bd9Sstevel@tonic-gate status = NSS_STR_PARSE_ERANGE; 8747c478bd9Sstevel@tonic-gate break; 8757c478bd9Sstevel@tonic-gate } 8767c478bd9Sstevel@tonic-gate 8773d047983Smichen rc = split_triple(buffer, &hostname, &username, 8783d047983Smichen &domain); 8797c478bd9Sstevel@tonic-gate attrs++; 8807c478bd9Sstevel@tonic-gate if (attrs != NULL && *attrs != NULL) 8817c478bd9Sstevel@tonic-gate p->attrs = attrs; 8827c478bd9Sstevel@tonic-gate else 8837c478bd9Sstevel@tonic-gate p->attrs = NULL; 8847c478bd9Sstevel@tonic-gate if (rc == 0) { 8857c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_MACHINE] = hostname; 8867c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_USER] = username; 8877c478bd9Sstevel@tonic-gate args->retp[NSS_NETGR_DOMAIN] = domain; 8887c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_FOUND; 889*ca883132SSerge Dussud #ifdef DEBUG 890*ca883132SSerge Dussud syslog(LOG_DEBUG, "nss_ldap: " 891*ca883132SSerge Dussud "getnetgr_ldap_getent: found triple " 892*ca883132SSerge Dussud "(%s, %s, %s), 0x%x to process", 893*ca883132SSerge Dussud hostname ? hostname : "", 894*ca883132SSerge Dussud username ? username : "", 895*ca883132SSerge Dussud domain ? domain : "", 896*ca883132SSerge Dussud p->attrs); 897*ca883132SSerge Dussud #endif 8987c478bd9Sstevel@tonic-gate if (p->attrs != NULL) 8997c478bd9Sstevel@tonic-gate break; 9007c478bd9Sstevel@tonic-gate } 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate 9037c478bd9Sstevel@tonic-gate if (p->attrs == NULL) { 9047c478bd9Sstevel@tonic-gate rc = add_netgroup_member_entry(p->entry, &p->tab); 9057c478bd9Sstevel@tonic-gate if (rc != 0) { 9067c478bd9Sstevel@tonic-gate args->status = NSS_NETGR_NO; 9077c478bd9Sstevel@tonic-gate break; 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate 9107c478bd9Sstevel@tonic-gate p->entry = p->entry->next; 9117c478bd9Sstevel@tonic-gate if (p->entry == NULL) 9127c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results); 9137c478bd9Sstevel@tonic-gate if (args->status == NSS_NETGR_FOUND) 9147c478bd9Sstevel@tonic-gate break; 9157c478bd9Sstevel@tonic-gate } 9167c478bd9Sstevel@tonic-gate } 9177c478bd9Sstevel@tonic-gate 9187c478bd9Sstevel@tonic-gate return (status); 9197c478bd9Sstevel@tonic-gate } 9207c478bd9Sstevel@tonic-gate 9217c478bd9Sstevel@tonic-gate static ldap_backend_op_t getnetgroup_ops[] = { 9227c478bd9Sstevel@tonic-gate getnetgr_ldap_destr, 9237c478bd9Sstevel@tonic-gate getnetgr_ldap_endent, 9247c478bd9Sstevel@tonic-gate getnetgr_ldap_setent, 9257c478bd9Sstevel@tonic-gate getnetgr_ldap_getent, 9267c478bd9Sstevel@tonic-gate }; 9277c478bd9Sstevel@tonic-gate 9287c478bd9Sstevel@tonic-gate /* 9297c478bd9Sstevel@tonic-gate * 9307c478bd9Sstevel@tonic-gate */ 9317c478bd9Sstevel@tonic-gate 9327c478bd9Sstevel@tonic-gate static nss_status_t 9337c478bd9Sstevel@tonic-gate netgr_set(ldap_backend_ptr be, void *a) 9347c478bd9Sstevel@tonic-gate { 9357c478bd9Sstevel@tonic-gate struct nss_setnetgrent_args *args = 9367c478bd9Sstevel@tonic-gate (struct nss_setnetgrent_args *)a; 9377c478bd9Sstevel@tonic-gate ldap_backend_ptr get_be; 9387c478bd9Sstevel@tonic-gate getnetgrent_cookie_t *p; 9397c478bd9Sstevel@tonic-gate 9407c478bd9Sstevel@tonic-gate #ifdef DEBUG 9417c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_set]\n"); 9427c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 9437c478bd9Sstevel@tonic-gate "\targs->netgroup: %s\n", ISNULL(args->netgroup)); 9447c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9457c478bd9Sstevel@tonic-gate 9467c478bd9Sstevel@tonic-gate if (args->netgroup == NULL) 9477c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie); 9507c478bd9Sstevel@tonic-gate p = (getnetgrent_cookie_t *)calloc(1, sizeof (getnetgrent_cookie_t)); 9517c478bd9Sstevel@tonic-gate if (p == NULL) 9527c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9537c478bd9Sstevel@tonic-gate p->netgroup = strdup(args->netgroup); 9547c478bd9Sstevel@tonic-gate if (p->netgroup == NULL) { 9557c478bd9Sstevel@tonic-gate free(p); 9567c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9577c478bd9Sstevel@tonic-gate } 9587c478bd9Sstevel@tonic-gate if (add_netgroup_name(args->netgroup, &p->tab) == -1) { 9597c478bd9Sstevel@tonic-gate free_getnetgrent_cookie(&p); 9607c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9617c478bd9Sstevel@tonic-gate } 9627c478bd9Sstevel@tonic-gate 9637c478bd9Sstevel@tonic-gate /* now allocate and return iteration backend structure */ 9647c478bd9Sstevel@tonic-gate if ((get_be = (ldap_backend_ptr)malloc(sizeof (*get_be))) == NULL) 9657c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 9667c478bd9Sstevel@tonic-gate get_be->ops = getnetgroup_ops; 9677c478bd9Sstevel@tonic-gate get_be->nops = sizeof (getnetgroup_ops) / sizeof (getnetgroup_ops[0]); 9687c478bd9Sstevel@tonic-gate get_be->tablename = NULL; 9697c478bd9Sstevel@tonic-gate get_be->attrs = netgrent_attrs; 9707c478bd9Sstevel@tonic-gate get_be->result = NULL; 971cb5caa98Sdjl get_be->ldapobj2str = NULL; 9727c478bd9Sstevel@tonic-gate get_be->setcalled = 1; 9737c478bd9Sstevel@tonic-gate get_be->filter = NULL; 9747c478bd9Sstevel@tonic-gate get_be->toglue = NULL; 9757c478bd9Sstevel@tonic-gate get_be->enumcookie = NULL; 9767c478bd9Sstevel@tonic-gate get_be->netgroup_cookie = p; 9777c478bd9Sstevel@tonic-gate args->iterator = (nss_backend_t *)get_be; 9787c478bd9Sstevel@tonic-gate 9797c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 9827c478bd9Sstevel@tonic-gate } 9837c478bd9Sstevel@tonic-gate 9847c478bd9Sstevel@tonic-gate 9857c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 9867c478bd9Sstevel@tonic-gate static nss_status_t 9877c478bd9Sstevel@tonic-gate netgr_ldap_destr(ldap_backend_ptr be, void *a) 9887c478bd9Sstevel@tonic-gate { 9897c478bd9Sstevel@tonic-gate 9907c478bd9Sstevel@tonic-gate #ifdef DEBUG 9917c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_ldap_destr]\n"); 9927c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate (void) _clean_ldap_backend(be); 9957c478bd9Sstevel@tonic-gate 9967c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 9977c478bd9Sstevel@tonic-gate } 9987c478bd9Sstevel@tonic-gate 9997c478bd9Sstevel@tonic-gate 10007c478bd9Sstevel@tonic-gate 10017c478bd9Sstevel@tonic-gate 10027c478bd9Sstevel@tonic-gate static ldap_backend_op_t netgroup_ops[] = { 10037c478bd9Sstevel@tonic-gate netgr_ldap_destr, 10047c478bd9Sstevel@tonic-gate 0, 10057c478bd9Sstevel@tonic-gate 0, 10067c478bd9Sstevel@tonic-gate 0, 10077c478bd9Sstevel@tonic-gate netgr_in, /* innetgr() */ 10087c478bd9Sstevel@tonic-gate netgr_set /* setnetgrent() */ 10097c478bd9Sstevel@tonic-gate }; 10107c478bd9Sstevel@tonic-gate 10117c478bd9Sstevel@tonic-gate 10127c478bd9Sstevel@tonic-gate /* 10137c478bd9Sstevel@tonic-gate * _nss_ldap_netgroup_constr is where life begins. This function calls the 10147c478bd9Sstevel@tonic-gate * generic ldap constructor function to define and build the abstract data 10157c478bd9Sstevel@tonic-gate * types required to support ldap operations. 10167c478bd9Sstevel@tonic-gate */ 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 10197c478bd9Sstevel@tonic-gate nss_backend_t * 10207c478bd9Sstevel@tonic-gate _nss_ldap_netgroup_constr(const char *dummy1, const char *dummy2, 10217c478bd9Sstevel@tonic-gate const char *dummy3) 10227c478bd9Sstevel@tonic-gate { 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate #ifdef DEBUG 10257c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 10267c478bd9Sstevel@tonic-gate "\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n"); 10277c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(netgroup_ops, 10307c478bd9Sstevel@tonic-gate sizeof (netgroup_ops)/sizeof (netgroup_ops[0]), _NETGROUP, 10317c478bd9Sstevel@tonic-gate netgrent_attrs, NULL)); 10327c478bd9Sstevel@tonic-gate } 1033