xref: /titanic_52/usr/src/lib/libsldap/common/ns_mapping.c (revision 9f2fd570dfad3c35512617ae887140b15e3ec4c5)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*9f2fd570SJulian Pullen  * Common Development and Distribution License (the "License").
6*9f2fd570SJulian Pullen  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*9f2fd570SJulian Pullen  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #include <stdlib.h>
267c478bd9Sstevel@tonic-gate #include <strings.h>
277c478bd9Sstevel@tonic-gate #include <ctype.h>
287c478bd9Sstevel@tonic-gate #include <locale.h>
297c478bd9Sstevel@tonic-gate #include <syslog.h>
307c478bd9Sstevel@tonic-gate #include "ns_internal.h"
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate  * Calculate a hash for a string
347c478bd9Sstevel@tonic-gate  * Based on elf_hash algorithm, hash is case insensitive
357c478bd9Sstevel@tonic-gate  * Uses tolower instead of _tolower because of I18N
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate static unsigned long
397c478bd9Sstevel@tonic-gate ns_hash(const char *str)
407c478bd9Sstevel@tonic-gate {
417c478bd9Sstevel@tonic-gate 	unsigned int	hval = 0;
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate 	while (*str) {
447c478bd9Sstevel@tonic-gate 		unsigned int	g;
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate 		hval = (hval << 4) + tolower(*str++);
477c478bd9Sstevel@tonic-gate 		if ((g = (hval & 0xf0000000)) != 0)
487c478bd9Sstevel@tonic-gate 			hval ^= g >> 24;
497c478bd9Sstevel@tonic-gate 		hval &= ~g;
507c478bd9Sstevel@tonic-gate 	}
517c478bd9Sstevel@tonic-gate 	return ((unsigned long)hval);
527c478bd9Sstevel@tonic-gate }
537c478bd9Sstevel@tonic-gate 
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate  * Scan a hash table hit for a matching hash entry.
567c478bd9Sstevel@tonic-gate  * Assume service and str are non-NULL.
577c478bd9Sstevel@tonic-gate  */
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate static ns_hash_t *
607c478bd9Sstevel@tonic-gate ns_scan_hash(ns_hashtype_t type, const char *service,
617c478bd9Sstevel@tonic-gate 		const char *str, ns_hash_t *idx)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	while (idx) {
647c478bd9Sstevel@tonic-gate 		if (idx->h_type == type &&
657c478bd9Sstevel@tonic-gate 		    strcasecmp(service, idx->h_map->service) == 0 &&
667c478bd9Sstevel@tonic-gate 		    strcasecmp(str, idx->h_map->orig) == 0) {
677c478bd9Sstevel@tonic-gate 			return (idx);
687c478bd9Sstevel@tonic-gate 		}
697c478bd9Sstevel@tonic-gate 		idx = idx->h_next;
707c478bd9Sstevel@tonic-gate 	}
717c478bd9Sstevel@tonic-gate 	return ((ns_hash_t *)NULL);
727c478bd9Sstevel@tonic-gate }
737c478bd9Sstevel@tonic-gate 
747c478bd9Sstevel@tonic-gate /*
757c478bd9Sstevel@tonic-gate  * Find an entry in the hash table
767c478bd9Sstevel@tonic-gate  */
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate static ns_hash_t *
797c478bd9Sstevel@tonic-gate ns_get_hash(const ns_config_t *config,
807c478bd9Sstevel@tonic-gate 	    ns_hashtype_t type, const char *service, const char *str)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	ns_hash_t	*idx, *hashp;
837c478bd9Sstevel@tonic-gate 	unsigned long	hash;
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate 	if (config == NULL || service == NULL || str == NULL)
867c478bd9Sstevel@tonic-gate 		return (NULL);
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate 	hash = ns_hash(str) % NS_HASH_MAX;
897c478bd9Sstevel@tonic-gate 	idx = config->hashTbl[hash];
907c478bd9Sstevel@tonic-gate 	hashp = ns_scan_hash(type, service, str, idx);
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate 	return (hashp);
937c478bd9Sstevel@tonic-gate }
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate /*
967c478bd9Sstevel@tonic-gate  * free a map entry
977c478bd9Sstevel@tonic-gate  */
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate static void
1007c478bd9Sstevel@tonic-gate ns_free_map(ns_mapping_t *mapp)
1017c478bd9Sstevel@tonic-gate {
1027c478bd9Sstevel@tonic-gate 	char	**ptr;
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate 	if (mapp == NULL)
1057c478bd9Sstevel@tonic-gate 		return;
1067c478bd9Sstevel@tonic-gate 	if (mapp->service) {
1077c478bd9Sstevel@tonic-gate 		free(mapp->service);
1087c478bd9Sstevel@tonic-gate 		mapp->service = NULL;
1097c478bd9Sstevel@tonic-gate 	}
1107c478bd9Sstevel@tonic-gate 	if (mapp->orig) {
1117c478bd9Sstevel@tonic-gate 		free(mapp->orig);
1127c478bd9Sstevel@tonic-gate 		mapp->orig = NULL;
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 	if (mapp->map) {
1157c478bd9Sstevel@tonic-gate 		for (ptr = mapp->map; *ptr; ptr++)
1167c478bd9Sstevel@tonic-gate 			free(*ptr);
1177c478bd9Sstevel@tonic-gate 		free(mapp->map);
1187c478bd9Sstevel@tonic-gate 		mapp->map = NULL;
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 	free(mapp);
1217c478bd9Sstevel@tonic-gate }
1227c478bd9Sstevel@tonic-gate 
1237c478bd9Sstevel@tonic-gate /*
1247c478bd9Sstevel@tonic-gate  * Remove a hash table entry.
1257c478bd9Sstevel@tonic-gate  * This function is not MT safe.
1267c478bd9Sstevel@tonic-gate  */
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate static ns_hash_t *
1297c478bd9Sstevel@tonic-gate ns_free_hash(ns_hash_t *p)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate 	ns_mapping_t	*map;
1327c478bd9Sstevel@tonic-gate 	ns_hash_t	*next;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	map = p->h_map;
1357c478bd9Sstevel@tonic-gate 	next = p->h_next;
1367c478bd9Sstevel@tonic-gate 	ns_free_map(map);
1377c478bd9Sstevel@tonic-gate 	free(p);
1387c478bd9Sstevel@tonic-gate 	return (next);
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate 
1417c478bd9Sstevel@tonic-gate /*
1427c478bd9Sstevel@tonic-gate  * destroy the hash table.
1437c478bd9Sstevel@tonic-gate  * This function is not MT safe.
1447c478bd9Sstevel@tonic-gate  */
1457c478bd9Sstevel@tonic-gate 
1467c478bd9Sstevel@tonic-gate void
1477c478bd9Sstevel@tonic-gate __s_api_destroy_hash(ns_config_t *config)
1487c478bd9Sstevel@tonic-gate {
1497c478bd9Sstevel@tonic-gate 	ns_hash_t	*next;
1507c478bd9Sstevel@tonic-gate 	int		i;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate 	if (config == NULL)
1537c478bd9Sstevel@tonic-gate 		return;
1547c478bd9Sstevel@tonic-gate 	for (i = 0; i < NS_HASH_MAX; i++) {
1557c478bd9Sstevel@tonic-gate 		next = config->hashTbl[i];
1567c478bd9Sstevel@tonic-gate 		while (next != NULL) {
1577c478bd9Sstevel@tonic-gate 			next = ns_free_hash(next);
1587c478bd9Sstevel@tonic-gate 		}
1597c478bd9Sstevel@tonic-gate 		config->hashTbl[i] = NULL;
1607c478bd9Sstevel@tonic-gate 	}
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate /*
1647c478bd9Sstevel@tonic-gate  * Add a hash entry to the hash table.
1657c478bd9Sstevel@tonic-gate  * This function is not MT safe.
1667c478bd9Sstevel@tonic-gate  * Assume map, map->orig, map->service are non-NULL.
1677c478bd9Sstevel@tonic-gate  */
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate int
1707c478bd9Sstevel@tonic-gate __s_api_add_map2hash(ns_config_t *config, ns_hashtype_t type,
1717c478bd9Sstevel@tonic-gate 			ns_mapping_t *map)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate 	ns_hash_t	*idx, *newp;
1747c478bd9Sstevel@tonic-gate 	unsigned long	hash;
1757c478bd9Sstevel@tonic-gate 
1767c478bd9Sstevel@tonic-gate 	if (config == NULL)
1777c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_CONFIG_ERROR);
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 	hash = ns_hash(map->orig) % NS_HASH_MAX;
1807c478bd9Sstevel@tonic-gate 	idx = config->hashTbl[hash];
1817c478bd9Sstevel@tonic-gate 	if (idx != NULL &&
1827c478bd9Sstevel@tonic-gate 	    ns_scan_hash(type, map->service, map->orig, idx) != NULL) {
1837c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_EXISTED);
1847c478bd9Sstevel@tonic-gate 	}
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	newp = (ns_hash_t *)malloc(sizeof (ns_hash_t));
1877c478bd9Sstevel@tonic-gate 	if (newp == NULL)
1887c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
1897c478bd9Sstevel@tonic-gate 	newp->h_type = type;
1907c478bd9Sstevel@tonic-gate 	newp->h_map = map;
1917c478bd9Sstevel@tonic-gate 	newp->h_next = idx;
1927c478bd9Sstevel@tonic-gate 	config->hashTbl[hash] = newp;
1937c478bd9Sstevel@tonic-gate 	newp->h_llnext = config->llHead;
1947c478bd9Sstevel@tonic-gate 	config->llHead = newp;
1957c478bd9Sstevel@tonic-gate 	return (NS_HASH_RC_SUCCESS);
1967c478bd9Sstevel@tonic-gate }
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate /*
2007c478bd9Sstevel@tonic-gate  * Parse an attribute map string.
2017c478bd9Sstevel@tonic-gate  * Assume space is the only legal whitespace.
2027c478bd9Sstevel@tonic-gate  * attributeMap syntax:
2037c478bd9Sstevel@tonic-gate  * attributeMap      = serviceId ":" origAttribute "="
2047c478bd9Sstevel@tonic-gate  * 			attributes
2057c478bd9Sstevel@tonic-gate  * origAttribute     = attribute
2067c478bd9Sstevel@tonic-gate  * attributes        = wattribute *( space wattribute )
2077c478bd9Sstevel@tonic-gate  * wattribute        = whsp newAttribute whsp
2087c478bd9Sstevel@tonic-gate  * newAttribute      = descr | "*NULL*"
2097c478bd9Sstevel@tonic-gate  * attribute         = descr
2107c478bd9Sstevel@tonic-gate  *
2117c478bd9Sstevel@tonic-gate  * objectclassMap syntax:
2127c478bd9Sstevel@tonic-gate  * objectclassMap    = serviceId ":" origObjectclass "="
2137c478bd9Sstevel@tonic-gate  * 			objectclass
2147c478bd9Sstevel@tonic-gate  * origObjectclass   = objectclass
2157c478bd9Sstevel@tonic-gate  * objectclass       = keystring
2167c478bd9Sstevel@tonic-gate  */
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate int
2197c478bd9Sstevel@tonic-gate __s_api_parse_map(char *cp, char **sid, char **origA, char ***mapA)
2207c478bd9Sstevel@tonic-gate {
2217c478bd9Sstevel@tonic-gate 	char	*sptr, *dptr, **mapp;
2227c478bd9Sstevel@tonic-gate 	int	i, max;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate 	*sid = NULL;
2257c478bd9Sstevel@tonic-gate 	*origA = NULL;
2267c478bd9Sstevel@tonic-gate 	*mapA = NULL;
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 	sptr = cp;
2297c478bd9Sstevel@tonic-gate 	dptr = strchr(sptr, COLONTOK);
2307c478bd9Sstevel@tonic-gate 	if (dptr == NULL)
2317c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_SYNTAX_ERROR);
2327c478bd9Sstevel@tonic-gate 	i = dptr - sptr + 1;
2337c478bd9Sstevel@tonic-gate 	*sid = (char *)malloc(i);
2347c478bd9Sstevel@tonic-gate 	if (*sid == NULL)
2357c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2367c478bd9Sstevel@tonic-gate 	(void) strlcpy(*sid, sptr, i);
2377c478bd9Sstevel@tonic-gate 	sptr = dptr+1;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	dptr = strchr(sptr, TOKENSEPARATOR);
2407c478bd9Sstevel@tonic-gate 	if (dptr == NULL) {
2417c478bd9Sstevel@tonic-gate 		free(*sid);
2427c478bd9Sstevel@tonic-gate 		*sid = NULL;
2437c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_SYNTAX_ERROR);
2447c478bd9Sstevel@tonic-gate 	}
2457c478bd9Sstevel@tonic-gate 	i = dptr - sptr + 1;
2467c478bd9Sstevel@tonic-gate 	*origA = (char *)malloc(i);
2477c478bd9Sstevel@tonic-gate 	if (*origA == NULL) {
2487c478bd9Sstevel@tonic-gate 		free(*sid);
2497c478bd9Sstevel@tonic-gate 		*sid = NULL;
2507c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2517c478bd9Sstevel@tonic-gate 	}
2527c478bd9Sstevel@tonic-gate 	(void) strlcpy(*origA, sptr, i);
2537c478bd9Sstevel@tonic-gate 	sptr = dptr+1;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	max = 1;
2567c478bd9Sstevel@tonic-gate 	for (dptr = sptr; *dptr; dptr++) {
2577c478bd9Sstevel@tonic-gate 		if (*dptr == SPACETOK) {
2587c478bd9Sstevel@tonic-gate 			max++;
2597c478bd9Sstevel@tonic-gate 			while (*(dptr+1) == SPACETOK)
2607c478bd9Sstevel@tonic-gate 				dptr++;
2617c478bd9Sstevel@tonic-gate 		}
2627c478bd9Sstevel@tonic-gate 	}
2637c478bd9Sstevel@tonic-gate 	*mapA = (char **)calloc(max+1, sizeof (char *));
2647c478bd9Sstevel@tonic-gate 	if (*mapA == NULL) {
2657c478bd9Sstevel@tonic-gate 		free(*sid);
2667c478bd9Sstevel@tonic-gate 		*sid = NULL;
2677c478bd9Sstevel@tonic-gate 		free(*origA);
2687c478bd9Sstevel@tonic-gate 		*origA = NULL;
2697c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2707c478bd9Sstevel@tonic-gate 	}
2717c478bd9Sstevel@tonic-gate 	mapp = *mapA;
2727c478bd9Sstevel@tonic-gate 
2737c478bd9Sstevel@tonic-gate 	while (*sptr) {
2747c478bd9Sstevel@tonic-gate 		while (*sptr == SPACETOK)
2757c478bd9Sstevel@tonic-gate 			sptr++;
2767c478bd9Sstevel@tonic-gate 		dptr = sptr;
2777c478bd9Sstevel@tonic-gate 		while (*dptr && *dptr != SPACETOK)
2787c478bd9Sstevel@tonic-gate 			dptr++;
2797c478bd9Sstevel@tonic-gate 		i = dptr - sptr + 1;
2807c478bd9Sstevel@tonic-gate 		*mapp = (char *)malloc(i);
2817c478bd9Sstevel@tonic-gate 		if (*mapp == NULL) {
2827c478bd9Sstevel@tonic-gate 			free(*sid);
2837c478bd9Sstevel@tonic-gate 			*sid = NULL;
2847c478bd9Sstevel@tonic-gate 			free(*origA);
2857c478bd9Sstevel@tonic-gate 			*origA = NULL;
2867c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(*mapA);
2877c478bd9Sstevel@tonic-gate 			*mapA = NULL;
2887c478bd9Sstevel@tonic-gate 			return (NS_HASH_RC_NO_MEMORY);
2897c478bd9Sstevel@tonic-gate 		}
2907c478bd9Sstevel@tonic-gate 		(void) strlcpy(*mapp, sptr, i);
2917c478bd9Sstevel@tonic-gate 		mapp++;
2927c478bd9Sstevel@tonic-gate 		sptr = dptr;
2937c478bd9Sstevel@tonic-gate 	}
2947c478bd9Sstevel@tonic-gate 	return (NS_HASH_RC_SUCCESS);
2957c478bd9Sstevel@tonic-gate }
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate static void
2997c478bd9Sstevel@tonic-gate __ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *ptr)
3007c478bd9Sstevel@tonic-gate {
3017c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
3027c478bd9Sstevel@tonic-gate 		return;
3037c478bd9Sstevel@tonic-gate 	if (ptr->basedn)
3047c478bd9Sstevel@tonic-gate 		free(ptr->basedn);
3057c478bd9Sstevel@tonic-gate 	if (ptr->filter)
3067c478bd9Sstevel@tonic-gate 		free(ptr->filter);
3077c478bd9Sstevel@tonic-gate 	free(ptr);
3087c478bd9Sstevel@tonic-gate }
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate /*
3117c478bd9Sstevel@tonic-gate  * Parse a service descriptor
3127c478bd9Sstevel@tonic-gate  * and create a service descriptor struct
3137c478bd9Sstevel@tonic-gate  * SD Format:
3147c478bd9Sstevel@tonic-gate  *    serviceid:[base][?[scope][?[filter]]];[[base][?[scope][?[filter]]]]
3157c478bd9Sstevel@tonic-gate  * desc format:
3167c478bd9Sstevel@tonic-gate  *    [base][?[scope][?[filter]]]
3177c478bd9Sstevel@tonic-gate  */
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate typedef enum _ns_parse_state {
3207c478bd9Sstevel@tonic-gate 	P_ERROR, P_INIT, P_BASEDN, P_SCOPE,
3217c478bd9Sstevel@tonic-gate 	P_INIFILTER, P_FILTER, P_END, P_EXIT, P_MEMERR
3227c478bd9Sstevel@tonic-gate } _ns_parse_state_t;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate static
3257c478bd9Sstevel@tonic-gate int
3267c478bd9Sstevel@tonic-gate __s_api_parseASearchDesc(const char *service,
3277c478bd9Sstevel@tonic-gate 	char **cur, ns_ldap_search_desc_t **ret)
3287c478bd9Sstevel@tonic-gate {
3297c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t	*ptr;
3307c478bd9Sstevel@tonic-gate 	char			*sptr, *dptr;
3317c478bd9Sstevel@tonic-gate 	char			buf[BUFSIZ];
3327c478bd9Sstevel@tonic-gate 	int			i, rc;
3337c478bd9Sstevel@tonic-gate 	ns_ldap_error_t		**errorp = NULL;
3347c478bd9Sstevel@tonic-gate 	ns_ldap_error_t		*error = NULL;
3357c478bd9Sstevel@tonic-gate 	void			**paramVal = NULL;
3367c478bd9Sstevel@tonic-gate 	char			**dns = NULL;
3377c478bd9Sstevel@tonic-gate 	_ns_parse_state_t	state = P_INIT;
3387c478bd9Sstevel@tonic-gate 	int			quoted = 0;
3397c478bd9Sstevel@tonic-gate 	int			wasquoted = 0;
3407c478bd9Sstevel@tonic-gate 	int			empty = 1;
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate 	if (ret == NULL)
3437c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
3447c478bd9Sstevel@tonic-gate 	*ret = NULL;
3457c478bd9Sstevel@tonic-gate 	if (cur == NULL)
3467c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	ptr = (ns_ldap_search_desc_t *)
3497c478bd9Sstevel@tonic-gate 	    calloc(1, sizeof (ns_ldap_search_desc_t));
3507c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
3517c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 	sptr = *cur;
3547c478bd9Sstevel@tonic-gate 
3557c478bd9Sstevel@tonic-gate 	/* Get the default scope */
3567c478bd9Sstevel@tonic-gate 	if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
3577c478bd9Sstevel@tonic-gate 	    &paramVal, errorp)) != NS_LDAP_SUCCESS) {
3587c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeError(errorp);
3597c478bd9Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
3607c478bd9Sstevel@tonic-gate 		ptr = NULL;
3617c478bd9Sstevel@tonic-gate 		return (NS_LDAP_MEMORY);
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 	if (paramVal && *paramVal)
3647c478bd9Sstevel@tonic-gate 		ptr->scope = * (ScopeType_t *)(*paramVal);
3657c478bd9Sstevel@tonic-gate 	else
3667c478bd9Sstevel@tonic-gate 		ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
3677c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeParam(&paramVal);
3687c478bd9Sstevel@tonic-gate 	paramVal = NULL;
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	for (/* none */; state != P_EXIT && sptr && *sptr; sptr++) {
3717c478bd9Sstevel@tonic-gate 		empty = 0;
3727c478bd9Sstevel@tonic-gate 		switch (state) {
3737c478bd9Sstevel@tonic-gate 		case P_INIT:
3747c478bd9Sstevel@tonic-gate 			if (*sptr == QUESTTOK) {
3757c478bd9Sstevel@tonic-gate 				/* No basedn */
3767c478bd9Sstevel@tonic-gate 				ptr->basedn = strdup("");
3777c478bd9Sstevel@tonic-gate 				if (!ptr->basedn) {
3787c478bd9Sstevel@tonic-gate 					state = P_MEMERR;
3797c478bd9Sstevel@tonic-gate 					break;
3807c478bd9Sstevel@tonic-gate 				}
3817c478bd9Sstevel@tonic-gate 				state = P_SCOPE;
3827c478bd9Sstevel@tonic-gate 				break;
3837c478bd9Sstevel@tonic-gate 			}
3847c478bd9Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
3857c478bd9Sstevel@tonic-gate 				/* No SSD */
3867c478bd9Sstevel@tonic-gate 				ptr->basedn = strdup("");
3877c478bd9Sstevel@tonic-gate 				if (!ptr->basedn) {
3887c478bd9Sstevel@tonic-gate 					state = P_MEMERR;
3897c478bd9Sstevel@tonic-gate 					break;
3907c478bd9Sstevel@tonic-gate 				}
3917c478bd9Sstevel@tonic-gate 				state = P_EXIT;
3927c478bd9Sstevel@tonic-gate 				break;
3937c478bd9Sstevel@tonic-gate 			}
3947c478bd9Sstevel@tonic-gate 			/* prepare to copy DN */
3957c478bd9Sstevel@tonic-gate 			i = strlen(sptr) + 1;
3967c478bd9Sstevel@tonic-gate 			ptr->basedn = dptr = (char *)calloc(i, sizeof (char));
3977c478bd9Sstevel@tonic-gate 			if (!ptr->basedn) {
3987c478bd9Sstevel@tonic-gate 				state = P_MEMERR;
3997c478bd9Sstevel@tonic-gate 				break;
4007c478bd9Sstevel@tonic-gate 			}
4017c478bd9Sstevel@tonic-gate 			if (*sptr == BSLTOK) {
4027c478bd9Sstevel@tonic-gate 				if (*(sptr+1) == '\0') {
4037c478bd9Sstevel@tonic-gate 					/* error */
4047c478bd9Sstevel@tonic-gate 					state = P_ERROR;
4057c478bd9Sstevel@tonic-gate 					break;
4067c478bd9Sstevel@tonic-gate 				}
4077c478bd9Sstevel@tonic-gate 				if (*(sptr+1) == QUOTETOK ||
4087c478bd9Sstevel@tonic-gate 				    *(sptr+1) == BSLTOK) {
4097c478bd9Sstevel@tonic-gate 					/* escaped CHARS */
4107c478bd9Sstevel@tonic-gate 					sptr++;
4117c478bd9Sstevel@tonic-gate 				} else {
4127c478bd9Sstevel@tonic-gate 					*dptr++ = *sptr++;
4137c478bd9Sstevel@tonic-gate 				}
4147c478bd9Sstevel@tonic-gate 				*dptr++ = *sptr;
4157c478bd9Sstevel@tonic-gate 			} else if (*sptr == QUOTETOK) {
4167c478bd9Sstevel@tonic-gate 				quoted = 1;
4177c478bd9Sstevel@tonic-gate 				wasquoted = 1;
4187c478bd9Sstevel@tonic-gate 			} else {
4197c478bd9Sstevel@tonic-gate 				*dptr++ = *sptr;
4207c478bd9Sstevel@tonic-gate 			}
4217c478bd9Sstevel@tonic-gate 			state = P_BASEDN;
4227c478bd9Sstevel@tonic-gate 			break;
4237c478bd9Sstevel@tonic-gate 		case P_INIFILTER:
4247c478bd9Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
4257c478bd9Sstevel@tonic-gate 				/* No filter and no more SSD */
4267c478bd9Sstevel@tonic-gate 				state = P_EXIT;
4277c478bd9Sstevel@tonic-gate 				break;
4287c478bd9Sstevel@tonic-gate 			}
4297c478bd9Sstevel@tonic-gate 			/* prepare to copy DN */
4307c478bd9Sstevel@tonic-gate 			i = strlen(sptr) + 1;
4317c478bd9Sstevel@tonic-gate 			ptr->filter = dptr = (char *)calloc(i, sizeof (char));
4327c478bd9Sstevel@tonic-gate 			if (!ptr->filter) {
4337c478bd9Sstevel@tonic-gate 				state = P_MEMERR;
4347c478bd9Sstevel@tonic-gate 				break;
4357c478bd9Sstevel@tonic-gate 			}
4367c478bd9Sstevel@tonic-gate 			if (*sptr == BSLTOK) {
4377c478bd9Sstevel@tonic-gate 				if (*(sptr+1) == '\0') {
4387c478bd9Sstevel@tonic-gate 					/* error */
4397c478bd9Sstevel@tonic-gate 					state = P_ERROR;
4407c478bd9Sstevel@tonic-gate 					break;
4417c478bd9Sstevel@tonic-gate 				}
4427c478bd9Sstevel@tonic-gate 				if (*(sptr+1) == QUOTETOK ||
4437c478bd9Sstevel@tonic-gate 				    *(sptr+1) == BSLTOK) {
4447c478bd9Sstevel@tonic-gate 					/* escaped CHARS */
4457c478bd9Sstevel@tonic-gate 					sptr++;
4467c478bd9Sstevel@tonic-gate 				} else {
4477c478bd9Sstevel@tonic-gate 					*dptr++ = *sptr++;
4487c478bd9Sstevel@tonic-gate 				}
4497c478bd9Sstevel@tonic-gate 				*dptr++ = *sptr;
4507c478bd9Sstevel@tonic-gate 			} else if (*sptr == QUOTETOK) {
4517c478bd9Sstevel@tonic-gate 				quoted = 1;
4527c478bd9Sstevel@tonic-gate 				wasquoted = 1;
4537c478bd9Sstevel@tonic-gate 			} else {
4547c478bd9Sstevel@tonic-gate 				*dptr++ = *sptr;
4557c478bd9Sstevel@tonic-gate 			}
4567c478bd9Sstevel@tonic-gate 			state = P_FILTER;
4577c478bd9Sstevel@tonic-gate 			break;
4587c478bd9Sstevel@tonic-gate 		case P_SCOPE:
4597c478bd9Sstevel@tonic-gate 			buf[0] = '\0';
4607c478bd9Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
4617c478bd9Sstevel@tonic-gate 				/* no more SSD */
4627c478bd9Sstevel@tonic-gate 				state = P_EXIT;
4637c478bd9Sstevel@tonic-gate 				break;
4647c478bd9Sstevel@tonic-gate 			}
4657c478bd9Sstevel@tonic-gate 			if (strncasecmp(sptr, "base", 4) == 0) {
4667c478bd9Sstevel@tonic-gate 				sptr += 4;
4677c478bd9Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_BASE;
4687c478bd9Sstevel@tonic-gate 			} else if (strncasecmp(sptr, "one", 3) == 0) {
4697c478bd9Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
4707c478bd9Sstevel@tonic-gate 				sptr += 3;
4717c478bd9Sstevel@tonic-gate 			} else if (strncasecmp(sptr, "sub", 3) == 0) {
4727c478bd9Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_SUBTREE;
4737c478bd9Sstevel@tonic-gate 				sptr += 3;
4747c478bd9Sstevel@tonic-gate 			}
4757c478bd9Sstevel@tonic-gate 			if (*sptr == '\0' || (*sptr == SEMITOK)) {
4767c478bd9Sstevel@tonic-gate 				/* no more SSD */
4777c478bd9Sstevel@tonic-gate 				state = P_EXIT;
4787c478bd9Sstevel@tonic-gate 				sptr--;
4797c478bd9Sstevel@tonic-gate 				break;
4807c478bd9Sstevel@tonic-gate 			}
4817c478bd9Sstevel@tonic-gate 			if (*sptr != QUESTTOK) {
4827c478bd9Sstevel@tonic-gate 				state = P_ERROR;
4837c478bd9Sstevel@tonic-gate 				break;
4847c478bd9Sstevel@tonic-gate 			}
4857c478bd9Sstevel@tonic-gate 			state = P_INIFILTER;
4867c478bd9Sstevel@tonic-gate 			quoted = 0;
4877c478bd9Sstevel@tonic-gate 			wasquoted = 0;
4887c478bd9Sstevel@tonic-gate 			break;
4897c478bd9Sstevel@tonic-gate 		case P_BASEDN:
4907c478bd9Sstevel@tonic-gate 		case P_FILTER:
4917c478bd9Sstevel@tonic-gate 			if (quoted) {
4927c478bd9Sstevel@tonic-gate 				/* Quoted */
4937c478bd9Sstevel@tonic-gate 				if (*sptr == BSLTOK) {
4947c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == '\0') {
4957c478bd9Sstevel@tonic-gate 						state = P_ERROR;
4967c478bd9Sstevel@tonic-gate 						break;
4977c478bd9Sstevel@tonic-gate 					}
4987c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == QUOTETOK ||
4997c478bd9Sstevel@tonic-gate 					    *(sptr+1) == BSLTOK) {
5007c478bd9Sstevel@tonic-gate 						/* escaped CHARS */
5017c478bd9Sstevel@tonic-gate 						sptr++;
5027c478bd9Sstevel@tonic-gate 					} else {
5037c478bd9Sstevel@tonic-gate 						*dptr++ = *sptr++;
5047c478bd9Sstevel@tonic-gate 					}
5057c478bd9Sstevel@tonic-gate 					/* fall through to char copy */
5067c478bd9Sstevel@tonic-gate 				} else if (*sptr == QUOTETOK) {
5077c478bd9Sstevel@tonic-gate 					/* end of string */
5087c478bd9Sstevel@tonic-gate 					*dptr = '\0';
5097c478bd9Sstevel@tonic-gate 					quoted = 0;
5107c478bd9Sstevel@tonic-gate 					break;
5117c478bd9Sstevel@tonic-gate 				}
5127c478bd9Sstevel@tonic-gate 				/* else fall through to char copy */
5137c478bd9Sstevel@tonic-gate 			} else {
5147c478bd9Sstevel@tonic-gate 				/* Unquoted */
5157c478bd9Sstevel@tonic-gate 				if (wasquoted && *sptr != QUESTTOK) {
5167c478bd9Sstevel@tonic-gate 					/* error  past end of quoted string */
5177c478bd9Sstevel@tonic-gate 					state = P_ERROR;
5187c478bd9Sstevel@tonic-gate 					break;
5197c478bd9Sstevel@tonic-gate 				}
5207c478bd9Sstevel@tonic-gate 				if (*sptr == BSLTOK) {
5217c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == '\0') {
5227c478bd9Sstevel@tonic-gate 						state = P_ERROR;
5237c478bd9Sstevel@tonic-gate 						break;
5247c478bd9Sstevel@tonic-gate 					}
5257c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == SEMITOK ||
5267c478bd9Sstevel@tonic-gate 					    *(sptr+1) == QUESTTOK ||
5277c478bd9Sstevel@tonic-gate 					    *(sptr+1) == QUOTETOK ||
5287c478bd9Sstevel@tonic-gate 					    *(sptr+1) == BSLTOK) {
5297c478bd9Sstevel@tonic-gate 						/* escaped chars */
5307c478bd9Sstevel@tonic-gate 						sptr++;
5317c478bd9Sstevel@tonic-gate 					}
5327c478bd9Sstevel@tonic-gate 					/* fall through to char copy */
5337c478bd9Sstevel@tonic-gate 				} else if (*sptr == QUOTETOK) {
5347c478bd9Sstevel@tonic-gate 					/* error */
5357c478bd9Sstevel@tonic-gate 					state = P_ERROR;
5367c478bd9Sstevel@tonic-gate 					break;
5377c478bd9Sstevel@tonic-gate 				} else if (*sptr == QUESTTOK) {
5387c478bd9Sstevel@tonic-gate 					/* if filter error */
5397c478bd9Sstevel@tonic-gate 					if (state == P_FILTER) {
5407c478bd9Sstevel@tonic-gate 						state = P_ERROR;
5417c478bd9Sstevel@tonic-gate 						break;
5427c478bd9Sstevel@tonic-gate 					}
5437c478bd9Sstevel@tonic-gate 					/* end of basedn goto scope */
5447c478bd9Sstevel@tonic-gate 					*dptr = '\0';
5457c478bd9Sstevel@tonic-gate 					state = P_SCOPE;
5467c478bd9Sstevel@tonic-gate 					break;
5477c478bd9Sstevel@tonic-gate 				} else if (*sptr == SEMITOK) {
5487c478bd9Sstevel@tonic-gate 					/* end of current SSD */
5497c478bd9Sstevel@tonic-gate 					*dptr = '\0';
5507c478bd9Sstevel@tonic-gate 					state = P_EXIT;
5517c478bd9Sstevel@tonic-gate 					break;
5527c478bd9Sstevel@tonic-gate 				}
5537c478bd9Sstevel@tonic-gate 			}
5547c478bd9Sstevel@tonic-gate 			/* normal character to copy */
5557c478bd9Sstevel@tonic-gate 			*dptr++ = *sptr;
5567c478bd9Sstevel@tonic-gate 			break;
5577c478bd9Sstevel@tonic-gate 		case P_END:
5587c478bd9Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
5597c478bd9Sstevel@tonic-gate 				state = P_EXIT;
5607c478bd9Sstevel@tonic-gate 				break;
5617c478bd9Sstevel@tonic-gate 			}
5627c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5637c478bd9Sstevel@tonic-gate 			ptr = NULL;
5647c478bd9Sstevel@tonic-gate 			*cur = NULL;
5657c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
5667c478bd9Sstevel@tonic-gate 		default:	 /* error should never arrive here */
5677c478bd9Sstevel@tonic-gate 		case P_ERROR:
5687c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5697c478bd9Sstevel@tonic-gate 			ptr = NULL;
5707c478bd9Sstevel@tonic-gate 			*cur = NULL;
5717c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
5727c478bd9Sstevel@tonic-gate 		case P_MEMERR:
5737c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5747c478bd9Sstevel@tonic-gate 			ptr = NULL;
5757c478bd9Sstevel@tonic-gate 			*cur = NULL;
5767c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
5777c478bd9Sstevel@tonic-gate 		}
5787c478bd9Sstevel@tonic-gate 	}
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	if (quoted) {
5817c478bd9Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
5827c478bd9Sstevel@tonic-gate 		ptr = NULL;
5837c478bd9Sstevel@tonic-gate 		*cur = NULL;
5847c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
5857c478bd9Sstevel@tonic-gate 	}
5867c478bd9Sstevel@tonic-gate 
5877c478bd9Sstevel@tonic-gate 	if (empty || strlen(ptr->basedn) == 0) {
5887c478bd9Sstevel@tonic-gate 		if (ptr->basedn)
5897c478bd9Sstevel@tonic-gate 			free(ptr->basedn);
5907c478bd9Sstevel@tonic-gate 		/* get default base */
5917c478bd9Sstevel@tonic-gate 		rc = __s_api_getDNs(&dns, service, &error);
5927c478bd9Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS) {
5937c478bd9Sstevel@tonic-gate 			if (dns) {
5947c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(dns);
5957c478bd9Sstevel@tonic-gate 				dns = NULL;
5967c478bd9Sstevel@tonic-gate 			}
5977c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&error);
5987c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5997c478bd9Sstevel@tonic-gate 			ptr = NULL;
6007c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
6017c478bd9Sstevel@tonic-gate 		}
6027c478bd9Sstevel@tonic-gate 		ptr->basedn = strdup(dns[0]);
6037c478bd9Sstevel@tonic-gate 		__s_api_free2dArray(dns);
6047c478bd9Sstevel@tonic-gate 		dns = NULL;
6057c478bd9Sstevel@tonic-gate 	}
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	*cur = sptr;
6087c478bd9Sstevel@tonic-gate 	*ret = ptr;
6097c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate /*
6147c478bd9Sstevel@tonic-gate  * Build up the service descriptor array
6157c478bd9Sstevel@tonic-gate  */
6167c478bd9Sstevel@tonic-gate #define	NS_SDESC_MAX	4
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate static int
6197c478bd9Sstevel@tonic-gate __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist,
6207c478bd9Sstevel@tonic-gate 	int *cnt, int *max, ns_ldap_search_desc_t *ret)
6217c478bd9Sstevel@tonic-gate {
6227c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t	**tmplist;
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate 	if (*sdlist == NULL) {
6257c478bd9Sstevel@tonic-gate 		*cnt = 0;
6267c478bd9Sstevel@tonic-gate 		*max = NS_SDESC_MAX;
6277c478bd9Sstevel@tonic-gate 		*sdlist = (ns_ldap_search_desc_t **)
6287c478bd9Sstevel@tonic-gate 		    calloc(*max, sizeof (ns_ldap_search_desc_t *));
6297c478bd9Sstevel@tonic-gate 		if (*sdlist == NULL)
6307c478bd9Sstevel@tonic-gate 			return (-1);
6317c478bd9Sstevel@tonic-gate 	} else if (*cnt+1 >= *max) {
6327c478bd9Sstevel@tonic-gate 		*max += NS_SDESC_MAX;
6337c478bd9Sstevel@tonic-gate 		tmplist = (ns_ldap_search_desc_t **)
6347c478bd9Sstevel@tonic-gate 		    realloc((void *)(*sdlist),
6357c478bd9Sstevel@tonic-gate 		    *max * sizeof (ns_ldap_search_desc_t *));
6367c478bd9Sstevel@tonic-gate 		if (tmplist == NULL)
6377c478bd9Sstevel@tonic-gate 			return (-1);
6387c478bd9Sstevel@tonic-gate 		else
6397c478bd9Sstevel@tonic-gate 			*sdlist = tmplist;
6407c478bd9Sstevel@tonic-gate 	}
6417c478bd9Sstevel@tonic-gate 	(*sdlist)[*cnt] = ret;
6427c478bd9Sstevel@tonic-gate 	(*cnt)++;
6437c478bd9Sstevel@tonic-gate 	(*sdlist)[*cnt] = NULL;
6447c478bd9Sstevel@tonic-gate 	return (0);
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate /*
6497c478bd9Sstevel@tonic-gate  * Exported Search Descriptor Routines
6507c478bd9Sstevel@tonic-gate  */
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate int __ns_ldap_getSearchDescriptors(
6537c478bd9Sstevel@tonic-gate 	const char *service,
6547c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t ***desc,
6557c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
6567c478bd9Sstevel@tonic-gate {
6577c478bd9Sstevel@tonic-gate 	int			rc;
6587c478bd9Sstevel@tonic-gate 	int			slen;
6597c478bd9Sstevel@tonic-gate 	void			**param = NULL;
6607c478bd9Sstevel@tonic-gate 	void			**paramVal = NULL;
6617c478bd9Sstevel@tonic-gate 	char			**sdl, *srv, **sdl_save;
6627c478bd9Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
6637c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t	**sdlist;
6647c478bd9Sstevel@tonic-gate 	int			cnt, max;
6657c478bd9Sstevel@tonic-gate 	int			vers;
6667c478bd9Sstevel@tonic-gate 	ns_config_t		*cfg;
6677c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t 	*ret;
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 	if ((desc == NULL) || (errorp == NULL))
6707c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
6717c478bd9Sstevel@tonic-gate 
6727c478bd9Sstevel@tonic-gate 	*desc = NULL;
6737c478bd9Sstevel@tonic-gate 	*errorp = NULL;
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P,
6767c478bd9Sstevel@tonic-gate 	    (void ***)&param, errorp);
6777c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
6787c478bd9Sstevel@tonic-gate 		return (rc);
6797c478bd9Sstevel@tonic-gate 	}
6807c478bd9Sstevel@tonic-gate 	sdl = (char **)param;
6817c478bd9Sstevel@tonic-gate 	cnt = 0;
6827c478bd9Sstevel@tonic-gate 	max = 0;
6837c478bd9Sstevel@tonic-gate 	sdlist = NULL;
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
6867c478bd9Sstevel@tonic-gate 
6877c478bd9Sstevel@tonic-gate 	if (cfg == NULL) {
6887c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
6897c478bd9Sstevel@tonic-gate 		    gettext("No configuration information available."));
6907c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
6917c478bd9Sstevel@tonic-gate 		    NULL);
6927c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
6937c478bd9Sstevel@tonic-gate 	}
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate 	vers = cfg->version;
6967c478bd9Sstevel@tonic-gate 	__s_api_release_config(cfg);
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate 	/* If using version1 or no sd's process SEARCH_DN if available */
6997c478bd9Sstevel@tonic-gate 	if (vers == NS_LDAP_V1 && param == NULL) {
7007c478bd9Sstevel@tonic-gate 		rc = __s_api_get_search_DNs_v1(&sdl, service, errorp);
7017c478bd9Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS || sdl == NULL) {
7027c478bd9Sstevel@tonic-gate 			return (rc);
7037c478bd9Sstevel@tonic-gate 		}
7047c478bd9Sstevel@tonic-gate 		sdl_save = sdl;
7057c478bd9Sstevel@tonic-gate 		/* Convert a SEARCH_DN to a search descriptor */
7067c478bd9Sstevel@tonic-gate 		for (; *sdl; sdl++) {
7077c478bd9Sstevel@tonic-gate 			ret = (ns_ldap_search_desc_t *)
7087c478bd9Sstevel@tonic-gate 			    calloc(1, sizeof (ns_ldap_search_desc_t));
7097c478bd9Sstevel@tonic-gate 			if (ret == NULL) {
7107c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7117c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7127c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7137c478bd9Sstevel@tonic-gate 			}
7147c478bd9Sstevel@tonic-gate 			ret->basedn = strdup(*sdl);
7157c478bd9Sstevel@tonic-gate 			if (ret->basedn == NULL) {
7167c478bd9Sstevel@tonic-gate 				free(ret);
7177c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7187c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7197c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7207c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7217c478bd9Sstevel@tonic-gate 			}
7227c478bd9Sstevel@tonic-gate 
7237c478bd9Sstevel@tonic-gate 			/* default scope */
7247c478bd9Sstevel@tonic-gate 			if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
7257c478bd9Sstevel@tonic-gate 			    &paramVal, errorp)) != NS_LDAP_SUCCESS) {
7267c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7277c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7287c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7297c478bd9Sstevel@tonic-gate 				return (rc);
7307c478bd9Sstevel@tonic-gate 			}
7317c478bd9Sstevel@tonic-gate 			if (paramVal && *paramVal)
7327c478bd9Sstevel@tonic-gate 				ret->scope = * (ScopeType_t *)(*paramVal);
7337c478bd9Sstevel@tonic-gate 			else
7347c478bd9Sstevel@tonic-gate 				ret->scope = NS_LDAP_SCOPE_ONELEVEL;
7357c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeParam(&paramVal);
7367c478bd9Sstevel@tonic-gate 			paramVal = NULL;
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 			rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret);
7397c478bd9Sstevel@tonic-gate 			if (rc < 0) {
7407c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7417c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7427c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7437c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7447c478bd9Sstevel@tonic-gate 			}
7457c478bd9Sstevel@tonic-gate 		}
7467c478bd9Sstevel@tonic-gate 		__s_api_free2dArray(sdl_save);
7477c478bd9Sstevel@tonic-gate 		*desc = sdlist;
7487c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
7497c478bd9Sstevel@tonic-gate 	}
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate 	if (sdl == NULL || service == NULL) {
7527c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&param);
7537c478bd9Sstevel@tonic-gate 		param = NULL;
7547c478bd9Sstevel@tonic-gate 		*desc = NULL;
7557c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
7567c478bd9Sstevel@tonic-gate 	}
7577c478bd9Sstevel@tonic-gate 	slen = strlen(service);
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate 	/* Process the version2 sd's */
7607c478bd9Sstevel@tonic-gate 	for (; *sdl; sdl++) {
7617c478bd9Sstevel@tonic-gate 		srv = *sdl;
7627c478bd9Sstevel@tonic-gate 		if (strncasecmp(service, srv, slen) != 0)
7637c478bd9Sstevel@tonic-gate 			continue;
7647c478bd9Sstevel@tonic-gate 		srv += slen;
7657c478bd9Sstevel@tonic-gate 		if (*srv != COLONTOK)
7667c478bd9Sstevel@tonic-gate 			continue;
7677c478bd9Sstevel@tonic-gate 		srv++;
7687c478bd9Sstevel@tonic-gate 		while (srv != NULL && *srv != NULL) {
7697c478bd9Sstevel@tonic-gate 			/* Process 1 */
7707c478bd9Sstevel@tonic-gate 			rc = __s_api_parseASearchDesc(service, &srv, &ret);
7717c478bd9Sstevel@tonic-gate 			if (rc != NS_LDAP_SUCCESS) {
7727c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7737c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, (2 * MAXERROR), gettext(
7747c478bd9Sstevel@tonic-gate 				    "Invalid serviceSearchDescriptor (%s). "
7757c478bd9Sstevel@tonic-gate 				    "Illegal configuration"), *sdl);
7767c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&param);
7777c478bd9Sstevel@tonic-gate 				param = NULL;
7787c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
7797c478bd9Sstevel@tonic-gate 				    strdup(errstr), NULL);
7807c478bd9Sstevel@tonic-gate 				return (rc);
7817c478bd9Sstevel@tonic-gate 			}
7827c478bd9Sstevel@tonic-gate 			if (ret != NULL) {
7837c478bd9Sstevel@tonic-gate 				rc = __ns_ldap_saveSearchDesc(
7847c478bd9Sstevel@tonic-gate 				    &sdlist, &cnt, &max, ret);
7857c478bd9Sstevel@tonic-gate 			}
7867c478bd9Sstevel@tonic-gate 			if (rc < 0) {
7877c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7887c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&param);
7897c478bd9Sstevel@tonic-gate 				param = NULL;
7907c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7917c478bd9Sstevel@tonic-gate 			}
7927c478bd9Sstevel@tonic-gate 		}
7937c478bd9Sstevel@tonic-gate 	}
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeParam(&param);
7967c478bd9Sstevel@tonic-gate 	param = NULL;
7977c478bd9Sstevel@tonic-gate 	*desc = sdlist;
7987c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
7997c478bd9Sstevel@tonic-gate }
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate int
8027c478bd9Sstevel@tonic-gate __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc)
8037c478bd9Sstevel@tonic-gate {
8047c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t **dptr;
8057c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t *ptr;
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	if (*desc == NULL)
8087c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
8097c478bd9Sstevel@tonic-gate 	for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) {
8107c478bd9Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
8117c478bd9Sstevel@tonic-gate 	}
8127c478bd9Sstevel@tonic-gate 	free(*desc);
8137c478bd9Sstevel@tonic-gate 	*desc = NULL;
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
8167c478bd9Sstevel@tonic-gate }
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate /*
8227c478bd9Sstevel@tonic-gate  * Exported Attribute/Objectclass mapping functions.
8237c478bd9Sstevel@tonic-gate  */
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate /*
8267c478bd9Sstevel@tonic-gate  * This function is not supported.
8277c478bd9Sstevel@tonic-gate  */
8287c478bd9Sstevel@tonic-gate /* ARGSUSED */
8297c478bd9Sstevel@tonic-gate int __ns_ldap_getAttributeMaps(
8307c478bd9Sstevel@tonic-gate 	const char *service,
8317c478bd9Sstevel@tonic-gate 	ns_ldap_attribute_map_t ***maps,
8327c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
8337c478bd9Sstevel@tonic-gate {
8347c478bd9Sstevel@tonic-gate 	*maps = NULL;
8357c478bd9Sstevel@tonic-gate 	return (NS_LDAP_OP_FAILED);
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate int
8397c478bd9Sstevel@tonic-gate __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps)
8407c478bd9Sstevel@tonic-gate {
8417c478bd9Sstevel@tonic-gate 	ns_ldap_attribute_map_t **dptr;
8427c478bd9Sstevel@tonic-gate 	ns_ldap_attribute_map_t *ptr;
8437c478bd9Sstevel@tonic-gate 	char **cpp, *cp;
8447c478bd9Sstevel@tonic-gate 
8457c478bd9Sstevel@tonic-gate 	if (*maps == NULL)
8467c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
8477c478bd9Sstevel@tonic-gate 	for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
8487c478bd9Sstevel@tonic-gate 		if (ptr->origAttr) {
8497c478bd9Sstevel@tonic-gate 			free(ptr->origAttr);
8507c478bd9Sstevel@tonic-gate 			ptr->origAttr = NULL;
8517c478bd9Sstevel@tonic-gate 		}
8527c478bd9Sstevel@tonic-gate 		if (ptr->mappedAttr) {
8537c478bd9Sstevel@tonic-gate 			for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++)
8547c478bd9Sstevel@tonic-gate 				free(cp);
8557c478bd9Sstevel@tonic-gate 			free(ptr->mappedAttr);
8567c478bd9Sstevel@tonic-gate 			ptr->mappedAttr = NULL;
8577c478bd9Sstevel@tonic-gate 		}
8587c478bd9Sstevel@tonic-gate 		free(ptr);
8597c478bd9Sstevel@tonic-gate 	}
8607c478bd9Sstevel@tonic-gate 	free(*maps);
8617c478bd9Sstevel@tonic-gate 	*maps = NULL;
8627c478bd9Sstevel@tonic-gate 
8637c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
8647c478bd9Sstevel@tonic-gate }
8657c478bd9Sstevel@tonic-gate 
8667c478bd9Sstevel@tonic-gate char **__ns_ldap_getMappedAttributes(
8677c478bd9Sstevel@tonic-gate 	const char *service,
8687c478bd9Sstevel@tonic-gate 	const char *origAttribute)
8697c478bd9Sstevel@tonic-gate {
8707c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
8717c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
8727c478bd9Sstevel@tonic-gate 	char		**ret;
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
8757c478bd9Sstevel@tonic-gate 		return (NULL);
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute);
8787c478bd9Sstevel@tonic-gate 
8797c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
8807c478bd9Sstevel@tonic-gate 		ret = NULL;
8817c478bd9Sstevel@tonic-gate 	else
8827c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
8837c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
8847c478bd9Sstevel@tonic-gate 	return (ret);
8857c478bd9Sstevel@tonic-gate }
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate char **__ns_ldap_getOrigAttribute(
8887c478bd9Sstevel@tonic-gate 	const char *service,
8897c478bd9Sstevel@tonic-gate 	const char *mappedAttribute)
8907c478bd9Sstevel@tonic-gate {
8917c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
8927c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
8937c478bd9Sstevel@tonic-gate 	char		**ret;
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
8967c478bd9Sstevel@tonic-gate 		return (NULL);
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute);
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9017c478bd9Sstevel@tonic-gate 		ret = NULL;
9027c478bd9Sstevel@tonic-gate 	else
9037c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9047c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9057c478bd9Sstevel@tonic-gate 	return (ret);
9067c478bd9Sstevel@tonic-gate }
9077c478bd9Sstevel@tonic-gate 
9087c478bd9Sstevel@tonic-gate /*
9097c478bd9Sstevel@tonic-gate  * This function is not supported.
9107c478bd9Sstevel@tonic-gate  */
9117c478bd9Sstevel@tonic-gate /* ARGSUSED */
9127c478bd9Sstevel@tonic-gate int __ns_ldap_getObjectClassMaps(
9137c478bd9Sstevel@tonic-gate 	const char *service,
9147c478bd9Sstevel@tonic-gate 	ns_ldap_objectclass_map_t ***maps,
9157c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
9167c478bd9Sstevel@tonic-gate {
9177c478bd9Sstevel@tonic-gate 	*maps = NULL;
9187c478bd9Sstevel@tonic-gate 	return (NS_LDAP_OP_FAILED);
9197c478bd9Sstevel@tonic-gate }
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate int
9227c478bd9Sstevel@tonic-gate __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps)
9237c478bd9Sstevel@tonic-gate {
9247c478bd9Sstevel@tonic-gate 	ns_ldap_objectclass_map_t **dptr;
9257c478bd9Sstevel@tonic-gate 	ns_ldap_objectclass_map_t *ptr;
9267c478bd9Sstevel@tonic-gate 
9277c478bd9Sstevel@tonic-gate 	if (*maps == NULL)
9287c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
9297c478bd9Sstevel@tonic-gate 	for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
9307c478bd9Sstevel@tonic-gate 		if (ptr->origOC) {
9317c478bd9Sstevel@tonic-gate 			free(ptr->origOC);
9327c478bd9Sstevel@tonic-gate 			ptr->origOC = NULL;
9337c478bd9Sstevel@tonic-gate 		}
9347c478bd9Sstevel@tonic-gate 		if (ptr->mappedOC) {
9357c478bd9Sstevel@tonic-gate 			free(ptr->mappedOC);
9367c478bd9Sstevel@tonic-gate 			ptr->mappedOC = NULL;
9377c478bd9Sstevel@tonic-gate 		}
9387c478bd9Sstevel@tonic-gate 		free(ptr);
9397c478bd9Sstevel@tonic-gate 	}
9407c478bd9Sstevel@tonic-gate 	free(*maps);
9417c478bd9Sstevel@tonic-gate 	*maps = NULL;
9427c478bd9Sstevel@tonic-gate 
9437c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
9447c478bd9Sstevel@tonic-gate }
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate char **__ns_ldap_getMappedObjectClass(
9477c478bd9Sstevel@tonic-gate 	const char *service,
9487c478bd9Sstevel@tonic-gate 	const char *origObjectClass)
9497c478bd9Sstevel@tonic-gate {
9507c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
9517c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
9527c478bd9Sstevel@tonic-gate 	char		**ret;
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
9557c478bd9Sstevel@tonic-gate 		return (NULL);
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass);
9587c478bd9Sstevel@tonic-gate 
9597c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9607c478bd9Sstevel@tonic-gate 		ret = NULL;
9617c478bd9Sstevel@tonic-gate 	else
9627c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9637c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9647c478bd9Sstevel@tonic-gate 	return (ret);
9657c478bd9Sstevel@tonic-gate }
9667c478bd9Sstevel@tonic-gate 
9677c478bd9Sstevel@tonic-gate char **__ns_ldap_getOrigObjectClass(
9687c478bd9Sstevel@tonic-gate 	const char *service,
9697c478bd9Sstevel@tonic-gate 	const char *mappedObjectClass)
9707c478bd9Sstevel@tonic-gate {
9717c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
9727c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
9737c478bd9Sstevel@tonic-gate 	char		**ret;
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
9767c478bd9Sstevel@tonic-gate 		return (NULL);
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass);
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9817c478bd9Sstevel@tonic-gate 		ret = NULL;
9827c478bd9Sstevel@tonic-gate 	else
9837c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9847c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9857c478bd9Sstevel@tonic-gate 	return (ret);
9867c478bd9Sstevel@tonic-gate }
9877c478bd9Sstevel@tonic-gate 
9887c478bd9Sstevel@tonic-gate char **__ns_ldap_mapAttributeList(
9897c478bd9Sstevel@tonic-gate 	const char *service,
9907c478bd9Sstevel@tonic-gate 	const char * const *origAttrList)
9917c478bd9Sstevel@tonic-gate {
9927c478bd9Sstevel@tonic-gate 	const char * const *opp;
9937c478bd9Sstevel@tonic-gate 	char **cpp, **npp;
9947c478bd9Sstevel@tonic-gate 	int i;
9957c478bd9Sstevel@tonic-gate 
9967c478bd9Sstevel@tonic-gate 	if (origAttrList == NULL)
9977c478bd9Sstevel@tonic-gate 		return (NULL);
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate 	opp = origAttrList;
10007c478bd9Sstevel@tonic-gate 	for (i = 0; *opp; i++, opp++)
10017c478bd9Sstevel@tonic-gate 		;
10027c478bd9Sstevel@tonic-gate 	cpp = (char **)calloc(i+1, sizeof (char *));
10037c478bd9Sstevel@tonic-gate 	if (cpp == NULL)
10047c478bd9Sstevel@tonic-gate 		return (NULL);
10057c478bd9Sstevel@tonic-gate 
10067c478bd9Sstevel@tonic-gate 	opp = origAttrList;
10077c478bd9Sstevel@tonic-gate 	for (i = 0; *opp; i++, opp++) {
10087c478bd9Sstevel@tonic-gate 		npp =  __ns_ldap_getMappedAttributes(service, *opp);
10097c478bd9Sstevel@tonic-gate 		if (npp && npp[0]) {
10107c478bd9Sstevel@tonic-gate 			cpp[i] = strdup(npp[0]);
10117c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(npp);
10127c478bd9Sstevel@tonic-gate 			npp = NULL;
10137c478bd9Sstevel@tonic-gate 			if (cpp[i] == NULL) {
10147c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(cpp);
10157c478bd9Sstevel@tonic-gate 				return (NULL);
10167c478bd9Sstevel@tonic-gate 			}
10177c478bd9Sstevel@tonic-gate 		} else {
10187c478bd9Sstevel@tonic-gate 			cpp[i] = strdup(*opp);
10197c478bd9Sstevel@tonic-gate 			if (cpp[i] == NULL) {
10207c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(cpp);
10217c478bd9Sstevel@tonic-gate 				return (NULL);
10227c478bd9Sstevel@tonic-gate 			}
10237c478bd9Sstevel@tonic-gate 		}
10247c478bd9Sstevel@tonic-gate 	}
10257c478bd9Sstevel@tonic-gate 	return (cpp);
10267c478bd9Sstevel@tonic-gate }
1027*9f2fd570SJulian Pullen 
1028*9f2fd570SJulian Pullen char *
1029*9f2fd570SJulian Pullen __ns_ldap_mapAttribute(
1030*9f2fd570SJulian Pullen 	const char *service,
1031*9f2fd570SJulian Pullen 	const char *origAttr)
1032*9f2fd570SJulian Pullen {
1033*9f2fd570SJulian Pullen 	char **npp;
1034*9f2fd570SJulian Pullen 	char *mappedAttr;
1035*9f2fd570SJulian Pullen 
1036*9f2fd570SJulian Pullen 	if (origAttr == NULL)
1037*9f2fd570SJulian Pullen 		return (NULL);
1038*9f2fd570SJulian Pullen 
1039*9f2fd570SJulian Pullen 	npp = __ns_ldap_getMappedAttributes(service, origAttr);
1040*9f2fd570SJulian Pullen 	if (npp && npp[0]) {
1041*9f2fd570SJulian Pullen 		mappedAttr = strdup(npp[0]);
1042*9f2fd570SJulian Pullen 		__s_api_free2dArray(npp);
1043*9f2fd570SJulian Pullen 	} else {
1044*9f2fd570SJulian Pullen 		mappedAttr = strdup(origAttr);
1045*9f2fd570SJulian Pullen 	}
1046*9f2fd570SJulian Pullen 	return (mappedAttr);
1047*9f2fd570SJulian Pullen }
1048