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
get_hash(const char * s)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
add_netgroup_name(const char * name,netgroup_table_t * tab)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 *
get_next_netgroup(netgroup_table_t * tab)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
free_netgroup_table(netgroup_table_t * tab)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
domcmp(const char * n1,const char * n2)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
split_triple(char * triple,char ** hostname,char ** username,char ** domain)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
match_triple_entry(struct nss_innetgr_args * ia,const ns_ldap_entry_t * entry)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
match_triple(struct nss_innetgr_args * ia,ns_ldap_result_t * result)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
add_netgroup_member_entry(ns_ldap_entry_t * entry,netgroup_table_t * tab)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
add_netgroup_member(ns_ldap_result_t * result,netgroup_table_t * tab)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
top_down_search(struct nss_innetgr_args * ia,char * netgrname)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
__netgr_in(void * a,char * netgrname)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
netgr_in(ldap_backend_ptr be,void * a)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
getnetgr_ldap_setent(ldap_backend_ptr be,void * a)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
free_getnetgrent_cookie(getnetgrent_cookie_t ** cookie)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
getnetgr_ldap_endent(ldap_backend_ptr be,void * a)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
getnetgr_ldap_destr(ldap_backend_ptr be,void * a)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
getnetgr_ldap_getent(ldap_backend_ptr be,void * a)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
netgr_set(ldap_backend_ptr be,void * a)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
netgr_ldap_destr(ldap_backend_ptr be,void * a)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 *
_nss_ldap_netgroup_constr(const char * dummy1,const char * dummy2,const char * dummy3)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