xref: /onnv-gate/usr/src/lib/libsldap/common/ns_mapping.c (revision 12758:996c46be076f)
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
5*12758SJulian.Pullen@Sun.COM  * Common Development and Distribution License (the "License").
6*12758SJulian.Pullen@Sun.COM  * 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*12758SJulian.Pullen@Sun.COM  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate #include <stdlib.h>
260Sstevel@tonic-gate #include <strings.h>
270Sstevel@tonic-gate #include <ctype.h>
280Sstevel@tonic-gate #include <locale.h>
290Sstevel@tonic-gate #include <syslog.h>
300Sstevel@tonic-gate #include "ns_internal.h"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate /*
330Sstevel@tonic-gate  * Calculate a hash for a string
340Sstevel@tonic-gate  * Based on elf_hash algorithm, hash is case insensitive
350Sstevel@tonic-gate  * Uses tolower instead of _tolower because of I18N
360Sstevel@tonic-gate  */
370Sstevel@tonic-gate 
380Sstevel@tonic-gate static unsigned long
ns_hash(const char * str)390Sstevel@tonic-gate ns_hash(const char *str)
400Sstevel@tonic-gate {
410Sstevel@tonic-gate 	unsigned int	hval = 0;
420Sstevel@tonic-gate 
430Sstevel@tonic-gate 	while (*str) {
440Sstevel@tonic-gate 		unsigned int	g;
450Sstevel@tonic-gate 
460Sstevel@tonic-gate 		hval = (hval << 4) + tolower(*str++);
470Sstevel@tonic-gate 		if ((g = (hval & 0xf0000000)) != 0)
480Sstevel@tonic-gate 			hval ^= g >> 24;
490Sstevel@tonic-gate 		hval &= ~g;
500Sstevel@tonic-gate 	}
510Sstevel@tonic-gate 	return ((unsigned long)hval);
520Sstevel@tonic-gate }
530Sstevel@tonic-gate 
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate  * Scan a hash table hit for a matching hash entry.
560Sstevel@tonic-gate  * Assume service and str are non-NULL.
570Sstevel@tonic-gate  */
580Sstevel@tonic-gate 
590Sstevel@tonic-gate static ns_hash_t *
ns_scan_hash(ns_hashtype_t type,const char * service,const char * str,ns_hash_t * idx)600Sstevel@tonic-gate ns_scan_hash(ns_hashtype_t type, const char *service,
610Sstevel@tonic-gate 		const char *str, ns_hash_t *idx)
620Sstevel@tonic-gate {
630Sstevel@tonic-gate 	while (idx) {
640Sstevel@tonic-gate 		if (idx->h_type == type &&
650Sstevel@tonic-gate 		    strcasecmp(service, idx->h_map->service) == 0 &&
660Sstevel@tonic-gate 		    strcasecmp(str, idx->h_map->orig) == 0) {
670Sstevel@tonic-gate 			return (idx);
680Sstevel@tonic-gate 		}
690Sstevel@tonic-gate 		idx = idx->h_next;
700Sstevel@tonic-gate 	}
710Sstevel@tonic-gate 	return ((ns_hash_t *)NULL);
720Sstevel@tonic-gate }
730Sstevel@tonic-gate 
740Sstevel@tonic-gate /*
750Sstevel@tonic-gate  * Find an entry in the hash table
760Sstevel@tonic-gate  */
770Sstevel@tonic-gate 
780Sstevel@tonic-gate static ns_hash_t *
ns_get_hash(const ns_config_t * config,ns_hashtype_t type,const char * service,const char * str)790Sstevel@tonic-gate ns_get_hash(const ns_config_t *config,
800Sstevel@tonic-gate 	    ns_hashtype_t type, const char *service, const char *str)
810Sstevel@tonic-gate {
820Sstevel@tonic-gate 	ns_hash_t	*idx, *hashp;
830Sstevel@tonic-gate 	unsigned long	hash;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	if (config == NULL || service == NULL || str == NULL)
860Sstevel@tonic-gate 		return (NULL);
870Sstevel@tonic-gate 
880Sstevel@tonic-gate 	hash = ns_hash(str) % NS_HASH_MAX;
890Sstevel@tonic-gate 	idx = config->hashTbl[hash];
900Sstevel@tonic-gate 	hashp = ns_scan_hash(type, service, str, idx);
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	return (hashp);
930Sstevel@tonic-gate }
940Sstevel@tonic-gate 
950Sstevel@tonic-gate /*
960Sstevel@tonic-gate  * free a map entry
970Sstevel@tonic-gate  */
980Sstevel@tonic-gate 
990Sstevel@tonic-gate static void
ns_free_map(ns_mapping_t * mapp)1000Sstevel@tonic-gate ns_free_map(ns_mapping_t *mapp)
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate 	char	**ptr;
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	if (mapp == NULL)
1050Sstevel@tonic-gate 		return;
1060Sstevel@tonic-gate 	if (mapp->service) {
1070Sstevel@tonic-gate 		free(mapp->service);
1080Sstevel@tonic-gate 		mapp->service = NULL;
1090Sstevel@tonic-gate 	}
1100Sstevel@tonic-gate 	if (mapp->orig) {
1110Sstevel@tonic-gate 		free(mapp->orig);
1120Sstevel@tonic-gate 		mapp->orig = NULL;
1130Sstevel@tonic-gate 	}
1140Sstevel@tonic-gate 	if (mapp->map) {
1150Sstevel@tonic-gate 		for (ptr = mapp->map; *ptr; ptr++)
1160Sstevel@tonic-gate 			free(*ptr);
1170Sstevel@tonic-gate 		free(mapp->map);
1180Sstevel@tonic-gate 		mapp->map = NULL;
1190Sstevel@tonic-gate 	}
1200Sstevel@tonic-gate 	free(mapp);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate /*
1240Sstevel@tonic-gate  * Remove a hash table entry.
1250Sstevel@tonic-gate  * This function is not MT safe.
1260Sstevel@tonic-gate  */
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate static ns_hash_t *
ns_free_hash(ns_hash_t * p)1290Sstevel@tonic-gate ns_free_hash(ns_hash_t *p)
1300Sstevel@tonic-gate {
1310Sstevel@tonic-gate 	ns_mapping_t	*map;
1320Sstevel@tonic-gate 	ns_hash_t	*next;
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	map = p->h_map;
1350Sstevel@tonic-gate 	next = p->h_next;
1360Sstevel@tonic-gate 	ns_free_map(map);
1370Sstevel@tonic-gate 	free(p);
1380Sstevel@tonic-gate 	return (next);
1390Sstevel@tonic-gate }
1400Sstevel@tonic-gate 
1410Sstevel@tonic-gate /*
1420Sstevel@tonic-gate  * destroy the hash table.
1430Sstevel@tonic-gate  * This function is not MT safe.
1440Sstevel@tonic-gate  */
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate void
__s_api_destroy_hash(ns_config_t * config)1470Sstevel@tonic-gate __s_api_destroy_hash(ns_config_t *config)
1480Sstevel@tonic-gate {
1490Sstevel@tonic-gate 	ns_hash_t	*next;
1500Sstevel@tonic-gate 	int		i;
1510Sstevel@tonic-gate 
1520Sstevel@tonic-gate 	if (config == NULL)
1530Sstevel@tonic-gate 		return;
1540Sstevel@tonic-gate 	for (i = 0; i < NS_HASH_MAX; i++) {
1550Sstevel@tonic-gate 		next = config->hashTbl[i];
1560Sstevel@tonic-gate 		while (next != NULL) {
1570Sstevel@tonic-gate 			next = ns_free_hash(next);
1580Sstevel@tonic-gate 		}
1590Sstevel@tonic-gate 		config->hashTbl[i] = NULL;
1600Sstevel@tonic-gate 	}
1610Sstevel@tonic-gate }
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate /*
1640Sstevel@tonic-gate  * Add a hash entry to the hash table.
1650Sstevel@tonic-gate  * This function is not MT safe.
1660Sstevel@tonic-gate  * Assume map, map->orig, map->service are non-NULL.
1670Sstevel@tonic-gate  */
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate int
__s_api_add_map2hash(ns_config_t * config,ns_hashtype_t type,ns_mapping_t * map)1700Sstevel@tonic-gate __s_api_add_map2hash(ns_config_t *config, ns_hashtype_t type,
1710Sstevel@tonic-gate 			ns_mapping_t *map)
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate 	ns_hash_t	*idx, *newp;
1740Sstevel@tonic-gate 	unsigned long	hash;
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	if (config == NULL)
1770Sstevel@tonic-gate 		return (NS_HASH_RC_CONFIG_ERROR);
1780Sstevel@tonic-gate 
1790Sstevel@tonic-gate 	hash = ns_hash(map->orig) % NS_HASH_MAX;
1800Sstevel@tonic-gate 	idx = config->hashTbl[hash];
1810Sstevel@tonic-gate 	if (idx != NULL &&
1820Sstevel@tonic-gate 	    ns_scan_hash(type, map->service, map->orig, idx) != NULL) {
1830Sstevel@tonic-gate 		return (NS_HASH_RC_EXISTED);
1840Sstevel@tonic-gate 	}
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	newp = (ns_hash_t *)malloc(sizeof (ns_hash_t));
1870Sstevel@tonic-gate 	if (newp == NULL)
1880Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
1890Sstevel@tonic-gate 	newp->h_type = type;
1900Sstevel@tonic-gate 	newp->h_map = map;
1910Sstevel@tonic-gate 	newp->h_next = idx;
1920Sstevel@tonic-gate 	config->hashTbl[hash] = newp;
1930Sstevel@tonic-gate 	newp->h_llnext = config->llHead;
1940Sstevel@tonic-gate 	config->llHead = newp;
1950Sstevel@tonic-gate 	return (NS_HASH_RC_SUCCESS);
1960Sstevel@tonic-gate }
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 
1990Sstevel@tonic-gate /*
2000Sstevel@tonic-gate  * Parse an attribute map string.
2010Sstevel@tonic-gate  * Assume space is the only legal whitespace.
2020Sstevel@tonic-gate  * attributeMap syntax:
2030Sstevel@tonic-gate  * attributeMap      = serviceId ":" origAttribute "="
2040Sstevel@tonic-gate  * 			attributes
2050Sstevel@tonic-gate  * origAttribute     = attribute
2060Sstevel@tonic-gate  * attributes        = wattribute *( space wattribute )
2070Sstevel@tonic-gate  * wattribute        = whsp newAttribute whsp
2080Sstevel@tonic-gate  * newAttribute      = descr | "*NULL*"
2090Sstevel@tonic-gate  * attribute         = descr
2100Sstevel@tonic-gate  *
2110Sstevel@tonic-gate  * objectclassMap syntax:
2120Sstevel@tonic-gate  * objectclassMap    = serviceId ":" origObjectclass "="
2130Sstevel@tonic-gate  * 			objectclass
2140Sstevel@tonic-gate  * origObjectclass   = objectclass
2150Sstevel@tonic-gate  * objectclass       = keystring
2160Sstevel@tonic-gate  */
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate int
__s_api_parse_map(char * cp,char ** sid,char ** origA,char *** mapA)2190Sstevel@tonic-gate __s_api_parse_map(char *cp, char **sid, char **origA, char ***mapA)
2200Sstevel@tonic-gate {
2210Sstevel@tonic-gate 	char	*sptr, *dptr, **mapp;
2220Sstevel@tonic-gate 	int	i, max;
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate 	*sid = NULL;
2250Sstevel@tonic-gate 	*origA = NULL;
2260Sstevel@tonic-gate 	*mapA = NULL;
2270Sstevel@tonic-gate 
2280Sstevel@tonic-gate 	sptr = cp;
2290Sstevel@tonic-gate 	dptr = strchr(sptr, COLONTOK);
2300Sstevel@tonic-gate 	if (dptr == NULL)
2310Sstevel@tonic-gate 		return (NS_HASH_RC_SYNTAX_ERROR);
2320Sstevel@tonic-gate 	i = dptr - sptr + 1;
2330Sstevel@tonic-gate 	*sid = (char *)malloc(i);
2340Sstevel@tonic-gate 	if (*sid == NULL)
2350Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2360Sstevel@tonic-gate 	(void) strlcpy(*sid, sptr, i);
2370Sstevel@tonic-gate 	sptr = dptr+1;
2380Sstevel@tonic-gate 
2390Sstevel@tonic-gate 	dptr = strchr(sptr, TOKENSEPARATOR);
2400Sstevel@tonic-gate 	if (dptr == NULL) {
2410Sstevel@tonic-gate 		free(*sid);
2420Sstevel@tonic-gate 		*sid = NULL;
2430Sstevel@tonic-gate 		return (NS_HASH_RC_SYNTAX_ERROR);
2440Sstevel@tonic-gate 	}
2450Sstevel@tonic-gate 	i = dptr - sptr + 1;
2460Sstevel@tonic-gate 	*origA = (char *)malloc(i);
2470Sstevel@tonic-gate 	if (*origA == NULL) {
2480Sstevel@tonic-gate 		free(*sid);
2490Sstevel@tonic-gate 		*sid = NULL;
2500Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2510Sstevel@tonic-gate 	}
2520Sstevel@tonic-gate 	(void) strlcpy(*origA, sptr, i);
2530Sstevel@tonic-gate 	sptr = dptr+1;
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate 	max = 1;
2560Sstevel@tonic-gate 	for (dptr = sptr; *dptr; dptr++) {
2570Sstevel@tonic-gate 		if (*dptr == SPACETOK) {
2580Sstevel@tonic-gate 			max++;
2590Sstevel@tonic-gate 			while (*(dptr+1) == SPACETOK)
2600Sstevel@tonic-gate 				dptr++;
2610Sstevel@tonic-gate 		}
2620Sstevel@tonic-gate 	}
2630Sstevel@tonic-gate 	*mapA = (char **)calloc(max+1, sizeof (char *));
2640Sstevel@tonic-gate 	if (*mapA == NULL) {
2650Sstevel@tonic-gate 		free(*sid);
2660Sstevel@tonic-gate 		*sid = NULL;
2670Sstevel@tonic-gate 		free(*origA);
2680Sstevel@tonic-gate 		*origA = NULL;
2690Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2700Sstevel@tonic-gate 	}
2710Sstevel@tonic-gate 	mapp = *mapA;
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 	while (*sptr) {
2740Sstevel@tonic-gate 		while (*sptr == SPACETOK)
2750Sstevel@tonic-gate 			sptr++;
2760Sstevel@tonic-gate 		dptr = sptr;
2770Sstevel@tonic-gate 		while (*dptr && *dptr != SPACETOK)
2780Sstevel@tonic-gate 			dptr++;
2790Sstevel@tonic-gate 		i = dptr - sptr + 1;
2800Sstevel@tonic-gate 		*mapp = (char *)malloc(i);
2810Sstevel@tonic-gate 		if (*mapp == NULL) {
2820Sstevel@tonic-gate 			free(*sid);
2830Sstevel@tonic-gate 			*sid = NULL;
2840Sstevel@tonic-gate 			free(*origA);
2850Sstevel@tonic-gate 			*origA = NULL;
2860Sstevel@tonic-gate 			__s_api_free2dArray(*mapA);
2870Sstevel@tonic-gate 			*mapA = NULL;
2880Sstevel@tonic-gate 			return (NS_HASH_RC_NO_MEMORY);
2890Sstevel@tonic-gate 		}
2900Sstevel@tonic-gate 		(void) strlcpy(*mapp, sptr, i);
2910Sstevel@tonic-gate 		mapp++;
2920Sstevel@tonic-gate 		sptr = dptr;
2930Sstevel@tonic-gate 	}
2940Sstevel@tonic-gate 	return (NS_HASH_RC_SUCCESS);
2950Sstevel@tonic-gate }
2960Sstevel@tonic-gate 
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate static void
__ns_ldap_freeASearchDesc(ns_ldap_search_desc_t * ptr)2990Sstevel@tonic-gate __ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *ptr)
3000Sstevel@tonic-gate {
3010Sstevel@tonic-gate 	if (ptr == NULL)
3020Sstevel@tonic-gate 		return;
3030Sstevel@tonic-gate 	if (ptr->basedn)
3040Sstevel@tonic-gate 		free(ptr->basedn);
3050Sstevel@tonic-gate 	if (ptr->filter)
3060Sstevel@tonic-gate 		free(ptr->filter);
3070Sstevel@tonic-gate 	free(ptr);
3080Sstevel@tonic-gate }
3090Sstevel@tonic-gate 
3100Sstevel@tonic-gate /*
3110Sstevel@tonic-gate  * Parse a service descriptor
3120Sstevel@tonic-gate  * and create a service descriptor struct
3130Sstevel@tonic-gate  * SD Format:
3140Sstevel@tonic-gate  *    serviceid:[base][?[scope][?[filter]]];[[base][?[scope][?[filter]]]]
3150Sstevel@tonic-gate  * desc format:
3160Sstevel@tonic-gate  *    [base][?[scope][?[filter]]]
3170Sstevel@tonic-gate  */
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate typedef enum _ns_parse_state {
3200Sstevel@tonic-gate 	P_ERROR, P_INIT, P_BASEDN, P_SCOPE,
3210Sstevel@tonic-gate 	P_INIFILTER, P_FILTER, P_END, P_EXIT, P_MEMERR
3220Sstevel@tonic-gate } _ns_parse_state_t;
3230Sstevel@tonic-gate 
3240Sstevel@tonic-gate static
3250Sstevel@tonic-gate int
__s_api_parseASearchDesc(const char * service,char ** cur,ns_ldap_search_desc_t ** ret)3260Sstevel@tonic-gate __s_api_parseASearchDesc(const char *service,
3270Sstevel@tonic-gate 	char **cur, ns_ldap_search_desc_t **ret)
3280Sstevel@tonic-gate {
3290Sstevel@tonic-gate 	ns_ldap_search_desc_t	*ptr;
3300Sstevel@tonic-gate 	char			*sptr, *dptr;
3310Sstevel@tonic-gate 	char			buf[BUFSIZ];
3320Sstevel@tonic-gate 	int			i, rc;
3330Sstevel@tonic-gate 	ns_ldap_error_t		**errorp = NULL;
3340Sstevel@tonic-gate 	ns_ldap_error_t		*error = NULL;
3350Sstevel@tonic-gate 	void			**paramVal = NULL;
3360Sstevel@tonic-gate 	char			**dns = NULL;
3370Sstevel@tonic-gate 	_ns_parse_state_t	state = P_INIT;
3380Sstevel@tonic-gate 	int			quoted = 0;
3390Sstevel@tonic-gate 	int			wasquoted = 0;
3400Sstevel@tonic-gate 	int			empty = 1;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	if (ret == NULL)
3430Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
3440Sstevel@tonic-gate 	*ret = NULL;
3450Sstevel@tonic-gate 	if (cur == NULL)
3460Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 	ptr = (ns_ldap_search_desc_t *)
349*12758SJulian.Pullen@Sun.COM 	    calloc(1, sizeof (ns_ldap_search_desc_t));
3500Sstevel@tonic-gate 	if (ptr == NULL)
3510Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 	sptr = *cur;
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	/* Get the default scope */
3560Sstevel@tonic-gate 	if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
357*12758SJulian.Pullen@Sun.COM 	    &paramVal, errorp)) != NS_LDAP_SUCCESS) {
3580Sstevel@tonic-gate 		(void) __ns_ldap_freeError(errorp);
3590Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
3600Sstevel@tonic-gate 		ptr = NULL;
3610Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3620Sstevel@tonic-gate 	}
3630Sstevel@tonic-gate 	if (paramVal && *paramVal)
3640Sstevel@tonic-gate 		ptr->scope = * (ScopeType_t *)(*paramVal);
3650Sstevel@tonic-gate 	else
3660Sstevel@tonic-gate 		ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
3670Sstevel@tonic-gate 	(void) __ns_ldap_freeParam(&paramVal);
3680Sstevel@tonic-gate 	paramVal = NULL;
3690Sstevel@tonic-gate 
3700Sstevel@tonic-gate 	for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) {
3710Sstevel@tonic-gate 		empty = 0;
3720Sstevel@tonic-gate 		switch (state) {
3730Sstevel@tonic-gate 		case P_INIT:
3740Sstevel@tonic-gate 			if (*sptr == QUESTTOK) {
3750Sstevel@tonic-gate 				/* No basedn */
3760Sstevel@tonic-gate 				ptr->basedn = strdup("");
3770Sstevel@tonic-gate 				if (!ptr->basedn) {
3780Sstevel@tonic-gate 					state = P_MEMERR;
3790Sstevel@tonic-gate 					break;
3800Sstevel@tonic-gate 				}
3810Sstevel@tonic-gate 				state = P_SCOPE;
3820Sstevel@tonic-gate 				break;
3830Sstevel@tonic-gate 			}
3840Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
3850Sstevel@tonic-gate 				/* No SSD */
3860Sstevel@tonic-gate 				ptr->basedn = strdup("");
3870Sstevel@tonic-gate 				if (!ptr->basedn) {
3880Sstevel@tonic-gate 					state = P_MEMERR;
3890Sstevel@tonic-gate 					break;
3900Sstevel@tonic-gate 				}
3910Sstevel@tonic-gate 				state = P_EXIT;
3920Sstevel@tonic-gate 				break;
3930Sstevel@tonic-gate 			}
3940Sstevel@tonic-gate 			/* prepare to copy DN */
3950Sstevel@tonic-gate 			i = strlen(sptr) + 1;
3960Sstevel@tonic-gate 			ptr->basedn = dptr = (char *)calloc(i, sizeof (char));
3970Sstevel@tonic-gate 			if (!ptr->basedn) {
3980Sstevel@tonic-gate 				state = P_MEMERR;
3990Sstevel@tonic-gate 				break;
4000Sstevel@tonic-gate 			}
4010Sstevel@tonic-gate 			if (*sptr == BSLTOK) {
4020Sstevel@tonic-gate 				if (*(sptr+1) == '\0') {
4030Sstevel@tonic-gate 					/* error */
4040Sstevel@tonic-gate 					state = P_ERROR;
4050Sstevel@tonic-gate 					break;
4060Sstevel@tonic-gate 				}
4070Sstevel@tonic-gate 				if (*(sptr+1) == QUOTETOK ||
4080Sstevel@tonic-gate 				    *(sptr+1) == BSLTOK) {
4090Sstevel@tonic-gate 					/* escaped CHARS */
4100Sstevel@tonic-gate 					sptr++;
4110Sstevel@tonic-gate 				} else {
4120Sstevel@tonic-gate 					*dptr++ = *sptr++;
4130Sstevel@tonic-gate 				}
4140Sstevel@tonic-gate 				*dptr++ = *sptr;
4150Sstevel@tonic-gate 			} else if (*sptr == QUOTETOK) {
4160Sstevel@tonic-gate 				quoted = 1;
4170Sstevel@tonic-gate 				wasquoted = 1;
4180Sstevel@tonic-gate 			} else {
4190Sstevel@tonic-gate 				*dptr++ = *sptr;
4200Sstevel@tonic-gate 			}
4210Sstevel@tonic-gate 			state = P_BASEDN;
4220Sstevel@tonic-gate 			break;
4230Sstevel@tonic-gate 		case P_INIFILTER:
4240Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
4250Sstevel@tonic-gate 				/* No filter and no more SSD */
4260Sstevel@tonic-gate 				state = P_EXIT;
4270Sstevel@tonic-gate 				break;
4280Sstevel@tonic-gate 			}
4290Sstevel@tonic-gate 			/* prepare to copy DN */
4300Sstevel@tonic-gate 			i = strlen(sptr) + 1;
4310Sstevel@tonic-gate 			ptr->filter = dptr = (char *)calloc(i, sizeof (char));
4320Sstevel@tonic-gate 			if (!ptr->filter) {
4330Sstevel@tonic-gate 				state = P_MEMERR;
4340Sstevel@tonic-gate 				break;
4350Sstevel@tonic-gate 			}
4360Sstevel@tonic-gate 			if (*sptr == BSLTOK) {
4370Sstevel@tonic-gate 				if (*(sptr+1) == '\0') {
4380Sstevel@tonic-gate 					/* error */
4390Sstevel@tonic-gate 					state = P_ERROR;
4400Sstevel@tonic-gate 					break;
4410Sstevel@tonic-gate 				}
4420Sstevel@tonic-gate 				if (*(sptr+1) == QUOTETOK ||
4430Sstevel@tonic-gate 				    *(sptr+1) == BSLTOK) {
4440Sstevel@tonic-gate 					/* escaped CHARS */
4450Sstevel@tonic-gate 					sptr++;
4460Sstevel@tonic-gate 				} else {
4470Sstevel@tonic-gate 					*dptr++ = *sptr++;
4480Sstevel@tonic-gate 				}
4490Sstevel@tonic-gate 				*dptr++ = *sptr;
4500Sstevel@tonic-gate 			} else if (*sptr == QUOTETOK) {
4510Sstevel@tonic-gate 				quoted = 1;
4520Sstevel@tonic-gate 				wasquoted = 1;
4530Sstevel@tonic-gate 			} else {
4540Sstevel@tonic-gate 				*dptr++ = *sptr;
4550Sstevel@tonic-gate 			}
4560Sstevel@tonic-gate 			state = P_FILTER;
4570Sstevel@tonic-gate 			break;
4580Sstevel@tonic-gate 		case P_SCOPE:
4590Sstevel@tonic-gate 			buf[0] = '\0';
4600Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
4610Sstevel@tonic-gate 				/* no more SSD */
4620Sstevel@tonic-gate 				state = P_EXIT;
4630Sstevel@tonic-gate 				break;
4640Sstevel@tonic-gate 			}
4650Sstevel@tonic-gate 			if (strncasecmp(sptr, "base", 4) == 0) {
4660Sstevel@tonic-gate 				sptr += 4;
4670Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_BASE;
4680Sstevel@tonic-gate 			} else if (strncasecmp(sptr, "one", 3) == 0) {
4690Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
4700Sstevel@tonic-gate 				sptr += 3;
4710Sstevel@tonic-gate 			} else if (strncasecmp(sptr, "sub", 3) == 0) {
4720Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_SUBTREE;
4730Sstevel@tonic-gate 				sptr += 3;
4740Sstevel@tonic-gate 			}
4750Sstevel@tonic-gate 			if (*sptr == '\0' || (*sptr == SEMITOK)) {
4760Sstevel@tonic-gate 				/* no more SSD */
4770Sstevel@tonic-gate 				state = P_EXIT;
4780Sstevel@tonic-gate 				sptr--;
4790Sstevel@tonic-gate 				break;
4800Sstevel@tonic-gate 			}
4810Sstevel@tonic-gate 			if (*sptr != QUESTTOK) {
4820Sstevel@tonic-gate 				state = P_ERROR;
4830Sstevel@tonic-gate 				break;
4840Sstevel@tonic-gate 			}
4850Sstevel@tonic-gate 			state = P_INIFILTER;
4860Sstevel@tonic-gate 			quoted = 0;
4870Sstevel@tonic-gate 			wasquoted = 0;
4880Sstevel@tonic-gate 			break;
4890Sstevel@tonic-gate 		case P_BASEDN:
4900Sstevel@tonic-gate 		case P_FILTER:
4910Sstevel@tonic-gate 			if (quoted) {
4920Sstevel@tonic-gate 				/* Quoted */
4930Sstevel@tonic-gate 				if (*sptr == BSLTOK) {
4940Sstevel@tonic-gate 					if (*(sptr+1) == '\0') {
4950Sstevel@tonic-gate 						state = P_ERROR;
4960Sstevel@tonic-gate 						break;
4970Sstevel@tonic-gate 					}
4980Sstevel@tonic-gate 					if (*(sptr+1) == QUOTETOK ||
4990Sstevel@tonic-gate 					    *(sptr+1) == BSLTOK) {
5000Sstevel@tonic-gate 						/* escaped CHARS */
5010Sstevel@tonic-gate 						sptr++;
5020Sstevel@tonic-gate 					} else {
5030Sstevel@tonic-gate 						*dptr++ = *sptr++;
5040Sstevel@tonic-gate 					}
5050Sstevel@tonic-gate 					/* fall through to char copy */
5060Sstevel@tonic-gate 				} else if (*sptr == QUOTETOK) {
5070Sstevel@tonic-gate 					/* end of string */
5080Sstevel@tonic-gate 					*dptr = '\0';
5090Sstevel@tonic-gate 					quoted = 0;
5100Sstevel@tonic-gate 					break;
5110Sstevel@tonic-gate 				}
5120Sstevel@tonic-gate 				/* else fall through to char copy */
5130Sstevel@tonic-gate 			} else {
5140Sstevel@tonic-gate 				/* Unquoted */
5150Sstevel@tonic-gate 				if (wasquoted && *sptr != QUESTTOK) {
5160Sstevel@tonic-gate 					/* error  past end of quoted string */
5170Sstevel@tonic-gate 					state = P_ERROR;
5180Sstevel@tonic-gate 					break;
5190Sstevel@tonic-gate 				}
5200Sstevel@tonic-gate 				if (*sptr == BSLTOK) {
5210Sstevel@tonic-gate 					if (*(sptr+1) == '\0') {
5220Sstevel@tonic-gate 						state = P_ERROR;
5230Sstevel@tonic-gate 						break;
5240Sstevel@tonic-gate 					}
5250Sstevel@tonic-gate 					if (*(sptr+1) == SEMITOK ||
5260Sstevel@tonic-gate 					    *(sptr+1) == QUESTTOK ||
5270Sstevel@tonic-gate 					    *(sptr+1) == QUOTETOK ||
5280Sstevel@tonic-gate 					    *(sptr+1) == BSLTOK) {
5290Sstevel@tonic-gate 						/* escaped chars */
5300Sstevel@tonic-gate 						sptr++;
5310Sstevel@tonic-gate 					}
5320Sstevel@tonic-gate 					/* fall through to char copy */
5330Sstevel@tonic-gate 				} else if (*sptr == QUOTETOK) {
5340Sstevel@tonic-gate 					/* error */
5350Sstevel@tonic-gate 					state = P_ERROR;
5360Sstevel@tonic-gate 					break;
5370Sstevel@tonic-gate 				} else if (*sptr == QUESTTOK) {
5380Sstevel@tonic-gate 					/* if filter error */
5390Sstevel@tonic-gate 					if (state == P_FILTER) {
5400Sstevel@tonic-gate 						state = P_ERROR;
5410Sstevel@tonic-gate 						break;
5420Sstevel@tonic-gate 					}
5430Sstevel@tonic-gate 					/* end of basedn goto scope */
5440Sstevel@tonic-gate 					*dptr = '\0';
5450Sstevel@tonic-gate 					state = P_SCOPE;
5460Sstevel@tonic-gate 					break;
5470Sstevel@tonic-gate 				} else if (*sptr == SEMITOK) {
5480Sstevel@tonic-gate 					/* end of current SSD */
5490Sstevel@tonic-gate 					*dptr = '\0';
5500Sstevel@tonic-gate 					state = P_EXIT;
5510Sstevel@tonic-gate 					break;
5520Sstevel@tonic-gate 				}
5530Sstevel@tonic-gate 			}
5540Sstevel@tonic-gate 			/* normal character to copy */
5550Sstevel@tonic-gate 			*dptr++ = *sptr;
5560Sstevel@tonic-gate 			break;
5570Sstevel@tonic-gate 		case P_END:
5580Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
5590Sstevel@tonic-gate 				state = P_EXIT;
5600Sstevel@tonic-gate 				break;
5610Sstevel@tonic-gate 			}
5620Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5630Sstevel@tonic-gate 			ptr = NULL;
5640Sstevel@tonic-gate 			*cur = NULL;
5650Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
5660Sstevel@tonic-gate 		default:	 /* error should never arrive here */
5670Sstevel@tonic-gate 		case P_ERROR:
5680Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5690Sstevel@tonic-gate 			ptr = NULL;
5700Sstevel@tonic-gate 			*cur = NULL;
5710Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
5720Sstevel@tonic-gate 		case P_MEMERR:
5730Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5740Sstevel@tonic-gate 			ptr = NULL;
5750Sstevel@tonic-gate 			*cur = NULL;
5760Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
5770Sstevel@tonic-gate 		}
5780Sstevel@tonic-gate 	}
5790Sstevel@tonic-gate 
5800Sstevel@tonic-gate 	if (quoted) {
5810Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
5820Sstevel@tonic-gate 		ptr = NULL;
5830Sstevel@tonic-gate 		*cur = NULL;
5840Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
5850Sstevel@tonic-gate 	}
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	if (empty || strlen(ptr->basedn) == 0) {
5880Sstevel@tonic-gate 		if (ptr->basedn)
5890Sstevel@tonic-gate 			free(ptr->basedn);
5900Sstevel@tonic-gate 		/* get default base */
5910Sstevel@tonic-gate 		rc = __s_api_getDNs(&dns, service, &error);
5920Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS) {
5930Sstevel@tonic-gate 			if (dns) {
5940Sstevel@tonic-gate 				__s_api_free2dArray(dns);
5950Sstevel@tonic-gate 				dns = NULL;
5960Sstevel@tonic-gate 			}
5970Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&error);
5980Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5990Sstevel@tonic-gate 			ptr = NULL;
6000Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
6010Sstevel@tonic-gate 		}
6020Sstevel@tonic-gate 		ptr->basedn = strdup(dns[0]);
6030Sstevel@tonic-gate 		__s_api_free2dArray(dns);
6040Sstevel@tonic-gate 		dns = NULL;
6050Sstevel@tonic-gate 	}
6060Sstevel@tonic-gate 
6070Sstevel@tonic-gate 	*cur = sptr;
6080Sstevel@tonic-gate 	*ret = ptr;
6090Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
6100Sstevel@tonic-gate }
6110Sstevel@tonic-gate 
6120Sstevel@tonic-gate 
6130Sstevel@tonic-gate /*
6140Sstevel@tonic-gate  * Build up the service descriptor array
6150Sstevel@tonic-gate  */
6160Sstevel@tonic-gate #define	NS_SDESC_MAX	4
6170Sstevel@tonic-gate 
6180Sstevel@tonic-gate static int
__ns_ldap_saveSearchDesc(ns_ldap_search_desc_t *** sdlist,int * cnt,int * max,ns_ldap_search_desc_t * ret)6190Sstevel@tonic-gate __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist,
6200Sstevel@tonic-gate 	int *cnt, int *max, ns_ldap_search_desc_t *ret)
6210Sstevel@tonic-gate {
6220Sstevel@tonic-gate 	ns_ldap_search_desc_t	**tmplist;
6230Sstevel@tonic-gate 
6240Sstevel@tonic-gate 	if (*sdlist == NULL) {
6250Sstevel@tonic-gate 		*cnt = 0;
6260Sstevel@tonic-gate 		*max = NS_SDESC_MAX;
6270Sstevel@tonic-gate 		*sdlist = (ns_ldap_search_desc_t **)
628*12758SJulian.Pullen@Sun.COM 		    calloc(*max, sizeof (ns_ldap_search_desc_t *));
6290Sstevel@tonic-gate 		if (*sdlist == NULL)
6300Sstevel@tonic-gate 			return (-1);
6310Sstevel@tonic-gate 	} else if (*cnt+1 >= *max) {
6320Sstevel@tonic-gate 		*max += NS_SDESC_MAX;
6330Sstevel@tonic-gate 		tmplist = (ns_ldap_search_desc_t **)
634*12758SJulian.Pullen@Sun.COM 		    realloc((void *)(*sdlist),
635*12758SJulian.Pullen@Sun.COM 		    *max * sizeof (ns_ldap_search_desc_t *));
6360Sstevel@tonic-gate 		if (tmplist == NULL)
6370Sstevel@tonic-gate 			return (-1);
6380Sstevel@tonic-gate 		else
6390Sstevel@tonic-gate 			*sdlist = tmplist;
6400Sstevel@tonic-gate 	}
6410Sstevel@tonic-gate 	(*sdlist)[*cnt] = ret;
6420Sstevel@tonic-gate 	(*cnt)++;
6430Sstevel@tonic-gate 	(*sdlist)[*cnt] = NULL;
6440Sstevel@tonic-gate 	return (0);
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 
6480Sstevel@tonic-gate /*
6490Sstevel@tonic-gate  * Exported Search Descriptor Routines
6500Sstevel@tonic-gate  */
6510Sstevel@tonic-gate 
__ns_ldap_getSearchDescriptors(const char * service,ns_ldap_search_desc_t *** desc,ns_ldap_error_t ** errorp)6520Sstevel@tonic-gate int __ns_ldap_getSearchDescriptors(
6530Sstevel@tonic-gate 	const char *service,
6540Sstevel@tonic-gate 	ns_ldap_search_desc_t ***desc,
6550Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
6560Sstevel@tonic-gate {
6570Sstevel@tonic-gate 	int			rc;
6580Sstevel@tonic-gate 	int			slen;
6590Sstevel@tonic-gate 	void			**param = NULL;
6600Sstevel@tonic-gate 	void			**paramVal = NULL;
6610Sstevel@tonic-gate 	char			**sdl, *srv, **sdl_save;
6620Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
6630Sstevel@tonic-gate 	ns_ldap_search_desc_t	**sdlist;
6640Sstevel@tonic-gate 	int			cnt, max;
6650Sstevel@tonic-gate 	int			vers;
6660Sstevel@tonic-gate 	ns_config_t		*cfg;
6670Sstevel@tonic-gate 	ns_ldap_search_desc_t 	*ret;
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	if ((desc == NULL) || (errorp == NULL))
6700Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 	*desc = NULL;
6730Sstevel@tonic-gate 	*errorp = NULL;
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P,
676*12758SJulian.Pullen@Sun.COM 	    (void ***)&param, errorp);
6770Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
6780Sstevel@tonic-gate 		return (rc);
6790Sstevel@tonic-gate 	}
6800Sstevel@tonic-gate 	sdl = (char **)param;
6810Sstevel@tonic-gate 	cnt = 0;
6820Sstevel@tonic-gate 	max = 0;
6830Sstevel@tonic-gate 	sdlist = NULL;
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
6860Sstevel@tonic-gate 
6870Sstevel@tonic-gate 	if (cfg == NULL) {
6880Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
6890Sstevel@tonic-gate 		    gettext("No configuration information available."));
6900Sstevel@tonic-gate 		MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
691*12758SJulian.Pullen@Sun.COM 		    NULL);
6920Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
6930Sstevel@tonic-gate 	}
6940Sstevel@tonic-gate 
6950Sstevel@tonic-gate 	vers = cfg->version;
6960Sstevel@tonic-gate 	__s_api_release_config(cfg);
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	/* If using version1 or no sd's process SEARCH_DN if available */
6990Sstevel@tonic-gate 	if (vers == NS_LDAP_V1 && param == NULL) {
7000Sstevel@tonic-gate 		rc = __s_api_get_search_DNs_v1(&sdl, service, errorp);
7010Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS || sdl == NULL) {
7020Sstevel@tonic-gate 			return (rc);
7030Sstevel@tonic-gate 		}
7040Sstevel@tonic-gate 		sdl_save = sdl;
7050Sstevel@tonic-gate 		/* Convert a SEARCH_DN to a search descriptor */
7060Sstevel@tonic-gate 		for (; *sdl; sdl++) {
7070Sstevel@tonic-gate 			ret = (ns_ldap_search_desc_t *)
708*12758SJulian.Pullen@Sun.COM 			    calloc(1, sizeof (ns_ldap_search_desc_t));
7090Sstevel@tonic-gate 			if (ret == NULL) {
7100Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7110Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7120Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7130Sstevel@tonic-gate 			}
7140Sstevel@tonic-gate 			ret->basedn = strdup(*sdl);
7150Sstevel@tonic-gate 			if (ret->basedn == NULL) {
7160Sstevel@tonic-gate 				free(ret);
7170Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7180Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7190Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7200Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7210Sstevel@tonic-gate 			}
7220Sstevel@tonic-gate 
7230Sstevel@tonic-gate 			/* default scope */
7240Sstevel@tonic-gate 			if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
725*12758SJulian.Pullen@Sun.COM 			    &paramVal, errorp)) != NS_LDAP_SUCCESS) {
7260Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7270Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7280Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7290Sstevel@tonic-gate 				return (rc);
7300Sstevel@tonic-gate 			}
7310Sstevel@tonic-gate 			if (paramVal && *paramVal)
7320Sstevel@tonic-gate 				ret->scope = * (ScopeType_t *)(*paramVal);
7330Sstevel@tonic-gate 			else
7340Sstevel@tonic-gate 				ret->scope = NS_LDAP_SCOPE_ONELEVEL;
7350Sstevel@tonic-gate 			(void) __ns_ldap_freeParam(&paramVal);
7360Sstevel@tonic-gate 			paramVal = NULL;
7370Sstevel@tonic-gate 
7380Sstevel@tonic-gate 			rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret);
7390Sstevel@tonic-gate 			if (rc < 0) {
7400Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7410Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7420Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7430Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7440Sstevel@tonic-gate 			}
7450Sstevel@tonic-gate 		}
7460Sstevel@tonic-gate 		__s_api_free2dArray(sdl_save);
7470Sstevel@tonic-gate 		*desc = sdlist;
7480Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
7490Sstevel@tonic-gate 	}
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	if (sdl == NULL || service == NULL) {
7520Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&param);
7530Sstevel@tonic-gate 		param = NULL;
7540Sstevel@tonic-gate 		*desc = NULL;
7550Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
7560Sstevel@tonic-gate 	}
7570Sstevel@tonic-gate 	slen = strlen(service);
7580Sstevel@tonic-gate 
7590Sstevel@tonic-gate 	/* Process the version2 sd's */
7600Sstevel@tonic-gate 	for (; *sdl; sdl++) {
7610Sstevel@tonic-gate 		srv = *sdl;
7620Sstevel@tonic-gate 		if (strncasecmp(service, srv, slen) != 0)
7630Sstevel@tonic-gate 			continue;
7640Sstevel@tonic-gate 		srv += slen;
7650Sstevel@tonic-gate 		if (*srv != COLONTOK)
7660Sstevel@tonic-gate 			continue;
7670Sstevel@tonic-gate 		srv++;
7680Sstevel@tonic-gate 		while (srv != NULL && *srv != NULL) {
7690Sstevel@tonic-gate 			/* Process 1 */
7700Sstevel@tonic-gate 			rc = __s_api_parseASearchDesc(service, &srv, &ret);
7710Sstevel@tonic-gate 			if (rc != NS_LDAP_SUCCESS) {
7720Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7730Sstevel@tonic-gate 				(void) snprintf(errstr, (2 * MAXERROR), gettext(
774*12758SJulian.Pullen@Sun.COM 				    "Invalid serviceSearchDescriptor (%s). "
775*12758SJulian.Pullen@Sun.COM 				    "Illegal configuration"), *sdl);
7760Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&param);
7770Sstevel@tonic-gate 				param = NULL;
7780Sstevel@tonic-gate 				MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
779*12758SJulian.Pullen@Sun.COM 				    strdup(errstr), NULL);
7800Sstevel@tonic-gate 				return (rc);
7810Sstevel@tonic-gate 			}
7820Sstevel@tonic-gate 			if (ret != NULL) {
7830Sstevel@tonic-gate 				rc = __ns_ldap_saveSearchDesc(
784*12758SJulian.Pullen@Sun.COM 				    &sdlist, &cnt, &max, ret);
7850Sstevel@tonic-gate 			}
7860Sstevel@tonic-gate 			if (rc < 0) {
7870Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7880Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&param);
7890Sstevel@tonic-gate 				param = NULL;
7900Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7910Sstevel@tonic-gate 			}
7920Sstevel@tonic-gate 		}
7930Sstevel@tonic-gate 	}
7940Sstevel@tonic-gate 
7950Sstevel@tonic-gate 	(void) __ns_ldap_freeParam(&param);
7960Sstevel@tonic-gate 	param = NULL;
7970Sstevel@tonic-gate 	*desc = sdlist;
7980Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
7990Sstevel@tonic-gate }
8000Sstevel@tonic-gate 
8010Sstevel@tonic-gate int
__ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t *** desc)8020Sstevel@tonic-gate __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc)
8030Sstevel@tonic-gate {
8040Sstevel@tonic-gate 	ns_ldap_search_desc_t **dptr;
8050Sstevel@tonic-gate 	ns_ldap_search_desc_t *ptr;
8060Sstevel@tonic-gate 
8070Sstevel@tonic-gate 	if (*desc == NULL)
8080Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
8090Sstevel@tonic-gate 	for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) {
8100Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
8110Sstevel@tonic-gate 	}
8120Sstevel@tonic-gate 	free(*desc);
8130Sstevel@tonic-gate 	*desc = NULL;
8140Sstevel@tonic-gate 
8150Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
8160Sstevel@tonic-gate }
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate 
8210Sstevel@tonic-gate /*
8220Sstevel@tonic-gate  * Exported Attribute/Objectclass mapping functions.
8230Sstevel@tonic-gate  */
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate /*
8260Sstevel@tonic-gate  * This function is not supported.
8270Sstevel@tonic-gate  */
8280Sstevel@tonic-gate /* ARGSUSED */
__ns_ldap_getAttributeMaps(const char * service,ns_ldap_attribute_map_t *** maps,ns_ldap_error_t ** errorp)8290Sstevel@tonic-gate int __ns_ldap_getAttributeMaps(
8300Sstevel@tonic-gate 	const char *service,
8310Sstevel@tonic-gate 	ns_ldap_attribute_map_t ***maps,
8320Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
8330Sstevel@tonic-gate {
8340Sstevel@tonic-gate 	*maps = NULL;
8350Sstevel@tonic-gate 	return (NS_LDAP_OP_FAILED);
8360Sstevel@tonic-gate }
8370Sstevel@tonic-gate 
8380Sstevel@tonic-gate int
__ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t *** maps)8390Sstevel@tonic-gate __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps)
8400Sstevel@tonic-gate {
8410Sstevel@tonic-gate 	ns_ldap_attribute_map_t **dptr;
8420Sstevel@tonic-gate 	ns_ldap_attribute_map_t *ptr;
8430Sstevel@tonic-gate 	char **cpp, *cp;
8440Sstevel@tonic-gate 
8450Sstevel@tonic-gate 	if (*maps == NULL)
8460Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
8470Sstevel@tonic-gate 	for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
8480Sstevel@tonic-gate 		if (ptr->origAttr) {
8490Sstevel@tonic-gate 			free(ptr->origAttr);
8500Sstevel@tonic-gate 			ptr->origAttr = NULL;
8510Sstevel@tonic-gate 		}
8520Sstevel@tonic-gate 		if (ptr->mappedAttr) {
8530Sstevel@tonic-gate 			for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++)
8540Sstevel@tonic-gate 				free(cp);
8550Sstevel@tonic-gate 			free(ptr->mappedAttr);
8560Sstevel@tonic-gate 			ptr->mappedAttr = NULL;
8570Sstevel@tonic-gate 		}
8580Sstevel@tonic-gate 		free(ptr);
8590Sstevel@tonic-gate 	}
8600Sstevel@tonic-gate 	free(*maps);
8610Sstevel@tonic-gate 	*maps = NULL;
8620Sstevel@tonic-gate 
8630Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
8640Sstevel@tonic-gate }
8650Sstevel@tonic-gate 
__ns_ldap_getMappedAttributes(const char * service,const char * origAttribute)8660Sstevel@tonic-gate char **__ns_ldap_getMappedAttributes(
8670Sstevel@tonic-gate 	const char *service,
8680Sstevel@tonic-gate 	const char *origAttribute)
8690Sstevel@tonic-gate {
8700Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
8710Sstevel@tonic-gate 	ns_hash_t	*hp;
8720Sstevel@tonic-gate 	char		**ret;
8730Sstevel@tonic-gate 
8740Sstevel@tonic-gate 	if (ptr == NULL)
8750Sstevel@tonic-gate 		return (NULL);
8760Sstevel@tonic-gate 
8770Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute);
8780Sstevel@tonic-gate 
8790Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
8800Sstevel@tonic-gate 		ret = NULL;
8810Sstevel@tonic-gate 	else
8820Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
8830Sstevel@tonic-gate 	__s_api_release_config(ptr);
8840Sstevel@tonic-gate 	return (ret);
8850Sstevel@tonic-gate }
8860Sstevel@tonic-gate 
__ns_ldap_getOrigAttribute(const char * service,const char * mappedAttribute)8870Sstevel@tonic-gate char **__ns_ldap_getOrigAttribute(
8880Sstevel@tonic-gate 	const char *service,
8890Sstevel@tonic-gate 	const char *mappedAttribute)
8900Sstevel@tonic-gate {
8910Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
8920Sstevel@tonic-gate 	ns_hash_t	*hp;
8930Sstevel@tonic-gate 	char		**ret;
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 	if (ptr == NULL)
8960Sstevel@tonic-gate 		return (NULL);
8970Sstevel@tonic-gate 
8980Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute);
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9010Sstevel@tonic-gate 		ret = NULL;
9020Sstevel@tonic-gate 	else
9030Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9040Sstevel@tonic-gate 	__s_api_release_config(ptr);
9050Sstevel@tonic-gate 	return (ret);
9060Sstevel@tonic-gate }
9070Sstevel@tonic-gate 
9080Sstevel@tonic-gate /*
9090Sstevel@tonic-gate  * This function is not supported.
9100Sstevel@tonic-gate  */
9110Sstevel@tonic-gate /* ARGSUSED */
__ns_ldap_getObjectClassMaps(const char * service,ns_ldap_objectclass_map_t *** maps,ns_ldap_error_t ** errorp)9120Sstevel@tonic-gate int __ns_ldap_getObjectClassMaps(
9130Sstevel@tonic-gate 	const char *service,
9140Sstevel@tonic-gate 	ns_ldap_objectclass_map_t ***maps,
9150Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
9160Sstevel@tonic-gate {
9170Sstevel@tonic-gate 	*maps = NULL;
9180Sstevel@tonic-gate 	return (NS_LDAP_OP_FAILED);
9190Sstevel@tonic-gate }
9200Sstevel@tonic-gate 
9210Sstevel@tonic-gate int
__ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t *** maps)9220Sstevel@tonic-gate __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps)
9230Sstevel@tonic-gate {
9240Sstevel@tonic-gate 	ns_ldap_objectclass_map_t **dptr;
9250Sstevel@tonic-gate 	ns_ldap_objectclass_map_t *ptr;
9260Sstevel@tonic-gate 
9270Sstevel@tonic-gate 	if (*maps == NULL)
9280Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
9290Sstevel@tonic-gate 	for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
9300Sstevel@tonic-gate 		if (ptr->origOC) {
9310Sstevel@tonic-gate 			free(ptr->origOC);
9320Sstevel@tonic-gate 			ptr->origOC = NULL;
9330Sstevel@tonic-gate 		}
9340Sstevel@tonic-gate 		if (ptr->mappedOC) {
9350Sstevel@tonic-gate 			free(ptr->mappedOC);
9360Sstevel@tonic-gate 			ptr->mappedOC = NULL;
9370Sstevel@tonic-gate 		}
9380Sstevel@tonic-gate 		free(ptr);
9390Sstevel@tonic-gate 	}
9400Sstevel@tonic-gate 	free(*maps);
9410Sstevel@tonic-gate 	*maps = NULL;
9420Sstevel@tonic-gate 
9430Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
9440Sstevel@tonic-gate }
9450Sstevel@tonic-gate 
__ns_ldap_getMappedObjectClass(const char * service,const char * origObjectClass)9460Sstevel@tonic-gate char **__ns_ldap_getMappedObjectClass(
9470Sstevel@tonic-gate 	const char *service,
9480Sstevel@tonic-gate 	const char *origObjectClass)
9490Sstevel@tonic-gate {
9500Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
9510Sstevel@tonic-gate 	ns_hash_t	*hp;
9520Sstevel@tonic-gate 	char		**ret;
9530Sstevel@tonic-gate 
9540Sstevel@tonic-gate 	if (ptr == NULL)
9550Sstevel@tonic-gate 		return (NULL);
9560Sstevel@tonic-gate 
9570Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass);
9580Sstevel@tonic-gate 
9590Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9600Sstevel@tonic-gate 		ret = NULL;
9610Sstevel@tonic-gate 	else
9620Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9630Sstevel@tonic-gate 	__s_api_release_config(ptr);
9640Sstevel@tonic-gate 	return (ret);
9650Sstevel@tonic-gate }
9660Sstevel@tonic-gate 
__ns_ldap_getOrigObjectClass(const char * service,const char * mappedObjectClass)9670Sstevel@tonic-gate char **__ns_ldap_getOrigObjectClass(
9680Sstevel@tonic-gate 	const char *service,
9690Sstevel@tonic-gate 	const char *mappedObjectClass)
9700Sstevel@tonic-gate {
9710Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
9720Sstevel@tonic-gate 	ns_hash_t	*hp;
9730Sstevel@tonic-gate 	char		**ret;
9740Sstevel@tonic-gate 
9750Sstevel@tonic-gate 	if (ptr == NULL)
9760Sstevel@tonic-gate 		return (NULL);
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass);
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9810Sstevel@tonic-gate 		ret = NULL;
9820Sstevel@tonic-gate 	else
9830Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9840Sstevel@tonic-gate 	__s_api_release_config(ptr);
9850Sstevel@tonic-gate 	return (ret);
9860Sstevel@tonic-gate }
9870Sstevel@tonic-gate 
__ns_ldap_mapAttributeList(const char * service,const char * const * origAttrList)9880Sstevel@tonic-gate char **__ns_ldap_mapAttributeList(
9890Sstevel@tonic-gate 	const char *service,
9900Sstevel@tonic-gate 	const char * const *origAttrList)
9910Sstevel@tonic-gate {
9920Sstevel@tonic-gate 	const char * const *opp;
9930Sstevel@tonic-gate 	char **cpp, **npp;
9940Sstevel@tonic-gate 	int i;
9950Sstevel@tonic-gate 
9960Sstevel@tonic-gate 	if (origAttrList == NULL)
9970Sstevel@tonic-gate 		return (NULL);
9980Sstevel@tonic-gate 
9990Sstevel@tonic-gate 	opp = origAttrList;
10000Sstevel@tonic-gate 	for (i = 0; *opp; i++, opp++)
10010Sstevel@tonic-gate 		;
10020Sstevel@tonic-gate 	cpp = (char **)calloc(i+1, sizeof (char *));
10030Sstevel@tonic-gate 	if (cpp == NULL)
10040Sstevel@tonic-gate 		return (NULL);
10050Sstevel@tonic-gate 
10060Sstevel@tonic-gate 	opp = origAttrList;
10070Sstevel@tonic-gate 	for (i = 0; *opp; i++, opp++) {
10080Sstevel@tonic-gate 		npp =  __ns_ldap_getMappedAttributes(service, *opp);
10090Sstevel@tonic-gate 		if (npp && npp[0]) {
10100Sstevel@tonic-gate 			cpp[i] = strdup(npp[0]);
10110Sstevel@tonic-gate 			__s_api_free2dArray(npp);
10120Sstevel@tonic-gate 			npp = NULL;
10130Sstevel@tonic-gate 			if (cpp[i] == NULL) {
10140Sstevel@tonic-gate 				__s_api_free2dArray(cpp);
10150Sstevel@tonic-gate 				return (NULL);
10160Sstevel@tonic-gate 			}
10170Sstevel@tonic-gate 		} else {
10180Sstevel@tonic-gate 			cpp[i] = strdup(*opp);
10190Sstevel@tonic-gate 			if (cpp[i] == NULL) {
10200Sstevel@tonic-gate 				__s_api_free2dArray(cpp);
10210Sstevel@tonic-gate 				return (NULL);
10220Sstevel@tonic-gate 			}
10230Sstevel@tonic-gate 		}
10240Sstevel@tonic-gate 	}
10250Sstevel@tonic-gate 	return (cpp);
10260Sstevel@tonic-gate }
1027*12758SJulian.Pullen@Sun.COM 
1028*12758SJulian.Pullen@Sun.COM char *
__ns_ldap_mapAttribute(const char * service,const char * origAttr)1029*12758SJulian.Pullen@Sun.COM __ns_ldap_mapAttribute(
1030*12758SJulian.Pullen@Sun.COM 	const char *service,
1031*12758SJulian.Pullen@Sun.COM 	const char *origAttr)
1032*12758SJulian.Pullen@Sun.COM {
1033*12758SJulian.Pullen@Sun.COM 	char **npp;
1034*12758SJulian.Pullen@Sun.COM 	char *mappedAttr;
1035*12758SJulian.Pullen@Sun.COM 
1036*12758SJulian.Pullen@Sun.COM 	if (origAttr == NULL)
1037*12758SJulian.Pullen@Sun.COM 		return (NULL);
1038*12758SJulian.Pullen@Sun.COM 
1039*12758SJulian.Pullen@Sun.COM 	npp = __ns_ldap_getMappedAttributes(service, origAttr);
1040*12758SJulian.Pullen@Sun.COM 	if (npp && npp[0]) {
1041*12758SJulian.Pullen@Sun.COM 		mappedAttr = strdup(npp[0]);
1042*12758SJulian.Pullen@Sun.COM 		__s_api_free2dArray(npp);
1043*12758SJulian.Pullen@Sun.COM 	} else {
1044*12758SJulian.Pullen@Sun.COM 		mappedAttr = strdup(origAttr);
1045*12758SJulian.Pullen@Sun.COM 	}
1046*12758SJulian.Pullen@Sun.COM 	return (mappedAttr);
1047*12758SJulian.Pullen@Sun.COM }
1048