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
59f2fd570SJulian Pullen  * Common Development and Distribution License (the "License").
69f2fd570SJulian 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 /*
229f2fd570SJulian Pullen  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
23*d7ab8532SJason King  * Copyright 2020 Joyent, Inc.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <stdlib.h>
277c478bd9Sstevel@tonic-gate #include <strings.h>
287c478bd9Sstevel@tonic-gate #include <ctype.h>
297c478bd9Sstevel@tonic-gate #include <locale.h>
307c478bd9Sstevel@tonic-gate #include <syslog.h>
317c478bd9Sstevel@tonic-gate #include "ns_internal.h"
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate  * Calculate a hash for a string
357c478bd9Sstevel@tonic-gate  * Based on elf_hash algorithm, hash is case insensitive
367c478bd9Sstevel@tonic-gate  * Uses tolower instead of _tolower because of I18N
377c478bd9Sstevel@tonic-gate  */
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate static unsigned long
ns_hash(const char * str)407c478bd9Sstevel@tonic-gate ns_hash(const char *str)
417c478bd9Sstevel@tonic-gate {
427c478bd9Sstevel@tonic-gate 	unsigned int	hval = 0;
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate 	while (*str) {
457c478bd9Sstevel@tonic-gate 		unsigned int	g;
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate 		hval = (hval << 4) + tolower(*str++);
487c478bd9Sstevel@tonic-gate 		if ((g = (hval & 0xf0000000)) != 0)
497c478bd9Sstevel@tonic-gate 			hval ^= g >> 24;
507c478bd9Sstevel@tonic-gate 		hval &= ~g;
517c478bd9Sstevel@tonic-gate 	}
527c478bd9Sstevel@tonic-gate 	return ((unsigned long)hval);
537c478bd9Sstevel@tonic-gate }
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate /*
567c478bd9Sstevel@tonic-gate  * Scan a hash table hit for a matching hash entry.
577c478bd9Sstevel@tonic-gate  * Assume service and str are non-NULL.
587c478bd9Sstevel@tonic-gate  */
597c478bd9Sstevel@tonic-gate 
607c478bd9Sstevel@tonic-gate static ns_hash_t *
ns_scan_hash(ns_hashtype_t type,const char * service,const char * str,ns_hash_t * idx)617c478bd9Sstevel@tonic-gate ns_scan_hash(ns_hashtype_t type, const char *service,
629b7c0935SToomas Soome     const char *str, ns_hash_t *idx)
637c478bd9Sstevel@tonic-gate {
647c478bd9Sstevel@tonic-gate 	while (idx) {
657c478bd9Sstevel@tonic-gate 		if (idx->h_type == type &&
667c478bd9Sstevel@tonic-gate 		    strcasecmp(service, idx->h_map->service) == 0 &&
677c478bd9Sstevel@tonic-gate 		    strcasecmp(str, idx->h_map->orig) == 0) {
687c478bd9Sstevel@tonic-gate 			return (idx);
697c478bd9Sstevel@tonic-gate 		}
707c478bd9Sstevel@tonic-gate 		idx = idx->h_next;
717c478bd9Sstevel@tonic-gate 	}
727c478bd9Sstevel@tonic-gate 	return ((ns_hash_t *)NULL);
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate /*
767c478bd9Sstevel@tonic-gate  * Find an entry in the hash table
777c478bd9Sstevel@tonic-gate  */
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate static ns_hash_t *
ns_get_hash(const ns_config_t * config,ns_hashtype_t type,const char * service,const char * str)807c478bd9Sstevel@tonic-gate ns_get_hash(const ns_config_t *config,
819b7c0935SToomas Soome     ns_hashtype_t type, const char *service, const char *str)
827c478bd9Sstevel@tonic-gate {
837c478bd9Sstevel@tonic-gate 	ns_hash_t	*idx, *hashp;
847c478bd9Sstevel@tonic-gate 	unsigned long	hash;
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	if (config == NULL || service == NULL || str == NULL)
877c478bd9Sstevel@tonic-gate 		return (NULL);
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate 	hash = ns_hash(str) % NS_HASH_MAX;
907c478bd9Sstevel@tonic-gate 	idx = config->hashTbl[hash];
917c478bd9Sstevel@tonic-gate 	hashp = ns_scan_hash(type, service, str, idx);
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate 	return (hashp);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * free a map entry
987c478bd9Sstevel@tonic-gate  */
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate static void
ns_free_map(ns_mapping_t * mapp)1017c478bd9Sstevel@tonic-gate ns_free_map(ns_mapping_t *mapp)
1027c478bd9Sstevel@tonic-gate {
1037c478bd9Sstevel@tonic-gate 	char	**ptr;
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate 	if (mapp == NULL)
1067c478bd9Sstevel@tonic-gate 		return;
1077c478bd9Sstevel@tonic-gate 	if (mapp->service) {
1087c478bd9Sstevel@tonic-gate 		free(mapp->service);
1097c478bd9Sstevel@tonic-gate 		mapp->service = NULL;
1107c478bd9Sstevel@tonic-gate 	}
1117c478bd9Sstevel@tonic-gate 	if (mapp->orig) {
1127c478bd9Sstevel@tonic-gate 		free(mapp->orig);
1137c478bd9Sstevel@tonic-gate 		mapp->orig = NULL;
1147c478bd9Sstevel@tonic-gate 	}
1157c478bd9Sstevel@tonic-gate 	if (mapp->map) {
1167c478bd9Sstevel@tonic-gate 		for (ptr = mapp->map; *ptr; ptr++)
1177c478bd9Sstevel@tonic-gate 			free(*ptr);
1187c478bd9Sstevel@tonic-gate 		free(mapp->map);
1197c478bd9Sstevel@tonic-gate 		mapp->map = NULL;
1207c478bd9Sstevel@tonic-gate 	}
1217c478bd9Sstevel@tonic-gate 	free(mapp);
1227c478bd9Sstevel@tonic-gate }
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate /*
1257c478bd9Sstevel@tonic-gate  * Remove a hash table entry.
1267c478bd9Sstevel@tonic-gate  * This function is not MT safe.
1277c478bd9Sstevel@tonic-gate  */
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate static ns_hash_t *
ns_free_hash(ns_hash_t * p)1307c478bd9Sstevel@tonic-gate ns_free_hash(ns_hash_t *p)
1317c478bd9Sstevel@tonic-gate {
1327c478bd9Sstevel@tonic-gate 	ns_mapping_t	*map;
1337c478bd9Sstevel@tonic-gate 	ns_hash_t	*next;
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate 	map = p->h_map;
1367c478bd9Sstevel@tonic-gate 	next = p->h_next;
1377c478bd9Sstevel@tonic-gate 	ns_free_map(map);
1387c478bd9Sstevel@tonic-gate 	free(p);
1397c478bd9Sstevel@tonic-gate 	return (next);
1407c478bd9Sstevel@tonic-gate }
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate /*
1437c478bd9Sstevel@tonic-gate  * destroy the hash table.
1447c478bd9Sstevel@tonic-gate  * This function is not MT safe.
1457c478bd9Sstevel@tonic-gate  */
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate void
__s_api_destroy_hash(ns_config_t * config)1487c478bd9Sstevel@tonic-gate __s_api_destroy_hash(ns_config_t *config)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	ns_hash_t	*next;
1517c478bd9Sstevel@tonic-gate 	int		i;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	if (config == NULL)
1547c478bd9Sstevel@tonic-gate 		return;
1557c478bd9Sstevel@tonic-gate 	for (i = 0; i < NS_HASH_MAX; i++) {
1567c478bd9Sstevel@tonic-gate 		next = config->hashTbl[i];
1577c478bd9Sstevel@tonic-gate 		while (next != NULL) {
1587c478bd9Sstevel@tonic-gate 			next = ns_free_hash(next);
1597c478bd9Sstevel@tonic-gate 		}
1607c478bd9Sstevel@tonic-gate 		config->hashTbl[i] = NULL;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate /*
1657c478bd9Sstevel@tonic-gate  * Add a hash entry to the hash table.
1667c478bd9Sstevel@tonic-gate  * This function is not MT safe.
1677c478bd9Sstevel@tonic-gate  * Assume map, map->orig, map->service are non-NULL.
1687c478bd9Sstevel@tonic-gate  */
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate int
__s_api_add_map2hash(ns_config_t * config,ns_hashtype_t type,ns_mapping_t * map)1717c478bd9Sstevel@tonic-gate __s_api_add_map2hash(ns_config_t *config, ns_hashtype_t type,
1729b7c0935SToomas Soome     ns_mapping_t *map)
1737c478bd9Sstevel@tonic-gate {
1747c478bd9Sstevel@tonic-gate 	ns_hash_t	*idx, *newp;
1757c478bd9Sstevel@tonic-gate 	unsigned long	hash;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate 	if (config == NULL)
1787c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_CONFIG_ERROR);
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	hash = ns_hash(map->orig) % NS_HASH_MAX;
1817c478bd9Sstevel@tonic-gate 	idx = config->hashTbl[hash];
1827c478bd9Sstevel@tonic-gate 	if (idx != NULL &&
1837c478bd9Sstevel@tonic-gate 	    ns_scan_hash(type, map->service, map->orig, idx) != NULL) {
1847c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_EXISTED);
1857c478bd9Sstevel@tonic-gate 	}
1867c478bd9Sstevel@tonic-gate 
1877c478bd9Sstevel@tonic-gate 	newp = (ns_hash_t *)malloc(sizeof (ns_hash_t));
1887c478bd9Sstevel@tonic-gate 	if (newp == NULL)
1897c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
1907c478bd9Sstevel@tonic-gate 	newp->h_type = type;
1917c478bd9Sstevel@tonic-gate 	newp->h_map = map;
1927c478bd9Sstevel@tonic-gate 	newp->h_next = idx;
1937c478bd9Sstevel@tonic-gate 	config->hashTbl[hash] = newp;
1947c478bd9Sstevel@tonic-gate 	newp->h_llnext = config->llHead;
1957c478bd9Sstevel@tonic-gate 	config->llHead = newp;
1967c478bd9Sstevel@tonic-gate 	return (NS_HASH_RC_SUCCESS);
1977c478bd9Sstevel@tonic-gate }
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate /*
2017c478bd9Sstevel@tonic-gate  * Parse an attribute map string.
2027c478bd9Sstevel@tonic-gate  * Assume space is the only legal whitespace.
2037c478bd9Sstevel@tonic-gate  * attributeMap syntax:
2047c478bd9Sstevel@tonic-gate  * attributeMap      = serviceId ":" origAttribute "="
205*d7ab8532SJason King  *			attributes
2067c478bd9Sstevel@tonic-gate  * origAttribute     = attribute
2077c478bd9Sstevel@tonic-gate  * attributes        = wattribute *( space wattribute )
2087c478bd9Sstevel@tonic-gate  * wattribute        = whsp newAttribute whsp
2097c478bd9Sstevel@tonic-gate  * newAttribute      = descr | "*NULL*"
2107c478bd9Sstevel@tonic-gate  * attribute         = descr
2117c478bd9Sstevel@tonic-gate  *
2127c478bd9Sstevel@tonic-gate  * objectclassMap syntax:
2137c478bd9Sstevel@tonic-gate  * objectclassMap    = serviceId ":" origObjectclass "="
214*d7ab8532SJason King  *			objectclass
2157c478bd9Sstevel@tonic-gate  * origObjectclass   = objectclass
2167c478bd9Sstevel@tonic-gate  * objectclass       = keystring
2177c478bd9Sstevel@tonic-gate  */
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate int
__s_api_parse_map(char * cp,char ** sid,char ** origA,char *** mapA)2207c478bd9Sstevel@tonic-gate __s_api_parse_map(char *cp, char **sid, char **origA, char ***mapA)
2217c478bd9Sstevel@tonic-gate {
2227c478bd9Sstevel@tonic-gate 	char	*sptr, *dptr, **mapp;
2237c478bd9Sstevel@tonic-gate 	int	i, max;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	*sid = NULL;
2267c478bd9Sstevel@tonic-gate 	*origA = NULL;
2277c478bd9Sstevel@tonic-gate 	*mapA = NULL;
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	sptr = cp;
2307c478bd9Sstevel@tonic-gate 	dptr = strchr(sptr, COLONTOK);
2317c478bd9Sstevel@tonic-gate 	if (dptr == NULL)
2327c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_SYNTAX_ERROR);
2337c478bd9Sstevel@tonic-gate 	i = dptr - sptr + 1;
2347c478bd9Sstevel@tonic-gate 	*sid = (char *)malloc(i);
2357c478bd9Sstevel@tonic-gate 	if (*sid == NULL)
2367c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2377c478bd9Sstevel@tonic-gate 	(void) strlcpy(*sid, sptr, i);
2387c478bd9Sstevel@tonic-gate 	sptr = dptr+1;
2397c478bd9Sstevel@tonic-gate 
2407c478bd9Sstevel@tonic-gate 	dptr = strchr(sptr, TOKENSEPARATOR);
2417c478bd9Sstevel@tonic-gate 	if (dptr == NULL) {
2427c478bd9Sstevel@tonic-gate 		free(*sid);
2437c478bd9Sstevel@tonic-gate 		*sid = NULL;
2447c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_SYNTAX_ERROR);
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 	i = dptr - sptr + 1;
2477c478bd9Sstevel@tonic-gate 	*origA = (char *)malloc(i);
2487c478bd9Sstevel@tonic-gate 	if (*origA == NULL) {
2497c478bd9Sstevel@tonic-gate 		free(*sid);
2507c478bd9Sstevel@tonic-gate 		*sid = NULL;
2517c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2527c478bd9Sstevel@tonic-gate 	}
2537c478bd9Sstevel@tonic-gate 	(void) strlcpy(*origA, sptr, i);
2547c478bd9Sstevel@tonic-gate 	sptr = dptr+1;
2557c478bd9Sstevel@tonic-gate 
2567c478bd9Sstevel@tonic-gate 	max = 1;
2577c478bd9Sstevel@tonic-gate 	for (dptr = sptr; *dptr; dptr++) {
2587c478bd9Sstevel@tonic-gate 		if (*dptr == SPACETOK) {
2597c478bd9Sstevel@tonic-gate 			max++;
2607c478bd9Sstevel@tonic-gate 			while (*(dptr+1) == SPACETOK)
2617c478bd9Sstevel@tonic-gate 				dptr++;
2627c478bd9Sstevel@tonic-gate 		}
2637c478bd9Sstevel@tonic-gate 	}
2647c478bd9Sstevel@tonic-gate 	*mapA = (char **)calloc(max+1, sizeof (char *));
2657c478bd9Sstevel@tonic-gate 	if (*mapA == NULL) {
2667c478bd9Sstevel@tonic-gate 		free(*sid);
2677c478bd9Sstevel@tonic-gate 		*sid = NULL;
2687c478bd9Sstevel@tonic-gate 		free(*origA);
2697c478bd9Sstevel@tonic-gate 		*origA = NULL;
2707c478bd9Sstevel@tonic-gate 		return (NS_HASH_RC_NO_MEMORY);
2717c478bd9Sstevel@tonic-gate 	}
2727c478bd9Sstevel@tonic-gate 	mapp = *mapA;
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	while (*sptr) {
2757c478bd9Sstevel@tonic-gate 		while (*sptr == SPACETOK)
2767c478bd9Sstevel@tonic-gate 			sptr++;
2777c478bd9Sstevel@tonic-gate 		dptr = sptr;
2787c478bd9Sstevel@tonic-gate 		while (*dptr && *dptr != SPACETOK)
2797c478bd9Sstevel@tonic-gate 			dptr++;
2807c478bd9Sstevel@tonic-gate 		i = dptr - sptr + 1;
2817c478bd9Sstevel@tonic-gate 		*mapp = (char *)malloc(i);
2827c478bd9Sstevel@tonic-gate 		if (*mapp == NULL) {
2837c478bd9Sstevel@tonic-gate 			free(*sid);
2847c478bd9Sstevel@tonic-gate 			*sid = NULL;
2857c478bd9Sstevel@tonic-gate 			free(*origA);
2867c478bd9Sstevel@tonic-gate 			*origA = NULL;
2877c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(*mapA);
2887c478bd9Sstevel@tonic-gate 			*mapA = NULL;
2897c478bd9Sstevel@tonic-gate 			return (NS_HASH_RC_NO_MEMORY);
2907c478bd9Sstevel@tonic-gate 		}
2917c478bd9Sstevel@tonic-gate 		(void) strlcpy(*mapp, sptr, i);
2927c478bd9Sstevel@tonic-gate 		mapp++;
2937c478bd9Sstevel@tonic-gate 		sptr = dptr;
2947c478bd9Sstevel@tonic-gate 	}
2957c478bd9Sstevel@tonic-gate 	return (NS_HASH_RC_SUCCESS);
2967c478bd9Sstevel@tonic-gate }
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 
299*d7ab8532SJason King void
__ns_ldap_freeASearchDesc(ns_ldap_search_desc_t * ptr)3007c478bd9Sstevel@tonic-gate __ns_ldap_freeASearchDesc(ns_ldap_search_desc_t *ptr)
3017c478bd9Sstevel@tonic-gate {
3027c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
3037c478bd9Sstevel@tonic-gate 		return;
3047c478bd9Sstevel@tonic-gate 	if (ptr->basedn)
3057c478bd9Sstevel@tonic-gate 		free(ptr->basedn);
3067c478bd9Sstevel@tonic-gate 	if (ptr->filter)
3077c478bd9Sstevel@tonic-gate 		free(ptr->filter);
3087c478bd9Sstevel@tonic-gate 	free(ptr);
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate 
3117c478bd9Sstevel@tonic-gate /*
3127c478bd9Sstevel@tonic-gate  * Parse a service descriptor
3137c478bd9Sstevel@tonic-gate  * and create a service descriptor struct
3147c478bd9Sstevel@tonic-gate  * SD Format:
3157c478bd9Sstevel@tonic-gate  *    serviceid:[base][?[scope][?[filter]]];[[base][?[scope][?[filter]]]]
3167c478bd9Sstevel@tonic-gate  * desc format:
3177c478bd9Sstevel@tonic-gate  *    [base][?[scope][?[filter]]]
3187c478bd9Sstevel@tonic-gate  */
3197c478bd9Sstevel@tonic-gate 
3207c478bd9Sstevel@tonic-gate typedef enum _ns_parse_state {
3217c478bd9Sstevel@tonic-gate 	P_ERROR, P_INIT, P_BASEDN, P_SCOPE,
3227c478bd9Sstevel@tonic-gate 	P_INIFILTER, P_FILTER, P_END, P_EXIT, P_MEMERR
3237c478bd9Sstevel@tonic-gate } _ns_parse_state_t;
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate static
3267c478bd9Sstevel@tonic-gate int
__s_api_parseASearchDesc(const char * service,char ** cur,ns_ldap_search_desc_t ** ret)3277c478bd9Sstevel@tonic-gate __s_api_parseASearchDesc(const char *service,
3289b7c0935SToomas Soome     char **cur, ns_ldap_search_desc_t **ret)
3297c478bd9Sstevel@tonic-gate {
3307c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t	*ptr;
3317c478bd9Sstevel@tonic-gate 	char			*sptr, *dptr;
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 *)
3499f2fd570SJulian Pullen 	    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,
3579f2fd570SJulian Pullen 	    &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 			if (*sptr == SEMITOK) {
4607c478bd9Sstevel@tonic-gate 				/* no more SSD */
4617c478bd9Sstevel@tonic-gate 				state = P_EXIT;
4627c478bd9Sstevel@tonic-gate 				break;
4637c478bd9Sstevel@tonic-gate 			}
4647c478bd9Sstevel@tonic-gate 			if (strncasecmp(sptr, "base", 4) == 0) {
4657c478bd9Sstevel@tonic-gate 				sptr += 4;
4667c478bd9Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_BASE;
4677c478bd9Sstevel@tonic-gate 			} else if (strncasecmp(sptr, "one", 3) == 0) {
4687c478bd9Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_ONELEVEL;
4697c478bd9Sstevel@tonic-gate 				sptr += 3;
4707c478bd9Sstevel@tonic-gate 			} else if (strncasecmp(sptr, "sub", 3) == 0) {
4717c478bd9Sstevel@tonic-gate 				ptr->scope = NS_LDAP_SCOPE_SUBTREE;
4727c478bd9Sstevel@tonic-gate 				sptr += 3;
4737c478bd9Sstevel@tonic-gate 			}
4747c478bd9Sstevel@tonic-gate 			if (*sptr == '\0' || (*sptr == SEMITOK)) {
4757c478bd9Sstevel@tonic-gate 				/* no more SSD */
4767c478bd9Sstevel@tonic-gate 				state = P_EXIT;
4777c478bd9Sstevel@tonic-gate 				sptr--;
4787c478bd9Sstevel@tonic-gate 				break;
4797c478bd9Sstevel@tonic-gate 			}
4807c478bd9Sstevel@tonic-gate 			if (*sptr != QUESTTOK) {
4817c478bd9Sstevel@tonic-gate 				state = P_ERROR;
4827c478bd9Sstevel@tonic-gate 				break;
4837c478bd9Sstevel@tonic-gate 			}
4847c478bd9Sstevel@tonic-gate 			state = P_INIFILTER;
4857c478bd9Sstevel@tonic-gate 			quoted = 0;
4867c478bd9Sstevel@tonic-gate 			wasquoted = 0;
4877c478bd9Sstevel@tonic-gate 			break;
4887c478bd9Sstevel@tonic-gate 		case P_BASEDN:
4897c478bd9Sstevel@tonic-gate 		case P_FILTER:
4907c478bd9Sstevel@tonic-gate 			if (quoted) {
4917c478bd9Sstevel@tonic-gate 				/* Quoted */
4927c478bd9Sstevel@tonic-gate 				if (*sptr == BSLTOK) {
4937c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == '\0') {
4947c478bd9Sstevel@tonic-gate 						state = P_ERROR;
4957c478bd9Sstevel@tonic-gate 						break;
4967c478bd9Sstevel@tonic-gate 					}
4977c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == QUOTETOK ||
4987c478bd9Sstevel@tonic-gate 					    *(sptr+1) == BSLTOK) {
4997c478bd9Sstevel@tonic-gate 						/* escaped CHARS */
5007c478bd9Sstevel@tonic-gate 						sptr++;
5017c478bd9Sstevel@tonic-gate 					} else {
5027c478bd9Sstevel@tonic-gate 						*dptr++ = *sptr++;
5037c478bd9Sstevel@tonic-gate 					}
5047c478bd9Sstevel@tonic-gate 					/* fall through to char copy */
5057c478bd9Sstevel@tonic-gate 				} else if (*sptr == QUOTETOK) {
5067c478bd9Sstevel@tonic-gate 					/* end of string */
5077c478bd9Sstevel@tonic-gate 					*dptr = '\0';
5087c478bd9Sstevel@tonic-gate 					quoted = 0;
5097c478bd9Sstevel@tonic-gate 					break;
5107c478bd9Sstevel@tonic-gate 				}
5117c478bd9Sstevel@tonic-gate 				/* else fall through to char copy */
5127c478bd9Sstevel@tonic-gate 			} else {
5137c478bd9Sstevel@tonic-gate 				/* Unquoted */
5147c478bd9Sstevel@tonic-gate 				if (wasquoted && *sptr != QUESTTOK) {
5157c478bd9Sstevel@tonic-gate 					/* error  past end of quoted string */
5167c478bd9Sstevel@tonic-gate 					state = P_ERROR;
5177c478bd9Sstevel@tonic-gate 					break;
5187c478bd9Sstevel@tonic-gate 				}
5197c478bd9Sstevel@tonic-gate 				if (*sptr == BSLTOK) {
5207c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == '\0') {
5217c478bd9Sstevel@tonic-gate 						state = P_ERROR;
5227c478bd9Sstevel@tonic-gate 						break;
5237c478bd9Sstevel@tonic-gate 					}
5247c478bd9Sstevel@tonic-gate 					if (*(sptr+1) == SEMITOK ||
5257c478bd9Sstevel@tonic-gate 					    *(sptr+1) == QUESTTOK ||
5267c478bd9Sstevel@tonic-gate 					    *(sptr+1) == QUOTETOK ||
5277c478bd9Sstevel@tonic-gate 					    *(sptr+1) == BSLTOK) {
5287c478bd9Sstevel@tonic-gate 						/* escaped chars */
5297c478bd9Sstevel@tonic-gate 						sptr++;
5307c478bd9Sstevel@tonic-gate 					}
5317c478bd9Sstevel@tonic-gate 					/* fall through to char copy */
5327c478bd9Sstevel@tonic-gate 				} else if (*sptr == QUOTETOK) {
5337c478bd9Sstevel@tonic-gate 					/* error */
5347c478bd9Sstevel@tonic-gate 					state = P_ERROR;
5357c478bd9Sstevel@tonic-gate 					break;
5367c478bd9Sstevel@tonic-gate 				} else if (*sptr == QUESTTOK) {
5377c478bd9Sstevel@tonic-gate 					/* if filter error */
5387c478bd9Sstevel@tonic-gate 					if (state == P_FILTER) {
5397c478bd9Sstevel@tonic-gate 						state = P_ERROR;
5407c478bd9Sstevel@tonic-gate 						break;
5417c478bd9Sstevel@tonic-gate 					}
5427c478bd9Sstevel@tonic-gate 					/* end of basedn goto scope */
5437c478bd9Sstevel@tonic-gate 					*dptr = '\0';
5447c478bd9Sstevel@tonic-gate 					state = P_SCOPE;
5457c478bd9Sstevel@tonic-gate 					break;
5467c478bd9Sstevel@tonic-gate 				} else if (*sptr == SEMITOK) {
5477c478bd9Sstevel@tonic-gate 					/* end of current SSD */
5487c478bd9Sstevel@tonic-gate 					*dptr = '\0';
5497c478bd9Sstevel@tonic-gate 					state = P_EXIT;
5507c478bd9Sstevel@tonic-gate 					break;
5517c478bd9Sstevel@tonic-gate 				}
5527c478bd9Sstevel@tonic-gate 			}
5537c478bd9Sstevel@tonic-gate 			/* normal character to copy */
5547c478bd9Sstevel@tonic-gate 			*dptr++ = *sptr;
5557c478bd9Sstevel@tonic-gate 			break;
5567c478bd9Sstevel@tonic-gate 		case P_END:
5577c478bd9Sstevel@tonic-gate 			if (*sptr == SEMITOK) {
5587c478bd9Sstevel@tonic-gate 				state = P_EXIT;
5597c478bd9Sstevel@tonic-gate 				break;
5607c478bd9Sstevel@tonic-gate 			}
5617c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5627c478bd9Sstevel@tonic-gate 			ptr = NULL;
5637c478bd9Sstevel@tonic-gate 			*cur = NULL;
5647c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
5657c478bd9Sstevel@tonic-gate 		default:	 /* error should never arrive here */
5667c478bd9Sstevel@tonic-gate 		case P_ERROR:
5677c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5687c478bd9Sstevel@tonic-gate 			ptr = NULL;
5697c478bd9Sstevel@tonic-gate 			*cur = NULL;
5707c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
5717c478bd9Sstevel@tonic-gate 		case P_MEMERR:
5727c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5737c478bd9Sstevel@tonic-gate 			ptr = NULL;
5747c478bd9Sstevel@tonic-gate 			*cur = NULL;
5757c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
5767c478bd9Sstevel@tonic-gate 		}
5777c478bd9Sstevel@tonic-gate 	}
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 	if (quoted) {
5807c478bd9Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
5817c478bd9Sstevel@tonic-gate 		ptr = NULL;
5827c478bd9Sstevel@tonic-gate 		*cur = NULL;
5837c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
5847c478bd9Sstevel@tonic-gate 	}
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate 	if (empty || strlen(ptr->basedn) == 0) {
5877c478bd9Sstevel@tonic-gate 		if (ptr->basedn)
5887c478bd9Sstevel@tonic-gate 			free(ptr->basedn);
5897c478bd9Sstevel@tonic-gate 		/* get default base */
5907c478bd9Sstevel@tonic-gate 		rc = __s_api_getDNs(&dns, service, &error);
5917c478bd9Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS) {
5927c478bd9Sstevel@tonic-gate 			if (dns) {
5937c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(dns);
5947c478bd9Sstevel@tonic-gate 				dns = NULL;
5957c478bd9Sstevel@tonic-gate 			}
5967c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&error);
5977c478bd9Sstevel@tonic-gate 			__ns_ldap_freeASearchDesc(ptr);
5987c478bd9Sstevel@tonic-gate 			ptr = NULL;
5997c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
6007c478bd9Sstevel@tonic-gate 		}
6017c478bd9Sstevel@tonic-gate 		ptr->basedn = strdup(dns[0]);
6027c478bd9Sstevel@tonic-gate 		__s_api_free2dArray(dns);
6037c478bd9Sstevel@tonic-gate 		dns = NULL;
6047c478bd9Sstevel@tonic-gate 	}
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	*cur = sptr;
6077c478bd9Sstevel@tonic-gate 	*ret = ptr;
6087c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
6097c478bd9Sstevel@tonic-gate }
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 
6127c478bd9Sstevel@tonic-gate /*
6137c478bd9Sstevel@tonic-gate  * Build up the service descriptor array
6147c478bd9Sstevel@tonic-gate  */
6157c478bd9Sstevel@tonic-gate #define	NS_SDESC_MAX	4
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate static int
__ns_ldap_saveSearchDesc(ns_ldap_search_desc_t *** sdlist,int * cnt,int * max,ns_ldap_search_desc_t * ret)6187c478bd9Sstevel@tonic-gate __ns_ldap_saveSearchDesc(ns_ldap_search_desc_t ***sdlist,
6199b7c0935SToomas Soome     int *cnt, int *max, ns_ldap_search_desc_t *ret)
6207c478bd9Sstevel@tonic-gate {
6217c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t	**tmplist;
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate 	if (*sdlist == NULL) {
6247c478bd9Sstevel@tonic-gate 		*cnt = 0;
6257c478bd9Sstevel@tonic-gate 		*max = NS_SDESC_MAX;
6267c478bd9Sstevel@tonic-gate 		*sdlist = (ns_ldap_search_desc_t **)
6279f2fd570SJulian Pullen 		    calloc(*max, sizeof (ns_ldap_search_desc_t *));
6287c478bd9Sstevel@tonic-gate 		if (*sdlist == NULL)
6297c478bd9Sstevel@tonic-gate 			return (-1);
6307c478bd9Sstevel@tonic-gate 	} else if (*cnt+1 >= *max) {
6317c478bd9Sstevel@tonic-gate 		*max += NS_SDESC_MAX;
6327c478bd9Sstevel@tonic-gate 		tmplist = (ns_ldap_search_desc_t **)
6339f2fd570SJulian Pullen 		    realloc((void *)(*sdlist),
6349f2fd570SJulian Pullen 		    *max * sizeof (ns_ldap_search_desc_t *));
6357c478bd9Sstevel@tonic-gate 		if (tmplist == NULL)
6367c478bd9Sstevel@tonic-gate 			return (-1);
6377c478bd9Sstevel@tonic-gate 		else
6387c478bd9Sstevel@tonic-gate 			*sdlist = tmplist;
6397c478bd9Sstevel@tonic-gate 	}
6407c478bd9Sstevel@tonic-gate 	(*sdlist)[*cnt] = ret;
6417c478bd9Sstevel@tonic-gate 	(*cnt)++;
6427c478bd9Sstevel@tonic-gate 	(*sdlist)[*cnt] = NULL;
6437c478bd9Sstevel@tonic-gate 	return (0);
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate /*
6487c478bd9Sstevel@tonic-gate  * Exported Search Descriptor Routines
6497c478bd9Sstevel@tonic-gate  */
6507c478bd9Sstevel@tonic-gate 
__ns_ldap_getSearchDescriptors(const char * service,ns_ldap_search_desc_t *** desc,ns_ldap_error_t ** errorp)6517c478bd9Sstevel@tonic-gate int __ns_ldap_getSearchDescriptors(
6527c478bd9Sstevel@tonic-gate 	const char *service,
6537c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t ***desc,
6547c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
6557c478bd9Sstevel@tonic-gate {
6567c478bd9Sstevel@tonic-gate 	int			rc;
6577c478bd9Sstevel@tonic-gate 	int			slen;
6587c478bd9Sstevel@tonic-gate 	void			**param = NULL;
6597c478bd9Sstevel@tonic-gate 	void			**paramVal = NULL;
6607c478bd9Sstevel@tonic-gate 	char			**sdl, *srv, **sdl_save;
6617c478bd9Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
6627c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t	**sdlist;
6637c478bd9Sstevel@tonic-gate 	int			cnt, max;
6647c478bd9Sstevel@tonic-gate 	int			vers;
6657c478bd9Sstevel@tonic-gate 	ns_config_t		*cfg;
666*d7ab8532SJason King 	ns_ldap_search_desc_t	*ret;
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 	if ((desc == NULL) || (errorp == NULL))
6697c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	*desc = NULL;
6727c478bd9Sstevel@tonic-gate 	*errorp = NULL;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 	rc = __ns_ldap_getParam(NS_LDAP_SERVICE_SEARCH_DESC_P,
6759f2fd570SJulian Pullen 	    (void ***)&param, errorp);
6767c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
6777c478bd9Sstevel@tonic-gate 		return (rc);
6787c478bd9Sstevel@tonic-gate 	}
6797c478bd9Sstevel@tonic-gate 	sdl = (char **)param;
6807c478bd9Sstevel@tonic-gate 	cnt = 0;
6817c478bd9Sstevel@tonic-gate 	max = 0;
6827c478bd9Sstevel@tonic-gate 	sdlist = NULL;
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 	if (cfg == NULL) {
6877c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
6887c478bd9Sstevel@tonic-gate 		    gettext("No configuration information available."));
6897c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
69051b02b29SToomas Soome 		    NS_LDAP_MEMORY);
6917c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
6927c478bd9Sstevel@tonic-gate 	}
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 	vers = cfg->version;
6957c478bd9Sstevel@tonic-gate 	__s_api_release_config(cfg);
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	/* If using version1 or no sd's process SEARCH_DN if available */
6987c478bd9Sstevel@tonic-gate 	if (vers == NS_LDAP_V1 && param == NULL) {
6997c478bd9Sstevel@tonic-gate 		rc = __s_api_get_search_DNs_v1(&sdl, service, errorp);
7007c478bd9Sstevel@tonic-gate 		if (rc != NS_LDAP_SUCCESS || sdl == NULL) {
7017c478bd9Sstevel@tonic-gate 			return (rc);
7027c478bd9Sstevel@tonic-gate 		}
7037c478bd9Sstevel@tonic-gate 		sdl_save = sdl;
7047c478bd9Sstevel@tonic-gate 		/* Convert a SEARCH_DN to a search descriptor */
7057c478bd9Sstevel@tonic-gate 		for (; *sdl; sdl++) {
7067c478bd9Sstevel@tonic-gate 			ret = (ns_ldap_search_desc_t *)
7079f2fd570SJulian Pullen 			    calloc(1, sizeof (ns_ldap_search_desc_t));
7087c478bd9Sstevel@tonic-gate 			if (ret == NULL) {
7097c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7107c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7117c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7127c478bd9Sstevel@tonic-gate 			}
7137c478bd9Sstevel@tonic-gate 			ret->basedn = strdup(*sdl);
7147c478bd9Sstevel@tonic-gate 			if (ret->basedn == NULL) {
7157c478bd9Sstevel@tonic-gate 				free(ret);
7167c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7177c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7187c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7197c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7207c478bd9Sstevel@tonic-gate 			}
7217c478bd9Sstevel@tonic-gate 
7227c478bd9Sstevel@tonic-gate 			/* default scope */
7237c478bd9Sstevel@tonic-gate 			if ((rc = __ns_ldap_getParam(NS_LDAP_SEARCH_SCOPE_P,
7249f2fd570SJulian Pullen 			    &paramVal, errorp)) != NS_LDAP_SUCCESS) {
7257c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7267c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7277c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7287c478bd9Sstevel@tonic-gate 				return (rc);
7297c478bd9Sstevel@tonic-gate 			}
7307c478bd9Sstevel@tonic-gate 			if (paramVal && *paramVal)
7317c478bd9Sstevel@tonic-gate 				ret->scope = * (ScopeType_t *)(*paramVal);
7327c478bd9Sstevel@tonic-gate 			else
7337c478bd9Sstevel@tonic-gate 				ret->scope = NS_LDAP_SCOPE_ONELEVEL;
7347c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeParam(&paramVal);
7357c478bd9Sstevel@tonic-gate 			paramVal = NULL;
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate 			rc = __ns_ldap_saveSearchDesc(&sdlist, &cnt, &max, ret);
7387c478bd9Sstevel@tonic-gate 			if (rc < 0) {
7397c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeASearchDesc(ret);
7407c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7417c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(sdl_save);
7427c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7437c478bd9Sstevel@tonic-gate 			}
7447c478bd9Sstevel@tonic-gate 		}
7457c478bd9Sstevel@tonic-gate 		__s_api_free2dArray(sdl_save);
7467c478bd9Sstevel@tonic-gate 		*desc = sdlist;
7477c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
7487c478bd9Sstevel@tonic-gate 	}
7497c478bd9Sstevel@tonic-gate 
7507c478bd9Sstevel@tonic-gate 	if (sdl == NULL || service == NULL) {
7517c478bd9Sstevel@tonic-gate 		(void) __ns_ldap_freeParam(&param);
7527c478bd9Sstevel@tonic-gate 		param = NULL;
7537c478bd9Sstevel@tonic-gate 		*desc = NULL;
7547c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
7557c478bd9Sstevel@tonic-gate 	}
7567c478bd9Sstevel@tonic-gate 	slen = strlen(service);
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 	/* Process the version2 sd's */
7597c478bd9Sstevel@tonic-gate 	for (; *sdl; sdl++) {
7607c478bd9Sstevel@tonic-gate 		srv = *sdl;
7617c478bd9Sstevel@tonic-gate 		if (strncasecmp(service, srv, slen) != 0)
7627c478bd9Sstevel@tonic-gate 			continue;
7637c478bd9Sstevel@tonic-gate 		srv += slen;
7647c478bd9Sstevel@tonic-gate 		if (*srv != COLONTOK)
7657c478bd9Sstevel@tonic-gate 			continue;
7667c478bd9Sstevel@tonic-gate 		srv++;
76751b02b29SToomas Soome 		while (srv != NULL && *srv != '\0') {
7687c478bd9Sstevel@tonic-gate 			/* Process 1 */
7697c478bd9Sstevel@tonic-gate 			rc = __s_api_parseASearchDesc(service, &srv, &ret);
7707c478bd9Sstevel@tonic-gate 			if (rc != NS_LDAP_SUCCESS) {
7717c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7727c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, (2 * MAXERROR), gettext(
7739f2fd570SJulian Pullen 				    "Invalid serviceSearchDescriptor (%s). "
7749f2fd570SJulian Pullen 				    "Illegal configuration"), *sdl);
7757c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&param);
7767c478bd9Sstevel@tonic-gate 				param = NULL;
7777c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
77851b02b29SToomas Soome 				    strdup(errstr), NS_LDAP_MEMORY);
7797c478bd9Sstevel@tonic-gate 				return (rc);
7807c478bd9Sstevel@tonic-gate 			}
7817c478bd9Sstevel@tonic-gate 			if (ret != NULL) {
7827c478bd9Sstevel@tonic-gate 				rc = __ns_ldap_saveSearchDesc(
7839f2fd570SJulian Pullen 				    &sdlist, &cnt, &max, ret);
7847c478bd9Sstevel@tonic-gate 			}
7857c478bd9Sstevel@tonic-gate 			if (rc < 0) {
7867c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeSearchDescriptors(&sdlist);
7877c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeParam(&param);
7887c478bd9Sstevel@tonic-gate 				param = NULL;
7897c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
7907c478bd9Sstevel@tonic-gate 			}
7917c478bd9Sstevel@tonic-gate 		}
7927c478bd9Sstevel@tonic-gate 	}
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeParam(&param);
7957c478bd9Sstevel@tonic-gate 	param = NULL;
7967c478bd9Sstevel@tonic-gate 	*desc = sdlist;
7977c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
7987c478bd9Sstevel@tonic-gate }
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate int
__ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t *** desc)8017c478bd9Sstevel@tonic-gate __ns_ldap_freeSearchDescriptors(ns_ldap_search_desc_t ***desc)
8027c478bd9Sstevel@tonic-gate {
8037c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t **dptr;
8047c478bd9Sstevel@tonic-gate 	ns_ldap_search_desc_t *ptr;
8057c478bd9Sstevel@tonic-gate 
8067c478bd9Sstevel@tonic-gate 	if (*desc == NULL)
8077c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
8087c478bd9Sstevel@tonic-gate 	for (dptr = *desc; (ptr = *dptr) != NULL; dptr++) {
8097c478bd9Sstevel@tonic-gate 		__ns_ldap_freeASearchDesc(ptr);
8107c478bd9Sstevel@tonic-gate 	}
8117c478bd9Sstevel@tonic-gate 	free(*desc);
8127c478bd9Sstevel@tonic-gate 	*desc = NULL;
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
8157c478bd9Sstevel@tonic-gate }
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate /*
8217c478bd9Sstevel@tonic-gate  * Exported Attribute/Objectclass mapping functions.
8227c478bd9Sstevel@tonic-gate  */
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate /*
8257c478bd9Sstevel@tonic-gate  * This function is not supported.
8267c478bd9Sstevel@tonic-gate  */
8277c478bd9Sstevel@tonic-gate /* ARGSUSED */
__ns_ldap_getAttributeMaps(const char * service,ns_ldap_attribute_map_t *** maps,ns_ldap_error_t ** errorp)8287c478bd9Sstevel@tonic-gate int __ns_ldap_getAttributeMaps(
8297c478bd9Sstevel@tonic-gate 	const char *service,
8307c478bd9Sstevel@tonic-gate 	ns_ldap_attribute_map_t ***maps,
8317c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
8327c478bd9Sstevel@tonic-gate {
8337c478bd9Sstevel@tonic-gate 	*maps = NULL;
8347c478bd9Sstevel@tonic-gate 	return (NS_LDAP_OP_FAILED);
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate 
8377c478bd9Sstevel@tonic-gate int
__ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t *** maps)8387c478bd9Sstevel@tonic-gate __ns_ldap_freeAttributeMaps(ns_ldap_attribute_map_t ***maps)
8397c478bd9Sstevel@tonic-gate {
8407c478bd9Sstevel@tonic-gate 	ns_ldap_attribute_map_t **dptr;
8417c478bd9Sstevel@tonic-gate 	ns_ldap_attribute_map_t *ptr;
8427c478bd9Sstevel@tonic-gate 	char **cpp, *cp;
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	if (*maps == NULL)
8457c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
8467c478bd9Sstevel@tonic-gate 	for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
8477c478bd9Sstevel@tonic-gate 		if (ptr->origAttr) {
8487c478bd9Sstevel@tonic-gate 			free(ptr->origAttr);
8497c478bd9Sstevel@tonic-gate 			ptr->origAttr = NULL;
8507c478bd9Sstevel@tonic-gate 		}
8517c478bd9Sstevel@tonic-gate 		if (ptr->mappedAttr) {
8527c478bd9Sstevel@tonic-gate 			for (cpp = ptr->mappedAttr; (cp = *cpp) != NULL; cpp++)
8537c478bd9Sstevel@tonic-gate 				free(cp);
8547c478bd9Sstevel@tonic-gate 			free(ptr->mappedAttr);
8557c478bd9Sstevel@tonic-gate 			ptr->mappedAttr = NULL;
8567c478bd9Sstevel@tonic-gate 		}
8577c478bd9Sstevel@tonic-gate 		free(ptr);
8587c478bd9Sstevel@tonic-gate 	}
8597c478bd9Sstevel@tonic-gate 	free(*maps);
8607c478bd9Sstevel@tonic-gate 	*maps = NULL;
8617c478bd9Sstevel@tonic-gate 
8627c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate 
__ns_ldap_getMappedAttributes(const char * service,const char * origAttribute)8657c478bd9Sstevel@tonic-gate char **__ns_ldap_getMappedAttributes(
8667c478bd9Sstevel@tonic-gate 	const char *service,
8677c478bd9Sstevel@tonic-gate 	const char *origAttribute)
8687c478bd9Sstevel@tonic-gate {
8697c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
8707c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
8717c478bd9Sstevel@tonic-gate 	char		**ret;
8727c478bd9Sstevel@tonic-gate 
8737c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
8747c478bd9Sstevel@tonic-gate 		return (NULL);
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_AMAP, service, origAttribute);
8777c478bd9Sstevel@tonic-gate 
8787c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
8797c478bd9Sstevel@tonic-gate 		ret = NULL;
8807c478bd9Sstevel@tonic-gate 	else
8817c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
8827c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
8837c478bd9Sstevel@tonic-gate 	return (ret);
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate 
__ns_ldap_getOrigAttribute(const char * service,const char * mappedAttribute)8867c478bd9Sstevel@tonic-gate char **__ns_ldap_getOrigAttribute(
8877c478bd9Sstevel@tonic-gate 	const char *service,
8887c478bd9Sstevel@tonic-gate 	const char *mappedAttribute)
8897c478bd9Sstevel@tonic-gate {
8907c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
8917c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
8927c478bd9Sstevel@tonic-gate 	char		**ret;
8937c478bd9Sstevel@tonic-gate 
8947c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
8957c478bd9Sstevel@tonic-gate 		return (NULL);
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_RAMAP, service, mappedAttribute);
8987c478bd9Sstevel@tonic-gate 
8997c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9007c478bd9Sstevel@tonic-gate 		ret = NULL;
9017c478bd9Sstevel@tonic-gate 	else
9027c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9037c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9047c478bd9Sstevel@tonic-gate 	return (ret);
9057c478bd9Sstevel@tonic-gate }
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate /*
9087c478bd9Sstevel@tonic-gate  * This function is not supported.
9097c478bd9Sstevel@tonic-gate  */
9107c478bd9Sstevel@tonic-gate /* ARGSUSED */
__ns_ldap_getObjectClassMaps(const char * service,ns_ldap_objectclass_map_t *** maps,ns_ldap_error_t ** errorp)9117c478bd9Sstevel@tonic-gate int __ns_ldap_getObjectClassMaps(
9127c478bd9Sstevel@tonic-gate 	const char *service,
9137c478bd9Sstevel@tonic-gate 	ns_ldap_objectclass_map_t ***maps,
9147c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **errorp)
9157c478bd9Sstevel@tonic-gate {
9167c478bd9Sstevel@tonic-gate 	*maps = NULL;
9177c478bd9Sstevel@tonic-gate 	return (NS_LDAP_OP_FAILED);
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate int
__ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t *** maps)9217c478bd9Sstevel@tonic-gate __ns_ldap_freeObjectClassMaps(ns_ldap_objectclass_map_t ***maps)
9227c478bd9Sstevel@tonic-gate {
9237c478bd9Sstevel@tonic-gate 	ns_ldap_objectclass_map_t **dptr;
9247c478bd9Sstevel@tonic-gate 	ns_ldap_objectclass_map_t *ptr;
9257c478bd9Sstevel@tonic-gate 
9267c478bd9Sstevel@tonic-gate 	if (*maps == NULL)
9277c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
9287c478bd9Sstevel@tonic-gate 	for (dptr = *maps; (ptr = *dptr) != NULL; dptr++) {
9297c478bd9Sstevel@tonic-gate 		if (ptr->origOC) {
9307c478bd9Sstevel@tonic-gate 			free(ptr->origOC);
9317c478bd9Sstevel@tonic-gate 			ptr->origOC = NULL;
9327c478bd9Sstevel@tonic-gate 		}
9337c478bd9Sstevel@tonic-gate 		if (ptr->mappedOC) {
9347c478bd9Sstevel@tonic-gate 			free(ptr->mappedOC);
9357c478bd9Sstevel@tonic-gate 			ptr->mappedOC = NULL;
9367c478bd9Sstevel@tonic-gate 		}
9377c478bd9Sstevel@tonic-gate 		free(ptr);
9387c478bd9Sstevel@tonic-gate 	}
9397c478bd9Sstevel@tonic-gate 	free(*maps);
9407c478bd9Sstevel@tonic-gate 	*maps = NULL;
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
9437c478bd9Sstevel@tonic-gate }
9447c478bd9Sstevel@tonic-gate 
__ns_ldap_getMappedObjectClass(const char * service,const char * origObjectClass)9457c478bd9Sstevel@tonic-gate char **__ns_ldap_getMappedObjectClass(
9467c478bd9Sstevel@tonic-gate 	const char *service,
9477c478bd9Sstevel@tonic-gate 	const char *origObjectClass)
9487c478bd9Sstevel@tonic-gate {
9497c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
9507c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
9517c478bd9Sstevel@tonic-gate 	char		**ret;
9527c478bd9Sstevel@tonic-gate 
9537c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
9547c478bd9Sstevel@tonic-gate 		return (NULL);
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_OMAP, service, origObjectClass);
9577c478bd9Sstevel@tonic-gate 
9587c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9597c478bd9Sstevel@tonic-gate 		ret = NULL;
9607c478bd9Sstevel@tonic-gate 	else
9617c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9627c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9637c478bd9Sstevel@tonic-gate 	return (ret);
9647c478bd9Sstevel@tonic-gate }
9657c478bd9Sstevel@tonic-gate 
__ns_ldap_getOrigObjectClass(const char * service,const char * mappedObjectClass)9667c478bd9Sstevel@tonic-gate char **__ns_ldap_getOrigObjectClass(
9677c478bd9Sstevel@tonic-gate 	const char *service,
9687c478bd9Sstevel@tonic-gate 	const char *mappedObjectClass)
9697c478bd9Sstevel@tonic-gate {
9707c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = __s_api_loadrefresh_config();
9717c478bd9Sstevel@tonic-gate 	ns_hash_t	*hp;
9727c478bd9Sstevel@tonic-gate 	char		**ret;
9737c478bd9Sstevel@tonic-gate 
9747c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
9757c478bd9Sstevel@tonic-gate 		return (NULL);
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 	hp = ns_get_hash(ptr, NS_HASH_ROMAP, service, mappedObjectClass);
9787c478bd9Sstevel@tonic-gate 
9797c478bd9Sstevel@tonic-gate 	if (hp == NULL || hp->h_map == NULL)
9807c478bd9Sstevel@tonic-gate 		ret = NULL;
9817c478bd9Sstevel@tonic-gate 	else
9827c478bd9Sstevel@tonic-gate 		ret = __s_api_cp2dArray(hp->h_map->map);
9837c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9847c478bd9Sstevel@tonic-gate 	return (ret);
9857c478bd9Sstevel@tonic-gate }
9867c478bd9Sstevel@tonic-gate 
__ns_ldap_mapAttributeList(const char * service,const char * const * origAttrList)9877c478bd9Sstevel@tonic-gate char **__ns_ldap_mapAttributeList(
9887c478bd9Sstevel@tonic-gate 	const char *service,
9897c478bd9Sstevel@tonic-gate 	const char * const *origAttrList)
9907c478bd9Sstevel@tonic-gate {
9917c478bd9Sstevel@tonic-gate 	const char * const *opp;
9927c478bd9Sstevel@tonic-gate 	char **cpp, **npp;
9937c478bd9Sstevel@tonic-gate 	int i;
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	if (origAttrList == NULL)
9967c478bd9Sstevel@tonic-gate 		return (NULL);
9977c478bd9Sstevel@tonic-gate 
9987c478bd9Sstevel@tonic-gate 	opp = origAttrList;
9997c478bd9Sstevel@tonic-gate 	for (i = 0; *opp; i++, opp++)
10007c478bd9Sstevel@tonic-gate 		;
10017c478bd9Sstevel@tonic-gate 	cpp = (char **)calloc(i+1, sizeof (char *));
10027c478bd9Sstevel@tonic-gate 	if (cpp == NULL)
10037c478bd9Sstevel@tonic-gate 		return (NULL);
10047c478bd9Sstevel@tonic-gate 
10057c478bd9Sstevel@tonic-gate 	opp = origAttrList;
10067c478bd9Sstevel@tonic-gate 	for (i = 0; *opp; i++, opp++) {
10077c478bd9Sstevel@tonic-gate 		npp =  __ns_ldap_getMappedAttributes(service, *opp);
10087c478bd9Sstevel@tonic-gate 		if (npp && npp[0]) {
10097c478bd9Sstevel@tonic-gate 			cpp[i] = strdup(npp[0]);
10107c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(npp);
10117c478bd9Sstevel@tonic-gate 			npp = NULL;
10127c478bd9Sstevel@tonic-gate 			if (cpp[i] == NULL) {
10137c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(cpp);
10147c478bd9Sstevel@tonic-gate 				return (NULL);
10157c478bd9Sstevel@tonic-gate 			}
10167c478bd9Sstevel@tonic-gate 		} else {
10177c478bd9Sstevel@tonic-gate 			cpp[i] = strdup(*opp);
10187c478bd9Sstevel@tonic-gate 			if (cpp[i] == NULL) {
10197c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(cpp);
10207c478bd9Sstevel@tonic-gate 				return (NULL);
10217c478bd9Sstevel@tonic-gate 			}
10227c478bd9Sstevel@tonic-gate 		}
10237c478bd9Sstevel@tonic-gate 	}
10247c478bd9Sstevel@tonic-gate 	return (cpp);
10257c478bd9Sstevel@tonic-gate }
10269f2fd570SJulian Pullen 
10279f2fd570SJulian Pullen char *
__ns_ldap_mapAttribute(const char * service,const char * origAttr)10289f2fd570SJulian Pullen __ns_ldap_mapAttribute(
10299f2fd570SJulian Pullen 	const char *service,
10309f2fd570SJulian Pullen 	const char *origAttr)
10319f2fd570SJulian Pullen {
10329f2fd570SJulian Pullen 	char **npp;
10339f2fd570SJulian Pullen 	char *mappedAttr;
10349f2fd570SJulian Pullen 
10359f2fd570SJulian Pullen 	if (origAttr == NULL)
10369f2fd570SJulian Pullen 		return (NULL);
10379f2fd570SJulian Pullen 
10389f2fd570SJulian Pullen 	npp = __ns_ldap_getMappedAttributes(service, origAttr);
10399f2fd570SJulian Pullen 	if (npp && npp[0]) {
10409f2fd570SJulian Pullen 		mappedAttr = strdup(npp[0]);
10419f2fd570SJulian Pullen 		__s_api_free2dArray(npp);
10429f2fd570SJulian Pullen 	} else {
10439f2fd570SJulian Pullen 		mappedAttr = strdup(origAttr);
10449f2fd570SJulian Pullen 	}
10459f2fd570SJulian Pullen 	return (mappedAttr);
10469f2fd570SJulian Pullen }
1047