10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52388Smj162486 * Common Development and Distribution License (the "License").
62388Smj162486 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*8777SSerge.Dussud@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
230Sstevel@tonic-gate * Use is subject to license terms.
240Sstevel@tonic-gate */
250Sstevel@tonic-gate
260Sstevel@tonic-gate
270Sstevel@tonic-gate #include <syslog.h>
280Sstevel@tonic-gate #include "ldap_common.h"
290Sstevel@tonic-gate
300Sstevel@tonic-gate /* netgroup attributes filters */
310Sstevel@tonic-gate #define _N_TRIPLE "nisnetgrouptriple"
320Sstevel@tonic-gate #define _N_MEMBER "membernisnetgroup"
330Sstevel@tonic-gate
340Sstevel@tonic-gate #define PRINT_VAL(a) (((a).argc == 0) || ((a).argv == NULL) || \
350Sstevel@tonic-gate ((a).argv[0] == NULL)) ? "*" : (a).argv[0]
360Sstevel@tonic-gate #define ISNULL(a) (a == NULL ? "<NULL>" : a)
370Sstevel@tonic-gate #define MAX_DOMAIN_LEN 1024
380Sstevel@tonic-gate #define MAX_TRIPLE_LEN (MAXHOSTNAMELEN + LOGNAME_MAX + \
390Sstevel@tonic-gate MAX_DOMAIN_LEN + 5)
400Sstevel@tonic-gate
410Sstevel@tonic-gate #define _F_SETMEMBER "(&(objectClass=nisNetGroup)(cn=%s))"
420Sstevel@tonic-gate #define _F_SETMEMBER_SSD "(&(%%s)(cn=%s))"
430Sstevel@tonic-gate
440Sstevel@tonic-gate #define N_HASH 257
452388Smj162486 #define COMMA ','
460Sstevel@tonic-gate
470Sstevel@tonic-gate static const char *netgrent_attrs[] = {
480Sstevel@tonic-gate _N_TRIPLE,
490Sstevel@tonic-gate _N_MEMBER,
500Sstevel@tonic-gate (char *)NULL
510Sstevel@tonic-gate };
520Sstevel@tonic-gate
530Sstevel@tonic-gate typedef struct netgroup_name {
540Sstevel@tonic-gate char *name;
550Sstevel@tonic-gate struct netgroup_name *next;
560Sstevel@tonic-gate struct netgroup_name *next_hash;
570Sstevel@tonic-gate } netgroup_name_t;
580Sstevel@tonic-gate
590Sstevel@tonic-gate typedef struct {
600Sstevel@tonic-gate netgroup_name_t *hash_list[N_HASH];
610Sstevel@tonic-gate netgroup_name_t *to_do;
620Sstevel@tonic-gate netgroup_name_t *done;
630Sstevel@tonic-gate } netgroup_table_t;
640Sstevel@tonic-gate
650Sstevel@tonic-gate typedef struct {
660Sstevel@tonic-gate ns_ldap_result_t *results;
670Sstevel@tonic-gate ns_ldap_entry_t *entry;
680Sstevel@tonic-gate char **attrs;
690Sstevel@tonic-gate char *netgroup;
700Sstevel@tonic-gate netgroup_table_t tab;
710Sstevel@tonic-gate } getnetgrent_cookie_t;
720Sstevel@tonic-gate
730Sstevel@tonic-gate typedef struct {
740Sstevel@tonic-gate struct nss_innetgr_args *ia;
750Sstevel@tonic-gate const char *ssd_filter;
760Sstevel@tonic-gate const char *netgrname;
770Sstevel@tonic-gate const char *membername;
780Sstevel@tonic-gate netgroup_table_t tab;
790Sstevel@tonic-gate } innetgr_cookie_t;
800Sstevel@tonic-gate
810Sstevel@tonic-gate typedef unsigned int hash_t;
820Sstevel@tonic-gate
830Sstevel@tonic-gate static hash_t
get_hash(const char * s)840Sstevel@tonic-gate get_hash(const char *s)
850Sstevel@tonic-gate {
860Sstevel@tonic-gate unsigned int sum = 0;
870Sstevel@tonic-gate unsigned int i;
880Sstevel@tonic-gate
890Sstevel@tonic-gate for (i = 0; s[i] != '\0'; i++)
900Sstevel@tonic-gate sum += ((unsigned char *)s)[i];
910Sstevel@tonic-gate
920Sstevel@tonic-gate return ((sum + i) % N_HASH);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate * Adds a name to the netgroup table
970Sstevel@tonic-gate *
980Sstevel@tonic-gate * Returns
990Sstevel@tonic-gate * 0 if successfully added or already present
100*8777SSerge.Dussud@Sun.COM * -1 if memory allocation error or NULL netgroup_table_t
101*8777SSerge.Dussud@Sun.COM * from caller.
1020Sstevel@tonic-gate */
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate static int
add_netgroup_name(const char * name,netgroup_table_t * tab)1050Sstevel@tonic-gate add_netgroup_name(const char *name, netgroup_table_t *tab)
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate hash_t h;
1080Sstevel@tonic-gate netgroup_name_t *ng;
1090Sstevel@tonic-gate netgroup_name_t *ng_new;
1100Sstevel@tonic-gate
111*8777SSerge.Dussud@Sun.COM if (tab == NULL) {
112*8777SSerge.Dussud@Sun.COM /*
113*8777SSerge.Dussud@Sun.COM * Should never happen. But if it does,
114*8777SSerge.Dussud@Sun.COM * that's an error condition.
115*8777SSerge.Dussud@Sun.COM */
116*8777SSerge.Dussud@Sun.COM return (-1);
117*8777SSerge.Dussud@Sun.COM }
118*8777SSerge.Dussud@Sun.COM if (name == NULL || *name == '\0') {
119*8777SSerge.Dussud@Sun.COM /* no name to add means success */
120*8777SSerge.Dussud@Sun.COM return (0);
121*8777SSerge.Dussud@Sun.COM }
1220Sstevel@tonic-gate
1230Sstevel@tonic-gate h = get_hash(name);
1240Sstevel@tonic-gate ng = tab->hash_list[h];
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate while (ng != NULL) {
1270Sstevel@tonic-gate if (strcmp(name, ng->name) == 0)
1280Sstevel@tonic-gate break;
1290Sstevel@tonic-gate ng = ng->next_hash;
1300Sstevel@tonic-gate }
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate if (ng == NULL) {
1330Sstevel@tonic-gate ng_new = (netgroup_name_t *)
1344953Smichen calloc(1, sizeof (netgroup_name_t));
1350Sstevel@tonic-gate if (ng_new == NULL)
1360Sstevel@tonic-gate return (-1);
1370Sstevel@tonic-gate ng_new->name = strdup(name);
1380Sstevel@tonic-gate if (ng_new->name == NULL) {
1390Sstevel@tonic-gate free(ng_new);
1400Sstevel@tonic-gate return (-1);
1410Sstevel@tonic-gate }
1420Sstevel@tonic-gate ng_new->next_hash = tab->hash_list[h];
1430Sstevel@tonic-gate tab->hash_list[h] = ng_new;
1440Sstevel@tonic-gate ng_new->next = tab->to_do;
1450Sstevel@tonic-gate tab->to_do = ng_new;
1460Sstevel@tonic-gate }
1470Sstevel@tonic-gate return (0);
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate static netgroup_name_t *
get_next_netgroup(netgroup_table_t * tab)1510Sstevel@tonic-gate get_next_netgroup(netgroup_table_t *tab)
1520Sstevel@tonic-gate {
1530Sstevel@tonic-gate netgroup_name_t *ng;
1540Sstevel@tonic-gate
1550Sstevel@tonic-gate if (tab == NULL)
1560Sstevel@tonic-gate return (NULL);
1570Sstevel@tonic-gate
1580Sstevel@tonic-gate ng = tab->to_do;
1590Sstevel@tonic-gate if (ng != NULL) {
1600Sstevel@tonic-gate tab->to_do = ng->next;
1610Sstevel@tonic-gate ng->next = tab->done;
1620Sstevel@tonic-gate tab->done = ng;
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate return (ng);
1650Sstevel@tonic-gate }
1660Sstevel@tonic-gate
1670Sstevel@tonic-gate static void
free_netgroup_table(netgroup_table_t * tab)1680Sstevel@tonic-gate free_netgroup_table(netgroup_table_t *tab)
1690Sstevel@tonic-gate {
1700Sstevel@tonic-gate netgroup_name_t *ng, *next;
1710Sstevel@tonic-gate
1720Sstevel@tonic-gate if (tab == NULL)
1730Sstevel@tonic-gate return;
1740Sstevel@tonic-gate
1750Sstevel@tonic-gate for (ng = tab->to_do; ng != NULL; ng = next) {
1760Sstevel@tonic-gate if (ng->name != NULL)
1770Sstevel@tonic-gate free(ng->name);
1780Sstevel@tonic-gate next = ng->next;
1790Sstevel@tonic-gate free(ng);
1800Sstevel@tonic-gate }
1810Sstevel@tonic-gate
1820Sstevel@tonic-gate for (ng = tab->done; ng != NULL; ng = next) {
1830Sstevel@tonic-gate if (ng->name != NULL)
1840Sstevel@tonic-gate free(ng->name);
1850Sstevel@tonic-gate next = ng->next;
1860Sstevel@tonic-gate free(ng);
1870Sstevel@tonic-gate }
1880Sstevel@tonic-gate (void) memset(tab, 0, sizeof (*tab));
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate
1910Sstevel@tonic-gate /*
1920Sstevel@tonic-gate * domain comparing routine
1930Sstevel@tonic-gate * n1: See if n1 is n2 or an ancestor of it
1940Sstevel@tonic-gate * n2: (in string terms, n1 is a suffix of n2)
1950Sstevel@tonic-gate * Returns ZERO for success, -1 for failure.
1960Sstevel@tonic-gate */
1970Sstevel@tonic-gate static int
domcmp(const char * n1,const char * n2)1980Sstevel@tonic-gate domcmp(const char *n1, const char *n2)
1990Sstevel@tonic-gate {
2000Sstevel@tonic-gate #define PASS 0
2010Sstevel@tonic-gate #define FAIL -1
2020Sstevel@tonic-gate
2030Sstevel@tonic-gate size_t l1, l2;
2040Sstevel@tonic-gate
2050Sstevel@tonic-gate if ((n1 == NULL) || (n2 == NULL))
2060Sstevel@tonic-gate return (FAIL);
2070Sstevel@tonic-gate
2080Sstevel@tonic-gate l1 = strlen(n1);
2090Sstevel@tonic-gate l2 = strlen(n2);
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate /* Turn a blind eye to the presence or absence of trailing periods */
2120Sstevel@tonic-gate if (l1 != 0 && n1[l1 - 1] == '.') {
2130Sstevel@tonic-gate --l1;
2140Sstevel@tonic-gate }
2150Sstevel@tonic-gate if (l2 != 0 && n2[l2 - 1] == '.') {
2160Sstevel@tonic-gate --l2;
2170Sstevel@tonic-gate }
2180Sstevel@tonic-gate if (l1 > l2) { /* Can't be a suffix */
2190Sstevel@tonic-gate return (FAIL);
2200Sstevel@tonic-gate } else if (l1 == 0) { /* Trivially a suffix; */
2210Sstevel@tonic-gate /* (do we want this case?) */
2220Sstevel@tonic-gate return (PASS);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate /* So 0 < l1 <= l2 */
2250Sstevel@tonic-gate if (l1 < l2 && n2[l2 - l1 - 1] != '.') {
2260Sstevel@tonic-gate return (FAIL);
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate if (strncasecmp(n1, &n2[l2 - l1], l1) == 0) {
2290Sstevel@tonic-gate return (PASS);
2300Sstevel@tonic-gate } else {
2310Sstevel@tonic-gate return (FAIL);
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate }
2340Sstevel@tonic-gate
2350Sstevel@tonic-gate static int
split_triple(char * triple,char ** hostname,char ** username,char ** domain)2360Sstevel@tonic-gate split_triple(char *triple, char **hostname, char **username, char **domain)
2370Sstevel@tonic-gate {
2380Sstevel@tonic-gate int i, syntax_err;
2390Sstevel@tonic-gate char *splittriple[3];
2400Sstevel@tonic-gate char *p = triple;
2410Sstevel@tonic-gate
2420Sstevel@tonic-gate #ifdef DEBUG
2430Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: split_triple]\n");
2440Sstevel@tonic-gate #endif /* DEBUG */
2450Sstevel@tonic-gate
2460Sstevel@tonic-gate if (triple == NULL)
2470Sstevel@tonic-gate return (-1);
2480Sstevel@tonic-gate
2490Sstevel@tonic-gate p++;
2500Sstevel@tonic-gate syntax_err = 0;
2510Sstevel@tonic-gate for (i = 0; i < 3; i++) {
2520Sstevel@tonic-gate char *start;
2530Sstevel@tonic-gate char *limit;
2540Sstevel@tonic-gate const char *terminators = ",) \t";
2550Sstevel@tonic-gate
2560Sstevel@tonic-gate if (i == 2) {
2570Sstevel@tonic-gate /* Don't allow comma */
2580Sstevel@tonic-gate terminators++;
2590Sstevel@tonic-gate }
2600Sstevel@tonic-gate while (isspace(*p)) {
2610Sstevel@tonic-gate p++;
2620Sstevel@tonic-gate }
2630Sstevel@tonic-gate start = p;
2640Sstevel@tonic-gate limit = strpbrk(start, terminators);
2650Sstevel@tonic-gate if (limit == 0) {
2660Sstevel@tonic-gate syntax_err++;
2670Sstevel@tonic-gate break;
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate p = limit;
2700Sstevel@tonic-gate while (isspace(*p)) {
2710Sstevel@tonic-gate p++;
2720Sstevel@tonic-gate }
2730Sstevel@tonic-gate if (*p == terminators[0]) {
2740Sstevel@tonic-gate /*
2750Sstevel@tonic-gate * Successfully parsed this name and
2760Sstevel@tonic-gate * the separator after it (comma or
2770Sstevel@tonic-gate * right paren); leave p ready for
2780Sstevel@tonic-gate * next parse.
2790Sstevel@tonic-gate */
2800Sstevel@tonic-gate p++;
2810Sstevel@tonic-gate if (start == limit) {
2820Sstevel@tonic-gate /* Wildcard */
2830Sstevel@tonic-gate splittriple[i] = NULL;
2840Sstevel@tonic-gate } else {
2850Sstevel@tonic-gate *limit = '\0';
2860Sstevel@tonic-gate splittriple[i] = start;
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate } else {
2890Sstevel@tonic-gate syntax_err++;
2900Sstevel@tonic-gate break;
2910Sstevel@tonic-gate }
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate if (syntax_err != 0)
2950Sstevel@tonic-gate return (-1);
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate *hostname = splittriple[0];
2980Sstevel@tonic-gate *username = splittriple[1];
2990Sstevel@tonic-gate *domain = splittriple[2];
3000Sstevel@tonic-gate
3010Sstevel@tonic-gate return (0);
3020Sstevel@tonic-gate }
3030Sstevel@tonic-gate
3040Sstevel@tonic-gate /*
3052388Smj162486 * Test membership in triple
3062388Smj162486 * return 0 = no match
3072388Smj162486 * return 1 = match
3080Sstevel@tonic-gate */
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate static int
match_triple_entry(struct nss_innetgr_args * ia,const ns_ldap_entry_t * entry)3110Sstevel@tonic-gate match_triple_entry(struct nss_innetgr_args *ia, const ns_ldap_entry_t *entry)
3120Sstevel@tonic-gate {
3130Sstevel@tonic-gate int ndomains;
3140Sstevel@tonic-gate char **pdomains;
3150Sstevel@tonic-gate int nhost;
3160Sstevel@tonic-gate char **phost;
3170Sstevel@tonic-gate int nusers;
3180Sstevel@tonic-gate char **pusers;
3190Sstevel@tonic-gate char **attr;
3200Sstevel@tonic-gate char triple[MAX_TRIPLE_LEN];
3210Sstevel@tonic-gate char *tuser, *thost, *tdomain;
3220Sstevel@tonic-gate int i;
3232388Smj162486 char *current, *limit;
3242388Smj162486 int pulen, phlen;
3252388Smj162486 char *pusers0, *phost0;
3260Sstevel@tonic-gate
3270Sstevel@tonic-gate nhost = ia->arg[NSS_NETGR_MACHINE].argc;
3280Sstevel@tonic-gate phost = (char **)ia->arg[NSS_NETGR_MACHINE].argv;
3292388Smj162486 if (phost == NULL || *phost == NULL) {
3300Sstevel@tonic-gate nhost = 0;
3312388Smj162486 } else {
3322388Smj162486 phost0 = phost[0];
3332388Smj162486 phlen = strlen(phost0);
334*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
335*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
336*8777SSerge.Dussud@Sun.COM "entering with host: %s", phost0 ? phost0 : "");
337*8777SSerge.Dussud@Sun.COM #endif
3382388Smj162486 }
3390Sstevel@tonic-gate nusers = ia->arg[NSS_NETGR_USER].argc;
3400Sstevel@tonic-gate pusers = (char **)ia->arg[NSS_NETGR_USER].argv;
3412388Smj162486 if (pusers == NULL || *pusers == NULL) {
3420Sstevel@tonic-gate nusers = 0;
3432388Smj162486 } else {
3442388Smj162486 pusers0 = pusers[0];
3452388Smj162486 pulen = strlen(pusers0);
346*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
347*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
348*8777SSerge.Dussud@Sun.COM "entering with user: %s", pusers0 ? pusers0 : "");
349*8777SSerge.Dussud@Sun.COM #endif
3502388Smj162486 }
3510Sstevel@tonic-gate ndomains = ia->arg[NSS_NETGR_DOMAIN].argc;
3520Sstevel@tonic-gate pdomains = (char **)ia->arg[NSS_NETGR_DOMAIN].argv;
3530Sstevel@tonic-gate if (pdomains == NULL || *pdomains == NULL)
3540Sstevel@tonic-gate ndomains = 0;
355*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
356*8777SSerge.Dussud@Sun.COM else
357*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
358*8777SSerge.Dussud@Sun.COM "entering with domain: %s", pdomains[0] ? pdomains[0] : "");
359*8777SSerge.Dussud@Sun.COM #endif
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate attr = __ns_ldap_getAttr(entry, _N_TRIPLE);
3620Sstevel@tonic-gate if (attr == NULL || *attr == NULL)
3630Sstevel@tonic-gate return (0);
3640Sstevel@tonic-gate
365*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
366*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
367*8777SSerge.Dussud@Sun.COM "(nusers: %d, nhost:%d, ndomains: %d)",
368*8777SSerge.Dussud@Sun.COM nusers, nhost, ndomains);
369*8777SSerge.Dussud@Sun.COM #endif
370*8777SSerge.Dussud@Sun.COM
3712388Smj162486 /* Special cases for speedup */
3722388Smj162486 if (nusers == 1 && nhost == 0 && ndomains == 0) {
3732388Smj162486 /* Special case for finding a single user in a netgroup */
3742388Smj162486 for (; *attr; attr++) {
3752388Smj162486 /* jump to first comma and check next character */
3762388Smj162486 current = *attr;
377*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
378*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
379*8777SSerge.Dussud@Sun.COM "current is: %s", current);
380*8777SSerge.Dussud@Sun.COM #endif
3812388Smj162486 if ((current = strchr(current, COMMA)) == NULL)
3822388Smj162486 continue;
3832388Smj162486 current++;
3842388Smj162486
3852388Smj162486 /* skip whitespaces */
3862388Smj162486 while (isspace(*current))
3872388Smj162486 current++;
3882388Smj162486
3892388Smj162486 /* if user part is null, then treat as wildcard */
3902388Smj162486 if (*current == COMMA)
3912388Smj162486 return (1);
3922388Smj162486
3932388Smj162486 /* compare first character */
3942388Smj162486 if (*pusers0 != *current)
3952388Smj162486 continue;
3962388Smj162486
3972388Smj162486 /* limit username to COMMA */
3982388Smj162486 if ((limit = strchr(current, COMMA)) == NULL)
3992388Smj162486 continue;
4002388Smj162486 *limit = '\0';
4012388Smj162486
4022388Smj162486 /* remove blanks before COMMA */
4032388Smj162486 if ((limit = strpbrk(current, " \t")) != NULL)
4042388Smj162486 *limit = '\0';
4052388Smj162486
4062388Smj162486 /* compare size of username */
4072388Smj162486 if (pulen != strlen(current)) {
4082388Smj162486 continue;
4092388Smj162486 }
4102388Smj162486
4112388Smj162486 /* do actual compare */
4122388Smj162486 if (strncmp(pusers0, current, pulen) == 0) {
4132388Smj162486 return (1);
4142388Smj162486 } else {
4152388Smj162486 continue;
4162388Smj162486 }
4172388Smj162486 }
4182388Smj162486 } else if (nusers == 0 && nhost == 1 && ndomains == 0) {
4192388Smj162486 /* Special case for finding a single host in a netgroup */
4202388Smj162486 for (; *attr; attr++) {
4212388Smj162486
4222388Smj162486 /* jump to first character and check */
4232388Smj162486 current = *attr;
424*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
425*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
426*8777SSerge.Dussud@Sun.COM "current is: %s", current);
427*8777SSerge.Dussud@Sun.COM #endif
4282388Smj162486 current++;
4292388Smj162486
4302388Smj162486 /* skip whitespaces */
4312388Smj162486 while (isspace(*current))
4322388Smj162486 current++;
4332388Smj162486
4342388Smj162486 /* if host part is null, then treat as wildcard */
4352388Smj162486 if (*current == COMMA)
4362388Smj162486 return (1);
4372388Smj162486
4382388Smj162486 /* limit hostname to COMMA */
4392388Smj162486 if ((limit = strchr(current, COMMA)) == NULL)
4402388Smj162486 continue;
4412388Smj162486 *limit = '\0';
4422388Smj162486
4432388Smj162486 /* remove blanks before COMMA */
4442388Smj162486 if ((limit = strpbrk(current, " \t")) != NULL)
4452388Smj162486 *limit = '\0';
4462388Smj162486
4472388Smj162486 /* compare size of hostname */
4482388Smj162486 if (phlen != strlen(current)) {
4492388Smj162486 continue;
4502388Smj162486 }
4512388Smj162486
4522388Smj162486 /* do actual compare */
4532388Smj162486 if (strncasecmp(phost0, current, phlen) == 0) {
4542388Smj162486 return (1);
4552388Smj162486 } else {
4562388Smj162486 continue;
4572388Smj162486 }
4582388Smj162486 }
4592388Smj162486 } else {
4602388Smj162486 for (; *attr; attr++) {
4612388Smj162486 if (strlcpy(triple, *attr,
4624953Smichen sizeof (triple)) >= sizeof (triple))
4632388Smj162486 continue;
464*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
465*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: match_triple_entry: "
466*8777SSerge.Dussud@Sun.COM "triple is: %s", triple);
467*8777SSerge.Dussud@Sun.COM #endif
4682388Smj162486 if (split_triple(triple, &thost, &tuser, &tdomain) != 0)
4692388Smj162486 continue;
4702388Smj162486 if (thost != NULL && *thost != '\0' && nhost != 0) {
4712388Smj162486 for (i = 0; i < nhost; i++)
4722388Smj162486 if (strcasecmp(thost, phost[i]) == 0)
4732388Smj162486 break;
4742388Smj162486 if (i == nhost)
4754953Smichen continue;
4762388Smj162486 }
4772388Smj162486 if (tuser != NULL && *tuser != '\0' && nusers != 0) {
4782388Smj162486 for (i = 0; i < nusers; i++)
4792388Smj162486 if (strcmp(tuser, pusers[i]) == 0)
4802388Smj162486 break;
4812388Smj162486 if (i == nusers)
4822388Smj162486 continue;
4832388Smj162486 }
4842388Smj162486 if (tdomain != NULL && *tdomain != '\0' &&
4854953Smichen ndomains != 0) {
4862388Smj162486 for (i = 0; i < ndomains; i++)
4872388Smj162486 if (domcmp(tdomain, pdomains[i]) == 0)
4882388Smj162486 break;
4892388Smj162486 if (i == ndomains)
4902388Smj162486 continue;
4912388Smj162486 }
4922388Smj162486 return (1);
4932388Smj162486 }
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate return (0);
4970Sstevel@tonic-gate }
4980Sstevel@tonic-gate
4990Sstevel@tonic-gate static int
match_triple(struct nss_innetgr_args * ia,ns_ldap_result_t * result)5000Sstevel@tonic-gate match_triple(struct nss_innetgr_args *ia, ns_ldap_result_t *result)
5010Sstevel@tonic-gate {
5020Sstevel@tonic-gate ns_ldap_entry_t *entry;
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next)
5054953Smichen if (match_triple_entry(ia, entry) == 1)
5064953Smichen return (1);
5070Sstevel@tonic-gate
5080Sstevel@tonic-gate return (0);
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate
5110Sstevel@tonic-gate static int
add_netgroup_member_entry(ns_ldap_entry_t * entry,netgroup_table_t * tab)5120Sstevel@tonic-gate add_netgroup_member_entry(ns_ldap_entry_t *entry, netgroup_table_t *tab)
5130Sstevel@tonic-gate {
5140Sstevel@tonic-gate char **attrs;
5150Sstevel@tonic-gate char **a;
5160Sstevel@tonic-gate
5170Sstevel@tonic-gate attrs = __ns_ldap_getAttr(entry, _N_MEMBER);
5180Sstevel@tonic-gate if (attrs == NULL || *attrs == NULL)
5190Sstevel@tonic-gate return (0);
5200Sstevel@tonic-gate
5210Sstevel@tonic-gate for (a = attrs; *a != NULL; a++) {}
5220Sstevel@tonic-gate
5230Sstevel@tonic-gate do {
5240Sstevel@tonic-gate a--;
5250Sstevel@tonic-gate if (add_netgroup_name(*a, tab) != 0)
5260Sstevel@tonic-gate return (-1);
5270Sstevel@tonic-gate } while (a > attrs);
5280Sstevel@tonic-gate return (0);
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate static int
add_netgroup_member(ns_ldap_result_t * result,netgroup_table_t * tab)5320Sstevel@tonic-gate add_netgroup_member(ns_ldap_result_t *result, netgroup_table_t *tab)
5330Sstevel@tonic-gate {
5340Sstevel@tonic-gate ns_ldap_entry_t *entry;
5350Sstevel@tonic-gate int ret = 0;
5360Sstevel@tonic-gate
5370Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) {
5384953Smichen ret = add_netgroup_member_entry(entry, tab);
5394953Smichen if (ret != 0)
5404953Smichen break;
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate return (ret);
5430Sstevel@tonic-gate }
5440Sstevel@tonic-gate
5450Sstevel@tonic-gate /*
5460Sstevel@tonic-gate * top_down_search checks only checks the netgroup specified in netgrname
5470Sstevel@tonic-gate */
5480Sstevel@tonic-gate static nss_status_t
top_down_search(struct nss_innetgr_args * ia,char * netgrname)5490Sstevel@tonic-gate top_down_search(struct nss_innetgr_args *ia, char *netgrname)
5500Sstevel@tonic-gate {
5510Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN];
5520Sstevel@tonic-gate char name[SEARCHFILTERLEN];
5530Sstevel@tonic-gate char userdata[SEARCHFILTERLEN];
5540Sstevel@tonic-gate ns_ldap_result_t *result = NULL;
5550Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
5560Sstevel@tonic-gate int rc;
5570Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND;
5584953Smichen nss_status_t status1;
5590Sstevel@tonic-gate netgroup_table_t tab;
5600Sstevel@tonic-gate netgroup_name_t *ng;
5610Sstevel@tonic-gate int ret;
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate (void) memset(&tab, 0, sizeof (tab));
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate if (add_netgroup_name(netgrname, &tab) != 0)
5664953Smichen return ((nss_status_t)NSS_NOTFOUND);
5670Sstevel@tonic-gate
5680Sstevel@tonic-gate while ((ng = get_next_netgroup(&tab)) != NULL) {
569*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
570*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: top_down_search: netgroup loop "
571*8777SSerge.Dussud@Sun.COM "(ng->name: %s)", ng->name ? ng->name : "null !");
572*8777SSerge.Dussud@Sun.COM #endif
5734953Smichen if (_ldap_filter_name(name, ng->name, sizeof (name)) != 0)
5744953Smichen break;
5754953Smichen ret = snprintf(searchfilter, sizeof (searchfilter),
5764953Smichen _F_SETMEMBER, name);
5774953Smichen if (ret >= sizeof (searchfilter) || ret < 0)
5784953Smichen break;
5794953Smichen
5804953Smichen ret = snprintf(userdata, sizeof (userdata), _F_SETMEMBER_SSD,
5810Sstevel@tonic-gate name);
5824953Smichen if (ret >= sizeof (userdata) || ret < 0)
5834953Smichen break;
5840Sstevel@tonic-gate
585*8777SSerge.Dussud@Sun.COM /* searching for current netgroup name entry */
586*8777SSerge.Dussud@Sun.COM rc = __ns_ldap_list(_NETGROUP, searchfilter,
587*8777SSerge.Dussud@Sun.COM _merge_SSD_filter, netgrent_attrs, NULL, 0, &result,
588*8777SSerge.Dussud@Sun.COM &error, NULL, userdata);
5890Sstevel@tonic-gate
5904953Smichen if (error != NULL) {
5914953Smichen status1 = switch_err(rc, error);
5924953Smichen if (status1 == NSS_TRYAGAIN) {
5934953Smichen (void) __ns_ldap_freeError(&error);
5944953Smichen free_netgroup_table(&tab);
5954953Smichen return (status1);
5964953Smichen }
5970Sstevel@tonic-gate }
5980Sstevel@tonic-gate
5990Sstevel@tonic-gate (void) __ns_ldap_freeError(&error);
600*8777SSerge.Dussud@Sun.COM if (rc == NS_LDAP_SUCCESS) {
6014953Smichen if (match_triple(ia, result) == 1) {
6024953Smichen /* We found a match */
6034953Smichen ia->status = NSS_NETGR_FOUND;
6044953Smichen status = NSS_SUCCESS;
605*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
606*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: top_down_search: "
607*8777SSerge.Dussud@Sun.COM "found match");
608*8777SSerge.Dussud@Sun.COM #endif
6094953Smichen break;
6104953Smichen }
6114953Smichen
612*8777SSerge.Dussud@Sun.COM /*
613*8777SSerge.Dussud@Sun.COM * No match found. Check for membernisnetgroup
614*8777SSerge.Dussud@Sun.COM * in result and if yes, start again with those.
615*8777SSerge.Dussud@Sun.COM */
6164953Smichen rc = add_netgroup_member(result, &tab);
617*8777SSerge.Dussud@Sun.COM if (rc != 0)
6184953Smichen break;
619*8777SSerge.Dussud@Sun.COM } else if (rc != NS_LDAP_NOTFOUND) {
620*8777SSerge.Dussud@Sun.COM break;
6214953Smichen }
6224953Smichen (void) __ns_ldap_freeResult(&result);
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate
6250Sstevel@tonic-gate (void) __ns_ldap_freeResult(&result);
6260Sstevel@tonic-gate free_netgroup_table(&tab);
6270Sstevel@tonic-gate return (status);
6280Sstevel@tonic-gate }
6290Sstevel@tonic-gate
6300Sstevel@tonic-gate /*
6310Sstevel@tonic-gate * __netgr_in checks only checks the netgroup specified in ngroup
6320Sstevel@tonic-gate */
6330Sstevel@tonic-gate static nss_status_t
__netgr_in(void * a,char * netgrname)6340Sstevel@tonic-gate __netgr_in(void *a, char *netgrname)
6350Sstevel@tonic-gate {
6360Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a;
6370Sstevel@tonic-gate nss_status_t status = NSS_NOTFOUND;
6380Sstevel@tonic-gate
6390Sstevel@tonic-gate #ifdef DEBUG
6400Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_in]\n");
6410Sstevel@tonic-gate (void) fprintf(stdout, "\tmachine: argc[%d]='%s' user: "
6424953Smichen "argc[%d]='%s',\n\tdomain:argc[%d]='%s' "
6434953Smichen "netgroup: argc[%d]='%s'\n",
6444953Smichen NSS_NETGR_MACHINE,
6454953Smichen PRINT_VAL(ia->arg[NSS_NETGR_MACHINE]),
6464953Smichen NSS_NETGR_USER,
6474953Smichen PRINT_VAL(ia->arg[NSS_NETGR_USER]),
6484953Smichen NSS_NETGR_DOMAIN,
6494953Smichen PRINT_VAL(ia->arg[NSS_NETGR_DOMAIN]),
6504953Smichen NSS_NETGR_N,
6514953Smichen PRINT_VAL(ia->arg[NSS_NETGR_N]));
6520Sstevel@tonic-gate (void) fprintf(stdout, "\tgroups='%s'\n", netgrname);
6530Sstevel@tonic-gate #endif /* DEBUG */
6540Sstevel@tonic-gate
6550Sstevel@tonic-gate ia->status = NSS_NETGR_NO;
6560Sstevel@tonic-gate
6570Sstevel@tonic-gate if (netgrname == NULL)
6580Sstevel@tonic-gate return (status);
6590Sstevel@tonic-gate
6602388Smj162486 return (top_down_search(ia, netgrname));
6610Sstevel@tonic-gate }
6620Sstevel@tonic-gate
6630Sstevel@tonic-gate /*ARGSUSED0*/
6640Sstevel@tonic-gate static nss_status_t
netgr_in(ldap_backend_ptr be,void * a)6650Sstevel@tonic-gate netgr_in(ldap_backend_ptr be, void *a)
6660Sstevel@tonic-gate {
6670Sstevel@tonic-gate struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a;
6680Sstevel@tonic-gate int i;
6690Sstevel@tonic-gate nss_status_t rc = (nss_status_t)NSS_NOTFOUND;
6700Sstevel@tonic-gate
6710Sstevel@tonic-gate ia->status = NSS_NETGR_NO;
6720Sstevel@tonic-gate for (i = 0; i < ia->groups.argc; i++) {
6730Sstevel@tonic-gate rc = __netgr_in(a, ia->groups.argv[i]);
6740Sstevel@tonic-gate if (ia->status == NSS_NETGR_FOUND)
6750Sstevel@tonic-gate return (NSS_SUCCESS);
6760Sstevel@tonic-gate }
6770Sstevel@tonic-gate return (rc);
6780Sstevel@tonic-gate }
6790Sstevel@tonic-gate
6800Sstevel@tonic-gate /*
6810Sstevel@tonic-gate *
6820Sstevel@tonic-gate */
6830Sstevel@tonic-gate
6840Sstevel@tonic-gate static nss_status_t
getnetgr_ldap_setent(ldap_backend_ptr be,void * a)6850Sstevel@tonic-gate getnetgr_ldap_setent(ldap_backend_ptr be, void *a)
6860Sstevel@tonic-gate {
6870Sstevel@tonic-gate const char *netgroup = (const char *) a;
6880Sstevel@tonic-gate getnetgrent_cookie_t *cookie;
6890Sstevel@tonic-gate
6900Sstevel@tonic-gate #ifdef DEBUG
6910Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_setent]\n");
6920Sstevel@tonic-gate #endif /* DEBUG */
6930Sstevel@tonic-gate
6940Sstevel@tonic-gate cookie = (getnetgrent_cookie_t *)be->netgroup_cookie;
6950Sstevel@tonic-gate if (cookie != NULL && cookie->netgroup != NULL) {
6960Sstevel@tonic-gate /* is this another set on the same netgroup */
6970Sstevel@tonic-gate if (strcmp(cookie->netgroup, netgroup) == 0)
6980Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate return (NSS_NOTFOUND);
7020Sstevel@tonic-gate }
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate static void
free_getnetgrent_cookie(getnetgrent_cookie_t ** cookie)7050Sstevel@tonic-gate free_getnetgrent_cookie(getnetgrent_cookie_t **cookie)
7060Sstevel@tonic-gate {
7070Sstevel@tonic-gate getnetgrent_cookie_t *p = *cookie;
7080Sstevel@tonic-gate
7090Sstevel@tonic-gate #ifdef DEBUG
7100Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: free_getnetgrent_cookie]\n");
7110Sstevel@tonic-gate #endif /* DEBUG */
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate if (p == NULL)
7140Sstevel@tonic-gate return;
7150Sstevel@tonic-gate
7160Sstevel@tonic-gate (void) __ns_ldap_freeResult(&p->results);
7170Sstevel@tonic-gate free_netgroup_table(&p->tab);
7180Sstevel@tonic-gate free(p->netgroup);
7190Sstevel@tonic-gate free(p);
7200Sstevel@tonic-gate *cookie = NULL;
7210Sstevel@tonic-gate }
7220Sstevel@tonic-gate
7230Sstevel@tonic-gate /*ARGSUSED1*/
7240Sstevel@tonic-gate static nss_status_t
getnetgr_ldap_endent(ldap_backend_ptr be,void * a)7250Sstevel@tonic-gate getnetgr_ldap_endent(ldap_backend_ptr be, void *a)
7260Sstevel@tonic-gate {
7270Sstevel@tonic-gate
7280Sstevel@tonic-gate #ifdef DEBUG
7290Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_endent]\n");
7300Sstevel@tonic-gate #endif /* DEBUG */
7310Sstevel@tonic-gate
7320Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie);
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
7350Sstevel@tonic-gate }
7360Sstevel@tonic-gate
7370Sstevel@tonic-gate
7380Sstevel@tonic-gate /*ARGSUSED1*/
7390Sstevel@tonic-gate static nss_status_t
getnetgr_ldap_destr(ldap_backend_ptr be,void * a)7400Sstevel@tonic-gate getnetgr_ldap_destr(ldap_backend_ptr be, void *a)
7410Sstevel@tonic-gate {
7420Sstevel@tonic-gate
7430Sstevel@tonic-gate #ifdef DEBUG
7440Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_destr]\n");
7450Sstevel@tonic-gate #endif /* DEBUG */
7460Sstevel@tonic-gate
7470Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie);
7480Sstevel@tonic-gate free(be);
7490Sstevel@tonic-gate
7500Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
7510Sstevel@tonic-gate }
7520Sstevel@tonic-gate
7530Sstevel@tonic-gate
7540Sstevel@tonic-gate static nss_status_t
getnetgr_ldap_getent(ldap_backend_ptr be,void * a)7550Sstevel@tonic-gate getnetgr_ldap_getent(ldap_backend_ptr be, void *a)
7560Sstevel@tonic-gate {
7570Sstevel@tonic-gate struct nss_getnetgrent_args *args;
7580Sstevel@tonic-gate getnetgrent_cookie_t *p;
7590Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN];
7600Sstevel@tonic-gate char userdata[SEARCHFILTERLEN];
7610Sstevel@tonic-gate char name[SEARCHFILTERLEN];
7620Sstevel@tonic-gate int rc;
7630Sstevel@tonic-gate ns_ldap_result_t *result = NULL;
7640Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
7650Sstevel@tonic-gate char **attrs;
7660Sstevel@tonic-gate char *hostname, *username, *domain;
7670Sstevel@tonic-gate char *buffer;
7680Sstevel@tonic-gate nss_status_t status = NSS_SUCCESS;
7690Sstevel@tonic-gate netgroup_name_t *ng;
7700Sstevel@tonic-gate int ret;
7710Sstevel@tonic-gate
7720Sstevel@tonic-gate #ifdef DEBUG
7730Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: getnetgr_ldap_getent]\n");
7740Sstevel@tonic-gate #endif /* DEBUG */
7750Sstevel@tonic-gate
7760Sstevel@tonic-gate args = (struct nss_getnetgrent_args *)a;
7770Sstevel@tonic-gate
7780Sstevel@tonic-gate args->status = NSS_NETGR_NO;
7790Sstevel@tonic-gate
7800Sstevel@tonic-gate p = (getnetgrent_cookie_t *)be->netgroup_cookie;
7810Sstevel@tonic-gate if (p == NULL)
7820Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
7830Sstevel@tonic-gate
7840Sstevel@tonic-gate for (;;) {
785*8777SSerge.Dussud@Sun.COM /*
786*8777SSerge.Dussud@Sun.COM * Search through each netgroup consecutively: only search
787*8777SSerge.Dussud@Sun.COM * next netgroup when results from previous netgroup are
788*8777SSerge.Dussud@Sun.COM * processed.
789*8777SSerge.Dussud@Sun.COM * Needed for nested netgroup (memberNisNetgroup attributes).
790*8777SSerge.Dussud@Sun.COM */
791*8777SSerge.Dussud@Sun.COM if (p->results == NULL) {
792*8777SSerge.Dussud@Sun.COM if ((ng = get_next_netgroup(&p->tab)) != NULL) {
793*8777SSerge.Dussud@Sun.COM if (_ldap_filter_name(name, ng->name,
794*8777SSerge.Dussud@Sun.COM sizeof (name)) != 0)
795*8777SSerge.Dussud@Sun.COM break;
7960Sstevel@tonic-gate
797*8777SSerge.Dussud@Sun.COM ret = snprintf(searchfilter,
798*8777SSerge.Dussud@Sun.COM sizeof (searchfilter),
799*8777SSerge.Dussud@Sun.COM _F_SETMEMBER, name);
800*8777SSerge.Dussud@Sun.COM if (ret >= sizeof (searchfilter) || ret < 0)
801*8777SSerge.Dussud@Sun.COM break;
8020Sstevel@tonic-gate
803*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
804*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: "
805*8777SSerge.Dussud@Sun.COM "getnetgr_ldap_getent: "
806*8777SSerge.Dussud@Sun.COM "netgroup name: %s", name);
807*8777SSerge.Dussud@Sun.COM #endif
808*8777SSerge.Dussud@Sun.COM ret = snprintf(userdata, sizeof (userdata),
809*8777SSerge.Dussud@Sun.COM _F_SETMEMBER_SSD, name);
810*8777SSerge.Dussud@Sun.COM if (ret >= sizeof (userdata) || ret < 0)
811*8777SSerge.Dussud@Sun.COM break;
8120Sstevel@tonic-gate
813*8777SSerge.Dussud@Sun.COM result = NULL;
814*8777SSerge.Dussud@Sun.COM rc = __ns_ldap_list(_NETGROUP, searchfilter,
815*8777SSerge.Dussud@Sun.COM _merge_SSD_filter, netgrent_attrs, NULL,
816*8777SSerge.Dussud@Sun.COM 0, &result, &error, NULL, userdata);
817*8777SSerge.Dussud@Sun.COM (void) __ns_ldap_freeError(&error);
8180Sstevel@tonic-gate
819*8777SSerge.Dussud@Sun.COM if (rc == NS_LDAP_SUCCESS && result != NULL) {
820*8777SSerge.Dussud@Sun.COM p->results = result;
821*8777SSerge.Dussud@Sun.COM } else {
822*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
823*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: "
824*8777SSerge.Dussud@Sun.COM "getnetgr_ldap_getent: "
825*8777SSerge.Dussud@Sun.COM "__ns_ldap_list() returned %d "
826*8777SSerge.Dussud@Sun.COM "(result: 0x%x)", rc, result);
827*8777SSerge.Dussud@Sun.COM #endif
828*8777SSerge.Dussud@Sun.COM /*
829*8777SSerge.Dussud@Sun.COM * Will exit when no more netgroup
830*8777SSerge.Dussud@Sun.COM * to search and no more p->results
831*8777SSerge.Dussud@Sun.COM * to process.
832*8777SSerge.Dussud@Sun.COM */
833*8777SSerge.Dussud@Sun.COM (void) __ns_ldap_freeResult(&result);
834*8777SSerge.Dussud@Sun.COM }
835*8777SSerge.Dussud@Sun.COM } else { /* no more netgroup to process */
836*8777SSerge.Dussud@Sun.COM /*
837*8777SSerge.Dussud@Sun.COM * If no more results to process, and since
838*8777SSerge.Dussud@Sun.COM * there's no more netgroup to process either,
839*8777SSerge.Dussud@Sun.COM * then it's time to break and exit the for
840*8777SSerge.Dussud@Sun.COM * loop.
841*8777SSerge.Dussud@Sun.COM */
842*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
843*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: "
844*8777SSerge.Dussud@Sun.COM "getnetgr_ldap_getent: no more netgroup "
845*8777SSerge.Dussud@Sun.COM "to process, p->results: 0x%x",
846*8777SSerge.Dussud@Sun.COM p->results);
847*8777SSerge.Dussud@Sun.COM #endif
848*8777SSerge.Dussud@Sun.COM if (p->results == NULL)
849*8777SSerge.Dussud@Sun.COM break;
8504953Smichen }
8510Sstevel@tonic-gate }
8524953Smichen if (p->results == NULL)
8534953Smichen continue;
8540Sstevel@tonic-gate
8554953Smichen if (p->entry == NULL)
8564953Smichen p->entry = p->results->entry;
8570Sstevel@tonic-gate
8584953Smichen if (p->entry == NULL)
8594953Smichen continue;
8600Sstevel@tonic-gate
8614953Smichen if (p->attrs == NULL) {
8624953Smichen attrs = __ns_ldap_getAttr(p->entry, _N_TRIPLE);
8634953Smichen if (attrs != NULL && *attrs != NULL)
8644953Smichen p->attrs = attrs;
8650Sstevel@tonic-gate }
8660Sstevel@tonic-gate
8674953Smichen if (p->attrs != NULL) {
8684953Smichen attrs = p->attrs;
8694953Smichen buffer = args->buffer;
8704953Smichen
8714953Smichen if (strlcpy(buffer, *attrs, args->buflen) >=
8724953Smichen args->buflen) {
8734953Smichen status = NSS_STR_PARSE_ERANGE;
8744953Smichen break;
8754953Smichen }
8760Sstevel@tonic-gate
8774953Smichen rc = split_triple(buffer, &hostname, &username,
8784953Smichen &domain);
8794953Smichen attrs++;
8804953Smichen if (attrs != NULL && *attrs != NULL)
8814953Smichen p->attrs = attrs;
8824953Smichen else
8834953Smichen p->attrs = NULL;
8844953Smichen if (rc == 0) {
8854953Smichen args->retp[NSS_NETGR_MACHINE] = hostname;
8864953Smichen args->retp[NSS_NETGR_USER] = username;
8874953Smichen args->retp[NSS_NETGR_DOMAIN] = domain;
8884953Smichen args->status = NSS_NETGR_FOUND;
889*8777SSerge.Dussud@Sun.COM #ifdef DEBUG
890*8777SSerge.Dussud@Sun.COM syslog(LOG_DEBUG, "nss_ldap: "
891*8777SSerge.Dussud@Sun.COM "getnetgr_ldap_getent: found triple "
892*8777SSerge.Dussud@Sun.COM "(%s, %s, %s), 0x%x to process",
893*8777SSerge.Dussud@Sun.COM hostname ? hostname : "",
894*8777SSerge.Dussud@Sun.COM username ? username : "",
895*8777SSerge.Dussud@Sun.COM domain ? domain : "",
896*8777SSerge.Dussud@Sun.COM p->attrs);
897*8777SSerge.Dussud@Sun.COM #endif
8984953Smichen if (p->attrs != NULL)
8994953Smichen break;
9004953Smichen }
9010Sstevel@tonic-gate }
9020Sstevel@tonic-gate
9034953Smichen if (p->attrs == NULL) {
9044953Smichen rc = add_netgroup_member_entry(p->entry, &p->tab);
9054953Smichen if (rc != 0) {
9064953Smichen args->status = NSS_NETGR_NO;
9074953Smichen break;
9084953Smichen }
9094953Smichen
9104953Smichen p->entry = p->entry->next;
9114953Smichen if (p->entry == NULL)
9124953Smichen (void) __ns_ldap_freeResult(&p->results);
9134953Smichen if (args->status == NSS_NETGR_FOUND)
9144953Smichen break;
9154953Smichen }
9160Sstevel@tonic-gate }
9170Sstevel@tonic-gate
9180Sstevel@tonic-gate return (status);
9190Sstevel@tonic-gate }
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate static ldap_backend_op_t getnetgroup_ops[] = {
9220Sstevel@tonic-gate getnetgr_ldap_destr,
9230Sstevel@tonic-gate getnetgr_ldap_endent,
9240Sstevel@tonic-gate getnetgr_ldap_setent,
9250Sstevel@tonic-gate getnetgr_ldap_getent,
9260Sstevel@tonic-gate };
9270Sstevel@tonic-gate
9280Sstevel@tonic-gate /*
9290Sstevel@tonic-gate *
9300Sstevel@tonic-gate */
9310Sstevel@tonic-gate
9320Sstevel@tonic-gate static nss_status_t
netgr_set(ldap_backend_ptr be,void * a)9330Sstevel@tonic-gate netgr_set(ldap_backend_ptr be, void *a)
9340Sstevel@tonic-gate {
9350Sstevel@tonic-gate struct nss_setnetgrent_args *args =
9364953Smichen (struct nss_setnetgrent_args *)a;
9370Sstevel@tonic-gate ldap_backend_ptr get_be;
9380Sstevel@tonic-gate getnetgrent_cookie_t *p;
9390Sstevel@tonic-gate
9400Sstevel@tonic-gate #ifdef DEBUG
9410Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_set]\n");
9420Sstevel@tonic-gate (void) fprintf(stdout,
9434953Smichen "\targs->netgroup: %s\n", ISNULL(args->netgroup));
9440Sstevel@tonic-gate #endif /* DEBUG */
9450Sstevel@tonic-gate
9460Sstevel@tonic-gate if (args->netgroup == NULL)
9470Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
9480Sstevel@tonic-gate
9490Sstevel@tonic-gate free_getnetgrent_cookie((getnetgrent_cookie_t **)&be->netgroup_cookie);
9500Sstevel@tonic-gate p = (getnetgrent_cookie_t *)calloc(1, sizeof (getnetgrent_cookie_t));
9510Sstevel@tonic-gate if (p == NULL)
9520Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
9530Sstevel@tonic-gate p->netgroup = strdup(args->netgroup);
9540Sstevel@tonic-gate if (p->netgroup == NULL) {
9550Sstevel@tonic-gate free(p);
9560Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
9570Sstevel@tonic-gate }
9580Sstevel@tonic-gate if (add_netgroup_name(args->netgroup, &p->tab) == -1) {
9590Sstevel@tonic-gate free_getnetgrent_cookie(&p);
9600Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
9610Sstevel@tonic-gate }
9620Sstevel@tonic-gate
9630Sstevel@tonic-gate /* now allocate and return iteration backend structure */
9640Sstevel@tonic-gate if ((get_be = (ldap_backend_ptr)malloc(sizeof (*get_be))) == NULL)
9650Sstevel@tonic-gate return (NSS_UNAVAIL);
9660Sstevel@tonic-gate get_be->ops = getnetgroup_ops;
9670Sstevel@tonic-gate get_be->nops = sizeof (getnetgroup_ops) / sizeof (getnetgroup_ops[0]);
9680Sstevel@tonic-gate get_be->tablename = NULL;
9690Sstevel@tonic-gate get_be->attrs = netgrent_attrs;
9700Sstevel@tonic-gate get_be->result = NULL;
9712830Sdjl get_be->ldapobj2str = NULL;
9720Sstevel@tonic-gate get_be->setcalled = 1;
9730Sstevel@tonic-gate get_be->filter = NULL;
9740Sstevel@tonic-gate get_be->toglue = NULL;
9750Sstevel@tonic-gate get_be->enumcookie = NULL;
9760Sstevel@tonic-gate get_be->netgroup_cookie = p;
9770Sstevel@tonic-gate args->iterator = (nss_backend_t *)get_be;
9780Sstevel@tonic-gate
9790Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result);
9800Sstevel@tonic-gate
9810Sstevel@tonic-gate return (NSS_SUCCESS);
9820Sstevel@tonic-gate }
9830Sstevel@tonic-gate
9840Sstevel@tonic-gate
9850Sstevel@tonic-gate /*ARGSUSED1*/
9860Sstevel@tonic-gate static nss_status_t
netgr_ldap_destr(ldap_backend_ptr be,void * a)9870Sstevel@tonic-gate netgr_ldap_destr(ldap_backend_ptr be, void *a)
9880Sstevel@tonic-gate {
9890Sstevel@tonic-gate
9900Sstevel@tonic-gate #ifdef DEBUG
9910Sstevel@tonic-gate (void) fprintf(stdout, "\n[getnetgrent.c: netgr_ldap_destr]\n");
9920Sstevel@tonic-gate #endif /* DEBUG */
9930Sstevel@tonic-gate
9940Sstevel@tonic-gate (void) _clean_ldap_backend(be);
9950Sstevel@tonic-gate
9960Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
9970Sstevel@tonic-gate }
9980Sstevel@tonic-gate
9990Sstevel@tonic-gate
10000Sstevel@tonic-gate
10010Sstevel@tonic-gate
10020Sstevel@tonic-gate static ldap_backend_op_t netgroup_ops[] = {
10030Sstevel@tonic-gate netgr_ldap_destr,
10040Sstevel@tonic-gate 0,
10050Sstevel@tonic-gate 0,
10060Sstevel@tonic-gate 0,
10070Sstevel@tonic-gate netgr_in, /* innetgr() */
10080Sstevel@tonic-gate netgr_set /* setnetgrent() */
10090Sstevel@tonic-gate };
10100Sstevel@tonic-gate
10110Sstevel@tonic-gate
10120Sstevel@tonic-gate /*
10130Sstevel@tonic-gate * _nss_ldap_netgroup_constr is where life begins. This function calls the
10140Sstevel@tonic-gate * generic ldap constructor function to define and build the abstract data
10150Sstevel@tonic-gate * types required to support ldap operations.
10160Sstevel@tonic-gate */
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate /*ARGSUSED0*/
10190Sstevel@tonic-gate nss_backend_t *
_nss_ldap_netgroup_constr(const char * dummy1,const char * dummy2,const char * dummy3)10200Sstevel@tonic-gate _nss_ldap_netgroup_constr(const char *dummy1, const char *dummy2,
10210Sstevel@tonic-gate const char *dummy3)
10220Sstevel@tonic-gate {
10230Sstevel@tonic-gate
10240Sstevel@tonic-gate #ifdef DEBUG
10250Sstevel@tonic-gate (void) fprintf(stdout,
10264953Smichen "\n[getnetgrent.c: _nss_ldap_netgroup_constr]\n");
10270Sstevel@tonic-gate #endif /* DEBUG */
10280Sstevel@tonic-gate
10290Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(netgroup_ops,
10304953Smichen sizeof (netgroup_ops)/sizeof (netgroup_ops[0]), _NETGROUP,
10314953Smichen netgrent_attrs, NULL));
10320Sstevel@tonic-gate }
1033