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
5cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6cb5caa98Sdjl  * 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*e1dd0a2fSth  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * libsldap - library side configuration components
307c478bd9Sstevel@tonic-gate  * Routines to manage the config structure
317c478bd9Sstevel@tonic-gate  */
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate #include <stdio.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
35*e1dd0a2fSth #include <stddef.h>
367c478bd9Sstevel@tonic-gate #include <string.h>
377c478bd9Sstevel@tonic-gate #include <strings.h>
387c478bd9Sstevel@tonic-gate #include <libintl.h>
397c478bd9Sstevel@tonic-gate #include <locale.h>
407c478bd9Sstevel@tonic-gate #include <thread.h>
417c478bd9Sstevel@tonic-gate #include <synch.h>
427c478bd9Sstevel@tonic-gate #include <errno.h>
437c478bd9Sstevel@tonic-gate #include <unistd.h>
447c478bd9Sstevel@tonic-gate #include <fcntl.h>
457c478bd9Sstevel@tonic-gate #include <ctype.h>
467c478bd9Sstevel@tonic-gate #include <crypt.h>
477c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
487c478bd9Sstevel@tonic-gate #include <sys/types.h>
497c478bd9Sstevel@tonic-gate #include <sys/stat.h>
507c478bd9Sstevel@tonic-gate #include <syslog.h>
517c478bd9Sstevel@tonic-gate #include <netdb.h>
527c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
537c478bd9Sstevel@tonic-gate #include <sys/mman.h>
547c478bd9Sstevel@tonic-gate #include <sys/time.h>
557c478bd9Sstevel@tonic-gate #include <limits.h>
567c478bd9Sstevel@tonic-gate #include "ns_sldap.h"
577c478bd9Sstevel@tonic-gate #include "ns_internal.h"
587c478bd9Sstevel@tonic-gate #include "ns_cache_door.h"
59*e1dd0a2fSth #include "ns_connmgmt.h"
607c478bd9Sstevel@tonic-gate 
61*e1dd0a2fSth #pragma fini(__s_api_free_sessionPool, __s_api_shutdown_conn_mgmt, \
62*e1dd0a2fSth 	_free_config, __ns_ldap_doorfd_close)
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate static mutex_t		ns_parse_lock = DEFAULTMUTEX;
657c478bd9Sstevel@tonic-gate static mutex_t		ns_loadrefresh_lock = DEFAULTMUTEX;
667c478bd9Sstevel@tonic-gate static ns_config_t	*current_config = NULL;
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate static int		cache_server = FALSE;
69*e1dd0a2fSth extern thread_key_t	ns_cmgkey;
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate  * Parameter Index Type validation routines
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate static int
757c478bd9Sstevel@tonic-gate __s_val_postime(ParamIndexType i, ns_default_config *def,
767c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
777c478bd9Sstevel@tonic-gate static int
787c478bd9Sstevel@tonic-gate __s_val_basedn(ParamIndexType i, ns_default_config *def,
797c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate static int
827c478bd9Sstevel@tonic-gate __s_val_binddn(ParamIndexType i, ns_default_config *def,
837c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
847c478bd9Sstevel@tonic-gate 
857c478bd9Sstevel@tonic-gate static int
867c478bd9Sstevel@tonic-gate __s_val_bindpw(ParamIndexType i, ns_default_config *def,
877c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate static int
907c478bd9Sstevel@tonic-gate __s_val_serverList(ParamIndexType i, ns_default_config *def,
917c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate /*
947c478bd9Sstevel@tonic-gate  * Forward declarations
957c478bd9Sstevel@tonic-gate  */
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate static ns_parse_status
987c478bd9Sstevel@tonic-gate verify_value(ns_config_t *cfg, char *name, char *value, char *errstr);
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate static int
1017c478bd9Sstevel@tonic-gate set_default_value(ns_config_t *configptr, char *name, char *value,
1027c478bd9Sstevel@tonic-gate 	ns_ldap_error_t **error);
1037c478bd9Sstevel@tonic-gate 
1047c478bd9Sstevel@tonic-gate static void
1057c478bd9Sstevel@tonic-gate set_curr_config(ns_config_t *ptr);
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate static int
1087c478bd9Sstevel@tonic-gate __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error);
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate static ns_config_t *
1117c478bd9Sstevel@tonic-gate SetDoorInfo(char *buffer, ns_ldap_error_t **errorp);
1127c478bd9Sstevel@tonic-gate 
1137c478bd9Sstevel@tonic-gate static boolean_t
1147c478bd9Sstevel@tonic-gate timetorefresh(ns_config_t *cfg);
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate static ns_config_t *
117*e1dd0a2fSth LoadCacheConfiguration(ns_config_t *, ns_ldap_error_t **error);
1187c478bd9Sstevel@tonic-gate 
1197c478bd9Sstevel@tonic-gate static void **
1207c478bd9Sstevel@tonic-gate dupParam(ns_param_t *ptr);
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate static time_t
1237c478bd9Sstevel@tonic-gate conv_time(char *s);
1247c478bd9Sstevel@tonic-gate 
1257c478bd9Sstevel@tonic-gate /*
1267c478bd9Sstevel@tonic-gate  * Structures used in enum <-> string mapping routines
1277c478bd9Sstevel@tonic-gate  */
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate static ns_enum_map ns_auth_enum_v1[] = {
1307c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_NONE), "NS_LDAP_AUTH_NONE" },
1317c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SIMPLE), "NS_LDAP_AUTH_SIMPLE" },
1327c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5), "NS_LDAP_AUTH_SASL_CRAM_MD5" },
1337c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1347c478bd9Sstevel@tonic-gate };
1357c478bd9Sstevel@tonic-gate 
1367c478bd9Sstevel@tonic-gate static ns_enum_map ns_auth_enum_v2[] = {
1377c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_NONE), "none" },
1387c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SIMPLE), "simple" },
1397c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5), "sasl/CRAM-MD5" },
1407c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5), "sasl/DIGEST-MD5" },
1417c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_INT),
1427c478bd9Sstevel@tonic-gate 			"sasl/DIGEST-MD5:auth-int" },
1437c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_CONF),
1447c478bd9Sstevel@tonic-gate 			"sasl/DIGEST-MD5:auth-conf" },
1457c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_EXTERNAL), "sasl/EXTERNAL" },
146cb5caa98Sdjl 	{ ENUM2INT(NS_LDAP_EA_SASL_GSSAPI), "sasl/GSSAPI" },
1477c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_NONE), "tls:none" },
1487c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SIMPLE), "tls:simple" },
1497c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_CRAM_MD5), "tls:sasl/CRAM-MD5" },
1507c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5), "tls:sasl/DIGEST-MD5" },
1517c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT),
1527c478bd9Sstevel@tonic-gate 			"tls:sasl/DIGEST-MD5:auth-int" },
1537c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF),
1547c478bd9Sstevel@tonic-gate 			"tls:sasl/DIGEST-MD5:auth-conf" },
1557c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_EXTERNAL), "tls:sasl/EXTERNAL" },
1567c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1577c478bd9Sstevel@tonic-gate };
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate 	/* V1 ONLY */
1607c478bd9Sstevel@tonic-gate static ns_enum_map ns_sec_enum_v1[] = {
1617c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_TLS_NONE), "NS_LDAP_SEC_NONE" },
1627c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1637c478bd9Sstevel@tonic-gate };
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 	/* V2 ONLY */
1667c478bd9Sstevel@tonic-gate static ns_enum_map ns_cred_enum_v2[] = {
1677c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_CRED_ANON), "anonymous" },
1687c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_CRED_PROXY), "proxy" },
1697c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_CRED_SELF), "self" },
1707c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1717c478bd9Sstevel@tonic-gate };
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate static ns_enum_map ns_ref_enum_v1[] = {
1747c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_FOLLOWREF), "NS_LDAP_FOLLOWREF" },
1757c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_NOREF), "NS_LDAP_NOREF" },
1767c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1777c478bd9Sstevel@tonic-gate };
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate static ns_enum_map ns_ref_enum_v2[] = {
1807c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_FOLLOWREF), "TRUE" },
1817c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_NOREF), "FALSE" },
1827c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1837c478bd9Sstevel@tonic-gate };
1847c478bd9Sstevel@tonic-gate 
1857c478bd9Sstevel@tonic-gate static ns_enum_map ns_scope_enum_v1[] = {
1867c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_BASE), "NS_LDAP_SCOPE_BASE" },
1877c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_ONELEVEL), "NS_LDAP_SCOPE_ONELEVEL" },
1887c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_SUBTREE), "NS_LDAP_SCOPE_SUBTREE" },
1897c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1907c478bd9Sstevel@tonic-gate };
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate static ns_enum_map ns_scope_enum_v2[] = {
1937c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_BASE), "base" },
1947c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_ONELEVEL), "one" },
1957c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_SUBTREE), "sub" },
1967c478bd9Sstevel@tonic-gate 	{ -1, NULL },
1977c478bd9Sstevel@tonic-gate };
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate static ns_enum_map ns_pref_enum[] = {
2007c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_PREF_FALSE), "NS_LDAP_FALSE" },
2017c478bd9Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_PREF_TRUE), "NS_LDAP_TRUE" },
2027c478bd9Sstevel@tonic-gate 	{ -1, NULL },
2037c478bd9Sstevel@tonic-gate };
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate static int	ns_def_auth_v1[] = {
2067c478bd9Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_EA_NONE),
2077c478bd9Sstevel@tonic-gate 	0
2087c478bd9Sstevel@tonic-gate };
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate static int	ns_def_auth_v2[] = {
2117c478bd9Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_EA_NONE),
2127c478bd9Sstevel@tonic-gate 	0
2137c478bd9Sstevel@tonic-gate };
2147c478bd9Sstevel@tonic-gate 
2157c478bd9Sstevel@tonic-gate static int	ns_def_cred_v1[] = {
2167c478bd9Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_CRED_PROXY),
2177c478bd9Sstevel@tonic-gate 	0
2187c478bd9Sstevel@tonic-gate };
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate static int	ns_def_cred_v2[] = {
2217c478bd9Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_CRED_ANON),
2227c478bd9Sstevel@tonic-gate 	0
2237c478bd9Sstevel@tonic-gate };
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate  * The next macro places an integer in the first sizeof(int) bytes of a
2277c478bd9Sstevel@tonic-gate  * void pointer location. For 32-bit, it is the same as "(void *) i". It
2287c478bd9Sstevel@tonic-gate  * is used to solve a problem found during 64-bit testing.  The problem
2297c478bd9Sstevel@tonic-gate  * was that for a configuration parameter such as NS_LDAP_SEARCH_REF_P,
2307c478bd9Sstevel@tonic-gate  * which is of type INT and has defined default value, an int
2317c478bd9Sstevel@tonic-gate  * variable(ns_param.ns_pu.i) defined inside an union(ns_pu) structure, is
2327c478bd9Sstevel@tonic-gate  * used to access the defined default value. This requires the default
2337c478bd9Sstevel@tonic-gate  * value to be in the first sizeof(int) bytes of the union element.  If
2347c478bd9Sstevel@tonic-gate  * just using "(void *) intval" to declare the default value in the
2357c478bd9Sstevel@tonic-gate  * following defconfig[] structure, the intval data will be placed is the
2367c478bd9Sstevel@tonic-gate  * last sizeof(int) bytes. In which case, when accessing via ns_pu_i in
2377c478bd9Sstevel@tonic-gate  * a 64-bit system, ZERO will be returned as the default value, not the
2387c478bd9Sstevel@tonic-gate  * defined one.
2397c478bd9Sstevel@tonic-gate  *
2407c478bd9Sstevel@tonic-gate  * Note since amd64 is little-endian, the problem is not an issue.
2417c478bd9Sstevel@tonic-gate  * INT2VOIDPTR will just leave the data (i) unchanged.
2427c478bd9Sstevel@tonic-gate  */
2437c478bd9Sstevel@tonic-gate #if defined(__amd64)
2447c478bd9Sstevel@tonic-gate #define	INT2VOIDPTR(i)	(void *)i
2457c478bd9Sstevel@tonic-gate #else
2467c478bd9Sstevel@tonic-gate #define	INT2VOIDPTR(i)	\
2477c478bd9Sstevel@tonic-gate 	(void *)(((long)(i))<<(8*(sizeof (void *) - sizeof (int))))
2487c478bd9Sstevel@tonic-gate #endif
2497c478bd9Sstevel@tonic-gate /*
2507c478bd9Sstevel@tonic-gate  * The default configuration table
2517c478bd9Sstevel@tonic-gate  * Version 1 entries are first, V2 entries follow.
2527c478bd9Sstevel@tonic-gate  */
2537c478bd9Sstevel@tonic-gate static ns_default_config defconfig[] = {
2547c478bd9Sstevel@tonic-gate 	/* optional V1 profile */
2557c478bd9Sstevel@tonic-gate 	{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
2567c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2577c478bd9Sstevel@tonic-gate 		NULL,	/* No version number defined in V1 */
2587c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)NS_LDAP_VERSION_1 },
2597c478bd9Sstevel@tonic-gate 		NULL, NULL },
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	/* ---------- V1 profile ---------- */
2627c478bd9Sstevel@tonic-gate 	{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
2637c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2647c478bd9Sstevel@tonic-gate 		_P1_BINDDN,
2657c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
2667c478bd9Sstevel@tonic-gate 		__s_val_binddn, NULL },
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate 	{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
2697c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2707c478bd9Sstevel@tonic-gate 		_P1_BINDPASSWORD,
2717c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
2727c478bd9Sstevel@tonic-gate 		__s_val_bindpw, NULL },
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
2757c478bd9Sstevel@tonic-gate 		SERVERCONFIG,	ARRAYCP,	FALSE,	NS_LDAP_V1,
2767c478bd9Sstevel@tonic-gate 		_P1_SERVERS,
2777c478bd9Sstevel@tonic-gate 		{ ARRAYCP, 0, NULL },
2787c478bd9Sstevel@tonic-gate 		__s_val_serverList, NULL },
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
2817c478bd9Sstevel@tonic-gate 		SERVERCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2827c478bd9Sstevel@tonic-gate 		_P1_SEARCHBASEDN,
2837c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
2847c478bd9Sstevel@tonic-gate 		__s_val_basedn, NULL },
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate 	{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
2877c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYAUTH,	FALSE,	NS_LDAP_V1,
2887c478bd9Sstevel@tonic-gate 		_P1_AUTHMETHOD,
2897c478bd9Sstevel@tonic-gate 		{ ARRAYAUTH, 1, (void *)&ns_def_auth_v1[0] },
2907c478bd9Sstevel@tonic-gate 		NULL, ns_auth_enum_v1 },
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	{"NS_LDAP_TRANSPORT_SEC", NS_LDAP_TRANSPORT_SEC_P,
2937c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
2947c478bd9Sstevel@tonic-gate 		_P1_TRANSPORTSECURITY,
2957c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_TLS_NONE) },
2967c478bd9Sstevel@tonic-gate 		NULL, ns_sec_enum_v1 },
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
2997c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3007c478bd9Sstevel@tonic-gate 		_P1_SEARCHREFERRAL,
3017c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF) },
3027c478bd9Sstevel@tonic-gate 		NULL, ns_ref_enum_v1 },
3037c478bd9Sstevel@tonic-gate 
3047c478bd9Sstevel@tonic-gate 	{"NS_LDAP_DOMAIN", NS_LDAP_DOMAIN_P,
3057c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3067c478bd9Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
3077c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3087c478bd9Sstevel@tonic-gate 		NULL, NULL },
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	{"NS_LDAP_EXP", NS_LDAP_EXP_P,
3117c478bd9Sstevel@tonic-gate 		SERVERCONFIG,	TIMET,		TRUE,	NS_LDAP_V1,
3127c478bd9Sstevel@tonic-gate 		NULL,	/* initialized by code to time+NS_LDAP_CACHETTL */
3137c478bd9Sstevel@tonic-gate 		{ INT, 0, 0 },
3147c478bd9Sstevel@tonic-gate 		NULL, NULL },
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	{"NS_LDAP_CERT_PATH", NS_LDAP_CERT_PATH_P,
3177c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3187c478bd9Sstevel@tonic-gate 		_P1_CERTIFICATEPATH,
3197c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3207c478bd9Sstevel@tonic-gate 		NULL, NULL },
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate 	{"NS_LDAP_CERT_PASS", NS_LDAP_CERT_PASS_P,
3237c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3247c478bd9Sstevel@tonic-gate 		_P1_CERTIFICATEPASSWORD,
3257c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3267c478bd9Sstevel@tonic-gate 		NULL, NULL },
3277c478bd9Sstevel@tonic-gate 
3287c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_DN", NS_LDAP_SEARCH_DN_P,
3297c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	SSDLIST,	FALSE,	NS_LDAP_V1,
3307c478bd9Sstevel@tonic-gate 		_P1_DATASEARCHDN,
3317c478bd9Sstevel@tonic-gate 		{ SSDLIST, 0, NULL },
3327c478bd9Sstevel@tonic-gate 		NULL, NULL },
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
3357c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3367c478bd9Sstevel@tonic-gate 		_P1_SEARCHSCOPE,
3377c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL) },
3387c478bd9Sstevel@tonic-gate 		NULL, ns_scope_enum_v1 },
3397c478bd9Sstevel@tonic-gate 
3407c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
3417c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3427c478bd9Sstevel@tonic-gate 		_P1_SEARCHTIMELIMIT,
3437c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
3447c478bd9Sstevel@tonic-gate 		NULL, NULL },
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
3477c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYCP,	FALSE,	NS_LDAP_V1,
3487c478bd9Sstevel@tonic-gate 		_P1_PREFERREDSERVER,
3497c478bd9Sstevel@tonic-gate 		{ ARRAYCP, 0, NULL },
3507c478bd9Sstevel@tonic-gate 		__s_val_serverList, NULL },
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	{"NS_LDAP_PREF_ONLY", NS_LDAP_PREF_ONLY_P,
3537c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3547c478bd9Sstevel@tonic-gate 		_P1_PREFERREDSERVERONLY,
3557c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_PREF_FALSE) },
3567c478bd9Sstevel@tonic-gate 		NULL, ns_pref_enum },
3577c478bd9Sstevel@tonic-gate 
3587c478bd9Sstevel@tonic-gate 	{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
3597c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3607c478bd9Sstevel@tonic-gate 		_P1_CACHETTL,
3617c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
3627c478bd9Sstevel@tonic-gate 		__s_val_postime, NULL },
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
3657c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3667c478bd9Sstevel@tonic-gate 		_P_CN,
3677c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
3687c478bd9Sstevel@tonic-gate 		NULL, NULL },
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate 	{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
3717c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3727c478bd9Sstevel@tonic-gate 		_P1_BINDTIMELIMIT,
3737c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
3747c478bd9Sstevel@tonic-gate 		NULL, NULL },
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	/* This configuration option is not visible in V1 */
3777c478bd9Sstevel@tonic-gate 	{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
3787c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYCRED,	TRUE,	NS_LDAP_V1,
3797c478bd9Sstevel@tonic-gate 		NULL,	/* No version defined in V1 */
3807c478bd9Sstevel@tonic-gate 		{ ARRAYCRED, 0, (void *)&ns_def_cred_v1[0] },
3817c478bd9Sstevel@tonic-gate 		NULL, NULL },
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	/* ---------- V2 profile ---------- */
3847c478bd9Sstevel@tonic-gate 	{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
3857c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
3867c478bd9Sstevel@tonic-gate 		NULL,	/* No version number defined in V1 */
3877c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)NS_LDAP_VERSION_2 },
3887c478bd9Sstevel@tonic-gate 		NULL, NULL },
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate 	{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
3917c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
3927c478bd9Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
3937c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3947c478bd9Sstevel@tonic-gate 		__s_val_binddn, NULL },
3957c478bd9Sstevel@tonic-gate 	{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
3967c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
3977c478bd9Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
3987c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3997c478bd9Sstevel@tonic-gate 		__s_val_bindpw, NULL },
4007c478bd9Sstevel@tonic-gate 	{"NS_LDAP_EXP", NS_LDAP_EXP_P,
4017c478bd9Sstevel@tonic-gate 		SERVERCONFIG,	TIMET,		TRUE,	NS_LDAP_V2,
4027c478bd9Sstevel@tonic-gate 		NULL,	/* initialized by code to time+NS_LDAP_CACHETTL */
4037c478bd9Sstevel@tonic-gate 		{ INT, 0, 0 },
4047c478bd9Sstevel@tonic-gate 		NULL, NULL },
4057c478bd9Sstevel@tonic-gate 
4067c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
4077c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	SERVLIST,	FALSE,	NS_LDAP_V2,
4087c478bd9Sstevel@tonic-gate 		_P2_PREFERREDSERVER,
4097c478bd9Sstevel@tonic-gate 		{ SERVLIST, 0, NULL },
4107c478bd9Sstevel@tonic-gate 		__s_val_serverList, NULL },
4117c478bd9Sstevel@tonic-gate 
4127c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
4137c478bd9Sstevel@tonic-gate 		SERVERCONFIG,	SERVLIST,	FALSE,	NS_LDAP_V2,
4147c478bd9Sstevel@tonic-gate 		_P2_DEFAULTSERVER,
4157c478bd9Sstevel@tonic-gate 		{ SERVLIST, 0, NULL },
4167c478bd9Sstevel@tonic-gate 		__s_val_serverList, NULL },
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
4197c478bd9Sstevel@tonic-gate 		SERVERCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4207c478bd9Sstevel@tonic-gate 		_P2_SEARCHBASEDN,
4217c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
4227c478bd9Sstevel@tonic-gate 		__s_val_basedn, NULL },
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
4257c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4267c478bd9Sstevel@tonic-gate 		_P2_SEARCHSCOPE,
4277c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL) },
4287c478bd9Sstevel@tonic-gate 		NULL, ns_scope_enum_v2 },
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate 	{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
4317c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYAUTH,	FALSE,	NS_LDAP_V2,
4327c478bd9Sstevel@tonic-gate 		_P2_AUTHMETHOD,
4337c478bd9Sstevel@tonic-gate 		{ ARRAYAUTH, 2, (void *)&ns_def_auth_v2[0] },
4347c478bd9Sstevel@tonic-gate 		NULL, ns_auth_enum_v2 },
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 	{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
4377c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYCRED,	FALSE,	NS_LDAP_V2,
4387c478bd9Sstevel@tonic-gate 		_P2_CREDENTIALLEVEL,
4397c478bd9Sstevel@tonic-gate 		{ ARRAYCRED, 0, (void *)&ns_def_cred_v2[0] },
4407c478bd9Sstevel@tonic-gate 		NULL, ns_cred_enum_v2 },
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVICE_SEARCH_DESC", NS_LDAP_SERVICE_SEARCH_DESC_P,
4437c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	SSDLIST,	FALSE,	NS_LDAP_V2,
4447c478bd9Sstevel@tonic-gate 		_P2_SERVICESEARCHDESC,
4457c478bd9Sstevel@tonic-gate 		{ SSDLIST, 0, NULL },
4467c478bd9Sstevel@tonic-gate 		NULL, NULL },
4477c478bd9Sstevel@tonic-gate 
4487c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
4497c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4507c478bd9Sstevel@tonic-gate 		_P2_SEARCHTIMELIMIT,
4517c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
4527c478bd9Sstevel@tonic-gate 		NULL, NULL },
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 	{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
4557c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4567c478bd9Sstevel@tonic-gate 		_P2_BINDTIMELIMIT,
4577c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
4587c478bd9Sstevel@tonic-gate 		NULL, NULL },
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
4617c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4627c478bd9Sstevel@tonic-gate 		_P2_FOLLOWREFERRALS,
4637c478bd9Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF) },
4647c478bd9Sstevel@tonic-gate 		NULL, ns_ref_enum_v2 },
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
4677c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4687c478bd9Sstevel@tonic-gate 		_P2_PROFILETTL,
4697c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
4707c478bd9Sstevel@tonic-gate 		__s_val_postime, NULL },
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate 	{"NS_LDAP_ATTRIBUTEMAP", NS_LDAP_ATTRIBUTEMAP_P,
4737c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	ATTRMAP,	FALSE,	NS_LDAP_V2,
4747c478bd9Sstevel@tonic-gate 		_P2_ATTRIBUTEMAP,
4757c478bd9Sstevel@tonic-gate 		{ ATTRMAP, 0, NULL },
4767c478bd9Sstevel@tonic-gate 		NULL, NULL },
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate 	{"NS_LDAP_OBJECTCLASSMAP", NS_LDAP_OBJECTCLASSMAP_P,
4797c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	OBJMAP,		FALSE,	NS_LDAP_V2,
4807c478bd9Sstevel@tonic-gate 		_P2_OBJECTCLASSMAP,
4817c478bd9Sstevel@tonic-gate 		{ OBJMAP, 0, NULL },
4827c478bd9Sstevel@tonic-gate 		NULL, NULL },
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 	{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
4857c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4867c478bd9Sstevel@tonic-gate 		_P_CN,
4877c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
4887c478bd9Sstevel@tonic-gate 		NULL, NULL },
4897c478bd9Sstevel@tonic-gate 
4907c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVICE_AUTH_METHOD", NS_LDAP_SERVICE_AUTH_METHOD_P,
4917c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	SAMLIST,	FALSE,	NS_LDAP_V2,
4927c478bd9Sstevel@tonic-gate 		_P2_SERVICEAUTHMETHOD,
4937c478bd9Sstevel@tonic-gate 		{ SAMLIST, 0, NULL },
4947c478bd9Sstevel@tonic-gate 		NULL, NULL },
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	{"NS_LDAP_SERVICE_CRED_LEVEL", NS_LDAP_SERVICE_CRED_LEVEL_P,
4977c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	SCLLIST,	FALSE,	NS_LDAP_V2,
4987c478bd9Sstevel@tonic-gate 		_P2_SERVICECREDLEVEL,
4997c478bd9Sstevel@tonic-gate 		{ SCLLIST, 0, NULL },
5007c478bd9Sstevel@tonic-gate 		NULL, NULL },
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	{"NS_LDAP_HOST_CERTPATH", NS_LDAP_HOST_CERTPATH_P,
5037c478bd9Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
5047c478bd9Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
5057c478bd9Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)NSLDAPDIRECTORY },
5067c478bd9Sstevel@tonic-gate 		NULL, NULL },
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	/* array terminator [not an entry] */
5097c478bd9Sstevel@tonic-gate 	{NULL, NS_LDAP_FILE_VERSION_P,
5107c478bd9Sstevel@tonic-gate 		CLIENTCONFIG,	NS_UNKNOWN,	TRUE,	NULL,
5117c478bd9Sstevel@tonic-gate 		NULL,
5127c478bd9Sstevel@tonic-gate 		{ NS_UNKNOWN, 0, NULL },
5137c478bd9Sstevel@tonic-gate 		NULL, NULL },
5147c478bd9Sstevel@tonic-gate };
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate static char *
5177c478bd9Sstevel@tonic-gate __getdomainname()
5187c478bd9Sstevel@tonic-gate {
5197c478bd9Sstevel@tonic-gate 	/*
5207c478bd9Sstevel@tonic-gate 	 * The sysinfo man page recommends using a buffer size
5217c478bd9Sstevel@tonic-gate 	 * of 257 bytes. MAXHOSTNAMELEN is 256. So add 1 here.
5227c478bd9Sstevel@tonic-gate 	 */
5237c478bd9Sstevel@tonic-gate 	char	buf[MAXHOSTNAMELEN + 1];
5247c478bd9Sstevel@tonic-gate 	int	status;
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate 	status = sysinfo(SI_SRPC_DOMAIN, buf, MAXHOSTNAMELEN);
5277c478bd9Sstevel@tonic-gate 	if (status < 0)
5287c478bd9Sstevel@tonic-gate 		return (NULL);
5297c478bd9Sstevel@tonic-gate 	/* error: not enough space to hold returned value */
5307c478bd9Sstevel@tonic-gate 	if (status > sizeof (buf))
5317c478bd9Sstevel@tonic-gate 		return (NULL);
5327c478bd9Sstevel@tonic-gate 	return (strdup(buf));
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate 
5357c478bd9Sstevel@tonic-gate void
5367c478bd9Sstevel@tonic-gate __ns_ldap_setServer(int set)
5377c478bd9Sstevel@tonic-gate {
5387c478bd9Sstevel@tonic-gate 	cache_server = set;
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate static boolean_t
5427c478bd9Sstevel@tonic-gate timetorefresh(ns_config_t *cfg)
5437c478bd9Sstevel@tonic-gate {
5447c478bd9Sstevel@tonic-gate 	struct timeval	tp;
5457c478bd9Sstevel@tonic-gate 	static time_t	expire = 0;
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 	if (cfg == NULL || gettimeofday(&tp, NULL) == -1)
5487c478bd9Sstevel@tonic-gate 		return (B_TRUE);
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	if (cfg->paramList[NS_LDAP_EXP_P].ns_ptype == TIMET)
5517c478bd9Sstevel@tonic-gate 		expire = cfg->paramList[NS_LDAP_EXP_P].ns_tm;
5527c478bd9Sstevel@tonic-gate 	else
5537c478bd9Sstevel@tonic-gate 		return (B_TRUE);
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate 	return (expire != 0 && tp.tv_sec > expire);
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate int
5597c478bd9Sstevel@tonic-gate __s_get_enum_value(ns_config_t *ptr, char *value, ParamIndexType i)
5607c478bd9Sstevel@tonic-gate {
5617c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp;
5627c478bd9Sstevel@tonic-gate 	char			*pstart = value;
5637c478bd9Sstevel@tonic-gate 	char			*pend;
5647c478bd9Sstevel@tonic-gate 	int			len;
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate 	if (pstart == NULL)
5677c478bd9Sstevel@tonic-gate 		return (-1);
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 	/* skip leading spaces */
5707c478bd9Sstevel@tonic-gate 	while (*pstart == SPACETOK)
5717c478bd9Sstevel@tonic-gate 		pstart++;
5727c478bd9Sstevel@tonic-gate 	/* skip trailing spaces */
5737c478bd9Sstevel@tonic-gate 	pend = pstart + strlen(pstart) - 1;
5747ddae043Siz 	for (; pend >= pstart && *pend == SPACETOK; pend--)
5757ddae043Siz 		;
5767c478bd9Sstevel@tonic-gate 	len = pend - pstart + 1;
5777c478bd9Sstevel@tonic-gate 	if (len == 0)
5787c478bd9Sstevel@tonic-gate 		return (-1);
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 	switch (i) {
5817c478bd9Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
5827c478bd9Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
5837c478bd9Sstevel@tonic-gate 			mapp = &ns_auth_enum_v1[0];
5847c478bd9Sstevel@tonic-gate 		else
5857c478bd9Sstevel@tonic-gate 			mapp = &ns_auth_enum_v2[0];
5867c478bd9Sstevel@tonic-gate 		break;
5877c478bd9Sstevel@tonic-gate 	case NS_LDAP_TRANSPORT_SEC_P:
5887c478bd9Sstevel@tonic-gate 		return (-1);
5897c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
5907c478bd9Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
5917c478bd9Sstevel@tonic-gate 			mapp = &ns_scope_enum_v1[0];
5927c478bd9Sstevel@tonic-gate 		else
5937c478bd9Sstevel@tonic-gate 			mapp = &ns_scope_enum_v2[0];
5947c478bd9Sstevel@tonic-gate 		break;
5957c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_REF_P:
5967c478bd9Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
5977c478bd9Sstevel@tonic-gate 			mapp = &ns_ref_enum_v1[0];
5987c478bd9Sstevel@tonic-gate 		else
5997c478bd9Sstevel@tonic-gate 			mapp = &ns_ref_enum_v2[0];
6007c478bd9Sstevel@tonic-gate 		break;
6017c478bd9Sstevel@tonic-gate 	case NS_LDAP_PREF_ONLY_P:
6027c478bd9Sstevel@tonic-gate 		mapp = &ns_pref_enum[0];
6037c478bd9Sstevel@tonic-gate 		break;
6047c478bd9Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
6057c478bd9Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
6067c478bd9Sstevel@tonic-gate 			return (-1);
6077c478bd9Sstevel@tonic-gate 		else
6087c478bd9Sstevel@tonic-gate 			mapp = &ns_cred_enum_v2[0];
6097c478bd9Sstevel@tonic-gate 		break;
6107c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:
6117c478bd9Sstevel@tonic-gate 		mapp = &ns_auth_enum_v2[0];
6127c478bd9Sstevel@tonic-gate 		break;
6137c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:
6147c478bd9Sstevel@tonic-gate 		mapp = &ns_cred_enum_v2[0];
6157c478bd9Sstevel@tonic-gate 		break;
6167c478bd9Sstevel@tonic-gate 	default:
6177c478bd9Sstevel@tonic-gate 		return (-1);
6187c478bd9Sstevel@tonic-gate 	}
6197c478bd9Sstevel@tonic-gate 
6207c478bd9Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
6217c478bd9Sstevel@tonic-gate 		if (strncasecmp(pstart, mapp->name, len) == 0 &&
6227ddae043Siz 		    (strlen(mapp->name) == len)) {
6237c478bd9Sstevel@tonic-gate 			return (mapp->value);
6247c478bd9Sstevel@tonic-gate 		}
6257c478bd9Sstevel@tonic-gate 	}
6267c478bd9Sstevel@tonic-gate 	return (-1);
6277c478bd9Sstevel@tonic-gate }
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate char *
6307c478bd9Sstevel@tonic-gate __s_get_auth_name(ns_config_t *ptr, AuthType_t type)
6317c478bd9Sstevel@tonic-gate {
6327c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp;
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1)
6357c478bd9Sstevel@tonic-gate 		mapp = &ns_auth_enum_v1[0];
6367c478bd9Sstevel@tonic-gate 	else
6377c478bd9Sstevel@tonic-gate 		mapp = &ns_auth_enum_v2[0];
6387c478bd9Sstevel@tonic-gate 
6397c478bd9Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
6407c478bd9Sstevel@tonic-gate 		if (type == INT2AUTHENUM(mapp->value)) {
6417c478bd9Sstevel@tonic-gate 			return (mapp->name);
6427c478bd9Sstevel@tonic-gate 		}
6437c478bd9Sstevel@tonic-gate 	}
6447c478bd9Sstevel@tonic-gate 	return ("Unknown AuthType_t type specified");
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate char *
6497c478bd9Sstevel@tonic-gate __s_get_security_name(ns_config_t *ptr, TlsType_t type)
6507c478bd9Sstevel@tonic-gate {
6517c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp;
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1) {
6547c478bd9Sstevel@tonic-gate 		mapp = &ns_sec_enum_v1[0];
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 		for (; mapp->name != NULL; mapp++) {
6577c478bd9Sstevel@tonic-gate 			if (type == INT2SECENUM(mapp->value)) {
6587c478bd9Sstevel@tonic-gate 				return (mapp->name);
6597c478bd9Sstevel@tonic-gate 			}
6607c478bd9Sstevel@tonic-gate 		}
6617c478bd9Sstevel@tonic-gate 	}
6627c478bd9Sstevel@tonic-gate 	return ("Unknown TlsType_t type specified");
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate char *
6677c478bd9Sstevel@tonic-gate __s_get_scope_name(ns_config_t *ptr, ScopeType_t type)
6687c478bd9Sstevel@tonic-gate {
6697c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp;
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1)
6727c478bd9Sstevel@tonic-gate 		mapp = &ns_scope_enum_v1[0];
6737c478bd9Sstevel@tonic-gate 	else
6747c478bd9Sstevel@tonic-gate 		mapp = &ns_scope_enum_v2[0];
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
6777c478bd9Sstevel@tonic-gate 		if (type == INT2SCOPEENUM(mapp->value)) {
6787c478bd9Sstevel@tonic-gate 			return (mapp->name);
6797c478bd9Sstevel@tonic-gate 		}
6807c478bd9Sstevel@tonic-gate 	}
6817c478bd9Sstevel@tonic-gate 	return ("Unknown ScopeType_t type specified");
6827c478bd9Sstevel@tonic-gate }
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate char *
6867c478bd9Sstevel@tonic-gate __s_get_pref_name(PrefOnly_t type)
6877c478bd9Sstevel@tonic-gate {
6887c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp = &ns_pref_enum[0];
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
6917c478bd9Sstevel@tonic-gate 		if (type == INT2PREFONLYENUM(mapp->value)) {
6927c478bd9Sstevel@tonic-gate 			return (mapp->name);
6937c478bd9Sstevel@tonic-gate 		}
6947c478bd9Sstevel@tonic-gate 	}
6957c478bd9Sstevel@tonic-gate 	return ("Unknown PrefOnly_t type specified");
6967c478bd9Sstevel@tonic-gate }
6977c478bd9Sstevel@tonic-gate 
6987c478bd9Sstevel@tonic-gate char *
6997c478bd9Sstevel@tonic-gate __s_get_searchref_name(ns_config_t *ptr, SearchRef_t type)
7007c478bd9Sstevel@tonic-gate {
7017c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp;
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1)
7047c478bd9Sstevel@tonic-gate 		mapp = &ns_ref_enum_v1[0];
7057c478bd9Sstevel@tonic-gate 	else
7067c478bd9Sstevel@tonic-gate 		mapp = &ns_ref_enum_v2[0];
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
7097c478bd9Sstevel@tonic-gate 		if (type == INT2SEARCHREFENUM(mapp->value)) {
7107c478bd9Sstevel@tonic-gate 			return (mapp->name);
7117c478bd9Sstevel@tonic-gate 		}
7127c478bd9Sstevel@tonic-gate 	}
7137c478bd9Sstevel@tonic-gate 	return ("Unknown SearchRef_t type specified");
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate 
7167c478bd9Sstevel@tonic-gate static char *
7177c478bd9Sstevel@tonic-gate __s_get_credlvl_name(ns_config_t *ptr, CredLevel_t type)
7187c478bd9Sstevel@tonic-gate {
7197c478bd9Sstevel@tonic-gate 	register ns_enum_map	*mapp;
7207c478bd9Sstevel@tonic-gate 
7217c478bd9Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V2) {
7227c478bd9Sstevel@tonic-gate 		mapp = &ns_cred_enum_v2[0];
7237c478bd9Sstevel@tonic-gate 		for (; mapp->name != NULL; mapp++) {
7247c478bd9Sstevel@tonic-gate 			if (type == INT2CREDLEVELENUM(mapp->value)) {
7257c478bd9Sstevel@tonic-gate 				return (mapp->name);
7267c478bd9Sstevel@tonic-gate 			}
7277c478bd9Sstevel@tonic-gate 		}
7287c478bd9Sstevel@tonic-gate 	}
7297c478bd9Sstevel@tonic-gate 	return ("Unknown CredLevel_t type specified");
7307c478bd9Sstevel@tonic-gate }
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate static void
7337c478bd9Sstevel@tonic-gate destroy_param(ns_config_t *ptr, ParamIndexType type)
7347c478bd9Sstevel@tonic-gate {
7357c478bd9Sstevel@tonic-gate 	int	i, j;
7367c478bd9Sstevel@tonic-gate 	char	**ppc;
7377c478bd9Sstevel@tonic-gate 
7387c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
7397c478bd9Sstevel@tonic-gate 		return;
7407c478bd9Sstevel@tonic-gate 
7417c478bd9Sstevel@tonic-gate 	/*
7427c478bd9Sstevel@tonic-gate 	 * This routine is not lock protected because
7437c478bd9Sstevel@tonic-gate 	 * the config param it may be destroying is not
7447c478bd9Sstevel@tonic-gate 	 * necessarily THE config.  Mutex protect elsewhere.
7457c478bd9Sstevel@tonic-gate 	 */
7467c478bd9Sstevel@tonic-gate 	switch (ptr->paramList[type].ns_ptype) {
7477c478bd9Sstevel@tonic-gate 	case CHARPTR:
7487c478bd9Sstevel@tonic-gate 		if (ptr->paramList[type].ns_pc) {
7497c478bd9Sstevel@tonic-gate 			free(ptr->paramList[type].ns_pc);
7507c478bd9Sstevel@tonic-gate 			ptr->paramList[type].ns_pc = NULL;
7517c478bd9Sstevel@tonic-gate 		}
7527c478bd9Sstevel@tonic-gate 		break;
7537c478bd9Sstevel@tonic-gate 	case SAMLIST:
7547c478bd9Sstevel@tonic-gate 	case SCLLIST:
7557c478bd9Sstevel@tonic-gate 	case SSDLIST:
7567c478bd9Sstevel@tonic-gate 	case ARRAYCP:
7577c478bd9Sstevel@tonic-gate 	case SERVLIST:
7587c478bd9Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ppc) {
7597c478bd9Sstevel@tonic-gate 			ppc = ptr->paramList[type].ns_ppc;
7607c478bd9Sstevel@tonic-gate 			j = ptr->paramList[type].ns_acnt;
7617c478bd9Sstevel@tonic-gate 			for (i = 0; i < j && ppc[i] != NULL; i++) {
7627c478bd9Sstevel@tonic-gate 				free((void *)ppc[i]);
7637c478bd9Sstevel@tonic-gate 			}
7647c478bd9Sstevel@tonic-gate 			free((void *)ppc);
7657c478bd9Sstevel@tonic-gate 			ptr->paramList[type].ns_ppc = NULL;
7667c478bd9Sstevel@tonic-gate 		}
7677c478bd9Sstevel@tonic-gate 		break;
7687c478bd9Sstevel@tonic-gate 	case ARRAYAUTH:
7697c478bd9Sstevel@tonic-gate 	case ARRAYCRED:
7707c478bd9Sstevel@tonic-gate 		if (ptr->paramList[type].ns_pi) {
7717c478bd9Sstevel@tonic-gate 			free(ptr->paramList[type].ns_pi);
7727c478bd9Sstevel@tonic-gate 			ptr->paramList[type].ns_pi = NULL;
7737c478bd9Sstevel@tonic-gate 		}
7747c478bd9Sstevel@tonic-gate 		break;
7757c478bd9Sstevel@tonic-gate 	case INT:
7767c478bd9Sstevel@tonic-gate 		ptr->paramList[type].ns_i = 0;
7777c478bd9Sstevel@tonic-gate 		break;
7787c478bd9Sstevel@tonic-gate 	case ATTRMAP:
7797c478bd9Sstevel@tonic-gate 		break;
7807c478bd9Sstevel@tonic-gate 	case OBJMAP:
7817c478bd9Sstevel@tonic-gate 		break;
7827c478bd9Sstevel@tonic-gate 	default:
7837c478bd9Sstevel@tonic-gate 		break;
7847c478bd9Sstevel@tonic-gate 	}
7857c478bd9Sstevel@tonic-gate 	ptr->paramList[type].ns_ptype = NS_UNKNOWN;
7867c478bd9Sstevel@tonic-gate }
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate static void
7897c478bd9Sstevel@tonic-gate destroy_config(ns_config_t *ptr)
7907c478bd9Sstevel@tonic-gate {
7917c478bd9Sstevel@tonic-gate 	ParamIndexType	i;
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate 	if (ptr != NULL) {
794*e1dd0a2fSth 		if (ptr == current_config)
795*e1dd0a2fSth 			current_config = NULL;
7967c478bd9Sstevel@tonic-gate 		if (ptr->domainName != NULL)
7977c478bd9Sstevel@tonic-gate 			free(ptr->domainName);
7987c478bd9Sstevel@tonic-gate 			ptr->domainName = NULL;
7997c478bd9Sstevel@tonic-gate 		for (i = 0; i <= LAST_VALUE; i++) {
8007c478bd9Sstevel@tonic-gate 			destroy_param(ptr, i);
8017c478bd9Sstevel@tonic-gate 		}
8027c478bd9Sstevel@tonic-gate 		__s_api_destroy_hash(ptr);
8037c478bd9Sstevel@tonic-gate 		free(ptr);
8047c478bd9Sstevel@tonic-gate 	}
8057c478bd9Sstevel@tonic-gate }
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate /*
8087c478bd9Sstevel@tonic-gate  * Marks the ns_config_t to be deleted and then releases it. (If no other
8097c478bd9Sstevel@tonic-gate  * caller is using, then __s_api_release_config will destroy it.)
8107c478bd9Sstevel@tonic-gate  *
8117c478bd9Sstevel@tonic-gate  * Note that __s_api_destroy_config should only be called if the caller has
8127c478bd9Sstevel@tonic-gate  * created the ns_config_t with __s_api_create_config (with the exception
8137c478bd9Sstevel@tonic-gate  * of set_curr_config). The ns_config_t should be private to the caller.
8147c478bd9Sstevel@tonic-gate  *
8157c478bd9Sstevel@tonic-gate  * This function should not be called with the current_config except by
8167c478bd9Sstevel@tonic-gate  * set_curr_config which locks ns_parse_lock to ensure that no thread
8177c478bd9Sstevel@tonic-gate  * will be waiting on current_config->config_mutex. This ensures that
8187c478bd9Sstevel@tonic-gate  * no caller with be waiting on cfg->config_mutex while it is being
8197c478bd9Sstevel@tonic-gate  * destroyed by __s_api_release_config.
8207c478bd9Sstevel@tonic-gate  */
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate void
8237c478bd9Sstevel@tonic-gate __s_api_destroy_config(ns_config_t *cfg)
8247c478bd9Sstevel@tonic-gate {
8257c478bd9Sstevel@tonic-gate 	if (cfg != NULL) {
8267c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&cfg->config_mutex);
8277c478bd9Sstevel@tonic-gate 		cfg->delete = TRUE;
8287c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&cfg->config_mutex);
8297c478bd9Sstevel@tonic-gate 		__s_api_release_config(cfg);
8307c478bd9Sstevel@tonic-gate 	}
8317c478bd9Sstevel@tonic-gate }
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 
8347c478bd9Sstevel@tonic-gate /*
8357c478bd9Sstevel@tonic-gate  * Increment the configuration use count by one - assumes ns_parse_lock has
836*e1dd0a2fSth  * been obtained.
8377c478bd9Sstevel@tonic-gate  */
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate static ns_config_t *
840*e1dd0a2fSth get_curr_config_unlocked(ns_config_t *cfg)
8417c478bd9Sstevel@tonic-gate {
8427c478bd9Sstevel@tonic-gate 	ns_config_t *ret;
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 	ret = cfg;
8457c478bd9Sstevel@tonic-gate 	if (cfg != NULL) {
8467c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&cfg->config_mutex);
8477c478bd9Sstevel@tonic-gate 		if (cfg->delete)
8487c478bd9Sstevel@tonic-gate 			ret = NULL;
8497c478bd9Sstevel@tonic-gate 		else
8507c478bd9Sstevel@tonic-gate 			cfg->nUse++;
8517c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&cfg->config_mutex);
8527c478bd9Sstevel@tonic-gate 	}
8537c478bd9Sstevel@tonic-gate 	return (ret);
8547c478bd9Sstevel@tonic-gate }
8557c478bd9Sstevel@tonic-gate 
8567c478bd9Sstevel@tonic-gate /*
857*e1dd0a2fSth  * set_curr_config_global sets the current global config to the
858*e1dd0a2fSth  * specified ns_config_t. Note that this function is similar
859*e1dd0a2fSth  * to the project private function __s_api_init_config_global
860*e1dd0a2fSth  * except that it does not release the new ns_config_t.
8617c478bd9Sstevel@tonic-gate  */
8627c478bd9Sstevel@tonic-gate static void
863*e1dd0a2fSth set_curr_config_global(ns_config_t *ptr)
8647c478bd9Sstevel@tonic-gate {
865*e1dd0a2fSth 	ns_config_t	*cfg;
866*e1dd0a2fSth 	ns_config_t	*cur_cfg;
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&ns_parse_lock);
869*e1dd0a2fSth 	cur_cfg = current_config;
870*e1dd0a2fSth 	cfg = get_curr_config_unlocked(cur_cfg);
8717c478bd9Sstevel@tonic-gate 	if (cfg != ptr) {
8727c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(cfg);
8737c478bd9Sstevel@tonic-gate 		current_config = ptr;
8747c478bd9Sstevel@tonic-gate 	}
8757c478bd9Sstevel@tonic-gate 	(void) mutex_unlock(&ns_parse_lock);
8767c478bd9Sstevel@tonic-gate }
8777c478bd9Sstevel@tonic-gate 
878*e1dd0a2fSth 
879*e1dd0a2fSth /*
880*e1dd0a2fSth  * set_curr_config sets the current config or the per connection
881*e1dd0a2fSth  * management one to the specified ns_config_t. Note that this function
882*e1dd0a2fSth  * is similar to the project private function __s_api_init_config
883*e1dd0a2fSth  * except that it does not release the new ns_config_t. Also note
884*e1dd0a2fSth  * that if there's no per connection management one to set, the
885*e1dd0a2fSth  * global current config will be set.
886*e1dd0a2fSth  */
887*e1dd0a2fSth 
888*e1dd0a2fSth static void
889*e1dd0a2fSth set_curr_config(ns_config_t *ptr)
890*e1dd0a2fSth {
891*e1dd0a2fSth 	ns_config_t	*cfg;
892*e1dd0a2fSth 	ns_config_t	*cur_cfg;
893*e1dd0a2fSth 	ns_conn_mgmt_t	*cmg;
894*e1dd0a2fSth 	int		rc;
895*e1dd0a2fSth 
896*e1dd0a2fSth 	rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
897*e1dd0a2fSth 
898*e1dd0a2fSth 	/* set the per connection management config if possible */
899*e1dd0a2fSth 	if (rc == 0 && cmg != NULL && cmg->config != NULL) {
900*e1dd0a2fSth 		(void) mutex_lock(&cmg->cfg_lock);
901*e1dd0a2fSth 		cur_cfg = cmg->config;
902*e1dd0a2fSth 		cfg = get_curr_config_unlocked(cur_cfg);
903*e1dd0a2fSth 		if (cfg != ptr) {
904*e1dd0a2fSth 			__s_api_destroy_config(cfg);
905*e1dd0a2fSth 			cmg->config = ptr;
906*e1dd0a2fSth 		}
907*e1dd0a2fSth 		(void) mutex_unlock(&cmg->cfg_lock);
908*e1dd0a2fSth 		return;
909*e1dd0a2fSth 	}
910*e1dd0a2fSth 
911*e1dd0a2fSth 	/* else set the global current config */
912*e1dd0a2fSth 	set_curr_config_global(ptr);
913*e1dd0a2fSth }
914*e1dd0a2fSth 
9157c478bd9Sstevel@tonic-gate /*
9167c478bd9Sstevel@tonic-gate  * Decrements the ns_config_t usage count by one. Delete if delete flag
9177c478bd9Sstevel@tonic-gate  * is set and no other callers are using.
9187c478bd9Sstevel@tonic-gate  */
9197c478bd9Sstevel@tonic-gate 
9207c478bd9Sstevel@tonic-gate void
9217c478bd9Sstevel@tonic-gate __s_api_release_config(ns_config_t *cfg)
9227c478bd9Sstevel@tonic-gate {
9237c478bd9Sstevel@tonic-gate 	if (cfg != NULL) {
9247c478bd9Sstevel@tonic-gate 		(void) mutex_lock(&cfg->config_mutex);
9257c478bd9Sstevel@tonic-gate 		cfg->nUse--;
9267c478bd9Sstevel@tonic-gate 		if (cfg->nUse == 0 && cfg->delete) {
9277c478bd9Sstevel@tonic-gate 			destroy_config(cfg);
9287c478bd9Sstevel@tonic-gate 		} else
9297c478bd9Sstevel@tonic-gate 			(void) mutex_unlock(&cfg->config_mutex);
9307c478bd9Sstevel@tonic-gate 	}
9317c478bd9Sstevel@tonic-gate }
9327c478bd9Sstevel@tonic-gate 
933*e1dd0a2fSth /*
934*e1dd0a2fSth  * __s_api_init_config function destroys the previous global configuration
935*e1dd0a2fSth  * sets the new global configuration and then releases it
936*e1dd0a2fSth  */
937*e1dd0a2fSth void
938*e1dd0a2fSth __s_api_init_config_global(ns_config_t *ptr)
939*e1dd0a2fSth {
940*e1dd0a2fSth 	set_curr_config_global(ptr);
941*e1dd0a2fSth 	__s_api_release_config(ptr);
942*e1dd0a2fSth }
943*e1dd0a2fSth 
9447c478bd9Sstevel@tonic-gate /*
9457c478bd9Sstevel@tonic-gate  * __s_api_init_config function destroys the previous configuration
946*e1dd0a2fSth  * sets the new configuration and then releases it. The configuration
947*e1dd0a2fSth  * may be the global one or the per connection management one.
9487c478bd9Sstevel@tonic-gate  */
9497c478bd9Sstevel@tonic-gate void
9507c478bd9Sstevel@tonic-gate __s_api_init_config(ns_config_t *ptr)
9517c478bd9Sstevel@tonic-gate {
9527c478bd9Sstevel@tonic-gate 	set_curr_config(ptr);
9537c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
9547c478bd9Sstevel@tonic-gate }
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate /*
9587c478bd9Sstevel@tonic-gate  * Create an ns_config_t, set the usage count to one
9597c478bd9Sstevel@tonic-gate  */
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate ns_config_t *
9627c478bd9Sstevel@tonic-gate __s_api_create_config(void)
9637c478bd9Sstevel@tonic-gate {
9647c478bd9Sstevel@tonic-gate 	ns_config_t	*ret;
9657c478bd9Sstevel@tonic-gate 	ret = (ns_config_t *)calloc(1, sizeof (ns_config_t));
9667c478bd9Sstevel@tonic-gate 	if (ret == NULL)
9677c478bd9Sstevel@tonic-gate 		return (NULL);
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 	ret->domainName = __getdomainname();
9707c478bd9Sstevel@tonic-gate 	if (ret->domainName == NULL) {
9717c478bd9Sstevel@tonic-gate 		free(ret);
9727c478bd9Sstevel@tonic-gate 		return (NULL);
9737c478bd9Sstevel@tonic-gate 	}
9747c478bd9Sstevel@tonic-gate 	ret->version = NS_LDAP_V1;
9757c478bd9Sstevel@tonic-gate 	(void) mutex_init(&ret->config_mutex, USYNC_THREAD, NULL);
9767c478bd9Sstevel@tonic-gate 	ret->nUse = 1;
9777c478bd9Sstevel@tonic-gate 	ret->delete = B_FALSE;
9787c478bd9Sstevel@tonic-gate 	return (ret);
9797c478bd9Sstevel@tonic-gate }
9807c478bd9Sstevel@tonic-gate 
981*e1dd0a2fSth /*
982*e1dd0a2fSth  * __s_api_get_default_config_global returns the current global config
983*e1dd0a2fSth  */
9847c478bd9Sstevel@tonic-gate ns_config_t *
985*e1dd0a2fSth __s_api_get_default_config_global(void)
9867c478bd9Sstevel@tonic-gate {
987*e1dd0a2fSth 	ns_config_t	*cfg;
988*e1dd0a2fSth 	ns_config_t	*cur_cfg;
9897c478bd9Sstevel@tonic-gate 
9907c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&ns_parse_lock);
991*e1dd0a2fSth 	cur_cfg = current_config;
992*e1dd0a2fSth 	cfg = get_curr_config_unlocked(cur_cfg);
9937c478bd9Sstevel@tonic-gate 	(void) mutex_unlock(&ns_parse_lock);
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate 	return (cfg);
9967c478bd9Sstevel@tonic-gate }
9977c478bd9Sstevel@tonic-gate 
998*e1dd0a2fSth /*
999*e1dd0a2fSth  * __s_api_get_default_config returns the current global config or the
1000*e1dd0a2fSth  * per connection management one.
1001*e1dd0a2fSth  */
1002*e1dd0a2fSth ns_config_t *
1003*e1dd0a2fSth __s_api_get_default_config(void)
1004*e1dd0a2fSth {
1005*e1dd0a2fSth 	ns_config_t	*cfg;
1006*e1dd0a2fSth 	ns_config_t	*cur_cfg;
1007*e1dd0a2fSth 	ns_conn_mgmt_t	*cmg;
1008*e1dd0a2fSth 	int		rc;
1009*e1dd0a2fSth 
1010*e1dd0a2fSth 	rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
1011*e1dd0a2fSth 
1012*e1dd0a2fSth 	/* get the per connection management config if available */
1013*e1dd0a2fSth 	if (rc == 0 && cmg != NULL && cmg->config != NULL) {
1014*e1dd0a2fSth 		(void) mutex_lock(&cmg->cfg_lock);
1015*e1dd0a2fSth 		cur_cfg = cmg->config;
1016*e1dd0a2fSth 		cfg = get_curr_config_unlocked(cur_cfg);
1017*e1dd0a2fSth 		(void) mutex_unlock(&cmg->cfg_lock);
1018*e1dd0a2fSth 		return (cfg);
1019*e1dd0a2fSth 	}
1020*e1dd0a2fSth 
1021*e1dd0a2fSth 	/* else get the global current config */
1022*e1dd0a2fSth 	return (__s_api_get_default_config_global());
1023*e1dd0a2fSth }
1024*e1dd0a2fSth 
10257c478bd9Sstevel@tonic-gate static char *
10267c478bd9Sstevel@tonic-gate stripdup(const char *instr)
10277c478bd9Sstevel@tonic-gate {
10287c478bd9Sstevel@tonic-gate 	char	*pstart = (char *)instr;
10297c478bd9Sstevel@tonic-gate 	char	*pend, *ret;
10307c478bd9Sstevel@tonic-gate 	int	len;
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 	if (pstart == NULL)
10337c478bd9Sstevel@tonic-gate 		return (NULL);
10347c478bd9Sstevel@tonic-gate 	/* remove leading spaces */
10357c478bd9Sstevel@tonic-gate 	while (*pstart == SPACETOK)
10367c478bd9Sstevel@tonic-gate 		pstart++;
10377c478bd9Sstevel@tonic-gate 	/* remove trailing spaces */
10387c478bd9Sstevel@tonic-gate 	pend = pstart + strlen(pstart) - 1;
10397ddae043Siz 	for (; pend >= pstart && *pend == SPACETOK; pend--)
10407ddae043Siz 		;
10417c478bd9Sstevel@tonic-gate 	len = pend - pstart + 1;
10427c478bd9Sstevel@tonic-gate 	if ((ret = malloc(len + 1)) == NULL)
10437c478bd9Sstevel@tonic-gate 		return (NULL);
10447c478bd9Sstevel@tonic-gate 	if (len != 0) {
10457c478bd9Sstevel@tonic-gate 		(void) strncpy(ret, pstart, len);
10467c478bd9Sstevel@tonic-gate 	}
10477c478bd9Sstevel@tonic-gate 	ret[len] = '\0';
10487c478bd9Sstevel@tonic-gate 	return (ret);
10497c478bd9Sstevel@tonic-gate }
10507c478bd9Sstevel@tonic-gate 
10517c478bd9Sstevel@tonic-gate /*
10527c478bd9Sstevel@tonic-gate  * Note that __s_api_crosscheck is assumed to be called with an ns_config_t
10537c478bd9Sstevel@tonic-gate  * that is properly protected - so that it will not change during the
10547c478bd9Sstevel@tonic-gate  * duration of the call
10557c478bd9Sstevel@tonic-gate  */
10567c478bd9Sstevel@tonic-gate 
10577c478bd9Sstevel@tonic-gate /* Size of errstr needs to be MAXERROR */
10587c478bd9Sstevel@tonic-gate ns_parse_status
10597c478bd9Sstevel@tonic-gate __s_api_crosscheck(ns_config_t *ptr, char *errstr, int check_dn)
10607c478bd9Sstevel@tonic-gate {
10617c478bd9Sstevel@tonic-gate 	int		value, j;
10627c478bd9Sstevel@tonic-gate 	time_t		tm;
10637c478bd9Sstevel@tonic-gate 	const char	*str, *str1;
1064*e1dd0a2fSth 	int		i, cnt;
1065*e1dd0a2fSth 	int		self, gssapi;
10667c478bd9Sstevel@tonic-gate 
10677c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
10687c478bd9Sstevel@tonic-gate 		return (NS_SUCCESS);
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate 	/* check for no server specified */
10717c478bd9Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_SERVERS_P].ns_ppc == NULL) {
10727c478bd9Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1) {
10737c478bd9Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
10747ddae043Siz 			    NS_LDAP_SERVERS_P));
10757c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
10767ddae043Siz 			    gettext("Configuration Error: No entry for "
10777ddae043Siz 			    "'%s' found"), str);
10787c478bd9Sstevel@tonic-gate 			return (NS_PARSE_ERR);
10797c478bd9Sstevel@tonic-gate 		} else if (ptr->paramList[NS_LDAP_SERVER_PREF_P].ns_ppc ==
10807ddae043Siz 		    NULL) {
10817c478bd9Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
10827ddae043Siz 			    NS_LDAP_SERVERS_P));
10837c478bd9Sstevel@tonic-gate 			str1 = NULL_OR_STR(__s_api_get_configname(
10847ddae043Siz 			    NS_LDAP_SERVER_PREF_P));
10857c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
10867ddae043Siz 			    gettext("Configuration Error: "
10877ddae043Siz 			    "Neither '%s' nor '%s' is defined"), str, str1);
10887c478bd9Sstevel@tonic-gate 			return (NS_PARSE_ERR);
10897c478bd9Sstevel@tonic-gate 		}
10907c478bd9Sstevel@tonic-gate 	}
10917c478bd9Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc != NULL &&
10927ddae043Siz 	    ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc == NULL) {
10937c478bd9Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
10947ddae043Siz 			    NS_LDAP_CERT_PASS_P));
10957c478bd9Sstevel@tonic-gate 			str1 = NULL_OR_STR(__s_api_get_configname(
10967ddae043Siz 			    NS_LDAP_CERT_PATH_P));
10977c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
10987c478bd9Sstevel@tonic-gate 			gettext("Configuration Error: %s specified "
10997ddae043Siz 			    "but no value for '%s' found"), str, str1);
11007c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
11017c478bd9Sstevel@tonic-gate 	}
11027c478bd9Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc == NULL &&
11037ddae043Siz 	    ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc != NULL) {
11047c478bd9Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
11057ddae043Siz 			    NS_LDAP_CERT_PATH_P));
11067c478bd9Sstevel@tonic-gate 			str1 = NULL_OR_STR(__s_api_get_configname(
11077ddae043Siz 			    NS_LDAP_CERT_PASS_P));
11087c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
11097c478bd9Sstevel@tonic-gate 			gettext("Configuration Error: %s specified "
11107ddae043Siz 			    "but no value for '%s' found"), str, str1);
11117c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
11127c478bd9Sstevel@tonic-gate 	}
11137c478bd9Sstevel@tonic-gate 	/* check if search basedn has been specified */
11147c478bd9Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ppc == NULL) {
11157c478bd9Sstevel@tonic-gate 		str = NULL_OR_STR(__s_api_get_configname(
11167ddae043Siz 		    NS_LDAP_SEARCH_BASEDN_P));
11177c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, MAXERROR,
11187ddae043Siz 		    gettext("Configuration Error: No entry for "
11197ddae043Siz 		    "'%s' found"), str);
11207c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
11217c478bd9Sstevel@tonic-gate 	}
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate 	if (check_dn) {
11247c478bd9Sstevel@tonic-gate 	    /* check for auth value....passwd/bindn if necessary */
11257c478bd9Sstevel@tonic-gate 
11267ddae043Siz 		for (j = 0; ptr->paramList[NS_LDAP_AUTH_P].ns_pi != NULL &&
11277c478bd9Sstevel@tonic-gate 		    ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j] != NULL; j++) {
11287c478bd9Sstevel@tonic-gate 		value = ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j];
11297c478bd9Sstevel@tonic-gate 		switch (value) {
11307ddae043Siz 		case NS_LDAP_EA_SIMPLE:
11317ddae043Siz 		case NS_LDAP_EA_SASL_CRAM_MD5:
11327ddae043Siz 		case NS_LDAP_EA_SASL_DIGEST_MD5:
11337ddae043Siz 		case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
11347ddae043Siz 		case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
11357ddae043Siz 		case NS_LDAP_EA_TLS_SIMPLE:
11367ddae043Siz 		case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
11377ddae043Siz 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
11387ddae043Siz 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
11397ddae043Siz 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
11407c478bd9Sstevel@tonic-gate 			if (ptr->paramList[NS_LDAP_BINDDN_P].ns_ppc == NULL) {
11417c478bd9Sstevel@tonic-gate 				str = NULL_OR_STR(__s_api_get_configname(
11427ddae043Siz 				    NS_LDAP_BINDDN_P));
11437c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, MAXERROR,
11447c478bd9Sstevel@tonic-gate 				gettext("Configuration Error: No entry for "
11457c478bd9Sstevel@tonic-gate 				    "'%s' found"), str);
11467c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
11477c478bd9Sstevel@tonic-gate 			}
11487c478bd9Sstevel@tonic-gate 			if (ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ppc
11497ddae043Siz 			    == NULL) {
11507c478bd9Sstevel@tonic-gate 				str = NULL_OR_STR(__s_api_get_configname(
11517ddae043Siz 				    NS_LDAP_BINDPASSWD_P));
11527c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, MAXERROR,
11537c478bd9Sstevel@tonic-gate 				gettext("Configuration Error: No entry for "
11547ddae043Siz 				    "'%s' found"), str);
11557c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
11567c478bd9Sstevel@tonic-gate 			}
11577c478bd9Sstevel@tonic-gate 			break;
11587c478bd9Sstevel@tonic-gate 		}
11597ddae043Siz 		}
11607c478bd9Sstevel@tonic-gate 	}
11617c478bd9Sstevel@tonic-gate 
11627c478bd9Sstevel@tonic-gate 	/*
11637c478bd9Sstevel@tonic-gate 	 * If NS_LDAP_CACHETTL is not specified,
11647c478bd9Sstevel@tonic-gate 	 * init NS_LDAP_EXP_P here. Otherwise,
11657c478bd9Sstevel@tonic-gate 	 * ldap_cachemgr will never refresh the profile.
11667c478bd9Sstevel@tonic-gate 	 * Set it to current time + default
11677c478bd9Sstevel@tonic-gate 	 * NS_LDAP_CACHETTL
11687c478bd9Sstevel@tonic-gate 	 */
11697c478bd9Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc == NULL) {
11707c478bd9Sstevel@tonic-gate 		tm = conv_time(
11717ddae043Siz 		    defconfig[NS_LDAP_CACHETTL_P].defval.ns_pc);
11727c478bd9Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
11737c478bd9Sstevel@tonic-gate 		if (tm != 0) {
11747c478bd9Sstevel@tonic-gate 			tm += time(NULL);
11757c478bd9Sstevel@tonic-gate 		}
11767c478bd9Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
11777c478bd9Sstevel@tonic-gate 	}
1178cb5caa98Sdjl 	/*
1179cb5caa98Sdjl 	 * If credential level self is defined, there should be
1180cb5caa98Sdjl 	 * at least an auth method sasl/GSSAPI and vice versa.
1181cb5caa98Sdjl 	 */
1182cb5caa98Sdjl 	self = 0;
1183cb5caa98Sdjl 	cnt = ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_acnt;
1184cb5caa98Sdjl 	for (i = 0; i < cnt; i++) {
1185cb5caa98Sdjl 		if (ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_pi[i] ==
11867ddae043Siz 		    NS_LDAP_CRED_SELF)
1187cb5caa98Sdjl 			self++;
1188cb5caa98Sdjl 	}
1189cb5caa98Sdjl 	gssapi = 0;
1190cb5caa98Sdjl 	cnt = ptr->paramList[NS_LDAP_AUTH_P].ns_acnt;
1191cb5caa98Sdjl 	for (i = 0; i < cnt; i++) {
1192cb5caa98Sdjl 		if (ptr->paramList[NS_LDAP_AUTH_P].ns_pi[i] ==
11937ddae043Siz 		    NS_LDAP_EA_SASL_GSSAPI)
1194cb5caa98Sdjl 			gssapi++;
1195cb5caa98Sdjl 	}
1196cb5caa98Sdjl 	if (gssapi == 0 && self > 0) {
1197cb5caa98Sdjl 		(void) snprintf(errstr, MAXERROR,
11987ddae043Siz 		    gettext("Configuration Error: "
11997ddae043Siz 		    "Credential level self requires "
12007ddae043Siz 		    "authentication method sasl/GSSAPI"));
1201cb5caa98Sdjl 		return (NS_PARSE_ERR);
1202cb5caa98Sdjl 	}
1203cb5caa98Sdjl 	if (gssapi > 0 && self == 0) {
1204cb5caa98Sdjl 		(void) snprintf(errstr, MAXERROR,
12057ddae043Siz 		    gettext("Configuration Error: "
12067ddae043Siz 		    "Authentication method sasl/GSSAPI "
12077ddae043Siz 		    "requires credential level self"));
1208cb5caa98Sdjl 		return (NS_PARSE_ERR);
1209cb5caa98Sdjl 	}
12107c478bd9Sstevel@tonic-gate 	return (NS_SUCCESS);
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate 
12137c478bd9Sstevel@tonic-gate 
12147c478bd9Sstevel@tonic-gate int
12157c478bd9Sstevel@tonic-gate __s_api_get_type(const char *value, ParamIndexType *type)
12167c478bd9Sstevel@tonic-gate {
12177c478bd9Sstevel@tonic-gate 	int	i;
12187c478bd9Sstevel@tonic-gate 
12197c478bd9Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
12207c478bd9Sstevel@tonic-gate 		if (strcasecmp(defconfig[i].name, value) == 0) {
12217c478bd9Sstevel@tonic-gate 			*type = defconfig[i].index;
12227c478bd9Sstevel@tonic-gate 			return (0);
12237c478bd9Sstevel@tonic-gate 		}
12247c478bd9Sstevel@tonic-gate 	}
12257c478bd9Sstevel@tonic-gate 	return (-1);
12267c478bd9Sstevel@tonic-gate }
12277c478bd9Sstevel@tonic-gate 
12287c478bd9Sstevel@tonic-gate /*
12297c478bd9Sstevel@tonic-gate  * Externally defined version of get_type.
12307c478bd9Sstevel@tonic-gate  * Includes extra error checking
12317c478bd9Sstevel@tonic-gate  */
12327c478bd9Sstevel@tonic-gate 
12337c478bd9Sstevel@tonic-gate int
12347c478bd9Sstevel@tonic-gate __ns_ldap_getParamType(const char *value, ParamIndexType *type)
12357c478bd9Sstevel@tonic-gate {
12367c478bd9Sstevel@tonic-gate 	if (value == NULL || type == NULL)
12377c478bd9Sstevel@tonic-gate 		return (-1);
12387c478bd9Sstevel@tonic-gate 	return (__s_api_get_type(value, type));
12397c478bd9Sstevel@tonic-gate }
12407c478bd9Sstevel@tonic-gate 
12417c478bd9Sstevel@tonic-gate int
12427c478bd9Sstevel@tonic-gate __s_api_get_versiontype(ns_config_t *ptr, char *value, ParamIndexType *type)
12437c478bd9Sstevel@tonic-gate {
12447c478bd9Sstevel@tonic-gate 	ns_version_t	ver;
12457c478bd9Sstevel@tonic-gate 	int		i;
12467c478bd9Sstevel@tonic-gate 
12477c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
12487c478bd9Sstevel@tonic-gate 		return (-1);
12497c478bd9Sstevel@tonic-gate 
12507c478bd9Sstevel@tonic-gate 	ver = ptr->version;
12517c478bd9Sstevel@tonic-gate 
12527c478bd9Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
12537c478bd9Sstevel@tonic-gate 		if (strcasecmp(defconfig[i].name, value) == 0) {
12547c478bd9Sstevel@tonic-gate 			if (defconfig[i].version == ver) {
12557c478bd9Sstevel@tonic-gate 				*type = defconfig[i].index;
12567c478bd9Sstevel@tonic-gate 				return (0);
12577c478bd9Sstevel@tonic-gate 			}
12587c478bd9Sstevel@tonic-gate 		}
12597c478bd9Sstevel@tonic-gate 	}
12607c478bd9Sstevel@tonic-gate 	return (-1);
12617c478bd9Sstevel@tonic-gate }
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate int
12647c478bd9Sstevel@tonic-gate __s_api_get_profiletype(char *value, ParamIndexType *type)
12657c478bd9Sstevel@tonic-gate {
12667c478bd9Sstevel@tonic-gate 	int	i;
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
12697c478bd9Sstevel@tonic-gate 		if (defconfig[i].profile_name == NULL)
12707c478bd9Sstevel@tonic-gate 			continue;
12717c478bd9Sstevel@tonic-gate 		if (strcasecmp(defconfig[i].profile_name, value) == 0) {
12727c478bd9Sstevel@tonic-gate 			*type = defconfig[i].index;
12737c478bd9Sstevel@tonic-gate 			return (0);
12747c478bd9Sstevel@tonic-gate 		}
12757c478bd9Sstevel@tonic-gate 	}
12767c478bd9Sstevel@tonic-gate 	return (-1);
12777c478bd9Sstevel@tonic-gate }
12787c478bd9Sstevel@tonic-gate 
12797c478bd9Sstevel@tonic-gate int
12807c478bd9Sstevel@tonic-gate __s_api_get_configtype(ParamIndexType type)
12817c478bd9Sstevel@tonic-gate {
12827c478bd9Sstevel@tonic-gate 	int i;
12837c478bd9Sstevel@tonic-gate 
12847c478bd9Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
12857c478bd9Sstevel@tonic-gate 		if (defconfig[i].index == type) {
12867c478bd9Sstevel@tonic-gate 			return (defconfig[i].config_type);
12877c478bd9Sstevel@tonic-gate 		}
12887c478bd9Sstevel@tonic-gate 	}
12897c478bd9Sstevel@tonic-gate 	return (-1);
12907c478bd9Sstevel@tonic-gate }
12917c478bd9Sstevel@tonic-gate 
12927c478bd9Sstevel@tonic-gate const char *
12937c478bd9Sstevel@tonic-gate __s_api_get_configname(ParamIndexType type)
12947c478bd9Sstevel@tonic-gate {
12957c478bd9Sstevel@tonic-gate 	int i;
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
12987c478bd9Sstevel@tonic-gate 		if (defconfig[i].index == type) {
12997c478bd9Sstevel@tonic-gate 			if (defconfig[i].name[0] == '\0')
13007c478bd9Sstevel@tonic-gate 				return (NULL);
13017c478bd9Sstevel@tonic-gate 			else
13027c478bd9Sstevel@tonic-gate 				return (defconfig[i].name);
13037c478bd9Sstevel@tonic-gate 		}
13047c478bd9Sstevel@tonic-gate 	}
13057c478bd9Sstevel@tonic-gate 	return (NULL);
13067c478bd9Sstevel@tonic-gate }
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate static ns_default_config *
13097c478bd9Sstevel@tonic-gate get_defconfig(ns_config_t *ptr, ParamIndexType type)
13107c478bd9Sstevel@tonic-gate {
13117c478bd9Sstevel@tonic-gate 	ns_version_t	ver;
13127c478bd9Sstevel@tonic-gate 	int		i;
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate 	ver = ptr->version;
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
13177c478bd9Sstevel@tonic-gate 		if (defconfig[i].index == type &&
13187c478bd9Sstevel@tonic-gate 		    defconfig[i].version == ver) {
13197c478bd9Sstevel@tonic-gate 			return (&defconfig[i]);
13207c478bd9Sstevel@tonic-gate 		}
13217c478bd9Sstevel@tonic-gate 	}
13227c478bd9Sstevel@tonic-gate 	return (NULL);
13237c478bd9Sstevel@tonic-gate }
13247c478bd9Sstevel@tonic-gate 
13257c478bd9Sstevel@tonic-gate static int
13267c478bd9Sstevel@tonic-gate set_default_value(ns_config_t *configptr, char *name,
13277c478bd9Sstevel@tonic-gate 			char *value, ns_ldap_error_t **error)
13287c478bd9Sstevel@tonic-gate {
13297c478bd9Sstevel@tonic-gate 	ParamIndexType	i;
13307c478bd9Sstevel@tonic-gate 	int		ret;
13317c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
13327c478bd9Sstevel@tonic-gate 
13337c478bd9Sstevel@tonic-gate 	if (__s_api_get_type(name, &i) < 0) {
13347c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr), gettext(
13357ddae043Siz 		    "Illegal type name (%s).\n"), name);
13367c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
13377ddae043Siz 		    NULL);
13387c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
13397c478bd9Sstevel@tonic-gate 	}
13407c478bd9Sstevel@tonic-gate 
13417c478bd9Sstevel@tonic-gate 	if (i != NS_LDAP_SERVERS_P &&
13427ddae043Siz 	    i != NS_LDAP_SERVICE_AUTH_METHOD_P &&
13437ddae043Siz 	    i != NS_LDAP_SERVICE_CRED_LEVEL_P &&
13447ddae043Siz 	    i != NS_LDAP_SERVICE_SEARCH_DESC_P &&
13457ddae043Siz 	    i != NS_LDAP_SERVER_PREF_P &&
13467ddae043Siz 	    i != NS_LDAP_SEARCH_DN_P) {
13477c478bd9Sstevel@tonic-gate 		if (configptr->paramList[i].ns_ptype != NS_UNKNOWN) {
13487c478bd9Sstevel@tonic-gate 			destroy_param(configptr, i);
13497c478bd9Sstevel@tonic-gate 		}
13507c478bd9Sstevel@tonic-gate 	}
13517c478bd9Sstevel@tonic-gate 
13527c478bd9Sstevel@tonic-gate 	ret = __ns_ldap_setParamValue(configptr, i, value, error);
13537c478bd9Sstevel@tonic-gate 	return (ret);
13547c478bd9Sstevel@tonic-gate }
13557c478bd9Sstevel@tonic-gate 
13567c478bd9Sstevel@tonic-gate 
13577c478bd9Sstevel@tonic-gate /*
13587c478bd9Sstevel@tonic-gate  * Initialize config to a default state
13597c478bd9Sstevel@tonic-gate  * By default leave configuration empty
13607c478bd9Sstevel@tonic-gate  * getParam will automatically get the
13617c478bd9Sstevel@tonic-gate  * appropriate default value if none exists
13627c478bd9Sstevel@tonic-gate  */
13637c478bd9Sstevel@tonic-gate 
13647c478bd9Sstevel@tonic-gate void
13657c478bd9Sstevel@tonic-gate __ns_ldap_default_config()
13667c478bd9Sstevel@tonic-gate {
13677c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
13687c478bd9Sstevel@tonic-gate 
13697c478bd9Sstevel@tonic-gate 	ptr = __s_api_create_config();
13707c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
13717c478bd9Sstevel@tonic-gate 		return;
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate 	set_curr_config(ptr);
13747c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
13757c478bd9Sstevel@tonic-gate }
13767c478bd9Sstevel@tonic-gate 
13777c478bd9Sstevel@tonic-gate /*
13787c478bd9Sstevel@tonic-gate  * Get the current configuration pointer and return it.
13797c478bd9Sstevel@tonic-gate  * If necessary initialize or refresh the current
1380*e1dd0a2fSth  * configuration as applicable. If global is set, returns
1381*e1dd0a2fSth  * the global one.
13827c478bd9Sstevel@tonic-gate  */
13837c478bd9Sstevel@tonic-gate 
1384*e1dd0a2fSth static ns_config_t *
1385*e1dd0a2fSth loadrefresh_config(boolean_t global)
13867c478bd9Sstevel@tonic-gate {
13877c478bd9Sstevel@tonic-gate 	ns_config_t		*cfg;
13887c478bd9Sstevel@tonic-gate 	ns_config_t		*new_cfg;
13897c478bd9Sstevel@tonic-gate 	ns_ldap_error_t		*errorp;
13907c478bd9Sstevel@tonic-gate 
13917c478bd9Sstevel@tonic-gate 	/* We want to refresh only one configuration at a time */
13927c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&ns_loadrefresh_lock);
1393*e1dd0a2fSth 	if (global == B_TRUE)
1394*e1dd0a2fSth 		cfg = __s_api_get_default_config_global();
1395*e1dd0a2fSth 	else
1396*e1dd0a2fSth 		cfg = __s_api_get_default_config();
13977c478bd9Sstevel@tonic-gate 
13987c478bd9Sstevel@tonic-gate 	/* (re)initialize configuration if necessary */
1399*e1dd0a2fSth 	if (!__s_api_isStandalone() && timetorefresh(cfg)) {
1400*e1dd0a2fSth 		new_cfg = LoadCacheConfiguration(cfg, &errorp);
1401*e1dd0a2fSth 		if (new_cfg != NULL && new_cfg != cfg) {
14027c478bd9Sstevel@tonic-gate 			__s_api_release_config(cfg);
1403*e1dd0a2fSth 			if (global == B_TRUE)
1404*e1dd0a2fSth 				set_curr_config_global(new_cfg);
1405*e1dd0a2fSth 			else
1406*e1dd0a2fSth 				set_curr_config(new_cfg);
14077c478bd9Sstevel@tonic-gate 			cfg = new_cfg;
14087c478bd9Sstevel@tonic-gate 		}
14097c478bd9Sstevel@tonic-gate 		if (errorp != NULL)
14107c478bd9Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
14117c478bd9Sstevel@tonic-gate 	}
14127c478bd9Sstevel@tonic-gate 	(void) mutex_unlock(&ns_loadrefresh_lock);
14137c478bd9Sstevel@tonic-gate 	return (cfg);
14147c478bd9Sstevel@tonic-gate }
14157c478bd9Sstevel@tonic-gate 
1416*e1dd0a2fSth /*
1417*e1dd0a2fSth  * Get the current global configuration pointer and return it.
1418*e1dd0a2fSth  * If necessary initialize or refresh the current
1419*e1dd0a2fSth  * configuration as applicable.
1420*e1dd0a2fSth  */
1421*e1dd0a2fSth 
1422*e1dd0a2fSth ns_config_t *
1423*e1dd0a2fSth __s_api_loadrefresh_config_global()
1424*e1dd0a2fSth {
1425*e1dd0a2fSth 	return (loadrefresh_config(B_TRUE));
1426*e1dd0a2fSth }
1427*e1dd0a2fSth 
1428*e1dd0a2fSth /*
1429*e1dd0a2fSth  * Get the current configuration pointer and return it.
1430*e1dd0a2fSth  * If necessary initialize or refresh the current
1431*e1dd0a2fSth  * configuration as applicable. The configuration may
1432*e1dd0a2fSth  * be the global one or the per connection management one.
1433*e1dd0a2fSth  */
1434*e1dd0a2fSth 
1435*e1dd0a2fSth ns_config_t *
1436*e1dd0a2fSth __s_api_loadrefresh_config()
1437*e1dd0a2fSth {
1438*e1dd0a2fSth 	return (loadrefresh_config(B_FALSE));
1439*e1dd0a2fSth }
1440*e1dd0a2fSth 
14417c478bd9Sstevel@tonic-gate /*
14427c478bd9Sstevel@tonic-gate  * In general this routine is not very usefull. Individual routines can be
14437c478bd9Sstevel@tonic-gate  * created to do this job.  Once that is done, this function can be removed.
14447c478bd9Sstevel@tonic-gate  * Size of errstr buffer needs to be MAXERROR.
14457c478bd9Sstevel@tonic-gate  */
14467c478bd9Sstevel@tonic-gate static ns_parse_status
14477c478bd9Sstevel@tonic-gate verify_value(ns_config_t *cfg, char *name, char *value, char *errstr)
14487c478bd9Sstevel@tonic-gate {
14497c478bd9Sstevel@tonic-gate 	ParamIndexType	index = 0;
14507c478bd9Sstevel@tonic-gate 	int		found = 0, j;
14517c478bd9Sstevel@tonic-gate 	char		*ptr = NULL, *strptr = NULL, buffer[BUFSIZE];
14527c478bd9Sstevel@tonic-gate 	char		*rest;
14537c478bd9Sstevel@tonic-gate 	ns_default_config	*def = NULL;
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate 	if (__s_api_get_type(name, &index) != 0) {
14567c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, MAXERROR,
14577ddae043Siz 		    gettext("Unknown keyword encountered '%s'."), name);
14587c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
14597c478bd9Sstevel@tonic-gate 	}
14607c478bd9Sstevel@tonic-gate 
14617c478bd9Sstevel@tonic-gate 	def = get_defconfig(cfg, index);
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate 	/* eat up beginning quote, if any */
14647c478bd9Sstevel@tonic-gate 	while (value != NULL && (*value == QUOTETOK || *value == SPACETOK))
14657c478bd9Sstevel@tonic-gate 		value++;
14667c478bd9Sstevel@tonic-gate 
14677c478bd9Sstevel@tonic-gate 	/* eat up space/quote at end of value */
14687c478bd9Sstevel@tonic-gate 	if (strlen(value) > 0)
14697c478bd9Sstevel@tonic-gate 		ptr = value + strlen(value) - 1;
14707c478bd9Sstevel@tonic-gate 	else
14717c478bd9Sstevel@tonic-gate 		ptr = value;
14727c478bd9Sstevel@tonic-gate 	for (; ptr != value && (*ptr == SPACETOK || *ptr == QUOTETOK); ptr--) {
14737c478bd9Sstevel@tonic-gate 		*ptr = '\0';
14747c478bd9Sstevel@tonic-gate 	}
14757c478bd9Sstevel@tonic-gate 
14767c478bd9Sstevel@tonic-gate 	switch (index) {
14777c478bd9Sstevel@tonic-gate 	case NS_LDAP_EXP_P:
14787c478bd9Sstevel@tonic-gate 	case NS_LDAP_CACHETTL_P:
14797c478bd9Sstevel@tonic-gate 	case NS_LDAP_CERT_PATH_P:
14807c478bd9Sstevel@tonic-gate 	case NS_LDAP_CERT_PASS_P:
14817c478bd9Sstevel@tonic-gate 	case NS_LDAP_CERT_NICKNAME_P:
14827c478bd9Sstevel@tonic-gate 	case NS_LDAP_BINDDN_P:
14837c478bd9Sstevel@tonic-gate 	case NS_LDAP_BINDPASSWD_P:
14847c478bd9Sstevel@tonic-gate 	case NS_LDAP_DOMAIN_P:
14857c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_BASEDN_P:
14867c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_TIME_P:
14877c478bd9Sstevel@tonic-gate 	case NS_LDAP_PROFILE_P:
14887c478bd9Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
14897c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
14907c478bd9Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
14917c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_SEARCH_DESC_P:
14927c478bd9Sstevel@tonic-gate 	case NS_LDAP_BIND_TIME_P:
14937c478bd9Sstevel@tonic-gate 	case NS_LDAP_ATTRIBUTEMAP_P:
14947c478bd9Sstevel@tonic-gate 	case NS_LDAP_OBJECTCLASSMAP_P:
14957c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:
14967c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:
14977c478bd9Sstevel@tonic-gate 	case NS_LDAP_HOST_CERTPATH_P:
14987c478bd9Sstevel@tonic-gate 		break;
14997c478bd9Sstevel@tonic-gate 	case NS_LDAP_SEARCH_DN_P:
15007c478bd9Sstevel@tonic-gate 		/* depreciated because of service descriptors */
15017c478bd9Sstevel@tonic-gate 		/* Parse as appropriate at descriptor create time */
15027c478bd9Sstevel@tonic-gate 		break;
15037c478bd9Sstevel@tonic-gate 	case NS_LDAP_FILE_VERSION_P:
15047c478bd9Sstevel@tonic-gate 		if (value != NULL &&
15057ddae043Siz 		    strcasecmp(value, NS_LDAP_VERSION_1) != 0 &&
15067ddae043Siz 		    strcasecmp(value, NS_LDAP_VERSION_2) != 0) {
15077c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
15087ddae043Siz 			    gettext("Version mismatch, expected "
15097ddae043Siz 			    "cache version '%s' or '%s' but "
15107ddae043Siz 			    "encountered version '%s'."),
15117ddae043Siz 			    NS_LDAP_VERSION_1,
15127ddae043Siz 			    NS_LDAP_VERSION_2, value);
15137c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
15147c478bd9Sstevel@tonic-gate 		}
15157c478bd9Sstevel@tonic-gate 		break;
15167c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVERS_P:
15177c478bd9Sstevel@tonic-gate 	case NS_LDAP_SERVER_PREF_P:
15187c478bd9Sstevel@tonic-gate 		(void) strcpy(buffer, value);
15197c478bd9Sstevel@tonic-gate 		strptr = strtok_r(buffer, ",", &rest);
15207c478bd9Sstevel@tonic-gate 		while (strptr != NULL) {
15217c478bd9Sstevel@tonic-gate 			char	*tmp = NULL;
15227c478bd9Sstevel@tonic-gate 			tmp = stripdup(strptr);
15237c478bd9Sstevel@tonic-gate 			if (tmp == NULL || (strchr(tmp, ' ') != NULL)) {
15247c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, MAXERROR,
15257c478bd9Sstevel@tonic-gate 				    gettext("Invalid parameter values "
15267c478bd9Sstevel@tonic-gate 				    "'%s' specified for keyword '%s'."),
15277c478bd9Sstevel@tonic-gate 				    tmp, name);
15287c478bd9Sstevel@tonic-gate 				free(tmp);
15297c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
15307c478bd9Sstevel@tonic-gate 			}
15317c478bd9Sstevel@tonic-gate 			free(tmp);
15327c478bd9Sstevel@tonic-gate 			strptr = strtok_r(NULL, ",", &rest);
15337c478bd9Sstevel@tonic-gate 		}
15347c478bd9Sstevel@tonic-gate 		break;
15357c478bd9Sstevel@tonic-gate 	default:
15367c478bd9Sstevel@tonic-gate 		found = 0; j = 0;
15377c478bd9Sstevel@tonic-gate 		while (def->allowed != NULL &&
15387ddae043Siz 		    def->allowed[j].name != NULL && j < DEFMAX) {
15397c478bd9Sstevel@tonic-gate 			if (strcmp(def->allowed[j].name,
15407c478bd9Sstevel@tonic-gate 			    value) == 0) {
15417c478bd9Sstevel@tonic-gate 				found = 1;
15427c478bd9Sstevel@tonic-gate 				break;
15437c478bd9Sstevel@tonic-gate 			}
15447c478bd9Sstevel@tonic-gate 			j++;
15457c478bd9Sstevel@tonic-gate 		}
15467c478bd9Sstevel@tonic-gate 		if (!found) {
15477ddae043Siz 			(void) snprintf(errstr, MAXERROR,
15487c478bd9Sstevel@tonic-gate 			    gettext("Invalid option specified for "
15497c478bd9Sstevel@tonic-gate 			    "'%s' keyword. '%s' is not a recognized "
15507c478bd9Sstevel@tonic-gate 			    "keyword value."), name, value);
15517c478bd9Sstevel@tonic-gate 			return (NS_PARSE_ERR);
15527c478bd9Sstevel@tonic-gate 		}
15537c478bd9Sstevel@tonic-gate 	}
15547c478bd9Sstevel@tonic-gate 
15557c478bd9Sstevel@tonic-gate 	return (NS_SUCCESS);
15567c478bd9Sstevel@tonic-gate }
15577c478bd9Sstevel@tonic-gate 
15587c478bd9Sstevel@tonic-gate void
15597c478bd9Sstevel@tonic-gate __s_api_split_key_value(char *buffer, char **name, char **value)
15607c478bd9Sstevel@tonic-gate {
15617c478bd9Sstevel@tonic-gate 	char	*ptr;
15627c478bd9Sstevel@tonic-gate 
15637c478bd9Sstevel@tonic-gate 	*name = buffer;
15647c478bd9Sstevel@tonic-gate 	/* split into name value pair */
15657c478bd9Sstevel@tonic-gate 	if ((ptr = strchr(buffer, TOKENSEPARATOR)) != NULL) {
15667c478bd9Sstevel@tonic-gate 		*ptr = '\0';
15677c478bd9Sstevel@tonic-gate 		ptr++;
15687c478bd9Sstevel@tonic-gate 		/* trim whitespace */
15697c478bd9Sstevel@tonic-gate 		while (*ptr == SPACETOK)
15707c478bd9Sstevel@tonic-gate 			ptr++;
15717c478bd9Sstevel@tonic-gate 		*value = ptr;
15727c478bd9Sstevel@tonic-gate 	}
15737c478bd9Sstevel@tonic-gate }
15747c478bd9Sstevel@tonic-gate 
15757c478bd9Sstevel@tonic-gate /*
15767c478bd9Sstevel@tonic-gate  * Set a parameter value in a generic configuration structure
15777c478bd9Sstevel@tonic-gate  * Assume any necessary locks are in place.  This routine would
15787c478bd9Sstevel@tonic-gate  * be better named: __ns_ldap_translateString2Param
15797c478bd9Sstevel@tonic-gate  *
15807c478bd9Sstevel@tonic-gate  * This routine translates external string format into internal
15817c478bd9Sstevel@tonic-gate  * param format and saves the result in the param table.
15827c478bd9Sstevel@tonic-gate  */
15837c478bd9Sstevel@tonic-gate int
15847c478bd9Sstevel@tonic-gate __ns_ldap_setParamValue(ns_config_t *ptr, const ParamIndexType type,
15857c478bd9Sstevel@tonic-gate 		const void *data, ns_ldap_error_t **error)
15867c478bd9Sstevel@tonic-gate {
15877c478bd9Sstevel@tonic-gate 	ns_default_config	*def = NULL;
15887c478bd9Sstevel@tonic-gate 	ns_param_t		conf;
15897c478bd9Sstevel@tonic-gate 	ns_mapping_t		*map, *rmap;
15907c478bd9Sstevel@tonic-gate 	int			i, j, len;
15917c478bd9Sstevel@tonic-gate 	char			*cp, *cp2, *end;
15927c478bd9Sstevel@tonic-gate 	char			*tcp = NULL;
15937c478bd9Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
15947c478bd9Sstevel@tonic-gate 	char			tbuf[100], *ptbuf;
15957c478bd9Sstevel@tonic-gate 	char			*sid, *origA, **mapA;
15967c478bd9Sstevel@tonic-gate 	char			**attr;
15977c478bd9Sstevel@tonic-gate 	time_t			tm;
15987c478bd9Sstevel@tonic-gate 	int 			free_memory, exitrc;
15997c478bd9Sstevel@tonic-gate 	char			**p;
16007c478bd9Sstevel@tonic-gate 
16017c478bd9Sstevel@tonic-gate 	/* Find ParamIndexType default configuration data */
16027c478bd9Sstevel@tonic-gate 	def = get_defconfig(ptr, type);
16037c478bd9Sstevel@tonic-gate 	if (def == NULL) {
16047c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
16057ddae043Siz 		    gettext("Unable to set value: "
16067ddae043Siz 		    "invalid ParamIndexType (%d)"), type);
16077c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
16087ddae043Siz 		    NULL);
16097c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
16107c478bd9Sstevel@tonic-gate 	}
16117c478bd9Sstevel@tonic-gate 
16127c478bd9Sstevel@tonic-gate 	(void) memset(&conf, 0, sizeof (conf));
16137c478bd9Sstevel@tonic-gate 
16147c478bd9Sstevel@tonic-gate 	/* data is actually const char */
16157c478bd9Sstevel@tonic-gate 	cp = (char *)data;
16167c478bd9Sstevel@tonic-gate 
16177c478bd9Sstevel@tonic-gate 	/* eat up beginning quote, if any */
16187c478bd9Sstevel@tonic-gate 	while (cp && (*cp == QUOTETOK || *cp == SPACETOK))
16197c478bd9Sstevel@tonic-gate 		cp++;
16207c478bd9Sstevel@tonic-gate 
16217c478bd9Sstevel@tonic-gate 	/* eat up space/quote at end of value */
16227c478bd9Sstevel@tonic-gate 	end = cp2 = cp + strlen(cp) - 1;
16237c478bd9Sstevel@tonic-gate 	for (; cp2 > cp && (*cp2 == SPACETOK || *cp2 == QUOTETOK); cp2--)
16247c478bd9Sstevel@tonic-gate 		;
16257c478bd9Sstevel@tonic-gate 	/* data is const, must duplicate */
16267c478bd9Sstevel@tonic-gate 	if (cp2 != end) {
16277c478bd9Sstevel@tonic-gate 		tcp = (char *)calloc((int)(cp2 - cp + 2), sizeof (char));
16287c478bd9Sstevel@tonic-gate 		if (tcp == NULL)
16297c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
16307c478bd9Sstevel@tonic-gate 		end = cp2;
16317c478bd9Sstevel@tonic-gate 		cp2 = tcp;
16327c478bd9Sstevel@tonic-gate 		while (cp <= end) {
16337c478bd9Sstevel@tonic-gate 			*cp2++ = *cp++;
16347c478bd9Sstevel@tonic-gate 		}
16357c478bd9Sstevel@tonic-gate 		*cp2 = '\0';
16367c478bd9Sstevel@tonic-gate 		cp = tcp;
16377c478bd9Sstevel@tonic-gate 	}
16387c478bd9Sstevel@tonic-gate 
16397c478bd9Sstevel@tonic-gate 	/* Parse data according to type */
16407c478bd9Sstevel@tonic-gate 	switch (def->data_type) {
16417c478bd9Sstevel@tonic-gate 	case INT:
16427c478bd9Sstevel@tonic-gate 		switch (def->index) {
16437c478bd9Sstevel@tonic-gate 		case NS_LDAP_PREF_ONLY_P:
16447c478bd9Sstevel@tonic-gate 		case NS_LDAP_SEARCH_REF_P:
16457c478bd9Sstevel@tonic-gate 		case NS_LDAP_SEARCH_SCOPE_P:
16467c478bd9Sstevel@tonic-gate 			i = __s_get_enum_value(ptr, cp, def->index);
16477c478bd9Sstevel@tonic-gate 			if (i < 0) {
16487c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
16497ddae043Siz 				    gettext("Unable to set value: "
16507ddae043Siz 				    "invalid %s (%d)"), def->name,
16517ddae043Siz 				    def->index);
16527c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
16537ddae043Siz 				    strdup(errstr), NULL);
16547c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
16557c478bd9Sstevel@tonic-gate 					free(tcp);
16567c478bd9Sstevel@tonic-gate 				return (NS_LDAP_CONFIG);
16577c478bd9Sstevel@tonic-gate 			}
16587c478bd9Sstevel@tonic-gate 			conf.ns_i = i;
16597c478bd9Sstevel@tonic-gate 			break;
16607c478bd9Sstevel@tonic-gate 		case NS_LDAP_TRANSPORT_SEC_P:	/* ignore TRANSPORT_SEC */
16617c478bd9Sstevel@tonic-gate 			break;
16627c478bd9Sstevel@tonic-gate 		default:
16637c478bd9Sstevel@tonic-gate 			cp2 = cp;
16647c478bd9Sstevel@tonic-gate 			if ((*cp2 == '+') || (*cp2 == '-'))
16657c478bd9Sstevel@tonic-gate 				cp2++;
16667c478bd9Sstevel@tonic-gate 			for (/* empty */; *cp2; cp2++) {
16677c478bd9Sstevel@tonic-gate 				if (isdigit(*cp2))
16687c478bd9Sstevel@tonic-gate 					continue;
16697c478bd9Sstevel@tonic-gate 
16707c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
16717ddae043Siz 				    gettext("Unable to set value: "
16727ddae043Siz 				    "invalid %s (%d)"), def->name,
16737ddae043Siz 				    def->index);
16747c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
16757ddae043Siz 				    strdup(errstr), NULL);
16767c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
16777c478bd9Sstevel@tonic-gate 					free(tcp);
16787c478bd9Sstevel@tonic-gate 				return (NS_LDAP_CONFIG);
16797c478bd9Sstevel@tonic-gate 			}
16807c478bd9Sstevel@tonic-gate 			i = atoi(cp);
16817c478bd9Sstevel@tonic-gate 			conf.ns_i = i;
16827c478bd9Sstevel@tonic-gate 			break;
16837c478bd9Sstevel@tonic-gate 		}
16847c478bd9Sstevel@tonic-gate 		break;
16857c478bd9Sstevel@tonic-gate 	case TIMET:
16867c478bd9Sstevel@tonic-gate 		/* Do nothing with a TIMET.  Initialize it below */
16877c478bd9Sstevel@tonic-gate 		break;
16887c478bd9Sstevel@tonic-gate 	case CHARPTR:
16897c478bd9Sstevel@tonic-gate 		conf.ns_pc = (char *)strdup(cp);
16907c478bd9Sstevel@tonic-gate 		if (conf.ns_pc == NULL) {
16917c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
16927c478bd9Sstevel@tonic-gate 				free(tcp);
16937c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
16947c478bd9Sstevel@tonic-gate 		}
16957c478bd9Sstevel@tonic-gate 		break;
16967c478bd9Sstevel@tonic-gate 	case SAMLIST:
16977c478bd9Sstevel@tonic-gate 		/* first check to see if colon (:) is there */
16987c478bd9Sstevel@tonic-gate 		if ((strchr(cp, COLONTOK)) == NULL) {
16997c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
17007ddae043Siz 			    gettext("Unable to set value: "
17017ddae043Siz 			    "invalid serviceAuthenticationMethod (%s)"),
17027ddae043Siz 			    cp);
17037c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
17047ddae043Siz 			    strdup(errstr), NULL);
17057c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
17067c478bd9Sstevel@tonic-gate 				free(tcp);
17077c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
17087c478bd9Sstevel@tonic-gate 		}
17097c478bd9Sstevel@tonic-gate 		/* Appends an entry to the existing list */
17107c478bd9Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ptype != SAMLIST) {
17117c478bd9Sstevel@tonic-gate 			conf.ns_ppc = (char **)calloc(2, sizeof (char *));
17127c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
17137c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
17147c478bd9Sstevel@tonic-gate 					free(tcp);
17157c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17167c478bd9Sstevel@tonic-gate 			}
17177c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 1;
17187c478bd9Sstevel@tonic-gate 			conf.ns_ppc[0] = (char *)strdup(cp);
17197c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc[0] == NULL) {
17207c478bd9Sstevel@tonic-gate 				free(conf.ns_ppc);
17217c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
17227c478bd9Sstevel@tonic-gate 					free(tcp);
17237c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17247c478bd9Sstevel@tonic-gate 			}
17257c478bd9Sstevel@tonic-gate 		} else {
17267c478bd9Sstevel@tonic-gate 			char *dp, *dpend;
17277c478bd9Sstevel@tonic-gate 			int fnd = 0;
17287c478bd9Sstevel@tonic-gate 
17297c478bd9Sstevel@tonic-gate 			/* Attempt to replace if possible */
17307c478bd9Sstevel@tonic-gate 			dpend = strchr(cp, COLONTOK);
17317c478bd9Sstevel@tonic-gate 			len = dpend - cp;
17327c478bd9Sstevel@tonic-gate 			dp = (char *)malloc(len+1);
17337c478bd9Sstevel@tonic-gate 			if (dp == NULL) {
17347c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
17357c478bd9Sstevel@tonic-gate 					free(tcp);
17367c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17377c478bd9Sstevel@tonic-gate 			}
17387c478bd9Sstevel@tonic-gate 			(void) strlcpy(dp, cp, len+1);
17397c478bd9Sstevel@tonic-gate 			fnd = 0;
17407c478bd9Sstevel@tonic-gate 			for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
17417c478bd9Sstevel@tonic-gate 				dpend = strchr(ptr->paramList[type].ns_ppc[j],
17427ddae043Siz 				    COLONTOK);
17437c478bd9Sstevel@tonic-gate 				if (dpend == NULL)
17447c478bd9Sstevel@tonic-gate 					continue;
17457c478bd9Sstevel@tonic-gate 				i = dpend - ptr->paramList[type].ns_ppc[j];
17467c478bd9Sstevel@tonic-gate 				if (i != len)
17477c478bd9Sstevel@tonic-gate 					continue;
17487c478bd9Sstevel@tonic-gate 				if (strncmp(ptr->paramList[type].ns_ppc[j],
17497ddae043Siz 				    dp, len) == 0) {
17507c478bd9Sstevel@tonic-gate 					conf.ns_acnt =
17517ddae043Siz 					    ptr->paramList[type].ns_acnt;
17527c478bd9Sstevel@tonic-gate 					conf.ns_ppc =
17537ddae043Siz 					    ptr->paramList[type].ns_ppc;
17547c478bd9Sstevel@tonic-gate 					ptr->paramList[type].ns_ppc = NULL;
17557c478bd9Sstevel@tonic-gate 					free(conf.ns_ppc[j]);
17567c478bd9Sstevel@tonic-gate 					conf.ns_ppc[j] = (char *)strdup(cp);
17577c478bd9Sstevel@tonic-gate 					if (conf.ns_ppc[j] == NULL) {
17587c478bd9Sstevel@tonic-gate 						free(dp);
17597c478bd9Sstevel@tonic-gate 						__s_api_free2dArray
17607ddae043Siz 						    (conf.ns_ppc);
17617c478bd9Sstevel@tonic-gate 						if (tcp != NULL)
17627c478bd9Sstevel@tonic-gate 							free(tcp);
17637c478bd9Sstevel@tonic-gate 						return (NS_LDAP_MEMORY);
17647c478bd9Sstevel@tonic-gate 					}
17657c478bd9Sstevel@tonic-gate 					fnd = 1;
17667c478bd9Sstevel@tonic-gate 					break;
17677c478bd9Sstevel@tonic-gate 				}
17687c478bd9Sstevel@tonic-gate 			}
17697c478bd9Sstevel@tonic-gate 			free(dp);
17707c478bd9Sstevel@tonic-gate 
17717c478bd9Sstevel@tonic-gate 			if (fnd)
17727c478bd9Sstevel@tonic-gate 				break;	/* Replaced completed */
17737c478bd9Sstevel@tonic-gate 
17747c478bd9Sstevel@tonic-gate 			/* Append */
17757c478bd9Sstevel@tonic-gate 			len = ptr->paramList[type].ns_acnt + 1;
17767c478bd9Sstevel@tonic-gate 			if (len > 1) {
17777c478bd9Sstevel@tonic-gate 				p = (char **)dupParam(&ptr->paramList[type]);
17787c478bd9Sstevel@tonic-gate 				if (p == NULL) {
17797c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
17807c478bd9Sstevel@tonic-gate 						free(tcp);
17817c478bd9Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
17827c478bd9Sstevel@tonic-gate 				}
17837c478bd9Sstevel@tonic-gate 			} else
17847c478bd9Sstevel@tonic-gate 				p = NULL;
17857c478bd9Sstevel@tonic-gate 			conf.ns_ppc =
17867ddae043Siz 			    (char **)realloc(p, (len+1) * sizeof (char *));
17877c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
17887c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(p);
17897c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
17907c478bd9Sstevel@tonic-gate 					free(tcp);
17917c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17927c478bd9Sstevel@tonic-gate 			}
17937c478bd9Sstevel@tonic-gate 			conf.ns_acnt = len;
17947c478bd9Sstevel@tonic-gate 			conf.ns_ppc[len-1] = (char *)strdup(cp);
17957c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc[len-1] == NULL) {
17967c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(conf.ns_ppc);
17977c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
17987c478bd9Sstevel@tonic-gate 					free(tcp);
17997c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18007c478bd9Sstevel@tonic-gate 			}
18017c478bd9Sstevel@tonic-gate 			conf.ns_ppc[len] = NULL;
18027c478bd9Sstevel@tonic-gate 		}
18037c478bd9Sstevel@tonic-gate 		break;
18047c478bd9Sstevel@tonic-gate 	case SCLLIST:
18057c478bd9Sstevel@tonic-gate 		/* first check to see if colon (:) is there */
18067c478bd9Sstevel@tonic-gate 		if ((strchr(cp, COLONTOK)) == NULL) {
18077c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
18087ddae043Siz 			    gettext("Unable to set value: "
18097ddae043Siz 			    "invalid serviceCredentialLevel (%s)"),
18107ddae043Siz 			    cp);
18117c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
18127ddae043Siz 			    strdup(errstr), NULL);
18137c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
18147c478bd9Sstevel@tonic-gate 				free(tcp);
18157c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
18167c478bd9Sstevel@tonic-gate 		}
18177c478bd9Sstevel@tonic-gate 		/* Appends an entry to the existing list */
18187c478bd9Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ptype != SCLLIST) {
18197c478bd9Sstevel@tonic-gate 			conf.ns_ppc = (char **)calloc(2, sizeof (char *));
18207c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
18217c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
18227c478bd9Sstevel@tonic-gate 					free(tcp);
18237c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18247c478bd9Sstevel@tonic-gate 			}
18257c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 1;
18267c478bd9Sstevel@tonic-gate 			conf.ns_ppc[0] = (char *)strdup(cp);
18277c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc[0] == NULL) {
18287c478bd9Sstevel@tonic-gate 				free(conf.ns_ppc);
18297c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
18307c478bd9Sstevel@tonic-gate 					free(tcp);
18317c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18327c478bd9Sstevel@tonic-gate 			}
18337c478bd9Sstevel@tonic-gate 		} else {
18347c478bd9Sstevel@tonic-gate 			char *dp, *dpend;
18357c478bd9Sstevel@tonic-gate 			int fnd = 0;
18367c478bd9Sstevel@tonic-gate 
18377c478bd9Sstevel@tonic-gate 			/* Attempt to replace if possible */
18387c478bd9Sstevel@tonic-gate 			dpend = strchr(cp, COLONTOK);
18397c478bd9Sstevel@tonic-gate 			len = dpend - cp;
18407c478bd9Sstevel@tonic-gate 			dp = (char *)malloc(len+1);
18417c478bd9Sstevel@tonic-gate 			if (dp == NULL) {
18427c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
18437c478bd9Sstevel@tonic-gate 					free(tcp);
18447c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18457c478bd9Sstevel@tonic-gate 			}
18467c478bd9Sstevel@tonic-gate 			(void) strlcpy(dp, cp, len+1);
18477c478bd9Sstevel@tonic-gate 			fnd = 0;
18487c478bd9Sstevel@tonic-gate 			for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
18497c478bd9Sstevel@tonic-gate 				dpend = strchr(ptr->paramList[type].ns_ppc[j],
18507ddae043Siz 				    COLONTOK);
18517c478bd9Sstevel@tonic-gate 				if (dpend == NULL)
18527c478bd9Sstevel@tonic-gate 					continue;
18537c478bd9Sstevel@tonic-gate 				i = dpend - ptr->paramList[type].ns_ppc[j];
18547c478bd9Sstevel@tonic-gate 				if (i != len)
18557c478bd9Sstevel@tonic-gate 					continue;
18567c478bd9Sstevel@tonic-gate 				if (strncmp(ptr->paramList[type].ns_ppc[j],
18577ddae043Siz 				    dp, len) == 0) {
18587c478bd9Sstevel@tonic-gate 					conf.ns_acnt =
18597ddae043Siz 					    ptr->paramList[type].ns_acnt;
18607c478bd9Sstevel@tonic-gate 					conf.ns_ppc =
18617ddae043Siz 					    ptr->paramList[type].ns_ppc;
18627c478bd9Sstevel@tonic-gate 					ptr->paramList[type].ns_ppc = NULL;
18637c478bd9Sstevel@tonic-gate 					free(conf.ns_ppc[j]);
18647c478bd9Sstevel@tonic-gate 					conf.ns_ppc[j] = (char *)strdup(cp);
18657c478bd9Sstevel@tonic-gate 					if (conf.ns_ppc[j] == NULL) {
18667c478bd9Sstevel@tonic-gate 						free(dp);
18677c478bd9Sstevel@tonic-gate 						__s_api_free2dArray
18687ddae043Siz 						    (conf.ns_ppc);
18697c478bd9Sstevel@tonic-gate 						if (tcp != NULL)
18707c478bd9Sstevel@tonic-gate 							free(tcp);
18717c478bd9Sstevel@tonic-gate 						return (NS_LDAP_MEMORY);
18727c478bd9Sstevel@tonic-gate 					}
18737c478bd9Sstevel@tonic-gate 					fnd = 1;
18747c478bd9Sstevel@tonic-gate 					break;
18757c478bd9Sstevel@tonic-gate 				}
18767c478bd9Sstevel@tonic-gate 			}
18777c478bd9Sstevel@tonic-gate 			free(dp);
18787c478bd9Sstevel@tonic-gate 
18797c478bd9Sstevel@tonic-gate 			if (fnd)
18807c478bd9Sstevel@tonic-gate 				break;	/* Replaced completed */
18817c478bd9Sstevel@tonic-gate 
18827c478bd9Sstevel@tonic-gate 			/* Append */
18837c478bd9Sstevel@tonic-gate 			len = ptr->paramList[type].ns_acnt + 1;
18847c478bd9Sstevel@tonic-gate 			if (len > 1) {
18857c478bd9Sstevel@tonic-gate 				p = (char **)dupParam(&ptr->paramList[type]);
18867c478bd9Sstevel@tonic-gate 				if (p == NULL) {
18877c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
18887c478bd9Sstevel@tonic-gate 						free(tcp);
18897c478bd9Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
18907c478bd9Sstevel@tonic-gate 				}
18917c478bd9Sstevel@tonic-gate 			} else
18927c478bd9Sstevel@tonic-gate 				p = NULL;
18937c478bd9Sstevel@tonic-gate 			conf.ns_ppc =
18947ddae043Siz 			    (char **)realloc(p, (len+1) * sizeof (char *));
18957c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
18967c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(p);
18977c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
18987c478bd9Sstevel@tonic-gate 					free(tcp);
18997c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19007c478bd9Sstevel@tonic-gate 			}
19017c478bd9Sstevel@tonic-gate 			conf.ns_acnt = len;
19027c478bd9Sstevel@tonic-gate 			conf.ns_ppc[len-1] = (char *)strdup(cp);
19037c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc[len-1] == NULL) {
19047c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(conf.ns_ppc);
19057c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
19067c478bd9Sstevel@tonic-gate 					free(tcp);
19077c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19087c478bd9Sstevel@tonic-gate 			}
19097c478bd9Sstevel@tonic-gate 			conf.ns_ppc[len] = NULL;
19107c478bd9Sstevel@tonic-gate 		}
19117c478bd9Sstevel@tonic-gate 		break;
19127c478bd9Sstevel@tonic-gate 	case SSDLIST:
19137c478bd9Sstevel@tonic-gate 		/*
19147c478bd9Sstevel@tonic-gate 		 * first check to see if colon (:) is there,
19157c478bd9Sstevel@tonic-gate 		 * if so, make sure the serviceId is specified,
19167c478bd9Sstevel@tonic-gate 		 * i.e., colon is not the first character
19177c478bd9Sstevel@tonic-gate 		 */
19187c478bd9Sstevel@tonic-gate 		if ((strchr(cp, COLONTOK)) == NULL || *cp == COLONTOK) {
19197c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
19207ddae043Siz 			    gettext("Unable to set value: "
19217ddae043Siz 			    "invalid serviceSearchDescriptor (%s)"),
19227ddae043Siz 			    cp);
19237c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
19247ddae043Siz 			    strdup(errstr), NULL);
19257c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
19267c478bd9Sstevel@tonic-gate 				free(tcp);
19277c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
19287c478bd9Sstevel@tonic-gate 		}
19297c478bd9Sstevel@tonic-gate 		/* Appends an entry to the existing list */
19307c478bd9Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ptype != SSDLIST) {
19317c478bd9Sstevel@tonic-gate 			conf.ns_ppc = (char **)calloc(2, sizeof (char *));
19327c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
19337c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
19347c478bd9Sstevel@tonic-gate 					free(tcp);
19357c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19367c478bd9Sstevel@tonic-gate 			}
19377c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 1;
19387c478bd9Sstevel@tonic-gate 			conf.ns_ppc[0] = (char *)strdup(cp);
19397c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc[0] == NULL) {
19407c478bd9Sstevel@tonic-gate 				free(conf.ns_ppc);
19417c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
19427c478bd9Sstevel@tonic-gate 					free(tcp);
19437c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19447c478bd9Sstevel@tonic-gate 			}
19457c478bd9Sstevel@tonic-gate 		} else {
19467c478bd9Sstevel@tonic-gate 			char *dp, *dpend;
19477c478bd9Sstevel@tonic-gate 			int fnd = 0;
19487c478bd9Sstevel@tonic-gate 
19497c478bd9Sstevel@tonic-gate 			/* Attempt to replace if possible */
19507c478bd9Sstevel@tonic-gate 			dpend = strchr(cp, COLONTOK);
19517c478bd9Sstevel@tonic-gate 			len = dpend - cp;
19527c478bd9Sstevel@tonic-gate 			dp = (char *)malloc(len+1);
19537c478bd9Sstevel@tonic-gate 			if (dp == NULL) {
19547c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
19557c478bd9Sstevel@tonic-gate 					free(tcp);
19567c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19577c478bd9Sstevel@tonic-gate 			}
19587c478bd9Sstevel@tonic-gate 			(void) strlcpy(dp, cp, len+1);
19597c478bd9Sstevel@tonic-gate 			fnd = 0;
19607c478bd9Sstevel@tonic-gate 			for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
19617c478bd9Sstevel@tonic-gate 				dpend = strchr(ptr->paramList[type].ns_ppc[j],
19627ddae043Siz 				    COLONTOK);
19637c478bd9Sstevel@tonic-gate 				if (dpend == NULL)
19647c478bd9Sstevel@tonic-gate 					continue;
19657c478bd9Sstevel@tonic-gate 				i = dpend - ptr->paramList[type].ns_ppc[j];
19667c478bd9Sstevel@tonic-gate 				if (i != len)
19677c478bd9Sstevel@tonic-gate 					continue;
19687c478bd9Sstevel@tonic-gate 				if (strncmp(ptr->paramList[type].ns_ppc[j],
19697ddae043Siz 				    dp, len) == 0) {
19707c478bd9Sstevel@tonic-gate 					conf.ns_acnt =
19717ddae043Siz 					    ptr->paramList[type].ns_acnt;
19727c478bd9Sstevel@tonic-gate 					conf.ns_ppc =
19737ddae043Siz 					    ptr->paramList[type].ns_ppc;
19747c478bd9Sstevel@tonic-gate 					ptr->paramList[type].ns_ppc = NULL;
19757c478bd9Sstevel@tonic-gate 					free(conf.ns_ppc[j]);
19767c478bd9Sstevel@tonic-gate 					conf.ns_ppc[j] = (char *)strdup(cp);
19777c478bd9Sstevel@tonic-gate 					if (conf.ns_ppc[j] == NULL) {
19787c478bd9Sstevel@tonic-gate 						free(dp);
19797c478bd9Sstevel@tonic-gate 						__s_api_free2dArray
19807ddae043Siz 						    (conf.ns_ppc);
19817c478bd9Sstevel@tonic-gate 						if (tcp != NULL)
19827c478bd9Sstevel@tonic-gate 							free(tcp);
19837c478bd9Sstevel@tonic-gate 						return (NS_LDAP_MEMORY);
19847c478bd9Sstevel@tonic-gate 					}
19857c478bd9Sstevel@tonic-gate 					fnd = 1;
19867c478bd9Sstevel@tonic-gate 					break;
19877c478bd9Sstevel@tonic-gate 				}
19887c478bd9Sstevel@tonic-gate 			}
19897c478bd9Sstevel@tonic-gate 			free(dp);
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate 			if (fnd)
19927c478bd9Sstevel@tonic-gate 				break;	/* Replaced completed */
19937c478bd9Sstevel@tonic-gate 
19947c478bd9Sstevel@tonic-gate 			/* Append */
19957c478bd9Sstevel@tonic-gate 			len = ptr->paramList[type].ns_acnt + 1;
19967c478bd9Sstevel@tonic-gate 			if (len > 1) {
19977c478bd9Sstevel@tonic-gate 				p = (char **)dupParam(&ptr->paramList[type]);
19987c478bd9Sstevel@tonic-gate 				if (p == NULL) {
19997c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
20007c478bd9Sstevel@tonic-gate 						free(tcp);
20017c478bd9Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
20027c478bd9Sstevel@tonic-gate 				}
20037c478bd9Sstevel@tonic-gate 			} else
20047c478bd9Sstevel@tonic-gate 				p = NULL;
20057c478bd9Sstevel@tonic-gate 			conf.ns_ppc =
20067ddae043Siz 			    (char **)realloc(p, (len+1) * sizeof (char *));
20077c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
20087c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(p);
20097c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
20107c478bd9Sstevel@tonic-gate 					free(tcp);
20117c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
20127c478bd9Sstevel@tonic-gate 			}
20137c478bd9Sstevel@tonic-gate 			conf.ns_acnt = len;
20147c478bd9Sstevel@tonic-gate 			conf.ns_ppc[len-1] = (char *)strdup(cp);
20157c478bd9Sstevel@tonic-gate 			if (conf.ns_ppc[len-1] == NULL) {
20167c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(conf.ns_ppc);
20177c478bd9Sstevel@tonic-gate 				if (tcp != NULL)
20187c478bd9Sstevel@tonic-gate 					free(tcp);
20197c478bd9Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
20207c478bd9Sstevel@tonic-gate 			}
20217c478bd9Sstevel@tonic-gate 			conf.ns_ppc[len] = NULL;
20227c478bd9Sstevel@tonic-gate 		}
20237c478bd9Sstevel@tonic-gate 		break;
20247c478bd9Sstevel@tonic-gate 	case ARRAYCP:
20257c478bd9Sstevel@tonic-gate 		len = 0;
20267c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
20277c478bd9Sstevel@tonic-gate 			if (*cp2 == COMMATOK)
20287c478bd9Sstevel@tonic-gate 				len++;
20297c478bd9Sstevel@tonic-gate 		}
20307c478bd9Sstevel@tonic-gate 		if (cp != cp2)
20317c478bd9Sstevel@tonic-gate 			len++;
20327c478bd9Sstevel@tonic-gate 		if (len == 0) {
20337c478bd9Sstevel@tonic-gate 			conf.ns_ppc = (char **)NULL;
20347c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 0;
20357c478bd9Sstevel@tonic-gate 			break;
20367c478bd9Sstevel@tonic-gate 		}
20377c478bd9Sstevel@tonic-gate 		conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
20387c478bd9Sstevel@tonic-gate 		if (conf.ns_ppc == NULL) {
20397c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
20407c478bd9Sstevel@tonic-gate 				free(tcp);
20417c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
20427c478bd9Sstevel@tonic-gate 		}
20437c478bd9Sstevel@tonic-gate 		conf.ns_acnt = len;
20447c478bd9Sstevel@tonic-gate 		i = 0;
20457c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
20467c478bd9Sstevel@tonic-gate 			if (*cp2 == COMMATOK) {
20477c478bd9Sstevel@tonic-gate 				j = cp2 - cp + 1;
20487c478bd9Sstevel@tonic-gate 				conf.ns_ppc[i] = (char *)malloc(j + 1);
20497c478bd9Sstevel@tonic-gate 				if (conf.ns_ppc[i] == NULL) {
20507c478bd9Sstevel@tonic-gate 					__s_api_free2dArray(conf.ns_ppc);
20517c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
20527c478bd9Sstevel@tonic-gate 						free(tcp);
20537c478bd9Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
20547c478bd9Sstevel@tonic-gate 				}
20557c478bd9Sstevel@tonic-gate 				(void) strlcpy(conf.ns_ppc[i], cp, j);
20567c478bd9Sstevel@tonic-gate 				cp = cp2+1;
20577c478bd9Sstevel@tonic-gate 				while (*cp == SPACETOK || *cp == COMMATOK)
20587c478bd9Sstevel@tonic-gate 					cp++;
20597c478bd9Sstevel@tonic-gate 				cp2 = cp - 1;
20607c478bd9Sstevel@tonic-gate 				i++;
20617c478bd9Sstevel@tonic-gate 			}
20627c478bd9Sstevel@tonic-gate 		}
20637c478bd9Sstevel@tonic-gate 		j = cp2 - cp + 1;
20647c478bd9Sstevel@tonic-gate 		conf.ns_ppc[i] = (char *)malloc(j + 1);
20657c478bd9Sstevel@tonic-gate 		if (conf.ns_ppc[i] == NULL) {
20667c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(conf.ns_ppc);
20677c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
20687c478bd9Sstevel@tonic-gate 				free(tcp);
20697c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
20707c478bd9Sstevel@tonic-gate 		}
20717c478bd9Sstevel@tonic-gate 		(void) strlcpy(conf.ns_ppc[i], cp, j);
20727c478bd9Sstevel@tonic-gate 		break;
20737c478bd9Sstevel@tonic-gate 	case SERVLIST:
20747c478bd9Sstevel@tonic-gate 		len = 0;
20757c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
20767c478bd9Sstevel@tonic-gate 			if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
20777c478bd9Sstevel@tonic-gate 				len++;
20787c478bd9Sstevel@tonic-gate 				for (; *(cp2 + 1) == SPACETOK ||
20797ddae043Siz 				    *(cp2 +1) == COMMATOK; cp2++)
20807c478bd9Sstevel@tonic-gate 					;
20817c478bd9Sstevel@tonic-gate 			}
20827c478bd9Sstevel@tonic-gate 		}
20837c478bd9Sstevel@tonic-gate 		if (cp != cp2)
20847c478bd9Sstevel@tonic-gate 			len++;
20857c478bd9Sstevel@tonic-gate 		if (len == 0) {
20867c478bd9Sstevel@tonic-gate 			conf.ns_ppc = (char **)NULL;
20877c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 0;
20887c478bd9Sstevel@tonic-gate 			break;
20897c478bd9Sstevel@tonic-gate 		}
20907c478bd9Sstevel@tonic-gate 		conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
20917c478bd9Sstevel@tonic-gate 		if (conf.ns_ppc == NULL) {
20927c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
20937c478bd9Sstevel@tonic-gate 				free(tcp);
20947c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
20957c478bd9Sstevel@tonic-gate 		}
20967c478bd9Sstevel@tonic-gate 		conf.ns_acnt = len;
20977c478bd9Sstevel@tonic-gate 		i = 0;
20987c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
20997c478bd9Sstevel@tonic-gate 			if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
21007c478bd9Sstevel@tonic-gate 				j = cp2 - cp + 1;
21017c478bd9Sstevel@tonic-gate 				conf.ns_ppc[i] = (char *)malloc(j + 1);
21027c478bd9Sstevel@tonic-gate 				if (conf.ns_ppc[i] == NULL) {
21037c478bd9Sstevel@tonic-gate 					__s_api_free2dArray(conf.ns_ppc);
21047c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
21057c478bd9Sstevel@tonic-gate 						free(tcp);
21067c478bd9Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
21077c478bd9Sstevel@tonic-gate 				}
21087c478bd9Sstevel@tonic-gate 				(void) strlcpy(conf.ns_ppc[i], cp, j);
21097c478bd9Sstevel@tonic-gate 				cp = cp2+1;
21107c478bd9Sstevel@tonic-gate 				while (*cp == SPACETOK || *cp == COMMATOK)
21117c478bd9Sstevel@tonic-gate 					cp++;
21127c478bd9Sstevel@tonic-gate 				cp2 = cp - 1;
21137c478bd9Sstevel@tonic-gate 				i++;
21147c478bd9Sstevel@tonic-gate 			}
21157c478bd9Sstevel@tonic-gate 		}
21167c478bd9Sstevel@tonic-gate 		j = cp2 - cp + 1;
21177c478bd9Sstevel@tonic-gate 		conf.ns_ppc[i] = (char *)malloc(j + 1);
21187c478bd9Sstevel@tonic-gate 		if (conf.ns_ppc[i] == NULL) {
21197c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(conf.ns_ppc);
21207c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
21217c478bd9Sstevel@tonic-gate 				free(tcp);
21227c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
21237c478bd9Sstevel@tonic-gate 		}
21247c478bd9Sstevel@tonic-gate 		(void) strlcpy(conf.ns_ppc[i], cp, j);
21257c478bd9Sstevel@tonic-gate 		break;
21267c478bd9Sstevel@tonic-gate 	case ARRAYAUTH:
21277c478bd9Sstevel@tonic-gate 		len = 0;
21287c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
21297c478bd9Sstevel@tonic-gate 			if (*cp2 == SEMITOK || *cp2 == COMMATOK)
21307c478bd9Sstevel@tonic-gate 				len++;
21317c478bd9Sstevel@tonic-gate 		}
21327c478bd9Sstevel@tonic-gate 		if (cp != cp2)
21337c478bd9Sstevel@tonic-gate 			len++;
21347c478bd9Sstevel@tonic-gate 		if (len == 0) {
21357c478bd9Sstevel@tonic-gate 			conf.ns_pi = (int *)NULL;
21367c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 0;
21377c478bd9Sstevel@tonic-gate 			break;
21387c478bd9Sstevel@tonic-gate 		}
21397c478bd9Sstevel@tonic-gate 		conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
21407c478bd9Sstevel@tonic-gate 		if (conf.ns_pi == NULL) {
21417c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
21427c478bd9Sstevel@tonic-gate 				free(tcp);
21437c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
21447c478bd9Sstevel@tonic-gate 		}
21457c478bd9Sstevel@tonic-gate 		conf.ns_acnt = len;
21467c478bd9Sstevel@tonic-gate 		i = 0;
21477c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
21487c478bd9Sstevel@tonic-gate 			if (*cp2 == SEMITOK || *cp2 == COMMATOK) {
21497c478bd9Sstevel@tonic-gate 				j = cp2 - cp + 1;
21507c478bd9Sstevel@tonic-gate 				if (j > sizeof (tbuf)) {
21517c478bd9Sstevel@tonic-gate 					j = -1;
21527c478bd9Sstevel@tonic-gate 					ptbuf = cp;
21537c478bd9Sstevel@tonic-gate 				} else {
21547c478bd9Sstevel@tonic-gate 					(void) strlcpy(tbuf, cp, j);
21557c478bd9Sstevel@tonic-gate 					j = __s_get_enum_value(ptr, tbuf,
21567ddae043Siz 					    def->index);
21577c478bd9Sstevel@tonic-gate 					ptbuf = tbuf;
21587c478bd9Sstevel@tonic-gate 				}
21597c478bd9Sstevel@tonic-gate 				if (j < 0) {
21607c478bd9Sstevel@tonic-gate 					(void) snprintf(errstr, sizeof (errstr),
21617ddae043Siz 					    gettext("Unable to set value: "
21627ddae043Siz 					    "invalid "
21637ddae043Siz 					    "authenticationMethod (%s)"),
21647ddae043Siz 					    ptbuf);
21657c478bd9Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
21667ddae043Siz 					    NS_CONFIG_SYNTAX,
21677ddae043Siz 					    strdup(errstr), NULL);
21687c478bd9Sstevel@tonic-gate 					free(conf.ns_pi);
21697c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
21707c478bd9Sstevel@tonic-gate 						free(tcp);
21717c478bd9Sstevel@tonic-gate 					return (NS_LDAP_CONFIG);
21727c478bd9Sstevel@tonic-gate 				}
21737c478bd9Sstevel@tonic-gate 				conf.ns_pi[i] = j;
21747c478bd9Sstevel@tonic-gate 				cp = cp2+1;
21757c478bd9Sstevel@tonic-gate 				i++;
21767c478bd9Sstevel@tonic-gate 			}
21777c478bd9Sstevel@tonic-gate 		}
21787c478bd9Sstevel@tonic-gate 		j = cp2 - cp + 1;
21797c478bd9Sstevel@tonic-gate 		if (j > sizeof (tbuf)) {
21807c478bd9Sstevel@tonic-gate 			j = -1;
21817c478bd9Sstevel@tonic-gate 			ptbuf = cp;
21827c478bd9Sstevel@tonic-gate 		} else {
21837c478bd9Sstevel@tonic-gate 			(void) strlcpy(tbuf, cp, j);
21847c478bd9Sstevel@tonic-gate 			j = __s_get_enum_value(ptr, tbuf, def->index);
21857c478bd9Sstevel@tonic-gate 			ptbuf = tbuf;
21867c478bd9Sstevel@tonic-gate 		}
21877c478bd9Sstevel@tonic-gate 		if (j < 0) {
21887c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
21897ddae043Siz 			    gettext("Unable to set value: "
21907ddae043Siz 			    "invalid authenticationMethod (%s)"), ptbuf);
21917c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
21927ddae043Siz 			    strdup(errstr), NULL);
21937c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
21947c478bd9Sstevel@tonic-gate 				free(tcp);
21957c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
21967c478bd9Sstevel@tonic-gate 		}
21977c478bd9Sstevel@tonic-gate 		conf.ns_pi[i] = j;
21987c478bd9Sstevel@tonic-gate 		break;
21997c478bd9Sstevel@tonic-gate 	case ARRAYCRED:
22007c478bd9Sstevel@tonic-gate 		len = 0;
22017c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
22027c478bd9Sstevel@tonic-gate 			if (*cp2 == SPACETOK)
22037c478bd9Sstevel@tonic-gate 				len++;
22047c478bd9Sstevel@tonic-gate 		}
22057c478bd9Sstevel@tonic-gate 		if (cp != cp2)
22067c478bd9Sstevel@tonic-gate 			len++;
22077c478bd9Sstevel@tonic-gate 		if (len == 0) {
22087c478bd9Sstevel@tonic-gate 			conf.ns_pi = (int *)NULL;
22097c478bd9Sstevel@tonic-gate 			conf.ns_acnt = 0;
22107c478bd9Sstevel@tonic-gate 			break;
22117c478bd9Sstevel@tonic-gate 		}
22127c478bd9Sstevel@tonic-gate 		conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
22137c478bd9Sstevel@tonic-gate 		if (conf.ns_pi == NULL) {
22147c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
22157c478bd9Sstevel@tonic-gate 				free(tcp);
22167c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
22177c478bd9Sstevel@tonic-gate 		}
22187c478bd9Sstevel@tonic-gate 		conf.ns_acnt = len;
22197c478bd9Sstevel@tonic-gate 		i = 0;
22207c478bd9Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
22217c478bd9Sstevel@tonic-gate 			if (*cp2 == SPACETOK) {
22227c478bd9Sstevel@tonic-gate 				j = cp2 - cp + 1;
22237c478bd9Sstevel@tonic-gate 				if (j > sizeof (tbuf)) {
22247c478bd9Sstevel@tonic-gate 					j = -1;
22257c478bd9Sstevel@tonic-gate 					ptbuf = cp;
22267c478bd9Sstevel@tonic-gate 				} else {
22277c478bd9Sstevel@tonic-gate 					(void) strlcpy(tbuf, cp, j);
22287c478bd9Sstevel@tonic-gate 					j = __s_get_enum_value(ptr, tbuf,
22297ddae043Siz 					    def->index);
22307c478bd9Sstevel@tonic-gate 					ptbuf = tbuf;
22317c478bd9Sstevel@tonic-gate 				}
22327c478bd9Sstevel@tonic-gate 				if (j < 0) {
22337c478bd9Sstevel@tonic-gate 					(void) snprintf(errstr, sizeof (errstr),
22347ddae043Siz 					    gettext("Unable to set value: "
22357ddae043Siz 					    "invalid credentialLevel (%s)"),
22367ddae043Siz 					    ptbuf);
22377c478bd9Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
22387ddae043Siz 					    NS_CONFIG_SYNTAX,
22397ddae043Siz 					    strdup(errstr), NULL);
22407c478bd9Sstevel@tonic-gate 					free(conf.ns_pi);
22417c478bd9Sstevel@tonic-gate 					if (tcp != NULL)
22427c478bd9Sstevel@tonic-gate 						free(tcp);
22437c478bd9Sstevel@tonic-gate 					return (NS_LDAP_CONFIG);
22447c478bd9Sstevel@tonic-gate 				}
22457c478bd9Sstevel@tonic-gate 				conf.ns_pi[i] = j;
22467c478bd9Sstevel@tonic-gate 				cp = cp2+1;
22477c478bd9Sstevel@tonic-gate 				i++;
22487c478bd9Sstevel@tonic-gate 			}
22497c478bd9Sstevel@tonic-gate 		}
22507c478bd9Sstevel@tonic-gate 		j = cp2 - cp + 1;
22517c478bd9Sstevel@tonic-gate 		if (j > sizeof (tbuf)) {
22527c478bd9Sstevel@tonic-gate 			j = -1;
22537c478bd9Sstevel@tonic-gate 			ptbuf = cp;
22547c478bd9Sstevel@tonic-gate 		} else {
22557c478bd9Sstevel@tonic-gate 			(void) strlcpy(tbuf, cp, j);
22567c478bd9Sstevel@tonic-gate 			j = __s_get_enum_value(ptr, tbuf, def->index);
22577c478bd9Sstevel@tonic-gate 			ptbuf = tbuf;
22587c478bd9Sstevel@tonic-gate 		}
22597c478bd9Sstevel@tonic-gate 		if (j < 0) {
22607c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
22617ddae043Siz 			    gettext("Unable to set value: "
22627ddae043Siz 			    "invalid credentialLevel (%s)"), ptbuf);
22637c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
22647ddae043Siz 			    strdup(errstr), NULL);
22657c478bd9Sstevel@tonic-gate 			if (tcp != NULL)
22667c478bd9Sstevel@tonic-gate 				free(tcp);
22677c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
22687c478bd9Sstevel@tonic-gate 		}
22697c478bd9Sstevel@tonic-gate 		conf.ns_pi[i] = j;
22707c478bd9Sstevel@tonic-gate 		break;
22717c478bd9Sstevel@tonic-gate 	case ATTRMAP:
22727c478bd9Sstevel@tonic-gate 	case OBJMAP:
22737c478bd9Sstevel@tonic-gate 		i = __s_api_parse_map(cp, &sid, &origA, &mapA);
22747c478bd9Sstevel@tonic-gate 		if (i != NS_HASH_RC_SUCCESS) {
22757c478bd9Sstevel@tonic-gate 			if (i == NS_HASH_RC_NO_MEMORY) {
22767c478bd9Sstevel@tonic-gate 				exitrc = NS_LDAP_MEMORY;
22777c478bd9Sstevel@tonic-gate 			} else {
22787c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
22797c478bd9Sstevel@tonic-gate 				gettext("Unable to set value: "
22807c478bd9Sstevel@tonic-gate 				"invalid schema mapping (%s)"), cp);
22817c478bd9Sstevel@tonic-gate 				exitrc = NS_LDAP_CONFIG;
22827c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
22837ddae043Siz 				    strdup(errstr), NULL);
22847c478bd9Sstevel@tonic-gate 			}
22857c478bd9Sstevel@tonic-gate 			if (tcp)
22867c478bd9Sstevel@tonic-gate 				free(tcp);
22877c478bd9Sstevel@tonic-gate 			return (exitrc);
22887c478bd9Sstevel@tonic-gate 		}
22897c478bd9Sstevel@tonic-gate 
22907c478bd9Sstevel@tonic-gate 		/*
22917c478bd9Sstevel@tonic-gate 		 * Add reverse map first.
22927c478bd9Sstevel@tonic-gate 		 * There could be more than one.
22937c478bd9Sstevel@tonic-gate 		 */
22947c478bd9Sstevel@tonic-gate 		for (attr = mapA; *attr; attr++) {
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 			free_memory = 1;
22977c478bd9Sstevel@tonic-gate 			exitrc = NS_LDAP_MEMORY;
22987c478bd9Sstevel@tonic-gate 
22997c478bd9Sstevel@tonic-gate 			rmap = (ns_mapping_t *)calloc(1,
23007ddae043Siz 			    sizeof (ns_mapping_t));
23017c478bd9Sstevel@tonic-gate 			if (rmap) {
23027c478bd9Sstevel@tonic-gate 				rmap->service = strdup(sid);
23037c478bd9Sstevel@tonic-gate 				if (rmap->service) {
23047c478bd9Sstevel@tonic-gate 					rmap->orig = strdup(*attr);
23057c478bd9Sstevel@tonic-gate 					if (rmap->orig) {
23067c478bd9Sstevel@tonic-gate 						rmap->map = (char **)calloc(2,
23077ddae043Siz 						    sizeof (char *));
23087c478bd9Sstevel@tonic-gate 						if (rmap->map) {
23097c478bd9Sstevel@tonic-gate 							(rmap->map)[0] =
23107ddae043Siz 							    strdup(origA);
23117c478bd9Sstevel@tonic-gate 							if ((rmap->map)[0])
23127c478bd9Sstevel@tonic-gate 								free_memory = 0;
23137c478bd9Sstevel@tonic-gate 						}
23147c478bd9Sstevel@tonic-gate 					}
23157c478bd9Sstevel@tonic-gate 				}
23167c478bd9Sstevel@tonic-gate 			}
23177c478bd9Sstevel@tonic-gate 
23187c478bd9Sstevel@tonic-gate 			if (free_memory == 0) {
23197c478bd9Sstevel@tonic-gate 				if (def->data_type == ATTRMAP) {
23207c478bd9Sstevel@tonic-gate 					rmap->type = NS_ATTR_MAP;
23217c478bd9Sstevel@tonic-gate 					i = __s_api_add_map2hash(ptr,
23227ddae043Siz 					    NS_HASH_RAMAP, rmap);
23237c478bd9Sstevel@tonic-gate 				} else {
23247c478bd9Sstevel@tonic-gate 					rmap->type = NS_OBJ_MAP;
23257c478bd9Sstevel@tonic-gate 					i = __s_api_add_map2hash(ptr,
23267ddae043Siz 					    NS_HASH_ROMAP, rmap);
23277c478bd9Sstevel@tonic-gate 				}
23287c478bd9Sstevel@tonic-gate 
23297c478bd9Sstevel@tonic-gate 				if (i != NS_HASH_RC_SUCCESS) {
23307c478bd9Sstevel@tonic-gate 					switch (i) {
23317c478bd9Sstevel@tonic-gate 					case NS_HASH_RC_CONFIG_ERROR:
23327c478bd9Sstevel@tonic-gate 						exitrc = NS_LDAP_INTERNAL;
23337c478bd9Sstevel@tonic-gate 						(void) snprintf(errstr,
23347ddae043Siz 						    sizeof (errstr),
23357ddae043Siz 						    gettext(
23367ddae043Siz 						    "Unable to set value: "
23377ddae043Siz 						    "no configuration info "
23387ddae043Siz 						    "for schema map "
23397ddae043Siz 						    "update (%s)"), cp);
23407c478bd9Sstevel@tonic-gate 						MKERROR(LOG_ERR, *error,
23417ddae043Siz 						    NS_LDAP_INTERNAL,
23427ddae043Siz 						    strdup(errstr),
23437ddae043Siz 						    NULL);
23447c478bd9Sstevel@tonic-gate 						break;
23457c478bd9Sstevel@tonic-gate 					case NS_HASH_RC_EXISTED:
23467c478bd9Sstevel@tonic-gate 						exitrc = NS_LDAP_CONFIG;
23477c478bd9Sstevel@tonic-gate 						(void) snprintf(errstr,
23487ddae043Siz 						    sizeof (errstr),
23497ddae043Siz 						    gettext(
23507ddae043Siz 						    "Unable to set value: "
23517ddae043Siz 						    "schema map "
23527ddae043Siz 						    "already existed for "
23537ddae043Siz 						    "(%s, %s)."),
23547ddae043Siz 						    *attr, origA);
23557c478bd9Sstevel@tonic-gate 						MKERROR(LOG_ERR, *error,
23567ddae043Siz 						    NS_CONFIG_SYNTAX,
23577ddae043Siz 						    strdup(errstr),
23587ddae043Siz 						    NULL);
23597c478bd9Sstevel@tonic-gate 						break;
23607c478bd9Sstevel@tonic-gate 					case NS_HASH_RC_NO_MEMORY:
23617c478bd9Sstevel@tonic-gate 						exitrc = NS_LDAP_MEMORY;
23627c478bd9Sstevel@tonic-gate 						break;
23637c478bd9Sstevel@tonic-gate 					}
23647c478bd9Sstevel@tonic-gate 					free_memory = 1;
23657c478bd9Sstevel@tonic-gate 				}
23667c478bd9Sstevel@tonic-gate 			}
23677c478bd9Sstevel@tonic-gate 
23687c478bd9Sstevel@tonic-gate 			if (free_memory) {
23697c478bd9Sstevel@tonic-gate 				if (tcp)
23707c478bd9Sstevel@tonic-gate 					free(tcp);
23717c478bd9Sstevel@tonic-gate 				free(sid);
23727c478bd9Sstevel@tonic-gate 				free(origA);
23737c478bd9Sstevel@tonic-gate 				__s_api_free2dArray(mapA);
23747c478bd9Sstevel@tonic-gate 				if (rmap) {
23757c478bd9Sstevel@tonic-gate 					if (rmap->service)
23767c478bd9Sstevel@tonic-gate 						free(rmap->service);
23777c478bd9Sstevel@tonic-gate 					if (rmap->orig)
23787c478bd9Sstevel@tonic-gate 						free(rmap->orig);
23797c478bd9Sstevel@tonic-gate 					if (rmap->map) {
23807c478bd9Sstevel@tonic-gate 						if ((rmap->map)[0])
23817c478bd9Sstevel@tonic-gate 							free((rmap->map)[0]);
23827c478bd9Sstevel@tonic-gate 						free(rmap->map);
23837c478bd9Sstevel@tonic-gate 					}
23847c478bd9Sstevel@tonic-gate 					free(rmap);
23857c478bd9Sstevel@tonic-gate 				}
23867c478bd9Sstevel@tonic-gate 				return (exitrc);
23877c478bd9Sstevel@tonic-gate 			}
23887c478bd9Sstevel@tonic-gate 		}
23897c478bd9Sstevel@tonic-gate 
23907c478bd9Sstevel@tonic-gate 		/*
23917c478bd9Sstevel@tonic-gate 		 * For performance gain,
23927c478bd9Sstevel@tonic-gate 		 * add a "schema mapping existed" indicator
23937c478bd9Sstevel@tonic-gate 		 * for the given service if not already added.
23947c478bd9Sstevel@tonic-gate 		 * This dummy map needs not be removed, if
23957c478bd9Sstevel@tonic-gate 		 * the next real map add operation fails.
23967c478bd9Sstevel@tonic-gate 		 * since the caller, e.g. ldap_cachemgr.
23977c478bd9Sstevel@tonic-gate 		 * should exit anyway.
23987c478bd9Sstevel@tonic-gate 		 */
23997c478bd9Sstevel@tonic-gate 		free_memory = 1;
24007c478bd9Sstevel@tonic-gate 		exitrc = NS_LDAP_MEMORY;
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate 		map = (ns_mapping_t *)calloc(1,
24037ddae043Siz 		    sizeof (ns_mapping_t));
24047c478bd9Sstevel@tonic-gate 		if (map) {
24057c478bd9Sstevel@tonic-gate 			map->service = strdup(sid);
24067c478bd9Sstevel@tonic-gate 			if (map->service) {
24077c478bd9Sstevel@tonic-gate 				map->orig = strdup(
24087ddae043Siz 				    NS_HASH_SCHEMA_MAPPING_EXISTED);
24097c478bd9Sstevel@tonic-gate 				if (map->orig) {
24107c478bd9Sstevel@tonic-gate 					map->map = (char **)calloc(2,
24117ddae043Siz 					    sizeof (char *));
24127c478bd9Sstevel@tonic-gate 					if (map->map) {
24137c478bd9Sstevel@tonic-gate 						(map->map)[0] =
24147ddae043Siz 						    strdup(sid);
24157c478bd9Sstevel@tonic-gate 						if ((map->map)[0])
24167c478bd9Sstevel@tonic-gate 							free_memory = 0;
24177c478bd9Sstevel@tonic-gate 					}
24187c478bd9Sstevel@tonic-gate 				}
24197c478bd9Sstevel@tonic-gate 			}
24207c478bd9Sstevel@tonic-gate 		}
24217c478bd9Sstevel@tonic-gate 
24227c478bd9Sstevel@tonic-gate 		if (free_memory == 0) {
24237c478bd9Sstevel@tonic-gate 			map->type = NS_ATTR_MAP;
24247c478bd9Sstevel@tonic-gate 			/*
24257c478bd9Sstevel@tonic-gate 			 * add to reverse map,
24267c478bd9Sstevel@tonic-gate 			 * so that "ldapclient list"
24277c478bd9Sstevel@tonic-gate 			 * would not show it
24287c478bd9Sstevel@tonic-gate 			 */
24297c478bd9Sstevel@tonic-gate 			i = __s_api_add_map2hash(ptr,
24307ddae043Siz 			    NS_HASH_RAMAP, map);
24317c478bd9Sstevel@tonic-gate 
24327c478bd9Sstevel@tonic-gate 			/*
24337c478bd9Sstevel@tonic-gate 			 * ignore "map already existed" error,
24347c478bd9Sstevel@tonic-gate 			 * just need one per service.
24357c478bd9Sstevel@tonic-gate 			 * Need however to free memory allocated
24367c478bd9Sstevel@tonic-gate 			 * for map.
24377c478bd9Sstevel@tonic-gate 			 */
24387c478bd9Sstevel@tonic-gate 			if (i != NS_HASH_RC_SUCCESS &&
24397ddae043Siz 			    i != NS_HASH_RC_EXISTED) {
24407c478bd9Sstevel@tonic-gate 				switch (i) {
24417c478bd9Sstevel@tonic-gate 				case NS_HASH_RC_CONFIG_ERROR:
24427c478bd9Sstevel@tonic-gate 					exitrc = NS_LDAP_INTERNAL;
24437c478bd9Sstevel@tonic-gate 					(void) snprintf(errstr,
24447ddae043Siz 					    sizeof (errstr),
24457ddae043Siz 					    gettext(
24467ddae043Siz 					    "Unable to set value: "
24477ddae043Siz 					    "no configuration info "
24487ddae043Siz 					    "for schema map "
24497ddae043Siz 					    "update (%s)"), cp);
24507c478bd9Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
24517ddae043Siz 					    NS_LDAP_INTERNAL,
24527ddae043Siz 					    strdup(errstr),
24537ddae043Siz 					    NULL);
24547c478bd9Sstevel@tonic-gate 					break;
24557c478bd9Sstevel@tonic-gate 				case NS_HASH_RC_NO_MEMORY:
24567c478bd9Sstevel@tonic-gate 					exitrc = NS_LDAP_MEMORY;
24577c478bd9Sstevel@tonic-gate 					break;
24587c478bd9Sstevel@tonic-gate 				}
24597c478bd9Sstevel@tonic-gate 				free_memory = 1;
24607c478bd9Sstevel@tonic-gate 			} else if (i == NS_HASH_RC_EXISTED) {
24617c478bd9Sstevel@tonic-gate 				if (map->service)
24627c478bd9Sstevel@tonic-gate 					free(map->service);
24637c478bd9Sstevel@tonic-gate 				if (map->orig)
24647c478bd9Sstevel@tonic-gate 					free(map->orig);
24657c478bd9Sstevel@tonic-gate 				if (map->map) {
24667c478bd9Sstevel@tonic-gate 					if ((map->map)[0])
24677c478bd9Sstevel@tonic-gate 						free((map->map)[0]);
24687c478bd9Sstevel@tonic-gate 					free(map->map);
24697c478bd9Sstevel@tonic-gate 				}
24707c478bd9Sstevel@tonic-gate 				free(map);
24717c478bd9Sstevel@tonic-gate 				map = NULL;
24727c478bd9Sstevel@tonic-gate 			}
24737c478bd9Sstevel@tonic-gate 		}
24747c478bd9Sstevel@tonic-gate 
24757c478bd9Sstevel@tonic-gate 		if (free_memory) {
24767c478bd9Sstevel@tonic-gate 			if (tcp)
24777c478bd9Sstevel@tonic-gate 				free(tcp);
24787c478bd9Sstevel@tonic-gate 			free(sid);
24797c478bd9Sstevel@tonic-gate 			free(origA);
24807c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(mapA);
24817c478bd9Sstevel@tonic-gate 			if (map) {
24827c478bd9Sstevel@tonic-gate 				if (map->service)
24837c478bd9Sstevel@tonic-gate 					free(map->service);
24847c478bd9Sstevel@tonic-gate 				if (map->orig)
24857c478bd9Sstevel@tonic-gate 					free(map->orig);
24867c478bd9Sstevel@tonic-gate 				if (map->map) {
24877c478bd9Sstevel@tonic-gate 					if ((map->map)[0])
24887c478bd9Sstevel@tonic-gate 						free((map->map)[0]);
24897c478bd9Sstevel@tonic-gate 					free(map->map);
24907c478bd9Sstevel@tonic-gate 				}
24917c478bd9Sstevel@tonic-gate 				free(map);
24927c478bd9Sstevel@tonic-gate 			}
24937c478bd9Sstevel@tonic-gate 			return (exitrc);
24947c478bd9Sstevel@tonic-gate 		}
24957c478bd9Sstevel@tonic-gate 
24967c478bd9Sstevel@tonic-gate 		/*
24977c478bd9Sstevel@tonic-gate 		 * add the real schema map
24987c478bd9Sstevel@tonic-gate 		 */
24997c478bd9Sstevel@tonic-gate 		free_memory = 1;
25007c478bd9Sstevel@tonic-gate 		exitrc = NS_LDAP_MEMORY;
25017c478bd9Sstevel@tonic-gate 		map = (ns_mapping_t *)calloc(1, sizeof (ns_mapping_t));
25027c478bd9Sstevel@tonic-gate 		if (map) {
25037c478bd9Sstevel@tonic-gate 			map->service = sid;
25047c478bd9Sstevel@tonic-gate 			map->orig = origA;
25057c478bd9Sstevel@tonic-gate 			map->map = mapA;
25067c478bd9Sstevel@tonic-gate 
25077c478bd9Sstevel@tonic-gate 			if (def->data_type == ATTRMAP) {
25087c478bd9Sstevel@tonic-gate 				map->type = NS_ATTR_MAP;
25097c478bd9Sstevel@tonic-gate 				i = __s_api_add_map2hash(ptr,
25107ddae043Siz 				    NS_HASH_AMAP, map);
25117c478bd9Sstevel@tonic-gate 			} else {
25127c478bd9Sstevel@tonic-gate 				map->type = NS_OBJ_MAP;
25137c478bd9Sstevel@tonic-gate 				i = __s_api_add_map2hash(ptr,
25147ddae043Siz 				    NS_HASH_OMAP, map);
25157c478bd9Sstevel@tonic-gate 			}
25167c478bd9Sstevel@tonic-gate 
25177c478bd9Sstevel@tonic-gate 			if (i != NS_HASH_RC_SUCCESS) {
25187c478bd9Sstevel@tonic-gate 				switch (i) {
25197c478bd9Sstevel@tonic-gate 				case NS_HASH_RC_CONFIG_ERROR:
25207c478bd9Sstevel@tonic-gate 					exitrc = NS_LDAP_INTERNAL;
25217c478bd9Sstevel@tonic-gate 					(void) snprintf(errstr,
25227ddae043Siz 					    sizeof (errstr),
25237ddae043Siz 					    gettext(
25247ddae043Siz 					    "Unable to set value: "
25257ddae043Siz 					    "no configuration info "
25267ddae043Siz 					    "for schema map "
25277ddae043Siz 					    "update (%s)"), cp);
25287c478bd9Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
25297ddae043Siz 					    NS_LDAP_INTERNAL,
25307ddae043Siz 					    strdup(errstr),
25317ddae043Siz 					    NULL);
25327c478bd9Sstevel@tonic-gate 					break;
25337c478bd9Sstevel@tonic-gate 				case NS_HASH_RC_EXISTED:
25347c478bd9Sstevel@tonic-gate 					exitrc = NS_LDAP_CONFIG;
25357c478bd9Sstevel@tonic-gate 					(void) snprintf(errstr,
25367ddae043Siz 					    sizeof (errstr),
25377ddae043Siz 					    gettext(
25387ddae043Siz 					    "Unable to set value: "
25397ddae043Siz 					    "schema map "
25407ddae043Siz 					    "already existed for "
25417ddae043Siz 					    "'%s'."), origA);
25427c478bd9Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
25437ddae043Siz 					    NS_CONFIG_SYNTAX,
25447ddae043Siz 					    strdup(errstr),
25457ddae043Siz 					    NULL);
25467c478bd9Sstevel@tonic-gate 					break;
25477c478bd9Sstevel@tonic-gate 				case NS_HASH_RC_NO_MEMORY:
25487c478bd9Sstevel@tonic-gate 					exitrc = NS_LDAP_MEMORY;
25497c478bd9Sstevel@tonic-gate 					break;
25507c478bd9Sstevel@tonic-gate 				}
25517c478bd9Sstevel@tonic-gate 				free_memory = 1;
25527c478bd9Sstevel@tonic-gate 			} else
25537c478bd9Sstevel@tonic-gate 				free_memory = 0;
25547c478bd9Sstevel@tonic-gate 		}
25557c478bd9Sstevel@tonic-gate 
25567c478bd9Sstevel@tonic-gate 		if (free_memory) {
25577c478bd9Sstevel@tonic-gate 			if (tcp)
25587c478bd9Sstevel@tonic-gate 				free(tcp);
25597c478bd9Sstevel@tonic-gate 			free(sid);
25607c478bd9Sstevel@tonic-gate 			free(origA);
25617c478bd9Sstevel@tonic-gate 			__s_api_free2dArray(mapA);
25627c478bd9Sstevel@tonic-gate 			if (map)
25637c478bd9Sstevel@tonic-gate 				free(map);
25647c478bd9Sstevel@tonic-gate 			return (exitrc);
25657c478bd9Sstevel@tonic-gate 		}
25667c478bd9Sstevel@tonic-gate 
25677c478bd9Sstevel@tonic-gate 		break;
25687c478bd9Sstevel@tonic-gate 	default:
25697c478bd9Sstevel@tonic-gate 		/* This should never happen. */
25707c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
25717ddae043Siz 		    gettext("Unable to set value: invalid configuration "
25727ddae043Siz 		    "type (%d)"), def->data_type);
25737c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
25747ddae043Siz 		    NULL);
25757c478bd9Sstevel@tonic-gate 		if (tcp != NULL)
25767c478bd9Sstevel@tonic-gate 			free(tcp);
25777c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
25787c478bd9Sstevel@tonic-gate 	}
25797c478bd9Sstevel@tonic-gate 	conf.ns_ptype = def->data_type;
25807c478bd9Sstevel@tonic-gate 	if (tcp != NULL)
25817c478bd9Sstevel@tonic-gate 		free(tcp);
25827c478bd9Sstevel@tonic-gate 
25837c478bd9Sstevel@tonic-gate 	/* Individually written verify routines here can replace */
25847c478bd9Sstevel@tonic-gate 	/* verify_value.  Verify conf (data) as appropriate here */
25857c478bd9Sstevel@tonic-gate 	if (def->ns_verify != NULL) {
25867c478bd9Sstevel@tonic-gate 		if ((*def->ns_verify)(type, def, &conf, errstr) != NS_SUCCESS) {
25877c478bd9Sstevel@tonic-gate 			ns_param_t sav_conf;
25887c478bd9Sstevel@tonic-gate 
25897c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
25907ddae043Siz 			    gettext("%s"), errstr);
25917c478bd9Sstevel@tonic-gate 			MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX,
25927ddae043Siz 			    strdup(errstr), NULL);
25937c478bd9Sstevel@tonic-gate 
25947c478bd9Sstevel@tonic-gate 			sav_conf = ptr->paramList[type];
25957c478bd9Sstevel@tonic-gate 			ptr->paramList[type] = conf;
25967c478bd9Sstevel@tonic-gate 			destroy_param(ptr, type);
25977c478bd9Sstevel@tonic-gate 			ptr->paramList[type] = sav_conf;
25987c478bd9Sstevel@tonic-gate 
25997c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
26007c478bd9Sstevel@tonic-gate 		}
26017c478bd9Sstevel@tonic-gate 	}
26027c478bd9Sstevel@tonic-gate 
26037c478bd9Sstevel@tonic-gate 	/* post evaluate the data */
26047c478bd9Sstevel@tonic-gate 
26057c478bd9Sstevel@tonic-gate 	/*
26067c478bd9Sstevel@tonic-gate 	 * if this is for setting a password,
26077c478bd9Sstevel@tonic-gate 	 * encrypt the password first.
26087c478bd9Sstevel@tonic-gate 	 * NOTE evalue() is smart and will just return
26097c478bd9Sstevel@tonic-gate 	 * the value passed if it is already encrypted.
26107c478bd9Sstevel@tonic-gate 	 *
26117c478bd9Sstevel@tonic-gate 	 * Init NS_LDAP_EXP_P here when CACHETTL is updated
26127c478bd9Sstevel@tonic-gate 	 */
26137c478bd9Sstevel@tonic-gate 	if (type == NS_LDAP_BINDPASSWD_P) {
26147c478bd9Sstevel@tonic-gate 		cp = conf.ns_pc;
26157c478bd9Sstevel@tonic-gate 		cp2 = evalue((char *)cp);
26167c478bd9Sstevel@tonic-gate 		conf.ns_pc = cp2;
26177c478bd9Sstevel@tonic-gate 		free(cp);
26187c478bd9Sstevel@tonic-gate 		cp = NULL;
26197c478bd9Sstevel@tonic-gate 	} else if (type == NS_LDAP_FILE_VERSION_P) {
26207c478bd9Sstevel@tonic-gate 		ptr->version = NS_LDAP_V1;
26217c478bd9Sstevel@tonic-gate 		if (strcasecmp(conf.ns_pc, NS_LDAP_VERSION_2) == 0) {
26227c478bd9Sstevel@tonic-gate 			ptr->version = NS_LDAP_V2;
26237c478bd9Sstevel@tonic-gate 		}
26247c478bd9Sstevel@tonic-gate 	} else if (type == NS_LDAP_CACHETTL_P) {
26257c478bd9Sstevel@tonic-gate 		cp = conf.ns_pc;
26267c478bd9Sstevel@tonic-gate 		tm = conv_time(cp);
26277c478bd9Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
26287c478bd9Sstevel@tonic-gate 		if (tm != 0) {
26297c478bd9Sstevel@tonic-gate 			tm += time(NULL);
26307c478bd9Sstevel@tonic-gate 		}
26317c478bd9Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
26327c478bd9Sstevel@tonic-gate 	}
26337c478bd9Sstevel@tonic-gate 
26347c478bd9Sstevel@tonic-gate 	/* Everything checks out move new values into param */
26357c478bd9Sstevel@tonic-gate 	destroy_param(ptr, type);
26367c478bd9Sstevel@tonic-gate 	/* Assign new/updated value into paramList */
26377c478bd9Sstevel@tonic-gate 	ptr->paramList[type] = conf;
26387c478bd9Sstevel@tonic-gate 
26397c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
26407c478bd9Sstevel@tonic-gate }
26417c478bd9Sstevel@tonic-gate 
26427c478bd9Sstevel@tonic-gate 
26437c478bd9Sstevel@tonic-gate /*
26447c478bd9Sstevel@tonic-gate  * Set a parameter value in the 'config' configuration structure
26457c478bd9Sstevel@tonic-gate  * Lock as appropriate
26467c478bd9Sstevel@tonic-gate  */
26477c478bd9Sstevel@tonic-gate 
26487c478bd9Sstevel@tonic-gate int
26497c478bd9Sstevel@tonic-gate __ns_ldap_setParam(const ParamIndexType type,
26507c478bd9Sstevel@tonic-gate 		const void *data, ns_ldap_error_t **error)
26517c478bd9Sstevel@tonic-gate {
26527c478bd9Sstevel@tonic-gate 	ns_ldap_error_t		*errorp;
26537c478bd9Sstevel@tonic-gate 	int			ret;
26547c478bd9Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
26557c478bd9Sstevel@tonic-gate 	ns_config_t		*cfg;
2656*e1dd0a2fSth 	ns_config_t		*cfg_g = (ns_config_t *)-1;
26577c478bd9Sstevel@tonic-gate 	ns_config_t		*new_cfg;
2658*e1dd0a2fSth 	boolean_t		reinit_connmgmt = B_FALSE;
26597c478bd9Sstevel@tonic-gate 
26607c478bd9Sstevel@tonic-gate 	/* We want to refresh only one configuration at a time */
26617c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&ns_loadrefresh_lock);
26627c478bd9Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
26637c478bd9Sstevel@tonic-gate 
26647c478bd9Sstevel@tonic-gate 	if (cache_server == TRUE) {
26657c478bd9Sstevel@tonic-gate 		if (cfg == NULL) {
26667ddae043Siz 			__ns_ldap_default_config();
26677ddae043Siz 			cfg = __s_api_get_default_config();
26687ddae043Siz 			if (cfg == NULL) {
26697ddae043Siz 				(void) mutex_unlock(&ns_loadrefresh_lock);
26707ddae043Siz 				return (NS_LDAP_MEMORY);
26717ddae043Siz 			}
26727c478bd9Sstevel@tonic-gate 		}
26737c478bd9Sstevel@tonic-gate 	} else {
26747c478bd9Sstevel@tonic-gate 		/*
26757c478bd9Sstevel@tonic-gate 		 * This code always return error here on client side,
26767c478bd9Sstevel@tonic-gate 		 * this needs to change once libsldap is used by more
26777c478bd9Sstevel@tonic-gate 		 * applications that need to set parameters.
26787c478bd9Sstevel@tonic-gate 		 */
26797c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
26807ddae043Siz 		    gettext("Unable to set parameter from a client in "
26817ddae043Siz 		    "__ns_ldap_setParam()"));
26827c478bd9Sstevel@tonic-gate 		MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX, strdup(errstr),
26837ddae043Siz 		    NULL);
26847c478bd9Sstevel@tonic-gate 		if (cfg != NULL)
26857c478bd9Sstevel@tonic-gate 			__s_api_release_config(cfg);
26867c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&ns_loadrefresh_lock);
26877c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
26887c478bd9Sstevel@tonic-gate 	}
26897c478bd9Sstevel@tonic-gate 
26907c478bd9Sstevel@tonic-gate 	/* (re)initialize configuration if necessary */
2691*e1dd0a2fSth 	if (!__s_api_isStandalone() &&
2692*e1dd0a2fSth 	    cache_server == FALSE && timetorefresh(cfg))
2693*e1dd0a2fSth 		cfg_g = __s_api_get_default_config_global();
2694*e1dd0a2fSth 	/* only (re)initialize the global configuration */
2695*e1dd0a2fSth 	if (cfg == cfg_g) {
2696*e1dd0a2fSth 		if (cfg_g != NULL)
2697*e1dd0a2fSth 			__s_api_release_config(cfg_g);
2698*e1dd0a2fSth 		new_cfg = LoadCacheConfiguration(cfg, &errorp);
2699*e1dd0a2fSth 		if (new_cfg != cfg)
2700*e1dd0a2fSth 			__s_api_release_config(cfg);
27017c478bd9Sstevel@tonic-gate 		if (new_cfg == NULL) {
27027c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
27037ddae043Siz 			    gettext("Unable to load configuration '%s' "
27047ddae043Siz 			    "('%s')."), NSCONFIGFILE,
27057ddae043Siz 			    errorp != NULL && errorp->message != NULL ?
27067ddae043Siz 			    errorp->message : "");
27077c478bd9Sstevel@tonic-gate 			MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
27087ddae043Siz 			    strdup(errstr), NULL);
27097c478bd9Sstevel@tonic-gate 			if (errorp != NULL)
27107c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeError(&errorp);
27117c478bd9Sstevel@tonic-gate 			(void) mutex_unlock(&ns_loadrefresh_lock);
27127c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
27137c478bd9Sstevel@tonic-gate 		}
2714*e1dd0a2fSth 		if (new_cfg != cfg) {
2715*e1dd0a2fSth 			set_curr_config_global(new_cfg);
2716*e1dd0a2fSth 			cfg = new_cfg;
2717*e1dd0a2fSth 			reinit_connmgmt = B_TRUE;
2718*e1dd0a2fSth 		}
27197c478bd9Sstevel@tonic-gate 	}
27207c478bd9Sstevel@tonic-gate 	(void) mutex_unlock(&ns_loadrefresh_lock);
27217c478bd9Sstevel@tonic-gate 
2722*e1dd0a2fSth 	if (reinit_connmgmt == B_TRUE)
2723*e1dd0a2fSth 		__s_api_reinit_conn_mgmt_new_config(cfg);
2724*e1dd0a2fSth 
27257c478bd9Sstevel@tonic-gate 	/* translate input and save in the parameter list */
27267c478bd9Sstevel@tonic-gate 	ret = __ns_ldap_setParamValue(cfg, type, data, error);
27277c478bd9Sstevel@tonic-gate 
27287c478bd9Sstevel@tonic-gate 	__s_api_release_config(cfg);
27297c478bd9Sstevel@tonic-gate 
27307c478bd9Sstevel@tonic-gate 	return (ret);
27317c478bd9Sstevel@tonic-gate }
27327c478bd9Sstevel@tonic-gate 
27337c478bd9Sstevel@tonic-gate 
27347c478bd9Sstevel@tonic-gate /*
27357c478bd9Sstevel@tonic-gate  * Make a copy of a parameter entry
27367c478bd9Sstevel@tonic-gate  */
27377c478bd9Sstevel@tonic-gate 
27387c478bd9Sstevel@tonic-gate static void **
27397c478bd9Sstevel@tonic-gate dupParam(ns_param_t *ptr)
27407c478bd9Sstevel@tonic-gate {
27417c478bd9Sstevel@tonic-gate 	int		count, i;
27427c478bd9Sstevel@tonic-gate 	void		**dupdata, *ret;
27437c478bd9Sstevel@tonic-gate 	int		*intptr;
27447c478bd9Sstevel@tonic-gate 	char		*cp, tmbuf[32];
27457c478bd9Sstevel@tonic-gate 	static time_t	expire = 0;
27467c478bd9Sstevel@tonic-gate 	ns_auth_t	*ap;
27477c478bd9Sstevel@tonic-gate 
27487c478bd9Sstevel@tonic-gate 	switch (ptr->ns_ptype) {
27497c478bd9Sstevel@tonic-gate 	case ARRAYAUTH:
27507c478bd9Sstevel@tonic-gate 	case ARRAYCRED:
27517c478bd9Sstevel@tonic-gate 	case SAMLIST:
27527c478bd9Sstevel@tonic-gate 	case SCLLIST:
27537c478bd9Sstevel@tonic-gate 	case SSDLIST:
27547c478bd9Sstevel@tonic-gate 	case SERVLIST:
27557c478bd9Sstevel@tonic-gate 	case ARRAYCP:
27567c478bd9Sstevel@tonic-gate 		count = ptr->ns_acnt;
27577c478bd9Sstevel@tonic-gate 		if (count == 0)
27587c478bd9Sstevel@tonic-gate 			return (NULL);
27597c478bd9Sstevel@tonic-gate 		break;
27607c478bd9Sstevel@tonic-gate 	case CHARPTR:
27617c478bd9Sstevel@tonic-gate 	case INT:
27627c478bd9Sstevel@tonic-gate 	case TIMET:
27637c478bd9Sstevel@tonic-gate 		count = 1;
27647c478bd9Sstevel@tonic-gate 	}
27657c478bd9Sstevel@tonic-gate 
27667c478bd9Sstevel@tonic-gate 	dupdata = (void **)calloc((count + 1), sizeof (void *));
27677c478bd9Sstevel@tonic-gate 	if (dupdata == NULL)
27687c478bd9Sstevel@tonic-gate 		return (NULL);
27697c478bd9Sstevel@tonic-gate 
27707c478bd9Sstevel@tonic-gate 	switch (ptr->ns_ptype) {
27717c478bd9Sstevel@tonic-gate 	case ARRAYAUTH:
27727c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
27737c478bd9Sstevel@tonic-gate 			ap = __s_api_AuthEnumtoStruct(
27747ddae043Siz 			    (EnumAuthType_t)ptr->ns_pi[i]);
27757c478bd9Sstevel@tonic-gate 			if (ap == NULL) {
27767c478bd9Sstevel@tonic-gate 				free(dupdata);
27777c478bd9Sstevel@tonic-gate 				return (NULL);
27787c478bd9Sstevel@tonic-gate 			}
27797c478bd9Sstevel@tonic-gate 			dupdata[i] = ap;
27807c478bd9Sstevel@tonic-gate 		}
27817c478bd9Sstevel@tonic-gate 		break;
27827c478bd9Sstevel@tonic-gate 	case ARRAYCRED:
27837c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
27847c478bd9Sstevel@tonic-gate 			intptr = (int *)malloc(sizeof (int));
27857c478bd9Sstevel@tonic-gate 			if (intptr == NULL) {
27867c478bd9Sstevel@tonic-gate 				free(dupdata);
27877c478bd9Sstevel@tonic-gate 				return (NULL);
27887c478bd9Sstevel@tonic-gate 			}
27897c478bd9Sstevel@tonic-gate 			dupdata[i] = (void *)intptr;
27907c478bd9Sstevel@tonic-gate 			*intptr = ptr->ns_pi[i];
27917c478bd9Sstevel@tonic-gate 		}
27927c478bd9Sstevel@tonic-gate 		break;
27937c478bd9Sstevel@tonic-gate 	case SAMLIST:
27947c478bd9Sstevel@tonic-gate 	case SCLLIST:
27957c478bd9Sstevel@tonic-gate 	case SSDLIST:
27967c478bd9Sstevel@tonic-gate 	case SERVLIST:
27977c478bd9Sstevel@tonic-gate 	case ARRAYCP:
27987c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
27997c478bd9Sstevel@tonic-gate 			ret = (void *)strdup(ptr->ns_ppc[i]);
28007c478bd9Sstevel@tonic-gate 			if (ret == NULL) {
28017c478bd9Sstevel@tonic-gate 				free(dupdata);
28027c478bd9Sstevel@tonic-gate 				return (NULL);
28037c478bd9Sstevel@tonic-gate 			}
28047c478bd9Sstevel@tonic-gate 			dupdata[i] = ret;
28057c478bd9Sstevel@tonic-gate 		}
28067c478bd9Sstevel@tonic-gate 		break;
28077c478bd9Sstevel@tonic-gate 	case CHARPTR:
28087c478bd9Sstevel@tonic-gate 		if (ptr->ns_pc == NULL) {
28097c478bd9Sstevel@tonic-gate 			free(dupdata);
28107c478bd9Sstevel@tonic-gate 			return (NULL);
28117c478bd9Sstevel@tonic-gate 		}
28127c478bd9Sstevel@tonic-gate 		ret = (void *)strdup(ptr->ns_pc);
28137c478bd9Sstevel@tonic-gate 		if (ret == NULL) {
28147c478bd9Sstevel@tonic-gate 			free(dupdata);
28157c478bd9Sstevel@tonic-gate 			return (NULL);
28167c478bd9Sstevel@tonic-gate 		}
28177c478bd9Sstevel@tonic-gate 		dupdata[0] = ret;
28187c478bd9Sstevel@tonic-gate 		break;
28197c478bd9Sstevel@tonic-gate 	case INT:
28207c478bd9Sstevel@tonic-gate 		intptr = (int *)malloc(sizeof (int));
28217c478bd9Sstevel@tonic-gate 		if (intptr == NULL) {
28227c478bd9Sstevel@tonic-gate 			free(dupdata);
28237c478bd9Sstevel@tonic-gate 			return (NULL);
28247c478bd9Sstevel@tonic-gate 		}
28257c478bd9Sstevel@tonic-gate 		*intptr = ptr->ns_i;
28267c478bd9Sstevel@tonic-gate 		dupdata[0] = (void *)intptr;
28277c478bd9Sstevel@tonic-gate 		break;
28287c478bd9Sstevel@tonic-gate 	case TIMET:
28297c478bd9Sstevel@tonic-gate 		expire = ptr->ns_tm;
28307c478bd9Sstevel@tonic-gate 		tmbuf[31] = '\0';
28317c478bd9Sstevel@tonic-gate 		cp = lltostr((long)expire, &tmbuf[31]);
28327c478bd9Sstevel@tonic-gate 		ret = (void *)strdup(cp);
28337c478bd9Sstevel@tonic-gate 		if (ret == NULL) {
28347c478bd9Sstevel@tonic-gate 			free(dupdata);
28357c478bd9Sstevel@tonic-gate 			return (NULL);
28367c478bd9Sstevel@tonic-gate 		}
28377c478bd9Sstevel@tonic-gate 		dupdata[0] = ret;
28387c478bd9Sstevel@tonic-gate 		break;
28397c478bd9Sstevel@tonic-gate 	}
28407c478bd9Sstevel@tonic-gate 	return (dupdata);
28417c478bd9Sstevel@tonic-gate }
28427c478bd9Sstevel@tonic-gate 
28437c478bd9Sstevel@tonic-gate int
28447c478bd9Sstevel@tonic-gate __ns_ldap_freeParam(void ***data)
28457c478bd9Sstevel@tonic-gate {
28467c478bd9Sstevel@tonic-gate 	void	**tmp;
28477c478bd9Sstevel@tonic-gate 	int	i = 0;
28487c478bd9Sstevel@tonic-gate 
28497c478bd9Sstevel@tonic-gate 	if (*data == NULL)
28507c478bd9Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
28517c478bd9Sstevel@tonic-gate 
28527c478bd9Sstevel@tonic-gate 	for (i = 0, tmp = *data; tmp[i] != NULL; i++)
28537c478bd9Sstevel@tonic-gate 		free(tmp[i]);
28547c478bd9Sstevel@tonic-gate 
28557c478bd9Sstevel@tonic-gate 	free(*data);
28567c478bd9Sstevel@tonic-gate 
28577c478bd9Sstevel@tonic-gate 	*data = NULL;
28587c478bd9Sstevel@tonic-gate 
28597c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
28607c478bd9Sstevel@tonic-gate }
28617c478bd9Sstevel@tonic-gate 
28627c478bd9Sstevel@tonic-gate /*
28637c478bd9Sstevel@tonic-gate  * Get the internal format for a parameter value.  This
28647c478bd9Sstevel@tonic-gate  * routine makes a copy of an internal param value from
28657c478bd9Sstevel@tonic-gate  * the currently active parameter list and returns it.
28667c478bd9Sstevel@tonic-gate  */
28677c478bd9Sstevel@tonic-gate 
28687c478bd9Sstevel@tonic-gate int
28697c478bd9Sstevel@tonic-gate __ns_ldap_getParam(const ParamIndexType Param,
28707c478bd9Sstevel@tonic-gate 		void ***data, ns_ldap_error_t **error)
28717c478bd9Sstevel@tonic-gate {
28727c478bd9Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
28737c478bd9Sstevel@tonic-gate 	ns_ldap_error_t		*errorp;
28747c478bd9Sstevel@tonic-gate 	ns_default_config	*def;
28757c478bd9Sstevel@tonic-gate 	ns_config_t		*cfg;
2876*e1dd0a2fSth 	ns_config_t		*cfg_g = (ns_config_t *)-1;
28777c478bd9Sstevel@tonic-gate 	ns_config_t		*new_cfg;
2878*e1dd0a2fSth 	boolean_t		reinit_connmgmt = B_FALSE;
28797c478bd9Sstevel@tonic-gate 
28807c478bd9Sstevel@tonic-gate 	if (data == NULL)
28817c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
28827c478bd9Sstevel@tonic-gate 
28837c478bd9Sstevel@tonic-gate 	*data = NULL;
28847c478bd9Sstevel@tonic-gate 
28857c478bd9Sstevel@tonic-gate 	/* We want to refresh only one configuration at a time */
28867c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&ns_loadrefresh_lock);
28877c478bd9Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
28887c478bd9Sstevel@tonic-gate 
28897c478bd9Sstevel@tonic-gate 	/* (re)initialize configuration if necessary */
2890*e1dd0a2fSth 	if (!__s_api_isStandalone() &&
2891*e1dd0a2fSth 	    cache_server == FALSE && timetorefresh(cfg))
2892*e1dd0a2fSth 		cfg_g = __s_api_get_default_config_global();
2893*e1dd0a2fSth 	/* only (re)initialize the global configuration */
2894*e1dd0a2fSth 	if (cfg == cfg_g) {
2895*e1dd0a2fSth 		if (cfg_g != NULL)
2896*e1dd0a2fSth 			__s_api_release_config(cfg_g);
2897*e1dd0a2fSth 		new_cfg = LoadCacheConfiguration(cfg, &errorp);
2898*e1dd0a2fSth 		if (new_cfg != cfg)
2899*e1dd0a2fSth 			__s_api_release_config(cfg);
29007c478bd9Sstevel@tonic-gate 		if (new_cfg == NULL) {
29017c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
29027ddae043Siz 			    gettext("Unable to load configuration "
29037ddae043Siz 			    "'%s' ('%s')."),
29047ddae043Siz 			    NSCONFIGFILE,
29057ddae043Siz 			    errorp != NULL && errorp->message != NULL ?
29067ddae043Siz 			    errorp->message : "");
29077c478bd9Sstevel@tonic-gate 			MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
29087ddae043Siz 			    strdup(errstr), NULL);
29097c478bd9Sstevel@tonic-gate 			if (errorp != NULL)
29107c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_freeError(&errorp);
29117c478bd9Sstevel@tonic-gate 			(void) mutex_unlock(&ns_loadrefresh_lock);
29127c478bd9Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
29137c478bd9Sstevel@tonic-gate 		}
2914*e1dd0a2fSth 		if (new_cfg != cfg) {
2915*e1dd0a2fSth 			set_curr_config_global(new_cfg);
2916*e1dd0a2fSth 			cfg = new_cfg;
2917*e1dd0a2fSth 			reinit_connmgmt = B_TRUE;
2918*e1dd0a2fSth 		}
29197c478bd9Sstevel@tonic-gate 	}
29207c478bd9Sstevel@tonic-gate 	(void) mutex_unlock(&ns_loadrefresh_lock);
29217c478bd9Sstevel@tonic-gate 
2922*e1dd0a2fSth 	if (reinit_connmgmt == B_TRUE)
2923*e1dd0a2fSth 		__s_api_reinit_conn_mgmt_new_config(cfg);
2924*e1dd0a2fSth 
29257c478bd9Sstevel@tonic-gate 	if (cfg == NULL) {
29267c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
29277c478bd9Sstevel@tonic-gate 		    gettext("No configuration information available."));
29287c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_NOTLOADED,
29297ddae043Siz 		    strdup(errstr), NULL);
29307c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
29317c478bd9Sstevel@tonic-gate 	}
29327c478bd9Sstevel@tonic-gate 
29337c478bd9Sstevel@tonic-gate 	if (Param == NS_LDAP_DOMAIN_P) {
29347c478bd9Sstevel@tonic-gate 		*data = (void **)calloc(2, sizeof (void *));
29357c478bd9Sstevel@tonic-gate 		if (*data == NULL) {
29367c478bd9Sstevel@tonic-gate 			__s_api_release_config(cfg);
29377c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
29387c478bd9Sstevel@tonic-gate 		}
29397c478bd9Sstevel@tonic-gate 		(*data)[0] = (void *)strdup(cfg->domainName);
29407c478bd9Sstevel@tonic-gate 		if ((*data)[0] == NULL) {
29417c478bd9Sstevel@tonic-gate 			free(*data);
29427c478bd9Sstevel@tonic-gate 			__s_api_release_config(cfg);
29437c478bd9Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
29447c478bd9Sstevel@tonic-gate 		}
29457c478bd9Sstevel@tonic-gate 	} else if (cfg->paramList[Param].ns_ptype == NS_UNKNOWN) {
29467c478bd9Sstevel@tonic-gate 		/* get default */
29477c478bd9Sstevel@tonic-gate 		def = get_defconfig(cfg, Param);
29487c478bd9Sstevel@tonic-gate 		if (def != NULL)
29497c478bd9Sstevel@tonic-gate 			*data = dupParam(&def->defval);
29507c478bd9Sstevel@tonic-gate 	} else {
29517c478bd9Sstevel@tonic-gate 		*data = dupParam(&(cfg->paramList[Param]));
29527c478bd9Sstevel@tonic-gate 	}
29537c478bd9Sstevel@tonic-gate 	__s_api_release_config(cfg);
29547c478bd9Sstevel@tonic-gate 
29557c478bd9Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
29567c478bd9Sstevel@tonic-gate }
29577c478bd9Sstevel@tonic-gate 
29587c478bd9Sstevel@tonic-gate /*
29597c478bd9Sstevel@tonic-gate  * This routine takes a parameter in internal format and
29607c478bd9Sstevel@tonic-gate  * translates it into a variety of string formats for various
29617c478bd9Sstevel@tonic-gate  * outputs (doors/file/ldif).  This routine would be better
29627c478bd9Sstevel@tonic-gate  * named: __ns_ldap_translateParam2String
29637c478bd9Sstevel@tonic-gate  */
29647c478bd9Sstevel@tonic-gate 
29657c478bd9Sstevel@tonic-gate char *
29667c478bd9Sstevel@tonic-gate __s_api_strValue(ns_config_t *cfg, char *str,
29677c478bd9Sstevel@tonic-gate 			int bufsz, ParamIndexType index,
29687c478bd9Sstevel@tonic-gate 			ns_strfmt_t fmt)
29697c478bd9Sstevel@tonic-gate {
29707c478bd9Sstevel@tonic-gate 	ns_default_config *def = NULL;
29717c478bd9Sstevel@tonic-gate 	ns_param_t	*ptr;
29727c478bd9Sstevel@tonic-gate 	ns_hash_t	*hptr;
29737c478bd9Sstevel@tonic-gate 	ns_mapping_t	*mptr;
29747c478bd9Sstevel@tonic-gate 	char		ibuf[14], *buf;
29757c478bd9Sstevel@tonic-gate 	char		abuf[64], **cpp;
29767c478bd9Sstevel@tonic-gate 	int		alen, count, i, sz;
29777c478bd9Sstevel@tonic-gate 	int		seplen = strlen(COMMASEP) + strlen(DOORLINESEP);
29787c478bd9Sstevel@tonic-gate 	int		first;
29797c478bd9Sstevel@tonic-gate 
29807c478bd9Sstevel@tonic-gate 	if (cfg == NULL || str == NULL)
29817c478bd9Sstevel@tonic-gate 		return (NULL);
29827c478bd9Sstevel@tonic-gate 
29837c478bd9Sstevel@tonic-gate 	/* NS_LDAP_EXP and TRANSPORT_SEC are not exported externally */
29847c478bd9Sstevel@tonic-gate 	if (index == NS_LDAP_EXP_P || index == NS_LDAP_TRANSPORT_SEC_P)
29857c478bd9Sstevel@tonic-gate 		return (NULL);
29867c478bd9Sstevel@tonic-gate 
29877c478bd9Sstevel@tonic-gate 	/* Return nothing if the value is the default */
29887c478bd9Sstevel@tonic-gate 	if (cfg->paramList[index].ns_ptype == NS_UNKNOWN)
29897c478bd9Sstevel@tonic-gate 		return (NULL);
29907c478bd9Sstevel@tonic-gate 
29917c478bd9Sstevel@tonic-gate 	ptr = &(cfg->paramList[index]);
29927c478bd9Sstevel@tonic-gate 
29937c478bd9Sstevel@tonic-gate 	abuf[0] = '\0';
29947c478bd9Sstevel@tonic-gate 	alen = 0;
29957c478bd9Sstevel@tonic-gate 
29967c478bd9Sstevel@tonic-gate 	/* get default */
29977c478bd9Sstevel@tonic-gate 	def = get_defconfig(cfg, index);
29987c478bd9Sstevel@tonic-gate 	if (def == NULL)
29997c478bd9Sstevel@tonic-gate 		return (NULL);
30007c478bd9Sstevel@tonic-gate 
30017c478bd9Sstevel@tonic-gate 	switch (fmt) {
30027c478bd9Sstevel@tonic-gate 	case NS_DOOR_FMT:
30037c478bd9Sstevel@tonic-gate 		(void) strlcpy(abuf, def->name, sizeof (abuf));
30047c478bd9Sstevel@tonic-gate 		(void) strlcat(abuf, EQUALSEP, sizeof (abuf));
30057c478bd9Sstevel@tonic-gate 		break;
30067c478bd9Sstevel@tonic-gate 	case NS_FILE_FMT:
30077c478bd9Sstevel@tonic-gate 		(void) strlcpy(abuf, def->name, sizeof (abuf));
30087c478bd9Sstevel@tonic-gate 		(void) strlcat(abuf, EQUSPSEP, sizeof (abuf));
30097c478bd9Sstevel@tonic-gate 		break;
30107c478bd9Sstevel@tonic-gate 	case NS_LDIF_FMT:
30117c478bd9Sstevel@tonic-gate 		/* If no LDIF attr exists ignore the entry */
30127c478bd9Sstevel@tonic-gate 		if (def->profile_name == NULL)
30137c478bd9Sstevel@tonic-gate 			return (NULL);
30147c478bd9Sstevel@tonic-gate 		(void) strlcpy(abuf, def->profile_name, sizeof (abuf));
30157c478bd9Sstevel@tonic-gate 		(void) strlcat(abuf, COLSPSEP, sizeof (abuf));
30167c478bd9Sstevel@tonic-gate 		break;
30177c478bd9Sstevel@tonic-gate 	default:
30187c478bd9Sstevel@tonic-gate 		break;
30197c478bd9Sstevel@tonic-gate 	}
30207c478bd9Sstevel@tonic-gate 	alen = strlen(abuf);
30217c478bd9Sstevel@tonic-gate 	if (alen > bufsz)
30227c478bd9Sstevel@tonic-gate 		return (NULL);
30237c478bd9Sstevel@tonic-gate 
30247c478bd9Sstevel@tonic-gate 	buf = str;
30257c478bd9Sstevel@tonic-gate 	(void) strlcpy(buf, abuf, bufsz);
30267c478bd9Sstevel@tonic-gate 
30277c478bd9Sstevel@tonic-gate 	switch (ptr->ns_ptype) {
30287c478bd9Sstevel@tonic-gate 	case ARRAYAUTH:
30297c478bd9Sstevel@tonic-gate 		count = ptr->ns_acnt;
30307c478bd9Sstevel@tonic-gate 		sz = 0;
30317c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
30327c478bd9Sstevel@tonic-gate 			sz += strlen(__s_get_auth_name(cfg,
30337ddae043Siz 			    (AuthType_t)(ptr->ns_pi[i]))) + seplen;
30347c478bd9Sstevel@tonic-gate 		}
30357c478bd9Sstevel@tonic-gate 		sz = sz + alen + 1;
30367c478bd9Sstevel@tonic-gate 		if (sz <= bufsz) {
30377c478bd9Sstevel@tonic-gate 			buf = str;
30387c478bd9Sstevel@tonic-gate 		} else {
30397c478bd9Sstevel@tonic-gate 			buf = (char *)calloc(sz, sizeof (char));
30407c478bd9Sstevel@tonic-gate 			if (buf == NULL)
30417c478bd9Sstevel@tonic-gate 				return (NULL);
30427c478bd9Sstevel@tonic-gate 			(void) strcpy(buf, abuf);
30437c478bd9Sstevel@tonic-gate 		}
30447c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
30457c478bd9Sstevel@tonic-gate 			(void) strcat(buf,
30467ddae043Siz 			    __s_get_auth_name(cfg,
30477ddae043Siz 			    (AuthType_t)(ptr->ns_pi[i])));
30487c478bd9Sstevel@tonic-gate 			if (i != count-1) {
30497c478bd9Sstevel@tonic-gate 				if (cfg->version == NS_LDAP_V1)
30507c478bd9Sstevel@tonic-gate 					(void) strcat(buf, COMMASEP);
30517c478bd9Sstevel@tonic-gate 				else
30527c478bd9Sstevel@tonic-gate 					(void) strcat(buf, SEMISEP);
30537c478bd9Sstevel@tonic-gate 			}
30547c478bd9Sstevel@tonic-gate 		}
30557c478bd9Sstevel@tonic-gate 		break;
30567c478bd9Sstevel@tonic-gate 	case ARRAYCRED:
30577c478bd9Sstevel@tonic-gate 		count = ptr->ns_acnt;
30587c478bd9Sstevel@tonic-gate 		sz = 0;
30597c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
30607c478bd9Sstevel@tonic-gate 			sz += strlen(__s_get_credlvl_name(cfg,
30617ddae043Siz 			    (CredLevel_t)ptr->ns_pi[i])) + seplen;
30627c478bd9Sstevel@tonic-gate 		}
30637c478bd9Sstevel@tonic-gate 		sz = sz + alen + 1;
30647c478bd9Sstevel@tonic-gate 		if (sz <= bufsz) {
30657c478bd9Sstevel@tonic-gate 			buf = str;
30667c478bd9Sstevel@tonic-gate 		} else {
30677c478bd9Sstevel@tonic-gate 			buf = (char *)calloc(sz, sizeof (char));
30687c478bd9Sstevel@tonic-gate 			if (buf == NULL)
30697c478bd9Sstevel@tonic-gate 				return (NULL);
30707c478bd9Sstevel@tonic-gate 			(void) strcpy(buf, abuf);
30717c478bd9Sstevel@tonic-gate 		}
30727c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
30737c478bd9Sstevel@tonic-gate 			(void) strcat(buf,
30747ddae043Siz 			    __s_get_credlvl_name(cfg,
30757ddae043Siz 			    (CredLevel_t)ptr->ns_pi[i]));
30767c478bd9Sstevel@tonic-gate 			if (i != count-1) {
30777c478bd9Sstevel@tonic-gate 				(void) strcat(buf, SPACESEP);
30787c478bd9Sstevel@tonic-gate 			}
30797c478bd9Sstevel@tonic-gate 		}
30807c478bd9Sstevel@tonic-gate 		break;
30817c478bd9Sstevel@tonic-gate 	case SAMLIST:
30827c478bd9Sstevel@tonic-gate 	case SCLLIST:
30837c478bd9Sstevel@tonic-gate 	case SSDLIST:
30847c478bd9Sstevel@tonic-gate 		count = ptr->ns_acnt;
30857c478bd9Sstevel@tonic-gate 		sz = 0;
30867c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
30877c478bd9Sstevel@tonic-gate 			sz += strlen(ptr->ns_ppc[i]) + seplen;
30887c478bd9Sstevel@tonic-gate 		}
30897c478bd9Sstevel@tonic-gate 		sz = sz + alen + 1;
30907c478bd9Sstevel@tonic-gate 		/*
30917c478bd9Sstevel@tonic-gate 		 * We need to allocate buffer depending on the 'fmt' and
30927c478bd9Sstevel@tonic-gate 		 * on the number of ns_ptype's present(count) as we add
30937c478bd9Sstevel@tonic-gate 		 * name' or 'profile_name' and DOORLINESEP or new line
30947c478bd9Sstevel@tonic-gate 		 * char to the buffer - see below.
30957c478bd9Sstevel@tonic-gate 		 */
30967c478bd9Sstevel@tonic-gate 		switch (fmt) {
30977c478bd9Sstevel@tonic-gate 		case NS_LDIF_FMT:
30987c478bd9Sstevel@tonic-gate 			sz += count * (strlen(def->profile_name)
30997ddae043Siz 			    + strlen(COLSPSEP) + strlen("\n"));
31007c478bd9Sstevel@tonic-gate 			break;
31017c478bd9Sstevel@tonic-gate 		case NS_FILE_FMT:
31027c478bd9Sstevel@tonic-gate 			sz += count * (strlen(def->name)
31037ddae043Siz 			    + strlen(EQUALSEP) + strlen("\n"));
31047c478bd9Sstevel@tonic-gate 			break;
31057c478bd9Sstevel@tonic-gate 		case NS_DOOR_FMT:
31067c478bd9Sstevel@tonic-gate 			sz += count * (strlen(def->name)
31077ddae043Siz 			    + strlen(EQUALSEP) + strlen(DOORLINESEP));
31087c478bd9Sstevel@tonic-gate 			break;
31097c478bd9Sstevel@tonic-gate 		}
31107c478bd9Sstevel@tonic-gate 		if (sz <= bufsz) {
31117c478bd9Sstevel@tonic-gate 			buf = str;
31127c478bd9Sstevel@tonic-gate 		} else {
31137c478bd9Sstevel@tonic-gate 			buf = (char *)calloc(sz, sizeof (char));
31147c478bd9Sstevel@tonic-gate 			if (buf == NULL)
31157c478bd9Sstevel@tonic-gate 				return (NULL);
31167c478bd9Sstevel@tonic-gate 			(void) strcpy(buf, abuf);
31177c478bd9Sstevel@tonic-gate 		}
31187c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
31197c478bd9Sstevel@tonic-gate 			(void) strcat(buf, ptr->ns_ppc[i]);
31207c478bd9Sstevel@tonic-gate 			if (i != count-1) {
31217c478bd9Sstevel@tonic-gate 				/* Separate items */
31227c478bd9Sstevel@tonic-gate 				switch (fmt) {
31237c478bd9Sstevel@tonic-gate 				case NS_DOOR_FMT:
31247c478bd9Sstevel@tonic-gate 					(void) strcat(buf, DOORLINESEP);
31257c478bd9Sstevel@tonic-gate 					(void) strcat(buf, def->name);
31267c478bd9Sstevel@tonic-gate 					(void) strcat(buf, EQUALSEP);
31277c478bd9Sstevel@tonic-gate 					break;
31287c478bd9Sstevel@tonic-gate 				case NS_FILE_FMT:
31297c478bd9Sstevel@tonic-gate 					(void) strcat(buf, "\n");
31307c478bd9Sstevel@tonic-gate 					(void) strcat(buf, def->name);
31317c478bd9Sstevel@tonic-gate 					(void) strcat(buf, EQUSPSEP);
31327c478bd9Sstevel@tonic-gate 					break;
31337c478bd9Sstevel@tonic-gate 				case NS_LDIF_FMT:
31347c478bd9Sstevel@tonic-gate 					(void) strcat(buf, "\n");
31357c478bd9Sstevel@tonic-gate 					(void) strcat(buf, def->profile_name);
31367c478bd9Sstevel@tonic-gate 					(void) strcat(buf, COLSPSEP);
31377c478bd9Sstevel@tonic-gate 					break;
31387c478bd9Sstevel@tonic-gate 				}
31397c478bd9Sstevel@tonic-gate 			}
31407c478bd9Sstevel@tonic-gate 		}
31417c478bd9Sstevel@tonic-gate 		break;
31427c478bd9Sstevel@tonic-gate 	case ARRAYCP:
31437c478bd9Sstevel@tonic-gate 		count = ptr->ns_acnt;
31447c478bd9Sstevel@tonic-gate 		sz = 0;
31457c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
31467c478bd9Sstevel@tonic-gate 			sz += strlen(ptr->ns_ppc[i]) + seplen;
31477c478bd9Sstevel@tonic-gate 		}
31487c478bd9Sstevel@tonic-gate 		sz = sz + alen + 1;
31497c478bd9Sstevel@tonic-gate 		if (sz <= bufsz) {
31507c478bd9Sstevel@tonic-gate 			buf = str;
31517c478bd9Sstevel@tonic-gate 		} else {
31527c478bd9Sstevel@tonic-gate 			buf = (char *)calloc(sz, sizeof (char));
31537c478bd9Sstevel@tonic-gate 			if (buf == NULL)
31547c478bd9Sstevel@tonic-gate 				return (NULL);
31557c478bd9Sstevel@tonic-gate 			(void) strcpy(buf, abuf);
31567c478bd9Sstevel@tonic-gate 		}
31577c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
31587c478bd9Sstevel@tonic-gate 			(void) strcat(buf, ptr->ns_ppc[i]);
31597c478bd9Sstevel@tonic-gate 			if (i != count-1) {
31607c478bd9Sstevel@tonic-gate 				(void) strcat(buf, COMMASEP);
31617c478bd9Sstevel@tonic-gate 			}
31627c478bd9Sstevel@tonic-gate 		}
31637c478bd9Sstevel@tonic-gate 		break;
31647c478bd9Sstevel@tonic-gate 	case SERVLIST:
31657c478bd9Sstevel@tonic-gate 		count = ptr->ns_acnt;
31667c478bd9Sstevel@tonic-gate 		sz = 0;
31677c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
31687c478bd9Sstevel@tonic-gate 			sz += strlen(ptr->ns_ppc[i]) + seplen;
31697c478bd9Sstevel@tonic-gate 		}
31707c478bd9Sstevel@tonic-gate 		sz = sz + alen + 1;
31717c478bd9Sstevel@tonic-gate 		if (sz <= bufsz) {
31727c478bd9Sstevel@tonic-gate 			buf = str;
31737c478bd9Sstevel@tonic-gate 		} else {
31747c478bd9Sstevel@tonic-gate 			buf = (char *)calloc(sz, sizeof (char));
31757c478bd9Sstevel@tonic-gate 			if (buf == NULL)
31767c478bd9Sstevel@tonic-gate 				return (NULL);
31777c478bd9Sstevel@tonic-gate 			(void) strcpy(buf, abuf);
31787c478bd9Sstevel@tonic-gate 		}
31797c478bd9Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
31807c478bd9Sstevel@tonic-gate 			(void) strcat(buf, ptr->ns_ppc[i]);
31817c478bd9Sstevel@tonic-gate 			if (i != count-1) {
31827c478bd9Sstevel@tonic-gate 				if (fmt == NS_LDIF_FMT)
31837c478bd9Sstevel@tonic-gate 					(void) strcat(buf, SPACESEP);
31847c478bd9Sstevel@tonic-gate 				else
31857c478bd9Sstevel@tonic-gate 					(void) strcat(buf, COMMASEP);
31867c478bd9Sstevel@tonic-gate 			}
31877c478bd9Sstevel@tonic-gate 		}
31887c478bd9Sstevel@tonic-gate 		break;
31897c478bd9Sstevel@tonic-gate 	case CHARPTR:
31907c478bd9Sstevel@tonic-gate 		if (ptr->ns_pc == NULL)
31917c478bd9Sstevel@tonic-gate 			break;
31927c478bd9Sstevel@tonic-gate 		sz = strlen(ptr->ns_pc) + alen + 1;
31937c478bd9Sstevel@tonic-gate 		if (sz > bufsz) {
31947c478bd9Sstevel@tonic-gate 			buf = (char *)calloc(sz, sizeof (char));
31957c478bd9Sstevel@tonic-gate 			if (buf == NULL)
31967c478bd9Sstevel@tonic-gate 				return (NULL);
31977c478bd9Sstevel@tonic-gate 			(void) strcpy(buf, abuf);
31987c478bd9Sstevel@tonic-gate 		}
31997c478bd9Sstevel@tonic-gate 		(void) strcat(buf, ptr->ns_pc);
32007c478bd9Sstevel@tonic-gate 		break;
32017c478bd9Sstevel@tonic-gate 	case INT:
32027c478bd9Sstevel@tonic-gate 		switch (def->index) {
32037c478bd9Sstevel@tonic-gate 		case NS_LDAP_PREF_ONLY_P:
32047c478bd9Sstevel@tonic-gate 			(void) strcat(buf,
32057ddae043Siz 			    __s_get_pref_name((PrefOnly_t)ptr->ns_i));
32067c478bd9Sstevel@tonic-gate 			break;
32077c478bd9Sstevel@tonic-gate 		case NS_LDAP_SEARCH_REF_P:
32087c478bd9Sstevel@tonic-gate 			(void) strcat(buf,
32097ddae043Siz 			    __s_get_searchref_name(cfg,
32107ddae043Siz 			    (SearchRef_t)ptr->ns_i));
32117c478bd9Sstevel@tonic-gate 			break;
32127c478bd9Sstevel@tonic-gate 		case NS_LDAP_SEARCH_SCOPE_P:
32137c478bd9Sstevel@tonic-gate 			(void) strcat(buf,
32147ddae043Siz 			    __s_get_scope_name(cfg,
32157ddae043Siz 			    (ScopeType_t)ptr->ns_i));
32167c478bd9Sstevel@tonic-gate 			break;
32177c478bd9Sstevel@tonic-gate 		default:
32187c478bd9Sstevel@tonic-gate 			(void) snprintf(ibuf, sizeof (ibuf),
32197ddae043Siz 			    "%d", ptr->ns_i);
32207c478bd9Sstevel@tonic-gate 			(void) strcat(buf, ibuf);
32217c478bd9Sstevel@tonic-gate 			break;
32227c478bd9Sstevel@tonic-gate 		}
32237c478bd9Sstevel@tonic-gate 		break;
32247c478bd9Sstevel@tonic-gate 	case ATTRMAP:
32257c478bd9Sstevel@tonic-gate 		buf[0] = '\0';
32267c478bd9Sstevel@tonic-gate 		first = 1;
32277c478bd9Sstevel@tonic-gate 		for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
32287c478bd9Sstevel@tonic-gate 			if (hptr->h_type != NS_HASH_AMAP) {
32297c478bd9Sstevel@tonic-gate 				continue;
32307c478bd9Sstevel@tonic-gate 			}
32317c478bd9Sstevel@tonic-gate 			if (!first) {
32327c478bd9Sstevel@tonic-gate 				if (fmt == NS_DOOR_FMT)
32337c478bd9Sstevel@tonic-gate 					(void) strcat(buf, DOORLINESEP);
32347c478bd9Sstevel@tonic-gate 				else
32357c478bd9Sstevel@tonic-gate 					(void) strcat(buf, "\n");
32367c478bd9Sstevel@tonic-gate 			}
32377c478bd9Sstevel@tonic-gate 			mptr = hptr->h_map;
32387c478bd9Sstevel@tonic-gate 			(void) strcat(buf, abuf);
32397c478bd9Sstevel@tonic-gate 			(void) strcat(buf, mptr->service);
32407c478bd9Sstevel@tonic-gate 			(void) strcat(buf, COLONSEP);
32417c478bd9Sstevel@tonic-gate 			(void) strcat(buf, mptr->orig);
32427c478bd9Sstevel@tonic-gate 			(void) strcat(buf, EQUALSEP);
32437c478bd9Sstevel@tonic-gate 			for (cpp = mptr->map; cpp && *cpp; cpp++) {
32447c478bd9Sstevel@tonic-gate 				if (cpp != mptr->map)
32457c478bd9Sstevel@tonic-gate 					(void) strcat(buf, SPACESEP);
32467c478bd9Sstevel@tonic-gate 				(void) strcat(buf, *cpp);
32477c478bd9Sstevel@tonic-gate 			}
32487c478bd9Sstevel@tonic-gate 			first = 0;
32497c478bd9Sstevel@tonic-gate 		}
32507c478bd9Sstevel@tonic-gate 		break;
32517c478bd9Sstevel@tonic-gate 	case OBJMAP:
32527c478bd9Sstevel@tonic-gate 		buf[0] = '\0';
32537c478bd9Sstevel@tonic-gate 		first = 1;
32547c478bd9Sstevel@tonic-gate 		for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
32557c478bd9Sstevel@tonic-gate 			if (hptr->h_type != NS_HASH_OMAP) {
32567c478bd9Sstevel@tonic-gate 				continue;
32577c478bd9Sstevel@tonic-gate 			}
32587c478bd9Sstevel@tonic-gate 			if (!first) {
32597c478bd9Sstevel@tonic-gate 				if (fmt == NS_DOOR_FMT)
32607c478bd9Sstevel@tonic-gate 					(void) strcat(buf, DOORLINESEP);
32617c478bd9Sstevel@tonic-gate 				else
32627c478bd9Sstevel@tonic-gate 					(void) strcat(buf, "\n");
32637c478bd9Sstevel@tonic-gate 			}
32647c478bd9Sstevel@tonic-gate 			mptr = hptr->h_map;
32657c478bd9Sstevel@tonic-gate 			(void) strcat(buf, abuf);
32667c478bd9Sstevel@tonic-gate 			(void) strcat(buf, mptr->service);
32677c478bd9Sstevel@tonic-gate 			(void) strcat(buf, COLONSEP);
32687c478bd9Sstevel@tonic-gate 			(void) strcat(buf, mptr->orig);
32697c478bd9Sstevel@tonic-gate 			(void) strcat(buf, EQUALSEP);
32707c478bd9Sstevel@tonic-gate 			for (cpp = mptr->map; cpp && *cpp; cpp++) {
32717c478bd9Sstevel@tonic-gate 				if (cpp != mptr->map)
32727c478bd9Sstevel@tonic-gate 					(void) strcat(buf, SPACESEP);
32737c478bd9Sstevel@tonic-gate 				(void) strcat(buf, *cpp);
32747c478bd9Sstevel@tonic-gate 			}
32757c478bd9Sstevel@tonic-gate 			first = 0;
32767c478bd9Sstevel@tonic-gate 		}
32777c478bd9Sstevel@tonic-gate 		break;
32787c478bd9Sstevel@tonic-gate 	}
32797c478bd9Sstevel@tonic-gate 	return (buf);
32807c478bd9Sstevel@tonic-gate }
32817c478bd9Sstevel@tonic-gate 
32827c478bd9Sstevel@tonic-gate static int
32837c478bd9Sstevel@tonic-gate __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error)
32847c478bd9Sstevel@tonic-gate {
32857c478bd9Sstevel@tonic-gate 	typedef union {
32867c478bd9Sstevel@tonic-gate 		ldap_data_t	s_d;
32877c478bd9Sstevel@tonic-gate 		char		s_b[DOORBUFFERSIZE];
32887c478bd9Sstevel@tonic-gate 	} space_t;
32897ddae043Siz 	space_t			*space;
32907c478bd9Sstevel@tonic-gate 
32917ddae043Siz 	ldap_data_t		*sptr;
32927ddae043Siz 	int			ndata;
32937ddae043Siz 	int			adata;
32947ddae043Siz 	char			errstr[MAXERROR];
32957ddae043Siz 	char			*domainname;
32967ddae043Siz 	ns_ldap_return_code	retCode;
3297*e1dd0a2fSth 	ldap_config_out_t	*cfghdr;
32987ddae043Siz 
32997ddae043Siz 	*error = NULL;
33007c478bd9Sstevel@tonic-gate 
33017c478bd9Sstevel@tonic-gate 	domainname = __getdomainname();
33027c478bd9Sstevel@tonic-gate 	if (domainname == NULL || buffer == NULL || buflen == NULL ||
33037c478bd9Sstevel@tonic-gate 	    (strlen(domainname) >= (sizeof (space_t)
33047ddae043Siz 	    - sizeof (space->s_d.ldap_call.ldap_callnumber)))) {
33057c478bd9Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
33067c478bd9Sstevel@tonic-gate 	}
33077c478bd9Sstevel@tonic-gate 
33087c478bd9Sstevel@tonic-gate 	space = (space_t *)calloc(1, sizeof (space_t));
33097c478bd9Sstevel@tonic-gate 	if (space == NULL)
33107ddae043Siz 		return (NS_LDAP_MEMORY);
33117c478bd9Sstevel@tonic-gate 
33127c478bd9Sstevel@tonic-gate 	adata = (sizeof (ldap_call_t) + strlen(domainname) +1);
33137c478bd9Sstevel@tonic-gate 	ndata = sizeof (space_t);
33147c478bd9Sstevel@tonic-gate 	space->s_d.ldap_call.ldap_callnumber = GETLDAPCONFIGV1;
33157c478bd9Sstevel@tonic-gate 	(void) strcpy(space->s_d.ldap_call.ldap_u.domainname, domainname);
33167c478bd9Sstevel@tonic-gate 	free(domainname);
33177c478bd9Sstevel@tonic-gate 	domainname = NULL;
33187c478bd9Sstevel@tonic-gate 	sptr = &space->s_d;
33197c478bd9Sstevel@tonic-gate 
33207c478bd9Sstevel@tonic-gate 	switch (__ns_ldap_trydoorcall(&sptr, &ndata, &adata)) {
3321*e1dd0a2fSth 	case NS_CACHE_SUCCESS:
33227c478bd9Sstevel@tonic-gate 		break;
3323*e1dd0a2fSth 	case NS_CACHE_NOTFOUND:
33247c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
33257ddae043Siz 		    gettext("Door call to "
33267ddae043Siz 		    "ldap_cachemgr failed - error: %d."),
33277ddae043Siz 		    space->s_d.ldap_ret.ldap_errno);
33287c478bd9Sstevel@tonic-gate 		MKERROR(LOG_WARNING, *error, NS_CONFIG_CACHEMGR,
33297ddae043Siz 		    strdup(errstr), NULL);
33307c478bd9Sstevel@tonic-gate 		free(space);
33317c478bd9Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
33327c478bd9Sstevel@tonic-gate 	default:
33337c478bd9Sstevel@tonic-gate 		free(space);
33347c478bd9Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
33357c478bd9Sstevel@tonic-gate 	}
33367c478bd9Sstevel@tonic-gate 
33377ddae043Siz 	retCode = NS_LDAP_SUCCESS;
33387ddae043Siz 
33397c478bd9Sstevel@tonic-gate 	/* copy info from door call to buffer here */
3340*e1dd0a2fSth 	cfghdr = &sptr->ldap_ret.ldap_u.config_str;
3341*e1dd0a2fSth 	*buflen = offsetof(ldap_config_out_t, config_str) +
3342*e1dd0a2fSth 	    cfghdr->data_size + 1;
33437c478bd9Sstevel@tonic-gate 	*buffer = calloc(*buflen, sizeof (char));
33447c478bd9Sstevel@tonic-gate 	if (*buffer == NULL) {
33457ddae043Siz 		retCode = NS_LDAP_MEMORY;
3346*e1dd0a2fSth 	} else
3347*e1dd0a2fSth 		(void) memcpy(*buffer, cfghdr, *buflen - 1);
33487c478bd9Sstevel@tonic-gate 
33497c478bd9Sstevel@tonic-gate 	if (sptr != &space->s_d) {
33507c478bd9Sstevel@tonic-gate 		(void) munmap((char *)sptr, ndata);
33517c478bd9Sstevel@tonic-gate 	}
33527ddae043Siz 	free(space);
33537c478bd9Sstevel@tonic-gate 
33547ddae043Siz 	return (retCode);
33557c478bd9Sstevel@tonic-gate }
33567c478bd9Sstevel@tonic-gate 
33577c478bd9Sstevel@tonic-gate /*
33587c478bd9Sstevel@tonic-gate  * SetDoorInfo parses ldapcachemgr configuration information
33597c478bd9Sstevel@tonic-gate  * and verifies that the profile is version 1 or version 2 based.
33607c478bd9Sstevel@tonic-gate  * version 2 profiles must have a version number as the first profile
33617c478bd9Sstevel@tonic-gate  * attribute in the configuration.
33627c478bd9Sstevel@tonic-gate  */
33637c478bd9Sstevel@tonic-gate static ns_config_t *
33647c478bd9Sstevel@tonic-gate SetDoorInfo(char *buffer, ns_ldap_error_t **errorp)
33657c478bd9Sstevel@tonic-gate {
33667c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
33677c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR], errbuf[MAXERROR];
33687c478bd9Sstevel@tonic-gate 	char		*name, *value, valbuf[BUFSIZE];
33697c478bd9Sstevel@tonic-gate 	char		*strptr;
33707c478bd9Sstevel@tonic-gate 	char		*rest;
33717c478bd9Sstevel@tonic-gate 	char		*bufptr = buffer;
33727c478bd9Sstevel@tonic-gate 	ParamIndexType	i;
33737c478bd9Sstevel@tonic-gate 	int		ret;
33747c478bd9Sstevel@tonic-gate 	int		first = 1;
33757c478bd9Sstevel@tonic-gate 	int		errfnd = 0;
3376*e1dd0a2fSth 	ldap_config_out_t *cfghdr;
33777c478bd9Sstevel@tonic-gate 
33787c478bd9Sstevel@tonic-gate 	if (errorp == NULL)
33797c478bd9Sstevel@tonic-gate 		return (NULL);
33807c478bd9Sstevel@tonic-gate 	*errorp = NULL;
33817c478bd9Sstevel@tonic-gate 
33827c478bd9Sstevel@tonic-gate 	ptr = __s_api_create_config();
33837c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
33847c478bd9Sstevel@tonic-gate 		return (NULL);
33857c478bd9Sstevel@tonic-gate 	}
33867c478bd9Sstevel@tonic-gate 
3387*e1dd0a2fSth 	/* get config cookie from the header */
3388*e1dd0a2fSth 	cfghdr = (ldap_config_out_t *)bufptr;
3389*e1dd0a2fSth 	ptr->config_cookie = cfghdr->cookie;
3390*e1dd0a2fSth 	bufptr = (char *)cfghdr->config_str;
3391*e1dd0a2fSth 
33927c478bd9Sstevel@tonic-gate 	strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
33937c478bd9Sstevel@tonic-gate 	for (; ; ) {
33947c478bd9Sstevel@tonic-gate 		if (strptr == NULL)
33957c478bd9Sstevel@tonic-gate 			break;
33967c478bd9Sstevel@tonic-gate 		(void) strlcpy(valbuf, strptr, sizeof (valbuf));
33977c478bd9Sstevel@tonic-gate 		__s_api_split_key_value(valbuf, &name, &value);
33987c478bd9Sstevel@tonic-gate 		/* Use get_versiontype and check for V1 vs V2 prototypes */
33997c478bd9Sstevel@tonic-gate 		if (__s_api_get_versiontype(ptr, name, &i) < 0) {
34007c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
34017ddae043Siz 			    "%s (%s)\n",
34027ddae043Siz 			    gettext("Illegal profile entry "
34037ddae043Siz 			    "line in configuration."),
34047ddae043Siz 			    name);
34057c478bd9Sstevel@tonic-gate 			errfnd++;
34067c478bd9Sstevel@tonic-gate 		/* Write verify routines and get rid of verify_value here */
34077c478bd9Sstevel@tonic-gate 		} else if (verify_value(ptr, name,
34087ddae043Siz 		    value, errbuf) != NS_SUCCESS) {
34097c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
34107ddae043Siz 			    gettext("%s\n"), errbuf);
34117c478bd9Sstevel@tonic-gate 			errfnd++;
34127c478bd9Sstevel@tonic-gate 		} else if (!first && i == NS_LDAP_FILE_VERSION_P) {
34137c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
34147ddae043Siz 			    gettext("Illegal NS_LDAP_FILE_VERSION "
34157ddae043Siz 			    "line in configuration.\n"));
34167c478bd9Sstevel@tonic-gate 			errfnd++;
34177c478bd9Sstevel@tonic-gate 		}
34187c478bd9Sstevel@tonic-gate 		if (errfnd) {
34197c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
34207ddae043Siz 			    strdup(errstr), NULL);
34217c478bd9Sstevel@tonic-gate 		} else {
34227c478bd9Sstevel@tonic-gate 			ret = set_default_value(ptr, name, value, errorp);
34237c478bd9Sstevel@tonic-gate 		}
34247c478bd9Sstevel@tonic-gate 		if (errfnd || ret != NS_SUCCESS) {
34257c478bd9Sstevel@tonic-gate 			__s_api_destroy_config(ptr);
34267c478bd9Sstevel@tonic-gate 			return (NULL);
34277c478bd9Sstevel@tonic-gate 		}
34287c478bd9Sstevel@tonic-gate 		first = 0;
34297c478bd9Sstevel@tonic-gate 
34307c478bd9Sstevel@tonic-gate 		strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
34317c478bd9Sstevel@tonic-gate 	}
34327c478bd9Sstevel@tonic-gate 
34337c478bd9Sstevel@tonic-gate 	if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
34347c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(ptr);
34357c478bd9Sstevel@tonic-gate 		MKERROR(LOG_WARNING, *errorp, NS_CONFIG_SYNTAX, strdup(errstr),
34367ddae043Siz 		    NULL);
34377c478bd9Sstevel@tonic-gate 		return (NULL);
34387c478bd9Sstevel@tonic-gate 	}
34397c478bd9Sstevel@tonic-gate 
34407c478bd9Sstevel@tonic-gate 	return (ptr);
34417c478bd9Sstevel@tonic-gate }
34427c478bd9Sstevel@tonic-gate 
34437c478bd9Sstevel@tonic-gate static ns_config_t *
3444*e1dd0a2fSth LoadCacheConfiguration(ns_config_t *oldcfg, ns_ldap_error_t **error)
34457c478bd9Sstevel@tonic-gate {
34467c478bd9Sstevel@tonic-gate 	char		*buffer = NULL;
34477c478bd9Sstevel@tonic-gate 	int		buflen = 0;
34487c478bd9Sstevel@tonic-gate 	int		ret;
34497c478bd9Sstevel@tonic-gate 	ns_config_t	*cfg;
3450*e1dd0a2fSth 	ldap_config_out_t *cfghdr;
3451*e1dd0a2fSth 	ldap_get_chg_cookie_t old_cookie;
3452*e1dd0a2fSth 	ldap_get_chg_cookie_t new_cookie;
34537c478bd9Sstevel@tonic-gate 
34547c478bd9Sstevel@tonic-gate 	*error = NULL;
34557c478bd9Sstevel@tonic-gate 	ret = __door_getldapconfig(&buffer, &buflen, error);
34567c478bd9Sstevel@tonic-gate 
34577c478bd9Sstevel@tonic-gate 	if (ret != NS_LDAP_SUCCESS) {
34587c478bd9Sstevel@tonic-gate 		if (*error != NULL && (*error)->message != NULL)
34597c478bd9Sstevel@tonic-gate 			syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
34607c478bd9Sstevel@tonic-gate 		return (NULL);
34617c478bd9Sstevel@tonic-gate 	}
34627c478bd9Sstevel@tonic-gate 
3463*e1dd0a2fSth 	/* No need to reload configuration if config cookie is the same */
3464*e1dd0a2fSth 	cfghdr = (ldap_config_out_t *)buffer;
3465*e1dd0a2fSth 	new_cookie = cfghdr->cookie;
3466*e1dd0a2fSth 	if (oldcfg != NULL)
3467*e1dd0a2fSth 		old_cookie = oldcfg->config_cookie;
3468*e1dd0a2fSth 
3469*e1dd0a2fSth 	if (oldcfg != NULL && old_cookie.mgr_pid == new_cookie.mgr_pid &&
3470*e1dd0a2fSth 	    old_cookie.seq_num == new_cookie.seq_num) {
3471*e1dd0a2fSth 		free(buffer);
3472*e1dd0a2fSth 		return (oldcfg);
3473*e1dd0a2fSth 	}
3474*e1dd0a2fSth 
34757c478bd9Sstevel@tonic-gate 	/* now convert from door format */
34767c478bd9Sstevel@tonic-gate 	cfg = SetDoorInfo(buffer, error);
34777c478bd9Sstevel@tonic-gate 	free(buffer);
34787c478bd9Sstevel@tonic-gate 
34797c478bd9Sstevel@tonic-gate 	if (cfg == NULL && *error != NULL && (*error)->message != NULL)
34807c478bd9Sstevel@tonic-gate 		syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
34817c478bd9Sstevel@tonic-gate 	return (cfg);
34827c478bd9Sstevel@tonic-gate }
34837c478bd9Sstevel@tonic-gate 
34847c478bd9Sstevel@tonic-gate /*
34857c478bd9Sstevel@tonic-gate  * converts the time string into seconds.  The time string can be specified
34867c478bd9Sstevel@tonic-gate  * using one of the following time units:
34877c478bd9Sstevel@tonic-gate  * 	#s (# of seconds)
34887c478bd9Sstevel@tonic-gate  *	#m (# of minutes)
34897c478bd9Sstevel@tonic-gate  *	#h (# of hours)
34907c478bd9Sstevel@tonic-gate  *	#d (# of days)
34917c478bd9Sstevel@tonic-gate  *	#w (# of weeks)
34927c478bd9Sstevel@tonic-gate  * NOTE: you can only specify one the above.  No combination of the above
34937c478bd9Sstevel@tonic-gate  * units is allowed.  If no unit specified, it will default to "seconds".
34947c478bd9Sstevel@tonic-gate  */
34957c478bd9Sstevel@tonic-gate static time_t
34967c478bd9Sstevel@tonic-gate conv_time(char *s)
34977c478bd9Sstevel@tonic-gate {
34987c478bd9Sstevel@tonic-gate 	time_t t;
34997c478bd9Sstevel@tonic-gate 	char c;
35007c478bd9Sstevel@tonic-gate 	int l, m;
35017c478bd9Sstevel@tonic-gate 	long tot;
35027c478bd9Sstevel@tonic-gate 
35037c478bd9Sstevel@tonic-gate 	l = strlen(s);
35047c478bd9Sstevel@tonic-gate 	if (l == 0)
35057c478bd9Sstevel@tonic-gate 		return (0);
35067c478bd9Sstevel@tonic-gate 	c = s[--l];
35077c478bd9Sstevel@tonic-gate 	m = 0;
35087c478bd9Sstevel@tonic-gate 	switch (c) {
35097c478bd9Sstevel@tonic-gate 	case 'w': /* weeks */
35107c478bd9Sstevel@tonic-gate 		m = 604800;
35117c478bd9Sstevel@tonic-gate 		break;
35127c478bd9Sstevel@tonic-gate 	case 'd': /* days */
35137c478bd9Sstevel@tonic-gate 		m = 86400;
35147c478bd9Sstevel@tonic-gate 		break;
35157c478bd9Sstevel@tonic-gate 	case 'h': /* hours */
35167c478bd9Sstevel@tonic-gate 		m = 3600;
35177c478bd9Sstevel@tonic-gate 		break;
35187c478bd9Sstevel@tonic-gate 	case 'm': /* minutes */
35197c478bd9Sstevel@tonic-gate 		m = 60;
35207c478bd9Sstevel@tonic-gate 		break;
35217c478bd9Sstevel@tonic-gate 	case 's': /* seconds */
35227c478bd9Sstevel@tonic-gate 		m = 1;
35237c478bd9Sstevel@tonic-gate 		break;
35247c478bd9Sstevel@tonic-gate 	/* the default case is set to "second" */
35257c478bd9Sstevel@tonic-gate 	}
35267c478bd9Sstevel@tonic-gate 	if (m != 0)
35277c478bd9Sstevel@tonic-gate 		s[l] = '\0';
35287c478bd9Sstevel@tonic-gate 	else
35297c478bd9Sstevel@tonic-gate 		m = 1;
35307c478bd9Sstevel@tonic-gate 	errno = 0;
35317c478bd9Sstevel@tonic-gate 	tot = atol(s);
35327c478bd9Sstevel@tonic-gate 	if ((0 == tot) && (EINVAL == errno))
35337c478bd9Sstevel@tonic-gate 		return (0);
35347c478bd9Sstevel@tonic-gate 	if (((LONG_MAX == tot) || (LONG_MIN == tot)) && (EINVAL == errno))
35357c478bd9Sstevel@tonic-gate 		return (0);
35367c478bd9Sstevel@tonic-gate 
35377c478bd9Sstevel@tonic-gate 	tot = tot * m;
35387c478bd9Sstevel@tonic-gate 	t = (time_t)tot;
35397c478bd9Sstevel@tonic-gate 	return (t);
35407c478bd9Sstevel@tonic-gate }
35417c478bd9Sstevel@tonic-gate 
35427c478bd9Sstevel@tonic-gate 
35437c478bd9Sstevel@tonic-gate ns_auth_t *
35447c478bd9Sstevel@tonic-gate __s_api_AuthEnumtoStruct(const EnumAuthType_t i)
35457c478bd9Sstevel@tonic-gate {
35467c478bd9Sstevel@tonic-gate 	ns_auth_t *ap;
35477c478bd9Sstevel@tonic-gate 
35487c478bd9Sstevel@tonic-gate 	ap = (ns_auth_t *)calloc(1, sizeof (ns_auth_t));
35497c478bd9Sstevel@tonic-gate 	if (ap == NULL)
35507c478bd9Sstevel@tonic-gate 		return (NULL);
35517c478bd9Sstevel@tonic-gate 	switch (i) {
35527c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_NONE:
35537c478bd9Sstevel@tonic-gate 			break;
35547c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_SIMPLE:
35557c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SIMPLE;
35567c478bd9Sstevel@tonic-gate 			break;
35577c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_CRAM_MD5:
35587c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
35597c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
35607c478bd9Sstevel@tonic-gate 			break;
35617c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_DIGEST_MD5:
35627c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
35637c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
35647c478bd9Sstevel@tonic-gate 			break;
35657c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
35667c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
35677c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
35687c478bd9Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_INT;
35697c478bd9Sstevel@tonic-gate 			break;
35707c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
35717c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
35727c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
35737c478bd9Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_PRIV;
35747c478bd9Sstevel@tonic-gate 			break;
35757c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_EXTERNAL:
35767c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
35777c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_EXTERNAL;
35787c478bd9Sstevel@tonic-gate 			break;
3579cb5caa98Sdjl 		case NS_LDAP_EA_SASL_GSSAPI:
3580cb5caa98Sdjl 			ap->type = NS_LDAP_AUTH_SASL;
3581cb5caa98Sdjl 			ap->saslmech = NS_LDAP_SASL_GSSAPI;
3582cb5caa98Sdjl 			ap->saslopt = NS_LDAP_SASLOPT_INT |
35837ddae043Siz 			    NS_LDAP_SASLOPT_PRIV;
3584cb5caa98Sdjl 			break;
35857c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_NONE:
35867c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
35877c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_NONE;
35887c478bd9Sstevel@tonic-gate 			break;
35897c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SIMPLE:
35907c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
35917c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SIMPLE;
35927c478bd9Sstevel@tonic-gate 			break;
35937c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
35947c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
35957c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
35967c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
35977c478bd9Sstevel@tonic-gate 			break;
35987c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
35997c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36007c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36017c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36027c478bd9Sstevel@tonic-gate 			break;
36037c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
36047c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36057c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36067c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36077c478bd9Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_INT;
36087c478bd9Sstevel@tonic-gate 			break;
36097c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
36107c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36117c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36127c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36137c478bd9Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_PRIV;
36147c478bd9Sstevel@tonic-gate 			break;
36157c478bd9Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_EXTERNAL:
36167c478bd9Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36177c478bd9Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36187c478bd9Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_EXTERNAL;
36197c478bd9Sstevel@tonic-gate 			break;
36207c478bd9Sstevel@tonic-gate 		default:
36217c478bd9Sstevel@tonic-gate 			/* should never get here */
36227c478bd9Sstevel@tonic-gate 			free(ap);
36237c478bd9Sstevel@tonic-gate 			return (NULL);
36247c478bd9Sstevel@tonic-gate 	}
36257c478bd9Sstevel@tonic-gate 	return (ap);
36267c478bd9Sstevel@tonic-gate }
36277c478bd9Sstevel@tonic-gate 
36287c478bd9Sstevel@tonic-gate 
36297c478bd9Sstevel@tonic-gate /*
36307c478bd9Sstevel@tonic-gate  * Parameter Index Type validation routines
36317c478bd9Sstevel@tonic-gate  */
36327c478bd9Sstevel@tonic-gate 
36337c478bd9Sstevel@tonic-gate /* Validate a positive integer */
36347c478bd9Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
36357c478bd9Sstevel@tonic-gate /* ARGSUSED */
36367c478bd9Sstevel@tonic-gate static int
36377c478bd9Sstevel@tonic-gate __s_val_postime(ParamIndexType i, ns_default_config *def,
36387c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
36397c478bd9Sstevel@tonic-gate {
36407c478bd9Sstevel@tonic-gate 	char	*cp;
36417c478bd9Sstevel@tonic-gate 	long	tot;
36427c478bd9Sstevel@tonic-gate 
36437c478bd9Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR && param->ns_pc) {
36447c478bd9Sstevel@tonic-gate 		for (cp = param->ns_pc; cp && *cp; cp++) {
36457c478bd9Sstevel@tonic-gate 			if (*cp >= '0' && *cp <= '9')
36467c478bd9Sstevel@tonic-gate 				continue;
36477c478bd9Sstevel@tonic-gate 			switch (*cp) {
36487c478bd9Sstevel@tonic-gate 			case 'w': /* weeks */
36497c478bd9Sstevel@tonic-gate 			case 'd': /* days */
36507c478bd9Sstevel@tonic-gate 			case 'h': /* hours */
36517c478bd9Sstevel@tonic-gate 			case 'm': /* minutes */
36527c478bd9Sstevel@tonic-gate 			case 's': /* seconds */
36537c478bd9Sstevel@tonic-gate 				if (*(cp+1) == '\0') {
36547c478bd9Sstevel@tonic-gate 					break;
36557c478bd9Sstevel@tonic-gate 				}
36567c478bd9Sstevel@tonic-gate 			default:
36577c478bd9Sstevel@tonic-gate 				(void) strcpy(errbuf, "Illegal time value");
36587c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
36597c478bd9Sstevel@tonic-gate 			}
36607c478bd9Sstevel@tonic-gate 		}
36617c478bd9Sstevel@tonic-gate 		/* Valid form:  [0-9][0-9]*[wdhms]* */
36627c478bd9Sstevel@tonic-gate 		tot = atol(param->ns_pc);	/* check overflow */
36637c478bd9Sstevel@tonic-gate 		if (tot >= 0)
36647c478bd9Sstevel@tonic-gate 			return (NS_SUCCESS);
36657c478bd9Sstevel@tonic-gate 	}
36667c478bd9Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
36677ddae043Siz 	    gettext("Illegal time value in %s"), def->name);
36687c478bd9Sstevel@tonic-gate 	return (NS_PARSE_ERR);
36697c478bd9Sstevel@tonic-gate }
36707c478bd9Sstevel@tonic-gate 
36717c478bd9Sstevel@tonic-gate 
36727c478bd9Sstevel@tonic-gate /* Validate the Base DN */
36737c478bd9Sstevel@tonic-gate /* It can be empty (RootDSE request) or needs to have an '=' */
36747c478bd9Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
36757c478bd9Sstevel@tonic-gate /* ARGSUSED */
36767c478bd9Sstevel@tonic-gate static int
36777c478bd9Sstevel@tonic-gate __s_val_basedn(ParamIndexType i, ns_default_config *def,
36787c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
36797c478bd9Sstevel@tonic-gate {
36807c478bd9Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR &&
36817c478bd9Sstevel@tonic-gate 	    i == NS_LDAP_SEARCH_BASEDN_P &&
36827ddae043Siz 	    ((param->ns_pc == NULL) || 		/* empty */
36837ddae043Siz 	    (*(param->ns_pc) == '\0') ||		/* empty */
36847ddae043Siz 	    (strchr(param->ns_pc, '=') != NULL)))	/* '=' */
36857c478bd9Sstevel@tonic-gate 	{
36867c478bd9Sstevel@tonic-gate 		return (NS_SUCCESS);
36877c478bd9Sstevel@tonic-gate 	}
36887c478bd9Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
36897ddae043Siz 	    gettext("Non-existent or invalid DN in %s"),
36907ddae043Siz 	    def->name);
36917c478bd9Sstevel@tonic-gate 	return (NS_PARSE_ERR);
36927c478bd9Sstevel@tonic-gate }
36937c478bd9Sstevel@tonic-gate 
36947c478bd9Sstevel@tonic-gate 
36957c478bd9Sstevel@tonic-gate /* Validate the serverList */
36967c478bd9Sstevel@tonic-gate /* For each server in list, check if valid IP or hostname */
36977c478bd9Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
36987c478bd9Sstevel@tonic-gate /* ARGSUSED */
36997c478bd9Sstevel@tonic-gate static int
37007c478bd9Sstevel@tonic-gate __s_val_serverList(ParamIndexType i, ns_default_config *def,
37017c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
37027c478bd9Sstevel@tonic-gate {
37037c478bd9Sstevel@tonic-gate 	for (i = 0; i < param->ns_acnt; i++) {
37047c478bd9Sstevel@tonic-gate 		if ((__s_api_isipv4(param->ns_ppc[i])) ||
37057ddae043Siz 		    (__s_api_isipv6(param->ns_ppc[i])) ||
37067ddae043Siz 		    (__s_api_ishost(param->ns_ppc[i]))) {
37077c478bd9Sstevel@tonic-gate 			continue;
37087c478bd9Sstevel@tonic-gate 		}
37097c478bd9Sstevel@tonic-gate 		/* err */
37107c478bd9Sstevel@tonic-gate 		(void) snprintf(errbuf, MAXERROR,
37117ddae043Siz 		    gettext("Invalid server (%s) in %s"),
37127ddae043Siz 		    param->ns_ppc[i], def->name);
37137c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
37147c478bd9Sstevel@tonic-gate 	}
37157c478bd9Sstevel@tonic-gate 
37167c478bd9Sstevel@tonic-gate 	return (NS_SUCCESS);
37177c478bd9Sstevel@tonic-gate }
37187c478bd9Sstevel@tonic-gate 
37197c478bd9Sstevel@tonic-gate 
37207c478bd9Sstevel@tonic-gate /* Check for a BINDDN */
37217c478bd9Sstevel@tonic-gate /* It can not be empty and needs to have an '=' */
37227c478bd9Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
37237c478bd9Sstevel@tonic-gate /* ARGSUSED */
37247c478bd9Sstevel@tonic-gate static int
37257c478bd9Sstevel@tonic-gate __s_val_binddn(ParamIndexType i, ns_default_config *def,
37267c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
37277c478bd9Sstevel@tonic-gate {
37287c478bd9Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR &&
37297c478bd9Sstevel@tonic-gate 	    i == NS_LDAP_BINDDN_P &&
37307ddae043Siz 	    ((param->ns_pc == NULL) ||
37317ddae043Siz 	    ((*(param->ns_pc) != '\0') &&
37327ddae043Siz 	    (strchr(param->ns_pc, '=') != NULL)))) {
37337c478bd9Sstevel@tonic-gate 		return (NS_SUCCESS);
37347c478bd9Sstevel@tonic-gate 	}
37357c478bd9Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
37367ddae043Siz 	    gettext("NULL or invalid proxy bind DN"));
37377c478bd9Sstevel@tonic-gate 	return (NS_PARSE_ERR);
37387c478bd9Sstevel@tonic-gate }
37397c478bd9Sstevel@tonic-gate 
37407c478bd9Sstevel@tonic-gate 
37417c478bd9Sstevel@tonic-gate /* Check for a BINDPASSWD */
37427c478bd9Sstevel@tonic-gate /* The string can not be NULL or empty */
37437c478bd9Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
37447c478bd9Sstevel@tonic-gate /* ARGSUSED */
37457c478bd9Sstevel@tonic-gate static int
37467c478bd9Sstevel@tonic-gate __s_val_bindpw(ParamIndexType i, ns_default_config *def,
37477c478bd9Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
37487c478bd9Sstevel@tonic-gate {
37497c478bd9Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR &&
37507c478bd9Sstevel@tonic-gate 	    i == NS_LDAP_BINDPASSWD_P &&
37517ddae043Siz 	    ((param->ns_pc == NULL) ||
37527ddae043Siz 	    (*(param->ns_pc) != '\0'))) {
37537c478bd9Sstevel@tonic-gate 		return (NS_SUCCESS);
37547c478bd9Sstevel@tonic-gate 	}
37557c478bd9Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
37567ddae043Siz 	    gettext("NULL proxy bind password"));
37577c478bd9Sstevel@tonic-gate 	return (NS_PARSE_ERR);
37587c478bd9Sstevel@tonic-gate }
37597c478bd9Sstevel@tonic-gate 
37607c478bd9Sstevel@tonic-gate /*
37617c478bd9Sstevel@tonic-gate  * __s_get_hostcertpath returns either the configured host certificate path
37627c478bd9Sstevel@tonic-gate  * or, if none, the default host certificate path (/var/ldap). Note that this
37637c478bd9Sstevel@tonic-gate  * does not use __ns_ldap_getParam because it may be called during connection
37647c478bd9Sstevel@tonic-gate  * setup. This can fail due to insufficient memory.
37657c478bd9Sstevel@tonic-gate  */
37667c478bd9Sstevel@tonic-gate 
37677c478bd9Sstevel@tonic-gate char *
37687c478bd9Sstevel@tonic-gate __s_get_hostcertpath(void)
37697c478bd9Sstevel@tonic-gate {
37707c478bd9Sstevel@tonic-gate 	ns_config_t		*cfg;
37717c478bd9Sstevel@tonic-gate 	ns_param_t		*param;
37727c478bd9Sstevel@tonic-gate 	char			*ret = NULL;
37737c478bd9Sstevel@tonic-gate 
37747c478bd9Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
37757c478bd9Sstevel@tonic-gate 	if (cfg != NULL) {
37767c478bd9Sstevel@tonic-gate 		param = &cfg->paramList[NS_LDAP_HOST_CERTPATH_P];
37777c478bd9Sstevel@tonic-gate 		if (param->ns_ptype == CHARPTR)
37787c478bd9Sstevel@tonic-gate 			ret = strdup(param->ns_pc);
37797c478bd9Sstevel@tonic-gate 		__s_api_release_config(cfg);
37807c478bd9Sstevel@tonic-gate 	}
37817c478bd9Sstevel@tonic-gate 	if (ret == NULL)
37827c478bd9Sstevel@tonic-gate 		ret = strdup(NSLDAPDIRECTORY);
37837c478bd9Sstevel@tonic-gate 	return (ret);
37847c478bd9Sstevel@tonic-gate }
37857c478bd9Sstevel@tonic-gate 
37867c478bd9Sstevel@tonic-gate static void
37877c478bd9Sstevel@tonic-gate _free_config()
37887c478bd9Sstevel@tonic-gate {
37897c478bd9Sstevel@tonic-gate 	if (current_config != NULL)
37907c478bd9Sstevel@tonic-gate 		destroy_config(current_config);
37917c478bd9Sstevel@tonic-gate 
37927c478bd9Sstevel@tonic-gate 	current_config = NULL;
37937c478bd9Sstevel@tonic-gate }
3794