xref: /onnv-gate/usr/src/lib/libsldap/common/ns_config.c (revision 10132:79e70ba10c05)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52830Sdjl  * Common Development and Distribution License (the "License").
62830Sdjl  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
228821SMichen.Chang@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * libsldap - library side configuration components
280Sstevel@tonic-gate  * Routines to manage the config structure
290Sstevel@tonic-gate  */
300Sstevel@tonic-gate 
310Sstevel@tonic-gate #include <stdio.h>
320Sstevel@tonic-gate #include <stdlib.h>
336842Sth160488 #include <stddef.h>
340Sstevel@tonic-gate #include <string.h>
350Sstevel@tonic-gate #include <strings.h>
360Sstevel@tonic-gate #include <libintl.h>
370Sstevel@tonic-gate #include <locale.h>
380Sstevel@tonic-gate #include <thread.h>
390Sstevel@tonic-gate #include <synch.h>
400Sstevel@tonic-gate #include <errno.h>
410Sstevel@tonic-gate #include <unistd.h>
420Sstevel@tonic-gate #include <fcntl.h>
430Sstevel@tonic-gate #include <ctype.h>
440Sstevel@tonic-gate #include <crypt.h>
450Sstevel@tonic-gate #include <arpa/inet.h>
460Sstevel@tonic-gate #include <sys/types.h>
470Sstevel@tonic-gate #include <sys/stat.h>
480Sstevel@tonic-gate #include <syslog.h>
490Sstevel@tonic-gate #include <netdb.h>
500Sstevel@tonic-gate #include <sys/systeminfo.h>
510Sstevel@tonic-gate #include <sys/mman.h>
520Sstevel@tonic-gate #include <sys/time.h>
530Sstevel@tonic-gate #include <limits.h>
540Sstevel@tonic-gate #include "ns_sldap.h"
550Sstevel@tonic-gate #include "ns_internal.h"
560Sstevel@tonic-gate #include "ns_cache_door.h"
576842Sth160488 #include "ns_connmgmt.h"
586842Sth160488 
597281Smichen #pragma fini(__s_api_shutdown_conn_mgmt, \
606842Sth160488 	_free_config, __ns_ldap_doorfd_close)
610Sstevel@tonic-gate 
620Sstevel@tonic-gate static mutex_t		ns_parse_lock = DEFAULTMUTEX;
630Sstevel@tonic-gate static mutex_t		ns_loadrefresh_lock = DEFAULTMUTEX;
640Sstevel@tonic-gate static ns_config_t	*current_config = NULL;
650Sstevel@tonic-gate 
660Sstevel@tonic-gate static int		cache_server = FALSE;
676842Sth160488 extern thread_key_t	ns_cmgkey;
680Sstevel@tonic-gate 
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate  * Parameter Index Type validation routines
710Sstevel@tonic-gate  */
720Sstevel@tonic-gate static int
730Sstevel@tonic-gate __s_val_postime(ParamIndexType i, ns_default_config *def,
740Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
750Sstevel@tonic-gate static int
760Sstevel@tonic-gate __s_val_basedn(ParamIndexType i, ns_default_config *def,
770Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
780Sstevel@tonic-gate 
790Sstevel@tonic-gate static int
800Sstevel@tonic-gate __s_val_binddn(ParamIndexType i, ns_default_config *def,
810Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
820Sstevel@tonic-gate 
830Sstevel@tonic-gate static int
840Sstevel@tonic-gate __s_val_bindpw(ParamIndexType i, ns_default_config *def,
850Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
860Sstevel@tonic-gate 
870Sstevel@tonic-gate static int
880Sstevel@tonic-gate __s_val_serverList(ParamIndexType i, ns_default_config *def,
890Sstevel@tonic-gate 		ns_param_t *param, char *errbuf);
900Sstevel@tonic-gate 
910Sstevel@tonic-gate /*
920Sstevel@tonic-gate  * Forward declarations
930Sstevel@tonic-gate  */
940Sstevel@tonic-gate 
950Sstevel@tonic-gate static ns_parse_status
960Sstevel@tonic-gate verify_value(ns_config_t *cfg, char *name, char *value, char *errstr);
970Sstevel@tonic-gate 
980Sstevel@tonic-gate static int
990Sstevel@tonic-gate set_default_value(ns_config_t *configptr, char *name, char *value,
1000Sstevel@tonic-gate 	ns_ldap_error_t **error);
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate static void
1030Sstevel@tonic-gate set_curr_config(ns_config_t *ptr);
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate static int
1060Sstevel@tonic-gate __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error);
1070Sstevel@tonic-gate 
1080Sstevel@tonic-gate static ns_config_t *
1090Sstevel@tonic-gate SetDoorInfo(char *buffer, ns_ldap_error_t **errorp);
1100Sstevel@tonic-gate 
1110Sstevel@tonic-gate static boolean_t
1120Sstevel@tonic-gate timetorefresh(ns_config_t *cfg);
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate static ns_config_t *
1156842Sth160488 LoadCacheConfiguration(ns_config_t *, ns_ldap_error_t **error);
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate static void **
1180Sstevel@tonic-gate dupParam(ns_param_t *ptr);
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate static time_t
1210Sstevel@tonic-gate conv_time(char *s);
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate /*
1240Sstevel@tonic-gate  * Structures used in enum <-> string mapping routines
1250Sstevel@tonic-gate  */
1260Sstevel@tonic-gate 
1270Sstevel@tonic-gate static ns_enum_map ns_auth_enum_v1[] = {
1280Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_NONE), "NS_LDAP_AUTH_NONE" },
1290Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SIMPLE), "NS_LDAP_AUTH_SIMPLE" },
1300Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5), "NS_LDAP_AUTH_SASL_CRAM_MD5" },
1310Sstevel@tonic-gate 	{ -1, NULL },
1320Sstevel@tonic-gate };
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate static ns_enum_map ns_auth_enum_v2[] = {
1350Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_NONE), "none" },
1360Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SIMPLE), "simple" },
1370Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_CRAM_MD5), "sasl/CRAM-MD5" },
1380Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5), "sasl/DIGEST-MD5" },
1390Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_INT),
1400Sstevel@tonic-gate 			"sasl/DIGEST-MD5:auth-int" },
1410Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_DIGEST_MD5_CONF),
1420Sstevel@tonic-gate 			"sasl/DIGEST-MD5:auth-conf" },
1430Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_SASL_EXTERNAL), "sasl/EXTERNAL" },
1442830Sdjl 	{ ENUM2INT(NS_LDAP_EA_SASL_GSSAPI), "sasl/GSSAPI" },
1450Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_NONE), "tls:none" },
1460Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SIMPLE), "tls:simple" },
1470Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_CRAM_MD5), "tls:sasl/CRAM-MD5" },
1480Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5), "tls:sasl/DIGEST-MD5" },
1490Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT),
1500Sstevel@tonic-gate 			"tls:sasl/DIGEST-MD5:auth-int" },
1510Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF),
1520Sstevel@tonic-gate 			"tls:sasl/DIGEST-MD5:auth-conf" },
1530Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_EA_TLS_SASL_EXTERNAL), "tls:sasl/EXTERNAL" },
1540Sstevel@tonic-gate 	{ -1, NULL },
1550Sstevel@tonic-gate };
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	/* V1 ONLY */
1580Sstevel@tonic-gate static ns_enum_map ns_sec_enum_v1[] = {
1590Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_TLS_NONE), "NS_LDAP_SEC_NONE" },
1600Sstevel@tonic-gate 	{ -1, NULL },
1610Sstevel@tonic-gate };
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	/* V2 ONLY */
1640Sstevel@tonic-gate static ns_enum_map ns_cred_enum_v2[] = {
1650Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_CRED_ANON), "anonymous" },
1660Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_CRED_PROXY), "proxy" },
1670Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_CRED_SELF), "self" },
1680Sstevel@tonic-gate 	{ -1, NULL },
1690Sstevel@tonic-gate };
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate static ns_enum_map ns_ref_enum_v1[] = {
1720Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_FOLLOWREF), "NS_LDAP_FOLLOWREF" },
1730Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_NOREF), "NS_LDAP_NOREF" },
1740Sstevel@tonic-gate 	{ -1, NULL },
1750Sstevel@tonic-gate };
1760Sstevel@tonic-gate 
1770Sstevel@tonic-gate static ns_enum_map ns_ref_enum_v2[] = {
1780Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_FOLLOWREF), "TRUE" },
1790Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_NOREF), "FALSE" },
1800Sstevel@tonic-gate 	{ -1, NULL },
1810Sstevel@tonic-gate };
1820Sstevel@tonic-gate 
1830Sstevel@tonic-gate static ns_enum_map ns_scope_enum_v1[] = {
1840Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_BASE), "NS_LDAP_SCOPE_BASE" },
1850Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_ONELEVEL), "NS_LDAP_SCOPE_ONELEVEL" },
1860Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_SUBTREE), "NS_LDAP_SCOPE_SUBTREE" },
1870Sstevel@tonic-gate 	{ -1, NULL },
1880Sstevel@tonic-gate };
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate static ns_enum_map ns_scope_enum_v2[] = {
1910Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_BASE), "base" },
1920Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_ONELEVEL), "one" },
1930Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_SCOPE_SUBTREE), "sub" },
1940Sstevel@tonic-gate 	{ -1, NULL },
1950Sstevel@tonic-gate };
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate static ns_enum_map ns_pref_enum[] = {
1980Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_PREF_FALSE), "NS_LDAP_FALSE" },
1990Sstevel@tonic-gate 	{ ENUM2INT(NS_LDAP_PREF_TRUE), "NS_LDAP_TRUE" },
2000Sstevel@tonic-gate 	{ -1, NULL },
2010Sstevel@tonic-gate };
2020Sstevel@tonic-gate 
2038821SMichen.Chang@Sun.COM static ns_enum_map ns_shadow_update_enum[] = {
2048821SMichen.Chang@Sun.COM 	{ ENUM2INT(NS_LDAP_ENABLE_SHADOW_UPDATE_FALSE), "FALSE" },
2058821SMichen.Chang@Sun.COM 	{ ENUM2INT(NS_LDAP_ENABLE_SHADOW_UPDATE_TRUE), "TRUE" },
2068821SMichen.Chang@Sun.COM 	{ -1, NULL },
2078821SMichen.Chang@Sun.COM };
2088821SMichen.Chang@Sun.COM 
2090Sstevel@tonic-gate static int	ns_def_auth_v1[] = {
2100Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_EA_NONE),
2110Sstevel@tonic-gate 	0
2120Sstevel@tonic-gate };
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate static int	ns_def_auth_v2[] = {
2150Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_EA_NONE),
2160Sstevel@tonic-gate 	0
2170Sstevel@tonic-gate };
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate static int	ns_def_cred_v1[] = {
2200Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_CRED_PROXY),
2210Sstevel@tonic-gate 	0
2220Sstevel@tonic-gate };
2230Sstevel@tonic-gate 
2240Sstevel@tonic-gate static int	ns_def_cred_v2[] = {
2250Sstevel@tonic-gate 	ENUM2INT(NS_LDAP_CRED_ANON),
2260Sstevel@tonic-gate 	0
2270Sstevel@tonic-gate };
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate /*
2300Sstevel@tonic-gate  * The next macro places an integer in the first sizeof(int) bytes of a
2310Sstevel@tonic-gate  * void pointer location. For 32-bit, it is the same as "(void *) i". It
2320Sstevel@tonic-gate  * is used to solve a problem found during 64-bit testing.  The problem
2330Sstevel@tonic-gate  * was that for a configuration parameter such as NS_LDAP_SEARCH_REF_P,
2340Sstevel@tonic-gate  * which is of type INT and has defined default value, an int
2350Sstevel@tonic-gate  * variable(ns_param.ns_pu.i) defined inside an union(ns_pu) structure, is
2360Sstevel@tonic-gate  * used to access the defined default value. This requires the default
2370Sstevel@tonic-gate  * value to be in the first sizeof(int) bytes of the union element.  If
2380Sstevel@tonic-gate  * just using "(void *) intval" to declare the default value in the
2390Sstevel@tonic-gate  * following defconfig[] structure, the intval data will be placed is the
2400Sstevel@tonic-gate  * last sizeof(int) bytes. In which case, when accessing via ns_pu_i in
2410Sstevel@tonic-gate  * a 64-bit system, ZERO will be returned as the default value, not the
2420Sstevel@tonic-gate  * defined one.
2430Sstevel@tonic-gate  *
2440Sstevel@tonic-gate  * Note since amd64 is little-endian, the problem is not an issue.
2450Sstevel@tonic-gate  * INT2VOIDPTR will just leave the data (i) unchanged.
2460Sstevel@tonic-gate  */
2470Sstevel@tonic-gate #if defined(__amd64)
2480Sstevel@tonic-gate #define	INT2VOIDPTR(i)	(void *)i
2490Sstevel@tonic-gate #else
2500Sstevel@tonic-gate #define	INT2VOIDPTR(i)	\
2510Sstevel@tonic-gate 	(void *)(((long)(i))<<(8*(sizeof (void *) - sizeof (int))))
2520Sstevel@tonic-gate #endif
2530Sstevel@tonic-gate /*
2540Sstevel@tonic-gate  * The default configuration table
2550Sstevel@tonic-gate  * Version 1 entries are first, V2 entries follow.
2560Sstevel@tonic-gate  */
2570Sstevel@tonic-gate static ns_default_config defconfig[] = {
2580Sstevel@tonic-gate 	/* optional V1 profile */
2590Sstevel@tonic-gate 	{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
2600Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2610Sstevel@tonic-gate 		NULL,	/* No version number defined in V1 */
2620Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)NS_LDAP_VERSION_1 },
2630Sstevel@tonic-gate 		NULL, NULL },
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	/* ---------- V1 profile ---------- */
2660Sstevel@tonic-gate 	{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
2670Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2680Sstevel@tonic-gate 		_P1_BINDDN,
2690Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
2700Sstevel@tonic-gate 		__s_val_binddn, NULL },
2710Sstevel@tonic-gate 
2720Sstevel@tonic-gate 	{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
2730Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2740Sstevel@tonic-gate 		_P1_BINDPASSWORD,
2750Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
2760Sstevel@tonic-gate 		__s_val_bindpw, NULL },
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate 	{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
2790Sstevel@tonic-gate 		SERVERCONFIG,	ARRAYCP,	FALSE,	NS_LDAP_V1,
2800Sstevel@tonic-gate 		_P1_SERVERS,
2810Sstevel@tonic-gate 		{ ARRAYCP, 0, NULL },
2820Sstevel@tonic-gate 		__s_val_serverList, NULL },
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
2850Sstevel@tonic-gate 		SERVERCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
2860Sstevel@tonic-gate 		_P1_SEARCHBASEDN,
2870Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
2880Sstevel@tonic-gate 		__s_val_basedn, NULL },
2890Sstevel@tonic-gate 
2900Sstevel@tonic-gate 	{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
2910Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYAUTH,	FALSE,	NS_LDAP_V1,
2920Sstevel@tonic-gate 		_P1_AUTHMETHOD,
2930Sstevel@tonic-gate 		{ ARRAYAUTH, 1, (void *)&ns_def_auth_v1[0] },
2940Sstevel@tonic-gate 		NULL, ns_auth_enum_v1 },
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	{"NS_LDAP_TRANSPORT_SEC", NS_LDAP_TRANSPORT_SEC_P,
2970Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
2980Sstevel@tonic-gate 		_P1_TRANSPORTSECURITY,
2990Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_TLS_NONE) },
3000Sstevel@tonic-gate 		NULL, ns_sec_enum_v1 },
3010Sstevel@tonic-gate 
3020Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
3030Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3040Sstevel@tonic-gate 		_P1_SEARCHREFERRAL,
3050Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF) },
3060Sstevel@tonic-gate 		NULL, ns_ref_enum_v1 },
3070Sstevel@tonic-gate 
3080Sstevel@tonic-gate 	{"NS_LDAP_DOMAIN", NS_LDAP_DOMAIN_P,
3090Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3100Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
3110Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3120Sstevel@tonic-gate 		NULL, NULL },
3130Sstevel@tonic-gate 
3140Sstevel@tonic-gate 	{"NS_LDAP_EXP", NS_LDAP_EXP_P,
3150Sstevel@tonic-gate 		SERVERCONFIG,	TIMET,		TRUE,	NS_LDAP_V1,
3160Sstevel@tonic-gate 		NULL,	/* initialized by code to time+NS_LDAP_CACHETTL */
3170Sstevel@tonic-gate 		{ INT, 0, 0 },
3180Sstevel@tonic-gate 		NULL, NULL },
3190Sstevel@tonic-gate 
3200Sstevel@tonic-gate 	{"NS_LDAP_CERT_PATH", NS_LDAP_CERT_PATH_P,
3210Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3220Sstevel@tonic-gate 		_P1_CERTIFICATEPATH,
3230Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3240Sstevel@tonic-gate 		NULL, NULL },
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 	{"NS_LDAP_CERT_PASS", NS_LDAP_CERT_PASS_P,
3270Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3280Sstevel@tonic-gate 		_P1_CERTIFICATEPASSWORD,
3290Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3300Sstevel@tonic-gate 		NULL, NULL },
3310Sstevel@tonic-gate 
3320Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_DN", NS_LDAP_SEARCH_DN_P,
3330Sstevel@tonic-gate 		CLIENTCONFIG,	SSDLIST,	FALSE,	NS_LDAP_V1,
3340Sstevel@tonic-gate 		_P1_DATASEARCHDN,
3350Sstevel@tonic-gate 		{ SSDLIST, 0, NULL },
3360Sstevel@tonic-gate 		NULL, NULL },
3370Sstevel@tonic-gate 
3380Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
3390Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3400Sstevel@tonic-gate 		_P1_SEARCHSCOPE,
3410Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL) },
3420Sstevel@tonic-gate 		NULL, ns_scope_enum_v1 },
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
3450Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3460Sstevel@tonic-gate 		_P1_SEARCHTIMELIMIT,
3470Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
3480Sstevel@tonic-gate 		NULL, NULL },
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate 	{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
3510Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYCP,	FALSE,	NS_LDAP_V1,
3520Sstevel@tonic-gate 		_P1_PREFERREDSERVER,
3530Sstevel@tonic-gate 		{ ARRAYCP, 0, NULL },
3540Sstevel@tonic-gate 		__s_val_serverList, NULL },
3550Sstevel@tonic-gate 
3560Sstevel@tonic-gate 	{"NS_LDAP_PREF_ONLY", NS_LDAP_PREF_ONLY_P,
3570Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3580Sstevel@tonic-gate 		_P1_PREFERREDSERVERONLY,
3590Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_PREF_FALSE) },
3600Sstevel@tonic-gate 		NULL, ns_pref_enum },
3610Sstevel@tonic-gate 
3620Sstevel@tonic-gate 	{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
3630Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3640Sstevel@tonic-gate 		_P1_CACHETTL,
3650Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
3660Sstevel@tonic-gate 		__s_val_postime, NULL },
3670Sstevel@tonic-gate 
3680Sstevel@tonic-gate 	{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
3690Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V1,
3700Sstevel@tonic-gate 		_P_CN,
3710Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
3720Sstevel@tonic-gate 		NULL, NULL },
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 	{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
3750Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V1,
3760Sstevel@tonic-gate 		_P1_BINDTIMELIMIT,
3770Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
3780Sstevel@tonic-gate 		NULL, NULL },
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate 	/* This configuration option is not visible in V1 */
3810Sstevel@tonic-gate 	{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
3820Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYCRED,	TRUE,	NS_LDAP_V1,
3830Sstevel@tonic-gate 		NULL,	/* No version defined in V1 */
3840Sstevel@tonic-gate 		{ ARRAYCRED, 0, (void *)&ns_def_cred_v1[0] },
3850Sstevel@tonic-gate 		NULL, NULL },
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate 	/* ---------- V2 profile ---------- */
3880Sstevel@tonic-gate 	{"NS_LDAP_FILE_VERSION", NS_LDAP_FILE_VERSION_P,
3890Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
3900Sstevel@tonic-gate 		NULL,	/* No version number defined in V1 */
3910Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)NS_LDAP_VERSION_2 },
3920Sstevel@tonic-gate 		NULL, NULL },
3930Sstevel@tonic-gate 
3940Sstevel@tonic-gate 	{"NS_LDAP_BINDDN", NS_LDAP_BINDDN_P,
3950Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
3960Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
3970Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
3980Sstevel@tonic-gate 		__s_val_binddn, NULL },
3998821SMichen.Chang@Sun.COM 
4000Sstevel@tonic-gate 	{"NS_LDAP_BINDPASSWD", NS_LDAP_BINDPASSWD_P,
4010Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4020Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
4030Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
4040Sstevel@tonic-gate 		__s_val_bindpw, NULL },
4058821SMichen.Chang@Sun.COM 
4068821SMichen.Chang@Sun.COM 	{"NS_LDAP_ENABLE_SHADOW_UPDATE", NS_LDAP_ENABLE_SHADOW_UPDATE_P,
4078821SMichen.Chang@Sun.COM 		CREDCONFIG,	INT,	TRUE,	NS_LDAP_V2,
4088821SMichen.Chang@Sun.COM 		NULL,	/* not defined in the Profile */
4098821SMichen.Chang@Sun.COM 		{ INT, 0, INT2VOIDPTR(NS_LDAP_ENABLE_SHADOW_UPDATE_FALSE) },
4108821SMichen.Chang@Sun.COM 		NULL, ns_shadow_update_enum },
4118821SMichen.Chang@Sun.COM 
4128821SMichen.Chang@Sun.COM 	{"NS_LDAP_ADMIN_BINDDN", NS_LDAP_ADMIN_BINDDN_P,
4138821SMichen.Chang@Sun.COM 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4148821SMichen.Chang@Sun.COM 		NULL,	/* not defined in the Profile */
4158821SMichen.Chang@Sun.COM 		{ CHARPTR, 0, NULL },
4168821SMichen.Chang@Sun.COM 		__s_val_binddn, NULL },
4178821SMichen.Chang@Sun.COM 
4188821SMichen.Chang@Sun.COM 	{"NS_LDAP_ADMIN_BINDPASSWD", NS_LDAP_ADMIN_BINDPASSWD_P,
4198821SMichen.Chang@Sun.COM 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4208821SMichen.Chang@Sun.COM 		NULL,	/* not defined in the Profile */
4218821SMichen.Chang@Sun.COM 		{ CHARPTR, 0, NULL },
4228821SMichen.Chang@Sun.COM 		__s_val_bindpw, NULL },
4238821SMichen.Chang@Sun.COM 
4240Sstevel@tonic-gate 	{"NS_LDAP_EXP", NS_LDAP_EXP_P,
4250Sstevel@tonic-gate 		SERVERCONFIG,	TIMET,		TRUE,	NS_LDAP_V2,
4260Sstevel@tonic-gate 		NULL,	/* initialized by code to time+NS_LDAP_CACHETTL */
4270Sstevel@tonic-gate 		{ INT, 0, 0 },
4280Sstevel@tonic-gate 		NULL, NULL },
4290Sstevel@tonic-gate 
4300Sstevel@tonic-gate 	{"NS_LDAP_SERVER_PREF", NS_LDAP_SERVER_PREF_P,
4310Sstevel@tonic-gate 		CLIENTCONFIG,	SERVLIST,	FALSE,	NS_LDAP_V2,
4320Sstevel@tonic-gate 		_P2_PREFERREDSERVER,
4330Sstevel@tonic-gate 		{ SERVLIST, 0, NULL },
4340Sstevel@tonic-gate 		__s_val_serverList, NULL },
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate 	{"NS_LDAP_SERVERS", NS_LDAP_SERVERS_P,
4370Sstevel@tonic-gate 		SERVERCONFIG,	SERVLIST,	FALSE,	NS_LDAP_V2,
4380Sstevel@tonic-gate 		_P2_DEFAULTSERVER,
4390Sstevel@tonic-gate 		{ SERVLIST, 0, NULL },
4400Sstevel@tonic-gate 		__s_val_serverList, NULL },
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_BASEDN", NS_LDAP_SEARCH_BASEDN_P,
4430Sstevel@tonic-gate 		SERVERCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4440Sstevel@tonic-gate 		_P2_SEARCHBASEDN,
4450Sstevel@tonic-gate 		{ CHARPTR, 0, NULL },
4460Sstevel@tonic-gate 		__s_val_basedn, NULL },
4470Sstevel@tonic-gate 
4480Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_SCOPE", NS_LDAP_SEARCH_SCOPE_P,
4490Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4500Sstevel@tonic-gate 		_P2_SEARCHSCOPE,
4510Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_SCOPE_ONELEVEL) },
4520Sstevel@tonic-gate 		NULL, ns_scope_enum_v2 },
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 	{"NS_LDAP_AUTH", NS_LDAP_AUTH_P,
4550Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYAUTH,	FALSE,	NS_LDAP_V2,
4560Sstevel@tonic-gate 		_P2_AUTHMETHOD,
4570Sstevel@tonic-gate 		{ ARRAYAUTH, 2, (void *)&ns_def_auth_v2[0] },
4580Sstevel@tonic-gate 		NULL, ns_auth_enum_v2 },
4590Sstevel@tonic-gate 
4600Sstevel@tonic-gate 	{"NS_LDAP_CREDENTIAL_LEVEL", NS_LDAP_CREDENTIAL_LEVEL_P,
4610Sstevel@tonic-gate 		CLIENTCONFIG,	ARRAYCRED,	FALSE,	NS_LDAP_V2,
4620Sstevel@tonic-gate 		_P2_CREDENTIALLEVEL,
4630Sstevel@tonic-gate 		{ ARRAYCRED, 0, (void *)&ns_def_cred_v2[0] },
4640Sstevel@tonic-gate 		NULL, ns_cred_enum_v2 },
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 	{"NS_LDAP_SERVICE_SEARCH_DESC", NS_LDAP_SERVICE_SEARCH_DESC_P,
4670Sstevel@tonic-gate 		CLIENTCONFIG,	SSDLIST,	FALSE,	NS_LDAP_V2,
4680Sstevel@tonic-gate 		_P2_SERVICESEARCHDESC,
4690Sstevel@tonic-gate 		{ SSDLIST, 0, NULL },
4700Sstevel@tonic-gate 		NULL, NULL },
4710Sstevel@tonic-gate 
4720Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_TIME", NS_LDAP_SEARCH_TIME_P,
4730Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4740Sstevel@tonic-gate 		_P2_SEARCHTIMELIMIT,
4750Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_SEARCH_TIMEOUT) },
4760Sstevel@tonic-gate 		NULL, NULL },
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate 	{"NS_LDAP_BIND_TIME", NS_LDAP_BIND_TIME_P,
4790Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4800Sstevel@tonic-gate 		_P2_BINDTIMELIMIT,
4810Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_DEFAULT_BIND_TIMEOUT) },
4820Sstevel@tonic-gate 		NULL, NULL },
4830Sstevel@tonic-gate 
4840Sstevel@tonic-gate 	{"NS_LDAP_SEARCH_REF", NS_LDAP_SEARCH_REF_P,
4850Sstevel@tonic-gate 		CLIENTCONFIG,	INT,		TRUE,	NS_LDAP_V2,
4860Sstevel@tonic-gate 		_P2_FOLLOWREFERRALS,
4870Sstevel@tonic-gate 		{ INT, 0, INT2VOIDPTR(NS_LDAP_FOLLOWREF) },
4880Sstevel@tonic-gate 		NULL, ns_ref_enum_v2 },
4890Sstevel@tonic-gate 
4900Sstevel@tonic-gate 	{"NS_LDAP_CACHETTL", NS_LDAP_CACHETTL_P,
4910Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
4920Sstevel@tonic-gate 		_P2_PROFILETTL,
4930Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)EXP_DEFAULT_TTL },
4940Sstevel@tonic-gate 		__s_val_postime, NULL },
4950Sstevel@tonic-gate 
4960Sstevel@tonic-gate 	{"NS_LDAP_ATTRIBUTEMAP", NS_LDAP_ATTRIBUTEMAP_P,
4970Sstevel@tonic-gate 		CLIENTCONFIG,	ATTRMAP,	FALSE,	NS_LDAP_V2,
4980Sstevel@tonic-gate 		_P2_ATTRIBUTEMAP,
4990Sstevel@tonic-gate 		{ ATTRMAP, 0, NULL },
5000Sstevel@tonic-gate 		NULL, NULL },
5010Sstevel@tonic-gate 
5020Sstevel@tonic-gate 	{"NS_LDAP_OBJECTCLASSMAP", NS_LDAP_OBJECTCLASSMAP_P,
5030Sstevel@tonic-gate 		CLIENTCONFIG,	OBJMAP,		FALSE,	NS_LDAP_V2,
5040Sstevel@tonic-gate 		_P2_OBJECTCLASSMAP,
5050Sstevel@tonic-gate 		{ OBJMAP, 0, NULL },
5060Sstevel@tonic-gate 		NULL, NULL },
5070Sstevel@tonic-gate 
5080Sstevel@tonic-gate 	{"NS_LDAP_PROFILE", NS_LDAP_PROFILE_P,
5090Sstevel@tonic-gate 		CLIENTCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
5100Sstevel@tonic-gate 		_P_CN,
5110Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)DEFAULTCONFIGNAME },
5120Sstevel@tonic-gate 		NULL, NULL },
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	{"NS_LDAP_SERVICE_AUTH_METHOD", NS_LDAP_SERVICE_AUTH_METHOD_P,
5150Sstevel@tonic-gate 		CLIENTCONFIG,	SAMLIST,	FALSE,	NS_LDAP_V2,
5160Sstevel@tonic-gate 		_P2_SERVICEAUTHMETHOD,
5170Sstevel@tonic-gate 		{ SAMLIST, 0, NULL },
5180Sstevel@tonic-gate 		NULL, NULL },
5190Sstevel@tonic-gate 
5200Sstevel@tonic-gate 	{"NS_LDAP_SERVICE_CRED_LEVEL", NS_LDAP_SERVICE_CRED_LEVEL_P,
5210Sstevel@tonic-gate 		CLIENTCONFIG,	SCLLIST,	FALSE,	NS_LDAP_V2,
5220Sstevel@tonic-gate 		_P2_SERVICECREDLEVEL,
5230Sstevel@tonic-gate 		{ SCLLIST, 0, NULL },
5240Sstevel@tonic-gate 		NULL, NULL },
5250Sstevel@tonic-gate 
5260Sstevel@tonic-gate 	{"NS_LDAP_HOST_CERTPATH", NS_LDAP_HOST_CERTPATH_P,
5270Sstevel@tonic-gate 		CREDCONFIG,	CHARPTR,	TRUE,	NS_LDAP_V2,
5280Sstevel@tonic-gate 		NULL,	/* not defined in the Profile */
5290Sstevel@tonic-gate 		{ CHARPTR, 0, (void *)NSLDAPDIRECTORY },
5300Sstevel@tonic-gate 		NULL, NULL },
5310Sstevel@tonic-gate 
5320Sstevel@tonic-gate 	/* array terminator [not an entry] */
5330Sstevel@tonic-gate 	{NULL, NS_LDAP_FILE_VERSION_P,
5340Sstevel@tonic-gate 		CLIENTCONFIG,	NS_UNKNOWN,	TRUE,	NULL,
5350Sstevel@tonic-gate 		NULL,
5360Sstevel@tonic-gate 		{ NS_UNKNOWN, 0, NULL },
5370Sstevel@tonic-gate 		NULL, NULL },
5380Sstevel@tonic-gate };
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate static char *
__getdomainname()5410Sstevel@tonic-gate __getdomainname()
5420Sstevel@tonic-gate {
5430Sstevel@tonic-gate 	/*
5440Sstevel@tonic-gate 	 * The sysinfo man page recommends using a buffer size
5450Sstevel@tonic-gate 	 * of 257 bytes. MAXHOSTNAMELEN is 256. So add 1 here.
5460Sstevel@tonic-gate 	 */
5470Sstevel@tonic-gate 	char	buf[MAXHOSTNAMELEN + 1];
5480Sstevel@tonic-gate 	int	status;
5490Sstevel@tonic-gate 
5500Sstevel@tonic-gate 	status = sysinfo(SI_SRPC_DOMAIN, buf, MAXHOSTNAMELEN);
5510Sstevel@tonic-gate 	if (status < 0)
5520Sstevel@tonic-gate 		return (NULL);
5530Sstevel@tonic-gate 	/* error: not enough space to hold returned value */
5540Sstevel@tonic-gate 	if (status > sizeof (buf))
5550Sstevel@tonic-gate 		return (NULL);
5560Sstevel@tonic-gate 	return (strdup(buf));
5570Sstevel@tonic-gate }
5580Sstevel@tonic-gate 
5590Sstevel@tonic-gate void
__ns_ldap_setServer(int set)5600Sstevel@tonic-gate __ns_ldap_setServer(int set)
5610Sstevel@tonic-gate {
5620Sstevel@tonic-gate 	cache_server = set;
5630Sstevel@tonic-gate }
5640Sstevel@tonic-gate 
5650Sstevel@tonic-gate static boolean_t
timetorefresh(ns_config_t * cfg)5660Sstevel@tonic-gate timetorefresh(ns_config_t *cfg)
5670Sstevel@tonic-gate {
5680Sstevel@tonic-gate 	struct timeval	tp;
5690Sstevel@tonic-gate 	static time_t	expire = 0;
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	if (cfg == NULL || gettimeofday(&tp, NULL) == -1)
5720Sstevel@tonic-gate 		return (B_TRUE);
5730Sstevel@tonic-gate 
5740Sstevel@tonic-gate 	if (cfg->paramList[NS_LDAP_EXP_P].ns_ptype == TIMET)
5750Sstevel@tonic-gate 		expire = cfg->paramList[NS_LDAP_EXP_P].ns_tm;
5760Sstevel@tonic-gate 	else
5770Sstevel@tonic-gate 		return (B_TRUE);
5780Sstevel@tonic-gate 
5790Sstevel@tonic-gate 	return (expire != 0 && tp.tv_sec > expire);
5800Sstevel@tonic-gate }
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate int
__s_get_enum_value(ns_config_t * ptr,char * value,ParamIndexType i)5830Sstevel@tonic-gate __s_get_enum_value(ns_config_t *ptr, char *value, ParamIndexType i)
5840Sstevel@tonic-gate {
5850Sstevel@tonic-gate 	register ns_enum_map	*mapp;
5860Sstevel@tonic-gate 	char			*pstart = value;
5870Sstevel@tonic-gate 	char			*pend;
5880Sstevel@tonic-gate 	int			len;
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	if (pstart == NULL)
5910Sstevel@tonic-gate 		return (-1);
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 	/* skip leading spaces */
5940Sstevel@tonic-gate 	while (*pstart == SPACETOK)
5950Sstevel@tonic-gate 		pstart++;
5960Sstevel@tonic-gate 	/* skip trailing spaces */
5970Sstevel@tonic-gate 	pend = pstart + strlen(pstart) - 1;
5985025Siz202018 	for (; pend >= pstart && *pend == SPACETOK; pend--)
5995025Siz202018 		;
6000Sstevel@tonic-gate 	len = pend - pstart + 1;
6010Sstevel@tonic-gate 	if (len == 0)
6020Sstevel@tonic-gate 		return (-1);
6030Sstevel@tonic-gate 
6040Sstevel@tonic-gate 	switch (i) {
6050Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
6060Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
6070Sstevel@tonic-gate 			mapp = &ns_auth_enum_v1[0];
6080Sstevel@tonic-gate 		else
6090Sstevel@tonic-gate 			mapp = &ns_auth_enum_v2[0];
6100Sstevel@tonic-gate 		break;
6110Sstevel@tonic-gate 	case NS_LDAP_TRANSPORT_SEC_P:
6120Sstevel@tonic-gate 		return (-1);
6130Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
6140Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
6150Sstevel@tonic-gate 			mapp = &ns_scope_enum_v1[0];
6160Sstevel@tonic-gate 		else
6170Sstevel@tonic-gate 			mapp = &ns_scope_enum_v2[0];
6180Sstevel@tonic-gate 		break;
6190Sstevel@tonic-gate 	case NS_LDAP_SEARCH_REF_P:
6200Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
6210Sstevel@tonic-gate 			mapp = &ns_ref_enum_v1[0];
6220Sstevel@tonic-gate 		else
6230Sstevel@tonic-gate 			mapp = &ns_ref_enum_v2[0];
6240Sstevel@tonic-gate 		break;
6250Sstevel@tonic-gate 	case NS_LDAP_PREF_ONLY_P:
6260Sstevel@tonic-gate 		mapp = &ns_pref_enum[0];
6270Sstevel@tonic-gate 		break;
6288821SMichen.Chang@Sun.COM 	case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
6298821SMichen.Chang@Sun.COM 		mapp = &ns_shadow_update_enum[0];
6308821SMichen.Chang@Sun.COM 		break;
6310Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
6320Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1)
6330Sstevel@tonic-gate 			return (-1);
6340Sstevel@tonic-gate 		else
6350Sstevel@tonic-gate 			mapp = &ns_cred_enum_v2[0];
6360Sstevel@tonic-gate 		break;
6370Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:
6380Sstevel@tonic-gate 		mapp = &ns_auth_enum_v2[0];
6390Sstevel@tonic-gate 		break;
6400Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:
6410Sstevel@tonic-gate 		mapp = &ns_cred_enum_v2[0];
6420Sstevel@tonic-gate 		break;
6430Sstevel@tonic-gate 	default:
6440Sstevel@tonic-gate 		return (-1);
6450Sstevel@tonic-gate 	}
6460Sstevel@tonic-gate 
6470Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
6480Sstevel@tonic-gate 		if (strncasecmp(pstart, mapp->name, len) == 0 &&
6495025Siz202018 		    (strlen(mapp->name) == len)) {
6500Sstevel@tonic-gate 			return (mapp->value);
6510Sstevel@tonic-gate 		}
6520Sstevel@tonic-gate 	}
6530Sstevel@tonic-gate 	return (-1);
6540Sstevel@tonic-gate }
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate char *
__s_get_auth_name(ns_config_t * ptr,AuthType_t type)6570Sstevel@tonic-gate __s_get_auth_name(ns_config_t *ptr, AuthType_t type)
6580Sstevel@tonic-gate {
6590Sstevel@tonic-gate 	register ns_enum_map	*mapp;
6600Sstevel@tonic-gate 
6610Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1)
6620Sstevel@tonic-gate 		mapp = &ns_auth_enum_v1[0];
6630Sstevel@tonic-gate 	else
6640Sstevel@tonic-gate 		mapp = &ns_auth_enum_v2[0];
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
6670Sstevel@tonic-gate 		if (type == INT2AUTHENUM(mapp->value)) {
6680Sstevel@tonic-gate 			return (mapp->name);
6690Sstevel@tonic-gate 		}
6700Sstevel@tonic-gate 	}
6710Sstevel@tonic-gate 	return ("Unknown AuthType_t type specified");
6720Sstevel@tonic-gate }
6730Sstevel@tonic-gate 
6740Sstevel@tonic-gate 
6750Sstevel@tonic-gate char *
__s_get_security_name(ns_config_t * ptr,TlsType_t type)6760Sstevel@tonic-gate __s_get_security_name(ns_config_t *ptr, TlsType_t type)
6770Sstevel@tonic-gate {
6780Sstevel@tonic-gate 	register ns_enum_map	*mapp;
6790Sstevel@tonic-gate 
6800Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1) {
6810Sstevel@tonic-gate 		mapp = &ns_sec_enum_v1[0];
6820Sstevel@tonic-gate 
6830Sstevel@tonic-gate 		for (; mapp->name != NULL; mapp++) {
6840Sstevel@tonic-gate 			if (type == INT2SECENUM(mapp->value)) {
6850Sstevel@tonic-gate 				return (mapp->name);
6860Sstevel@tonic-gate 			}
6870Sstevel@tonic-gate 		}
6880Sstevel@tonic-gate 	}
6890Sstevel@tonic-gate 	return ("Unknown TlsType_t type specified");
6900Sstevel@tonic-gate }
6910Sstevel@tonic-gate 
6920Sstevel@tonic-gate 
6930Sstevel@tonic-gate char *
__s_get_scope_name(ns_config_t * ptr,ScopeType_t type)6940Sstevel@tonic-gate __s_get_scope_name(ns_config_t *ptr, ScopeType_t type)
6950Sstevel@tonic-gate {
6960Sstevel@tonic-gate 	register ns_enum_map	*mapp;
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1)
6990Sstevel@tonic-gate 		mapp = &ns_scope_enum_v1[0];
7000Sstevel@tonic-gate 	else
7010Sstevel@tonic-gate 		mapp = &ns_scope_enum_v2[0];
7020Sstevel@tonic-gate 
7030Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
7040Sstevel@tonic-gate 		if (type == INT2SCOPEENUM(mapp->value)) {
7050Sstevel@tonic-gate 			return (mapp->name);
7060Sstevel@tonic-gate 		}
7070Sstevel@tonic-gate 	}
7080Sstevel@tonic-gate 	return ("Unknown ScopeType_t type specified");
7090Sstevel@tonic-gate }
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate char *
__s_get_pref_name(PrefOnly_t type)7130Sstevel@tonic-gate __s_get_pref_name(PrefOnly_t type)
7140Sstevel@tonic-gate {
7150Sstevel@tonic-gate 	register ns_enum_map	*mapp = &ns_pref_enum[0];
7160Sstevel@tonic-gate 
7170Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
7180Sstevel@tonic-gate 		if (type == INT2PREFONLYENUM(mapp->value)) {
7190Sstevel@tonic-gate 			return (mapp->name);
7200Sstevel@tonic-gate 		}
7210Sstevel@tonic-gate 	}
7220Sstevel@tonic-gate 	return ("Unknown PrefOnly_t type specified");
7230Sstevel@tonic-gate }
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate char *
__s_get_searchref_name(ns_config_t * ptr,SearchRef_t type)7260Sstevel@tonic-gate __s_get_searchref_name(ns_config_t *ptr, SearchRef_t type)
7270Sstevel@tonic-gate {
7280Sstevel@tonic-gate 	register ns_enum_map	*mapp;
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1)
7310Sstevel@tonic-gate 		mapp = &ns_ref_enum_v1[0];
7320Sstevel@tonic-gate 	else
7330Sstevel@tonic-gate 		mapp = &ns_ref_enum_v2[0];
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 	for (; mapp->name != NULL; mapp++) {
7360Sstevel@tonic-gate 		if (type == INT2SEARCHREFENUM(mapp->value)) {
7370Sstevel@tonic-gate 			return (mapp->name);
7380Sstevel@tonic-gate 		}
7390Sstevel@tonic-gate 	}
7400Sstevel@tonic-gate 	return ("Unknown SearchRef_t type specified");
7410Sstevel@tonic-gate }
7420Sstevel@tonic-gate 
7438821SMichen.Chang@Sun.COM char *
__s_get_shadowupdate_name(enableShadowUpdate_t type)7448821SMichen.Chang@Sun.COM __s_get_shadowupdate_name(enableShadowUpdate_t type)
7458821SMichen.Chang@Sun.COM {
7468821SMichen.Chang@Sun.COM 	register ns_enum_map	*mapp;
7478821SMichen.Chang@Sun.COM 
7488821SMichen.Chang@Sun.COM 	mapp = &ns_shadow_update_enum[0];
7498821SMichen.Chang@Sun.COM 
7508821SMichen.Chang@Sun.COM 	for (; mapp->name != NULL; mapp++) {
7518821SMichen.Chang@Sun.COM 		if (type == INT2SHADOWUPDATENUM(mapp->value)) {
7528821SMichen.Chang@Sun.COM 			return (mapp->name);
7538821SMichen.Chang@Sun.COM 		}
7548821SMichen.Chang@Sun.COM 	}
7558821SMichen.Chang@Sun.COM 	return ("Unknown enableShadowUpdate_t type specified");
7568821SMichen.Chang@Sun.COM }
7578821SMichen.Chang@Sun.COM 
7580Sstevel@tonic-gate static char *
__s_get_credlvl_name(ns_config_t * ptr,CredLevel_t type)7590Sstevel@tonic-gate __s_get_credlvl_name(ns_config_t *ptr, CredLevel_t type)
7600Sstevel@tonic-gate {
7610Sstevel@tonic-gate 	register ns_enum_map	*mapp;
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V2) {
7640Sstevel@tonic-gate 		mapp = &ns_cred_enum_v2[0];
7650Sstevel@tonic-gate 		for (; mapp->name != NULL; mapp++) {
7660Sstevel@tonic-gate 			if (type == INT2CREDLEVELENUM(mapp->value)) {
7670Sstevel@tonic-gate 				return (mapp->name);
7680Sstevel@tonic-gate 			}
7690Sstevel@tonic-gate 		}
7700Sstevel@tonic-gate 	}
7710Sstevel@tonic-gate 	return ("Unknown CredLevel_t type specified");
7720Sstevel@tonic-gate }
7730Sstevel@tonic-gate 
7740Sstevel@tonic-gate static void
destroy_param(ns_config_t * ptr,ParamIndexType type)7750Sstevel@tonic-gate destroy_param(ns_config_t *ptr, ParamIndexType type)
7760Sstevel@tonic-gate {
7770Sstevel@tonic-gate 	int	i, j;
7780Sstevel@tonic-gate 	char	**ppc;
7790Sstevel@tonic-gate 
7800Sstevel@tonic-gate 	if (ptr == NULL)
7810Sstevel@tonic-gate 		return;
7820Sstevel@tonic-gate 
7830Sstevel@tonic-gate 	/*
7840Sstevel@tonic-gate 	 * This routine is not lock protected because
7850Sstevel@tonic-gate 	 * the config param it may be destroying is not
7860Sstevel@tonic-gate 	 * necessarily THE config.  Mutex protect elsewhere.
7870Sstevel@tonic-gate 	 */
7880Sstevel@tonic-gate 	switch (ptr->paramList[type].ns_ptype) {
7890Sstevel@tonic-gate 	case CHARPTR:
7900Sstevel@tonic-gate 		if (ptr->paramList[type].ns_pc) {
7910Sstevel@tonic-gate 			free(ptr->paramList[type].ns_pc);
7920Sstevel@tonic-gate 			ptr->paramList[type].ns_pc = NULL;
7930Sstevel@tonic-gate 		}
7940Sstevel@tonic-gate 		break;
7950Sstevel@tonic-gate 	case SAMLIST:
7960Sstevel@tonic-gate 	case SCLLIST:
7970Sstevel@tonic-gate 	case SSDLIST:
7980Sstevel@tonic-gate 	case ARRAYCP:
7990Sstevel@tonic-gate 	case SERVLIST:
8000Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ppc) {
8010Sstevel@tonic-gate 			ppc = ptr->paramList[type].ns_ppc;
8020Sstevel@tonic-gate 			j = ptr->paramList[type].ns_acnt;
8030Sstevel@tonic-gate 			for (i = 0; i < j && ppc[i] != NULL; i++) {
8040Sstevel@tonic-gate 				free((void *)ppc[i]);
8050Sstevel@tonic-gate 			}
8060Sstevel@tonic-gate 			free((void *)ppc);
8070Sstevel@tonic-gate 			ptr->paramList[type].ns_ppc = NULL;
8080Sstevel@tonic-gate 		}
8090Sstevel@tonic-gate 		break;
8100Sstevel@tonic-gate 	case ARRAYAUTH:
8110Sstevel@tonic-gate 	case ARRAYCRED:
8120Sstevel@tonic-gate 		if (ptr->paramList[type].ns_pi) {
8130Sstevel@tonic-gate 			free(ptr->paramList[type].ns_pi);
8140Sstevel@tonic-gate 			ptr->paramList[type].ns_pi = NULL;
8150Sstevel@tonic-gate 		}
8160Sstevel@tonic-gate 		break;
8170Sstevel@tonic-gate 	case INT:
8180Sstevel@tonic-gate 		ptr->paramList[type].ns_i = 0;
8190Sstevel@tonic-gate 		break;
8200Sstevel@tonic-gate 	case ATTRMAP:
8210Sstevel@tonic-gate 		break;
8220Sstevel@tonic-gate 	case OBJMAP:
8230Sstevel@tonic-gate 		break;
8240Sstevel@tonic-gate 	default:
8250Sstevel@tonic-gate 		break;
8260Sstevel@tonic-gate 	}
8270Sstevel@tonic-gate 	ptr->paramList[type].ns_ptype = NS_UNKNOWN;
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate static void
destroy_config(ns_config_t * ptr)8310Sstevel@tonic-gate destroy_config(ns_config_t *ptr)
8320Sstevel@tonic-gate {
8330Sstevel@tonic-gate 	ParamIndexType	i;
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate 	if (ptr != NULL) {
8366842Sth160488 		if (ptr == current_config)
8376842Sth160488 			current_config = NULL;
8380Sstevel@tonic-gate 		if (ptr->domainName != NULL)
8390Sstevel@tonic-gate 			free(ptr->domainName);
8400Sstevel@tonic-gate 			ptr->domainName = NULL;
8410Sstevel@tonic-gate 		for (i = 0; i <= LAST_VALUE; i++) {
8420Sstevel@tonic-gate 			destroy_param(ptr, i);
8430Sstevel@tonic-gate 		}
8440Sstevel@tonic-gate 		__s_api_destroy_hash(ptr);
8450Sstevel@tonic-gate 		free(ptr);
8460Sstevel@tonic-gate 	}
8470Sstevel@tonic-gate }
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate /*
8500Sstevel@tonic-gate  * Marks the ns_config_t to be deleted and then releases it. (If no other
8510Sstevel@tonic-gate  * caller is using, then __s_api_release_config will destroy it.)
8520Sstevel@tonic-gate  *
8530Sstevel@tonic-gate  * Note that __s_api_destroy_config should only be called if the caller has
8540Sstevel@tonic-gate  * created the ns_config_t with __s_api_create_config (with the exception
8550Sstevel@tonic-gate  * of set_curr_config). The ns_config_t should be private to the caller.
8560Sstevel@tonic-gate  *
8570Sstevel@tonic-gate  * This function should not be called with the current_config except by
8580Sstevel@tonic-gate  * set_curr_config which locks ns_parse_lock to ensure that no thread
8590Sstevel@tonic-gate  * will be waiting on current_config->config_mutex. This ensures that
8600Sstevel@tonic-gate  * no caller with be waiting on cfg->config_mutex while it is being
8610Sstevel@tonic-gate  * destroyed by __s_api_release_config.
8620Sstevel@tonic-gate  */
8630Sstevel@tonic-gate 
8640Sstevel@tonic-gate void
__s_api_destroy_config(ns_config_t * cfg)8650Sstevel@tonic-gate __s_api_destroy_config(ns_config_t *cfg)
8660Sstevel@tonic-gate {
8670Sstevel@tonic-gate 	if (cfg != NULL) {
8680Sstevel@tonic-gate 		(void) mutex_lock(&cfg->config_mutex);
8690Sstevel@tonic-gate 		cfg->delete = TRUE;
8700Sstevel@tonic-gate 		(void) mutex_unlock(&cfg->config_mutex);
8710Sstevel@tonic-gate 		__s_api_release_config(cfg);
8720Sstevel@tonic-gate 	}
8730Sstevel@tonic-gate }
8740Sstevel@tonic-gate 
8750Sstevel@tonic-gate 
8760Sstevel@tonic-gate /*
8770Sstevel@tonic-gate  * Increment the configuration use count by one - assumes ns_parse_lock has
8786842Sth160488  * been obtained.
8790Sstevel@tonic-gate  */
8800Sstevel@tonic-gate 
8810Sstevel@tonic-gate static ns_config_t *
get_curr_config_unlocked(ns_config_t * cfg,boolean_t global)8826921Smichen get_curr_config_unlocked(ns_config_t *cfg, boolean_t global)
8830Sstevel@tonic-gate {
8840Sstevel@tonic-gate 	ns_config_t *ret;
8850Sstevel@tonic-gate 
8860Sstevel@tonic-gate 	ret = cfg;
8870Sstevel@tonic-gate 	if (cfg != NULL) {
8880Sstevel@tonic-gate 		(void) mutex_lock(&cfg->config_mutex);
8896921Smichen 		/*
8906921Smichen 		 * allow access to per connection management (non-global)
8916921Smichen 		 * config so operations on connection being closed can still
8926921Smichen 		 * be completed
8936921Smichen 		 */
8946921Smichen 		if (cfg->delete && global == B_TRUE)
8950Sstevel@tonic-gate 			ret = NULL;
8960Sstevel@tonic-gate 		else
8970Sstevel@tonic-gate 			cfg->nUse++;
8980Sstevel@tonic-gate 		(void) mutex_unlock(&cfg->config_mutex);
8990Sstevel@tonic-gate 	}
9000Sstevel@tonic-gate 	return (ret);
9010Sstevel@tonic-gate }
9020Sstevel@tonic-gate 
9030Sstevel@tonic-gate /*
9046842Sth160488  * set_curr_config_global sets the current global config to the
9056842Sth160488  * specified ns_config_t. Note that this function is similar
9066842Sth160488  * to the project private function __s_api_init_config_global
9076842Sth160488  * except that it does not release the new ns_config_t.
9086842Sth160488  */
9096842Sth160488 static void
set_curr_config_global(ns_config_t * ptr)9106842Sth160488 set_curr_config_global(ns_config_t *ptr)
9116842Sth160488 {
9126842Sth160488 	ns_config_t	*cfg;
9136842Sth160488 	ns_config_t	*cur_cfg;
9146842Sth160488 
9156842Sth160488 	(void) mutex_lock(&ns_parse_lock);
9166842Sth160488 	cur_cfg = current_config;
9176921Smichen 	cfg = get_curr_config_unlocked(cur_cfg, B_TRUE);
9186842Sth160488 	if (cfg != ptr) {
9196842Sth160488 		__s_api_destroy_config(cfg);
9206842Sth160488 		current_config = ptr;
9216842Sth160488 	}
9226842Sth160488 	(void) mutex_unlock(&ns_parse_lock);
9236842Sth160488 }
9246842Sth160488 
9256842Sth160488 
9266842Sth160488 /*
9276842Sth160488  * set_curr_config sets the current config or the per connection
9286842Sth160488  * management one to the specified ns_config_t. Note that this function
9290Sstevel@tonic-gate  * is similar to the project private function __s_api_init_config
9306842Sth160488  * except that it does not release the new ns_config_t. Also note
9316842Sth160488  * that if there's no per connection management one to set, the
9326842Sth160488  * global current config will be set.
9330Sstevel@tonic-gate  */
9340Sstevel@tonic-gate 
9350Sstevel@tonic-gate static void
set_curr_config(ns_config_t * ptr)9360Sstevel@tonic-gate set_curr_config(ns_config_t *ptr)
9370Sstevel@tonic-gate {
9386842Sth160488 	ns_config_t	*cfg;
9396842Sth160488 	ns_config_t	*cur_cfg;
9406842Sth160488 	ns_conn_mgmt_t	*cmg;
9416842Sth160488 	int		rc;
9426842Sth160488 
9436842Sth160488 	rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
9446842Sth160488 
9456842Sth160488 	/* set the per connection management config if possible */
9466842Sth160488 	if (rc == 0 && cmg != NULL && cmg->config != NULL) {
9476842Sth160488 		(void) mutex_lock(&cmg->cfg_lock);
9486842Sth160488 		cur_cfg = cmg->config;
9496921Smichen 		cfg = get_curr_config_unlocked(cur_cfg, B_FALSE);
9506842Sth160488 		if (cfg != ptr) {
9516842Sth160488 			__s_api_destroy_config(cfg);
9526842Sth160488 			cmg->config = ptr;
9536842Sth160488 		}
9546842Sth160488 		(void) mutex_unlock(&cmg->cfg_lock);
9556842Sth160488 		return;
9560Sstevel@tonic-gate 	}
9576842Sth160488 
9586842Sth160488 	/* else set the global current config */
9596842Sth160488 	set_curr_config_global(ptr);
9600Sstevel@tonic-gate }
9610Sstevel@tonic-gate 
9620Sstevel@tonic-gate /*
9630Sstevel@tonic-gate  * Decrements the ns_config_t usage count by one. Delete if delete flag
9640Sstevel@tonic-gate  * is set and no other callers are using.
9650Sstevel@tonic-gate  */
9660Sstevel@tonic-gate 
9670Sstevel@tonic-gate void
__s_api_release_config(ns_config_t * cfg)9680Sstevel@tonic-gate __s_api_release_config(ns_config_t *cfg)
9690Sstevel@tonic-gate {
9700Sstevel@tonic-gate 	if (cfg != NULL) {
9710Sstevel@tonic-gate 		(void) mutex_lock(&cfg->config_mutex);
9720Sstevel@tonic-gate 		cfg->nUse--;
9730Sstevel@tonic-gate 		if (cfg->nUse == 0 && cfg->delete) {
9740Sstevel@tonic-gate 			destroy_config(cfg);
9750Sstevel@tonic-gate 		} else
9760Sstevel@tonic-gate 			(void) mutex_unlock(&cfg->config_mutex);
9770Sstevel@tonic-gate 	}
9780Sstevel@tonic-gate }
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate /*
9816842Sth160488  * __s_api_init_config function destroys the previous global configuration
9826842Sth160488  * sets the new global configuration and then releases it
9836842Sth160488  */
9846842Sth160488 void
__s_api_init_config_global(ns_config_t * ptr)9856842Sth160488 __s_api_init_config_global(ns_config_t *ptr)
9866842Sth160488 {
9876842Sth160488 	set_curr_config_global(ptr);
9886842Sth160488 	__s_api_release_config(ptr);
9896842Sth160488 }
9906842Sth160488 
9916842Sth160488 /*
9920Sstevel@tonic-gate  * __s_api_init_config function destroys the previous configuration
9936842Sth160488  * sets the new configuration and then releases it. The configuration
9946842Sth160488  * may be the global one or the per connection management one.
9950Sstevel@tonic-gate  */
9960Sstevel@tonic-gate void
__s_api_init_config(ns_config_t * ptr)9970Sstevel@tonic-gate __s_api_init_config(ns_config_t *ptr)
9980Sstevel@tonic-gate {
9990Sstevel@tonic-gate 	set_curr_config(ptr);
10000Sstevel@tonic-gate 	__s_api_release_config(ptr);
10010Sstevel@tonic-gate }
10020Sstevel@tonic-gate 
10030Sstevel@tonic-gate 
10040Sstevel@tonic-gate /*
10050Sstevel@tonic-gate  * Create an ns_config_t, set the usage count to one
10060Sstevel@tonic-gate  */
10070Sstevel@tonic-gate 
10080Sstevel@tonic-gate ns_config_t *
__s_api_create_config(void)10090Sstevel@tonic-gate __s_api_create_config(void)
10100Sstevel@tonic-gate {
10110Sstevel@tonic-gate 	ns_config_t	*ret;
10120Sstevel@tonic-gate 	ret = (ns_config_t *)calloc(1, sizeof (ns_config_t));
10130Sstevel@tonic-gate 	if (ret == NULL)
10140Sstevel@tonic-gate 		return (NULL);
10150Sstevel@tonic-gate 
10160Sstevel@tonic-gate 	ret->domainName = __getdomainname();
10170Sstevel@tonic-gate 	if (ret->domainName == NULL) {
10180Sstevel@tonic-gate 		free(ret);
10190Sstevel@tonic-gate 		return (NULL);
10200Sstevel@tonic-gate 	}
10210Sstevel@tonic-gate 	ret->version = NS_LDAP_V1;
10220Sstevel@tonic-gate 	(void) mutex_init(&ret->config_mutex, USYNC_THREAD, NULL);
10230Sstevel@tonic-gate 	ret->nUse = 1;
10240Sstevel@tonic-gate 	ret->delete = B_FALSE;
10250Sstevel@tonic-gate 	return (ret);
10260Sstevel@tonic-gate }
10270Sstevel@tonic-gate 
10286842Sth160488 /*
10296842Sth160488  * __s_api_get_default_config_global returns the current global config
10306842Sth160488  */
10316842Sth160488 ns_config_t *
__s_api_get_default_config_global(void)10326842Sth160488 __s_api_get_default_config_global(void)
10336842Sth160488 {
10346842Sth160488 	ns_config_t	*cfg;
10356842Sth160488 	ns_config_t	*cur_cfg;
10366842Sth160488 
10376842Sth160488 	(void) mutex_lock(&ns_parse_lock);
10386842Sth160488 	cur_cfg = current_config;
10396921Smichen 	cfg = get_curr_config_unlocked(cur_cfg, B_TRUE);
10406842Sth160488 	(void) mutex_unlock(&ns_parse_lock);
10416842Sth160488 
10426842Sth160488 	return (cfg);
10436842Sth160488 }
10446842Sth160488 
10456842Sth160488 /*
10466842Sth160488  * __s_api_get_default_config returns the current global config or the
10476842Sth160488  * per connection management one.
10486842Sth160488  */
10490Sstevel@tonic-gate ns_config_t *
__s_api_get_default_config(void)10500Sstevel@tonic-gate __s_api_get_default_config(void)
10510Sstevel@tonic-gate {
10526842Sth160488 	ns_config_t	*cfg;
10536842Sth160488 	ns_config_t	*cur_cfg;
10546842Sth160488 	ns_conn_mgmt_t	*cmg;
10556842Sth160488 	int		rc;
10566842Sth160488 
10576842Sth160488 	rc = thr_getspecific(ns_cmgkey, (void **)&cmg);
10586842Sth160488 
10596842Sth160488 	/* get the per connection management config if available */
10606842Sth160488 	if (rc == 0 && cmg != NULL && cmg->config != NULL) {
10616842Sth160488 		(void) mutex_lock(&cmg->cfg_lock);
10626842Sth160488 		cur_cfg = cmg->config;
10636921Smichen 		cfg = get_curr_config_unlocked(cur_cfg, B_FALSE);
10646842Sth160488 		(void) mutex_unlock(&cmg->cfg_lock);
10656842Sth160488 		return (cfg);
10666842Sth160488 	}
10676842Sth160488 
10686842Sth160488 	/* else get the global current config */
10696842Sth160488 	return (__s_api_get_default_config_global());
10700Sstevel@tonic-gate }
10710Sstevel@tonic-gate 
10720Sstevel@tonic-gate static char *
stripdup(const char * instr)10730Sstevel@tonic-gate stripdup(const char *instr)
10740Sstevel@tonic-gate {
10750Sstevel@tonic-gate 	char	*pstart = (char *)instr;
10760Sstevel@tonic-gate 	char	*pend, *ret;
10770Sstevel@tonic-gate 	int	len;
10780Sstevel@tonic-gate 
10790Sstevel@tonic-gate 	if (pstart == NULL)
10800Sstevel@tonic-gate 		return (NULL);
10810Sstevel@tonic-gate 	/* remove leading spaces */
10820Sstevel@tonic-gate 	while (*pstart == SPACETOK)
10830Sstevel@tonic-gate 		pstart++;
10840Sstevel@tonic-gate 	/* remove trailing spaces */
10850Sstevel@tonic-gate 	pend = pstart + strlen(pstart) - 1;
10865025Siz202018 	for (; pend >= pstart && *pend == SPACETOK; pend--)
10875025Siz202018 		;
10880Sstevel@tonic-gate 	len = pend - pstart + 1;
10890Sstevel@tonic-gate 	if ((ret = malloc(len + 1)) == NULL)
10900Sstevel@tonic-gate 		return (NULL);
10910Sstevel@tonic-gate 	if (len != 0) {
10920Sstevel@tonic-gate 		(void) strncpy(ret, pstart, len);
10930Sstevel@tonic-gate 	}
10940Sstevel@tonic-gate 	ret[len] = '\0';
10950Sstevel@tonic-gate 	return (ret);
10960Sstevel@tonic-gate }
10970Sstevel@tonic-gate 
10980Sstevel@tonic-gate /*
10990Sstevel@tonic-gate  * Note that __s_api_crosscheck is assumed to be called with an ns_config_t
11000Sstevel@tonic-gate  * that is properly protected - so that it will not change during the
11010Sstevel@tonic-gate  * duration of the call
11020Sstevel@tonic-gate  */
11030Sstevel@tonic-gate 
11040Sstevel@tonic-gate /* Size of errstr needs to be MAXERROR */
11050Sstevel@tonic-gate ns_parse_status
__s_api_crosscheck(ns_config_t * ptr,char * errstr,int check_dn)11060Sstevel@tonic-gate __s_api_crosscheck(ns_config_t *ptr, char *errstr, int check_dn)
11070Sstevel@tonic-gate {
11080Sstevel@tonic-gate 	int		value, j;
11090Sstevel@tonic-gate 	time_t		tm;
11100Sstevel@tonic-gate 	const char	*str, *str1;
11116842Sth160488 	int		i, cnt;
11126842Sth160488 	int		self, gssapi;
11130Sstevel@tonic-gate 
11140Sstevel@tonic-gate 	if (ptr == NULL)
11150Sstevel@tonic-gate 		return (NS_SUCCESS);
11160Sstevel@tonic-gate 
11170Sstevel@tonic-gate 	/* check for no server specified */
11180Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_SERVERS_P].ns_ppc == NULL) {
11190Sstevel@tonic-gate 		if (ptr->version == NS_LDAP_V1) {
11200Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
11215025Siz202018 			    NS_LDAP_SERVERS_P));
11220Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
11235025Siz202018 			    gettext("Configuration Error: No entry for "
11245025Siz202018 			    "'%s' found"), str);
11250Sstevel@tonic-gate 			return (NS_PARSE_ERR);
11260Sstevel@tonic-gate 		} else if (ptr->paramList[NS_LDAP_SERVER_PREF_P].ns_ppc ==
11275025Siz202018 		    NULL) {
11280Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
11295025Siz202018 			    NS_LDAP_SERVERS_P));
11300Sstevel@tonic-gate 			str1 = NULL_OR_STR(__s_api_get_configname(
11315025Siz202018 			    NS_LDAP_SERVER_PREF_P));
11320Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
11335025Siz202018 			    gettext("Configuration Error: "
11345025Siz202018 			    "Neither '%s' nor '%s' is defined"), str, str1);
11350Sstevel@tonic-gate 			return (NS_PARSE_ERR);
11360Sstevel@tonic-gate 		}
11370Sstevel@tonic-gate 	}
11380Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc != NULL &&
11395025Siz202018 	    ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc == NULL) {
11400Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
11415025Siz202018 			    NS_LDAP_CERT_PASS_P));
11420Sstevel@tonic-gate 			str1 = NULL_OR_STR(__s_api_get_configname(
11435025Siz202018 			    NS_LDAP_CERT_PATH_P));
11440Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
11450Sstevel@tonic-gate 			gettext("Configuration Error: %s specified "
11465025Siz202018 			    "but no value for '%s' found"), str, str1);
11470Sstevel@tonic-gate 		return (NS_PARSE_ERR);
11480Sstevel@tonic-gate 	}
11490Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_CERT_PASS_P].ns_pc == NULL &&
11505025Siz202018 	    ptr->paramList[NS_LDAP_CERT_PATH_P].ns_pc != NULL) {
11510Sstevel@tonic-gate 			str = NULL_OR_STR(__s_api_get_configname(
11525025Siz202018 			    NS_LDAP_CERT_PATH_P));
11530Sstevel@tonic-gate 			str1 = NULL_OR_STR(__s_api_get_configname(
11545025Siz202018 			    NS_LDAP_CERT_PASS_P));
11550Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
11560Sstevel@tonic-gate 			gettext("Configuration Error: %s specified "
11575025Siz202018 			    "but no value for '%s' found"), str, str1);
11580Sstevel@tonic-gate 		return (NS_PARSE_ERR);
11590Sstevel@tonic-gate 	}
11600Sstevel@tonic-gate 	/* check if search basedn has been specified */
11610Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ppc == NULL) {
11620Sstevel@tonic-gate 		str = NULL_OR_STR(__s_api_get_configname(
11635025Siz202018 		    NS_LDAP_SEARCH_BASEDN_P));
11640Sstevel@tonic-gate 		(void) snprintf(errstr, MAXERROR,
11655025Siz202018 		    gettext("Configuration Error: No entry for "
11665025Siz202018 		    "'%s' found"), str);
11670Sstevel@tonic-gate 		return (NS_PARSE_ERR);
11680Sstevel@tonic-gate 	}
11690Sstevel@tonic-gate 
11700Sstevel@tonic-gate 	if (check_dn) {
11710Sstevel@tonic-gate 	    /* check for auth value....passwd/bindn if necessary */
11720Sstevel@tonic-gate 
11735025Siz202018 		for (j = 0; ptr->paramList[NS_LDAP_AUTH_P].ns_pi != NULL &&
11740Sstevel@tonic-gate 		    ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j] != NULL; j++) {
11750Sstevel@tonic-gate 		value = ptr->paramList[NS_LDAP_AUTH_P].ns_pi[j];
11760Sstevel@tonic-gate 		switch (value) {
11775025Siz202018 		case NS_LDAP_EA_SIMPLE:
11785025Siz202018 		case NS_LDAP_EA_SASL_CRAM_MD5:
11795025Siz202018 		case NS_LDAP_EA_SASL_DIGEST_MD5:
11805025Siz202018 		case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
11815025Siz202018 		case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
11825025Siz202018 		case NS_LDAP_EA_TLS_SIMPLE:
11835025Siz202018 		case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
11845025Siz202018 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
11855025Siz202018 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
11865025Siz202018 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
11870Sstevel@tonic-gate 			if (ptr->paramList[NS_LDAP_BINDDN_P].ns_ppc == NULL) {
11880Sstevel@tonic-gate 				str = NULL_OR_STR(__s_api_get_configname(
11895025Siz202018 				    NS_LDAP_BINDDN_P));
11900Sstevel@tonic-gate 				(void) snprintf(errstr, MAXERROR,
11910Sstevel@tonic-gate 				gettext("Configuration Error: No entry for "
11920Sstevel@tonic-gate 				    "'%s' found"), str);
11930Sstevel@tonic-gate 				return (NS_PARSE_ERR);
11940Sstevel@tonic-gate 			}
11950Sstevel@tonic-gate 			if (ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ppc
11965025Siz202018 			    == NULL) {
11970Sstevel@tonic-gate 				str = NULL_OR_STR(__s_api_get_configname(
11985025Siz202018 				    NS_LDAP_BINDPASSWD_P));
11990Sstevel@tonic-gate 				(void) snprintf(errstr, MAXERROR,
12000Sstevel@tonic-gate 				gettext("Configuration Error: No entry for "
12015025Siz202018 				    "'%s' found"), str);
12020Sstevel@tonic-gate 				return (NS_PARSE_ERR);
12030Sstevel@tonic-gate 			}
12040Sstevel@tonic-gate 			break;
12050Sstevel@tonic-gate 		}
12065025Siz202018 		}
12070Sstevel@tonic-gate 	}
12080Sstevel@tonic-gate 
12090Sstevel@tonic-gate 	/*
12100Sstevel@tonic-gate 	 * If NS_LDAP_CACHETTL is not specified,
12110Sstevel@tonic-gate 	 * init NS_LDAP_EXP_P here. Otherwise,
12120Sstevel@tonic-gate 	 * ldap_cachemgr will never refresh the profile.
12130Sstevel@tonic-gate 	 * Set it to current time + default
12140Sstevel@tonic-gate 	 * NS_LDAP_CACHETTL
12150Sstevel@tonic-gate 	 */
12160Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_CACHETTL_P].ns_pc == NULL) {
12170Sstevel@tonic-gate 		tm = conv_time(
12185025Siz202018 		    defconfig[NS_LDAP_CACHETTL_P].defval.ns_pc);
12190Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
12200Sstevel@tonic-gate 		if (tm != 0) {
12210Sstevel@tonic-gate 			tm += time(NULL);
12220Sstevel@tonic-gate 		}
12230Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
12240Sstevel@tonic-gate 	}
12252830Sdjl 	/*
12262830Sdjl 	 * If credential level self is defined, there should be
12272830Sdjl 	 * at least an auth method sasl/GSSAPI and vice versa.
12282830Sdjl 	 */
12292830Sdjl 	self = 0;
12302830Sdjl 	cnt = ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_acnt;
12312830Sdjl 	for (i = 0; i < cnt; i++) {
12322830Sdjl 		if (ptr->paramList[NS_LDAP_CREDENTIAL_LEVEL_P].ns_pi[i] ==
12335025Siz202018 		    NS_LDAP_CRED_SELF)
12342830Sdjl 			self++;
12352830Sdjl 	}
12362830Sdjl 	gssapi = 0;
12372830Sdjl 	cnt = ptr->paramList[NS_LDAP_AUTH_P].ns_acnt;
12382830Sdjl 	for (i = 0; i < cnt; i++) {
12392830Sdjl 		if (ptr->paramList[NS_LDAP_AUTH_P].ns_pi[i] ==
12405025Siz202018 		    NS_LDAP_EA_SASL_GSSAPI)
12412830Sdjl 			gssapi++;
12422830Sdjl 	}
12432830Sdjl 	if (gssapi == 0 && self > 0) {
12442830Sdjl 		(void) snprintf(errstr, MAXERROR,
12455025Siz202018 		    gettext("Configuration Error: "
12465025Siz202018 		    "Credential level self requires "
12475025Siz202018 		    "authentication method sasl/GSSAPI"));
12482830Sdjl 		return (NS_PARSE_ERR);
12492830Sdjl 	}
12502830Sdjl 	if (gssapi > 0 && self == 0) {
12512830Sdjl 		(void) snprintf(errstr, MAXERROR,
12525025Siz202018 		    gettext("Configuration Error: "
12535025Siz202018 		    "Authentication method sasl/GSSAPI "
12545025Siz202018 		    "requires credential level self"));
12552830Sdjl 		return (NS_PARSE_ERR);
12562830Sdjl 	}
12570Sstevel@tonic-gate 	return (NS_SUCCESS);
12580Sstevel@tonic-gate }
12590Sstevel@tonic-gate 
12600Sstevel@tonic-gate 
12610Sstevel@tonic-gate int
__s_api_get_type(const char * value,ParamIndexType * type)12620Sstevel@tonic-gate __s_api_get_type(const char *value, ParamIndexType *type)
12630Sstevel@tonic-gate {
12640Sstevel@tonic-gate 	int	i;
12650Sstevel@tonic-gate 
12660Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
12670Sstevel@tonic-gate 		if (strcasecmp(defconfig[i].name, value) == 0) {
12680Sstevel@tonic-gate 			*type = defconfig[i].index;
12690Sstevel@tonic-gate 			return (0);
12700Sstevel@tonic-gate 		}
12710Sstevel@tonic-gate 	}
12720Sstevel@tonic-gate 	return (-1);
12730Sstevel@tonic-gate }
12740Sstevel@tonic-gate 
12750Sstevel@tonic-gate /*
12760Sstevel@tonic-gate  * Externally defined version of get_type.
12770Sstevel@tonic-gate  * Includes extra error checking
12780Sstevel@tonic-gate  */
12790Sstevel@tonic-gate 
12800Sstevel@tonic-gate int
__ns_ldap_getParamType(const char * value,ParamIndexType * type)12810Sstevel@tonic-gate __ns_ldap_getParamType(const char *value, ParamIndexType *type)
12820Sstevel@tonic-gate {
12830Sstevel@tonic-gate 	if (value == NULL || type == NULL)
12840Sstevel@tonic-gate 		return (-1);
12850Sstevel@tonic-gate 	return (__s_api_get_type(value, type));
12860Sstevel@tonic-gate }
12870Sstevel@tonic-gate 
12880Sstevel@tonic-gate int
__s_api_get_versiontype(ns_config_t * ptr,char * value,ParamIndexType * type)12890Sstevel@tonic-gate __s_api_get_versiontype(ns_config_t *ptr, char *value, ParamIndexType *type)
12900Sstevel@tonic-gate {
12910Sstevel@tonic-gate 	ns_version_t	ver;
12920Sstevel@tonic-gate 	int		i;
12930Sstevel@tonic-gate 
12940Sstevel@tonic-gate 	if (ptr == NULL)
12950Sstevel@tonic-gate 		return (-1);
12960Sstevel@tonic-gate 
12970Sstevel@tonic-gate 	ver = ptr->version;
12980Sstevel@tonic-gate 
12990Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
13000Sstevel@tonic-gate 		if (strcasecmp(defconfig[i].name, value) == 0) {
13010Sstevel@tonic-gate 			if (defconfig[i].version == ver) {
13020Sstevel@tonic-gate 				*type = defconfig[i].index;
13030Sstevel@tonic-gate 				return (0);
13040Sstevel@tonic-gate 			}
13050Sstevel@tonic-gate 		}
13060Sstevel@tonic-gate 	}
13070Sstevel@tonic-gate 	return (-1);
13080Sstevel@tonic-gate }
13090Sstevel@tonic-gate 
13100Sstevel@tonic-gate int
__s_api_get_profiletype(char * value,ParamIndexType * type)13110Sstevel@tonic-gate __s_api_get_profiletype(char *value, ParamIndexType *type)
13120Sstevel@tonic-gate {
13130Sstevel@tonic-gate 	int	i;
13140Sstevel@tonic-gate 
13150Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
13160Sstevel@tonic-gate 		if (defconfig[i].profile_name == NULL)
13170Sstevel@tonic-gate 			continue;
13180Sstevel@tonic-gate 		if (strcasecmp(defconfig[i].profile_name, value) == 0) {
13190Sstevel@tonic-gate 			*type = defconfig[i].index;
13200Sstevel@tonic-gate 			return (0);
13210Sstevel@tonic-gate 		}
13220Sstevel@tonic-gate 	}
13230Sstevel@tonic-gate 	return (-1);
13240Sstevel@tonic-gate }
13250Sstevel@tonic-gate 
13260Sstevel@tonic-gate int
__s_api_get_configtype(ParamIndexType type)13270Sstevel@tonic-gate __s_api_get_configtype(ParamIndexType type)
13280Sstevel@tonic-gate {
13290Sstevel@tonic-gate 	int i;
13300Sstevel@tonic-gate 
13310Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
13320Sstevel@tonic-gate 		if (defconfig[i].index == type) {
13330Sstevel@tonic-gate 			return (defconfig[i].config_type);
13340Sstevel@tonic-gate 		}
13350Sstevel@tonic-gate 	}
13360Sstevel@tonic-gate 	return (-1);
13370Sstevel@tonic-gate }
13380Sstevel@tonic-gate 
13390Sstevel@tonic-gate const char *
__s_api_get_configname(ParamIndexType type)13400Sstevel@tonic-gate __s_api_get_configname(ParamIndexType type)
13410Sstevel@tonic-gate {
13420Sstevel@tonic-gate 	int i;
13430Sstevel@tonic-gate 
13440Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
13450Sstevel@tonic-gate 		if (defconfig[i].index == type) {
13460Sstevel@tonic-gate 			if (defconfig[i].name[0] == '\0')
13470Sstevel@tonic-gate 				return (NULL);
13480Sstevel@tonic-gate 			else
13490Sstevel@tonic-gate 				return (defconfig[i].name);
13500Sstevel@tonic-gate 		}
13510Sstevel@tonic-gate 	}
13520Sstevel@tonic-gate 	return (NULL);
13530Sstevel@tonic-gate }
13540Sstevel@tonic-gate 
13550Sstevel@tonic-gate static ns_default_config *
get_defconfig(ns_config_t * ptr,ParamIndexType type)13560Sstevel@tonic-gate get_defconfig(ns_config_t *ptr, ParamIndexType type)
13570Sstevel@tonic-gate {
13580Sstevel@tonic-gate 	ns_version_t	ver;
13590Sstevel@tonic-gate 	int		i;
13600Sstevel@tonic-gate 
13610Sstevel@tonic-gate 	ver = ptr->version;
13620Sstevel@tonic-gate 
13630Sstevel@tonic-gate 	for (i = 0; defconfig[i].name != NULL; i++) {
13640Sstevel@tonic-gate 		if (defconfig[i].index == type &&
13650Sstevel@tonic-gate 		    defconfig[i].version == ver) {
13660Sstevel@tonic-gate 			return (&defconfig[i]);
13670Sstevel@tonic-gate 		}
13680Sstevel@tonic-gate 	}
13690Sstevel@tonic-gate 	return (NULL);
13700Sstevel@tonic-gate }
13710Sstevel@tonic-gate 
13720Sstevel@tonic-gate static int
set_default_value(ns_config_t * configptr,char * name,char * value,ns_ldap_error_t ** error)13730Sstevel@tonic-gate set_default_value(ns_config_t *configptr, char *name,
13740Sstevel@tonic-gate 			char *value, ns_ldap_error_t **error)
13750Sstevel@tonic-gate {
13760Sstevel@tonic-gate 	ParamIndexType	i;
13770Sstevel@tonic-gate 	int		ret;
13780Sstevel@tonic-gate 	char		errstr[MAXERROR];
13790Sstevel@tonic-gate 
13800Sstevel@tonic-gate 	if (__s_api_get_type(name, &i) < 0) {
13810Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr), gettext(
13825025Siz202018 		    "Illegal type name (%s).\n"), name);
13830Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
13845025Siz202018 		    NULL);
13850Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
13860Sstevel@tonic-gate 	}
13870Sstevel@tonic-gate 
13880Sstevel@tonic-gate 	if (i != NS_LDAP_SERVERS_P &&
13895025Siz202018 	    i != NS_LDAP_SERVICE_AUTH_METHOD_P &&
13905025Siz202018 	    i != NS_LDAP_SERVICE_CRED_LEVEL_P &&
13915025Siz202018 	    i != NS_LDAP_SERVICE_SEARCH_DESC_P &&
13925025Siz202018 	    i != NS_LDAP_SERVER_PREF_P &&
13935025Siz202018 	    i != NS_LDAP_SEARCH_DN_P) {
13940Sstevel@tonic-gate 		if (configptr->paramList[i].ns_ptype != NS_UNKNOWN) {
13950Sstevel@tonic-gate 			destroy_param(configptr, i);
13960Sstevel@tonic-gate 		}
13970Sstevel@tonic-gate 	}
13980Sstevel@tonic-gate 
13990Sstevel@tonic-gate 	ret = __ns_ldap_setParamValue(configptr, i, value, error);
14000Sstevel@tonic-gate 	return (ret);
14010Sstevel@tonic-gate }
14020Sstevel@tonic-gate 
14030Sstevel@tonic-gate 
14040Sstevel@tonic-gate /*
14050Sstevel@tonic-gate  * Initialize config to a default state
14060Sstevel@tonic-gate  * By default leave configuration empty
14070Sstevel@tonic-gate  * getParam will automatically get the
14080Sstevel@tonic-gate  * appropriate default value if none exists
14090Sstevel@tonic-gate  */
14100Sstevel@tonic-gate 
14110Sstevel@tonic-gate void
__ns_ldap_default_config()14120Sstevel@tonic-gate __ns_ldap_default_config()
14130Sstevel@tonic-gate {
14140Sstevel@tonic-gate 	ns_config_t	*ptr;
14150Sstevel@tonic-gate 
14160Sstevel@tonic-gate 	ptr = __s_api_create_config();
14170Sstevel@tonic-gate 	if (ptr == NULL)
14180Sstevel@tonic-gate 		return;
14190Sstevel@tonic-gate 
14200Sstevel@tonic-gate 	set_curr_config(ptr);
14210Sstevel@tonic-gate 	__s_api_release_config(ptr);
14220Sstevel@tonic-gate }
14230Sstevel@tonic-gate 
14240Sstevel@tonic-gate /*
14250Sstevel@tonic-gate  * Get the current configuration pointer and return it.
14260Sstevel@tonic-gate  * If necessary initialize or refresh the current
14276842Sth160488  * configuration as applicable. If global is set, returns
14286842Sth160488  * the global one.
14290Sstevel@tonic-gate  */
14300Sstevel@tonic-gate 
14316842Sth160488 static ns_config_t *
loadrefresh_config(boolean_t global)14326842Sth160488 loadrefresh_config(boolean_t global)
14330Sstevel@tonic-gate {
14340Sstevel@tonic-gate 	ns_config_t		*cfg;
14350Sstevel@tonic-gate 	ns_config_t		*new_cfg;
14360Sstevel@tonic-gate 	ns_ldap_error_t		*errorp;
14370Sstevel@tonic-gate 
14380Sstevel@tonic-gate 	/* We want to refresh only one configuration at a time */
14390Sstevel@tonic-gate 	(void) mutex_lock(&ns_loadrefresh_lock);
14406842Sth160488 	if (global == B_TRUE)
14416842Sth160488 		cfg = __s_api_get_default_config_global();
14426842Sth160488 	else
14436842Sth160488 		cfg = __s_api_get_default_config();
14440Sstevel@tonic-gate 
14450Sstevel@tonic-gate 	/* (re)initialize configuration if necessary */
14466842Sth160488 	if (!__s_api_isStandalone() && timetorefresh(cfg)) {
14476842Sth160488 		new_cfg = LoadCacheConfiguration(cfg, &errorp);
14486842Sth160488 		if (new_cfg != NULL && new_cfg != cfg) {
14490Sstevel@tonic-gate 			__s_api_release_config(cfg);
14506842Sth160488 			if (global == B_TRUE)
14516842Sth160488 				set_curr_config_global(new_cfg);
14526842Sth160488 			else
14536842Sth160488 				set_curr_config(new_cfg);
14540Sstevel@tonic-gate 			cfg = new_cfg;
14550Sstevel@tonic-gate 		}
14560Sstevel@tonic-gate 		if (errorp != NULL)
14570Sstevel@tonic-gate 			(void) __ns_ldap_freeError(&errorp);
14580Sstevel@tonic-gate 	}
14590Sstevel@tonic-gate 	(void) mutex_unlock(&ns_loadrefresh_lock);
14600Sstevel@tonic-gate 	return (cfg);
14610Sstevel@tonic-gate }
14620Sstevel@tonic-gate 
14630Sstevel@tonic-gate /*
14646842Sth160488  * Get the current global configuration pointer and return it.
14656842Sth160488  * If necessary initialize or refresh the current
14666842Sth160488  * configuration as applicable.
14676842Sth160488  */
14686842Sth160488 
14696842Sth160488 ns_config_t *
__s_api_loadrefresh_config_global()14706842Sth160488 __s_api_loadrefresh_config_global()
14716842Sth160488 {
14726842Sth160488 	return (loadrefresh_config(B_TRUE));
14736842Sth160488 }
14746842Sth160488 
14756842Sth160488 /*
14766842Sth160488  * Get the current configuration pointer and return it.
14776842Sth160488  * If necessary initialize or refresh the current
14786842Sth160488  * configuration as applicable. The configuration may
14796842Sth160488  * be the global one or the per connection management one.
14806842Sth160488  */
14816842Sth160488 
14826842Sth160488 ns_config_t *
__s_api_loadrefresh_config()14836842Sth160488 __s_api_loadrefresh_config()
14846842Sth160488 {
14856842Sth160488 	return (loadrefresh_config(B_FALSE));
14866842Sth160488 }
14876842Sth160488 
14886842Sth160488 /*
14890Sstevel@tonic-gate  * In general this routine is not very usefull. Individual routines can be
14900Sstevel@tonic-gate  * created to do this job.  Once that is done, this function can be removed.
14910Sstevel@tonic-gate  * Size of errstr buffer needs to be MAXERROR.
14920Sstevel@tonic-gate  */
14930Sstevel@tonic-gate static ns_parse_status
verify_value(ns_config_t * cfg,char * name,char * value,char * errstr)14940Sstevel@tonic-gate verify_value(ns_config_t *cfg, char *name, char *value, char *errstr)
14950Sstevel@tonic-gate {
14960Sstevel@tonic-gate 	ParamIndexType	index = 0;
14970Sstevel@tonic-gate 	int		found = 0, j;
14980Sstevel@tonic-gate 	char		*ptr = NULL, *strptr = NULL, buffer[BUFSIZE];
14990Sstevel@tonic-gate 	char		*rest;
15000Sstevel@tonic-gate 	ns_default_config	*def = NULL;
15010Sstevel@tonic-gate 
15020Sstevel@tonic-gate 	if (__s_api_get_type(name, &index) != 0) {
15030Sstevel@tonic-gate 		(void) snprintf(errstr, MAXERROR,
15045025Siz202018 		    gettext("Unknown keyword encountered '%s'."), name);
15050Sstevel@tonic-gate 		return (NS_PARSE_ERR);
15060Sstevel@tonic-gate 	}
15070Sstevel@tonic-gate 
15080Sstevel@tonic-gate 	def = get_defconfig(cfg, index);
15090Sstevel@tonic-gate 
15100Sstevel@tonic-gate 	/* eat up beginning quote, if any */
15110Sstevel@tonic-gate 	while (value != NULL && (*value == QUOTETOK || *value == SPACETOK))
15120Sstevel@tonic-gate 		value++;
15130Sstevel@tonic-gate 
15140Sstevel@tonic-gate 	/* eat up space/quote at end of value */
15150Sstevel@tonic-gate 	if (strlen(value) > 0)
15160Sstevel@tonic-gate 		ptr = value + strlen(value) - 1;
15170Sstevel@tonic-gate 	else
15180Sstevel@tonic-gate 		ptr = value;
15190Sstevel@tonic-gate 	for (; ptr != value && (*ptr == SPACETOK || *ptr == QUOTETOK); ptr--) {
15200Sstevel@tonic-gate 		*ptr = '\0';
15210Sstevel@tonic-gate 	}
15220Sstevel@tonic-gate 
15230Sstevel@tonic-gate 	switch (index) {
15240Sstevel@tonic-gate 	case NS_LDAP_EXP_P:
15250Sstevel@tonic-gate 	case NS_LDAP_CACHETTL_P:
15260Sstevel@tonic-gate 	case NS_LDAP_CERT_PATH_P:
15270Sstevel@tonic-gate 	case NS_LDAP_CERT_PASS_P:
15280Sstevel@tonic-gate 	case NS_LDAP_CERT_NICKNAME_P:
15290Sstevel@tonic-gate 	case NS_LDAP_BINDDN_P:
15300Sstevel@tonic-gate 	case NS_LDAP_BINDPASSWD_P:
15318821SMichen.Chang@Sun.COM 	case NS_LDAP_ADMIN_BINDDN_P:
15328821SMichen.Chang@Sun.COM 	case NS_LDAP_ADMIN_BINDPASSWD_P:
15330Sstevel@tonic-gate 	case NS_LDAP_DOMAIN_P:
15340Sstevel@tonic-gate 	case NS_LDAP_SEARCH_BASEDN_P:
15350Sstevel@tonic-gate 	case NS_LDAP_SEARCH_TIME_P:
15360Sstevel@tonic-gate 	case NS_LDAP_PROFILE_P:
15370Sstevel@tonic-gate 	case NS_LDAP_AUTH_P:
15380Sstevel@tonic-gate 	case NS_LDAP_SEARCH_SCOPE_P:
15390Sstevel@tonic-gate 	case NS_LDAP_CREDENTIAL_LEVEL_P:
15400Sstevel@tonic-gate 	case NS_LDAP_SERVICE_SEARCH_DESC_P:
15410Sstevel@tonic-gate 	case NS_LDAP_BIND_TIME_P:
15420Sstevel@tonic-gate 	case NS_LDAP_ATTRIBUTEMAP_P:
15430Sstevel@tonic-gate 	case NS_LDAP_OBJECTCLASSMAP_P:
15440Sstevel@tonic-gate 	case NS_LDAP_SERVICE_AUTH_METHOD_P:
15450Sstevel@tonic-gate 	case NS_LDAP_SERVICE_CRED_LEVEL_P:
15460Sstevel@tonic-gate 	case NS_LDAP_HOST_CERTPATH_P:
15470Sstevel@tonic-gate 		break;
15480Sstevel@tonic-gate 	case NS_LDAP_SEARCH_DN_P:
15490Sstevel@tonic-gate 		/* depreciated because of service descriptors */
15500Sstevel@tonic-gate 		/* Parse as appropriate at descriptor create time */
15510Sstevel@tonic-gate 		break;
15520Sstevel@tonic-gate 	case NS_LDAP_FILE_VERSION_P:
15530Sstevel@tonic-gate 		if (value != NULL &&
15545025Siz202018 		    strcasecmp(value, NS_LDAP_VERSION_1) != 0 &&
15555025Siz202018 		    strcasecmp(value, NS_LDAP_VERSION_2) != 0) {
15560Sstevel@tonic-gate 			(void) snprintf(errstr, MAXERROR,
15575025Siz202018 			    gettext("Version mismatch, expected "
15585025Siz202018 			    "cache version '%s' or '%s' but "
15595025Siz202018 			    "encountered version '%s'."),
15605025Siz202018 			    NS_LDAP_VERSION_1,
15615025Siz202018 			    NS_LDAP_VERSION_2, value);
15620Sstevel@tonic-gate 				return (NS_PARSE_ERR);
15630Sstevel@tonic-gate 		}
15640Sstevel@tonic-gate 		break;
15650Sstevel@tonic-gate 	case NS_LDAP_SERVERS_P:
15660Sstevel@tonic-gate 	case NS_LDAP_SERVER_PREF_P:
15670Sstevel@tonic-gate 		(void) strcpy(buffer, value);
15680Sstevel@tonic-gate 		strptr = strtok_r(buffer, ",", &rest);
15690Sstevel@tonic-gate 		while (strptr != NULL) {
15700Sstevel@tonic-gate 			char	*tmp = NULL;
15710Sstevel@tonic-gate 			tmp = stripdup(strptr);
15720Sstevel@tonic-gate 			if (tmp == NULL || (strchr(tmp, ' ') != NULL)) {
15730Sstevel@tonic-gate 				(void) snprintf(errstr, MAXERROR,
15740Sstevel@tonic-gate 				    gettext("Invalid parameter values "
15750Sstevel@tonic-gate 				    "'%s' specified for keyword '%s'."),
15760Sstevel@tonic-gate 				    tmp, name);
15770Sstevel@tonic-gate 				free(tmp);
15780Sstevel@tonic-gate 				return (NS_PARSE_ERR);
15790Sstevel@tonic-gate 			}
15800Sstevel@tonic-gate 			free(tmp);
15810Sstevel@tonic-gate 			strptr = strtok_r(NULL, ",", &rest);
15820Sstevel@tonic-gate 		}
15830Sstevel@tonic-gate 		break;
15840Sstevel@tonic-gate 	default:
15850Sstevel@tonic-gate 		found = 0; j = 0;
15860Sstevel@tonic-gate 		while (def->allowed != NULL &&
15875025Siz202018 		    def->allowed[j].name != NULL && j < DEFMAX) {
15880Sstevel@tonic-gate 			if (strcmp(def->allowed[j].name,
15890Sstevel@tonic-gate 			    value) == 0) {
15900Sstevel@tonic-gate 				found = 1;
15910Sstevel@tonic-gate 				break;
15920Sstevel@tonic-gate 			}
15930Sstevel@tonic-gate 			j++;
15940Sstevel@tonic-gate 		}
15950Sstevel@tonic-gate 		if (!found) {
15965025Siz202018 			(void) snprintf(errstr, MAXERROR,
15970Sstevel@tonic-gate 			    gettext("Invalid option specified for "
15980Sstevel@tonic-gate 			    "'%s' keyword. '%s' is not a recognized "
15990Sstevel@tonic-gate 			    "keyword value."), name, value);
16000Sstevel@tonic-gate 			return (NS_PARSE_ERR);
16010Sstevel@tonic-gate 		}
16020Sstevel@tonic-gate 	}
16030Sstevel@tonic-gate 
16040Sstevel@tonic-gate 	return (NS_SUCCESS);
16050Sstevel@tonic-gate }
16060Sstevel@tonic-gate 
16070Sstevel@tonic-gate void
__s_api_split_key_value(char * buffer,char ** name,char ** value)16080Sstevel@tonic-gate __s_api_split_key_value(char *buffer, char **name, char **value)
16090Sstevel@tonic-gate {
16100Sstevel@tonic-gate 	char	*ptr;
16110Sstevel@tonic-gate 
16120Sstevel@tonic-gate 	*name = buffer;
16130Sstevel@tonic-gate 	/* split into name value pair */
16140Sstevel@tonic-gate 	if ((ptr = strchr(buffer, TOKENSEPARATOR)) != NULL) {
16150Sstevel@tonic-gate 		*ptr = '\0';
16160Sstevel@tonic-gate 		ptr++;
16170Sstevel@tonic-gate 		/* trim whitespace */
16180Sstevel@tonic-gate 		while (*ptr == SPACETOK)
16190Sstevel@tonic-gate 			ptr++;
16200Sstevel@tonic-gate 		*value = ptr;
16210Sstevel@tonic-gate 	}
16220Sstevel@tonic-gate }
16230Sstevel@tonic-gate 
16240Sstevel@tonic-gate /*
16250Sstevel@tonic-gate  * Set a parameter value in a generic configuration structure
16260Sstevel@tonic-gate  * Assume any necessary locks are in place.  This routine would
16270Sstevel@tonic-gate  * be better named: __ns_ldap_translateString2Param
16280Sstevel@tonic-gate  *
16290Sstevel@tonic-gate  * This routine translates external string format into internal
16300Sstevel@tonic-gate  * param format and saves the result in the param table.
16310Sstevel@tonic-gate  */
16320Sstevel@tonic-gate int
__ns_ldap_setParamValue(ns_config_t * ptr,const ParamIndexType type,const void * data,ns_ldap_error_t ** error)16330Sstevel@tonic-gate __ns_ldap_setParamValue(ns_config_t *ptr, const ParamIndexType type,
16340Sstevel@tonic-gate 		const void *data, ns_ldap_error_t **error)
16350Sstevel@tonic-gate {
16360Sstevel@tonic-gate 	ns_default_config	*def = NULL;
16370Sstevel@tonic-gate 	ns_param_t		conf;
16380Sstevel@tonic-gate 	ns_mapping_t		*map, *rmap;
16390Sstevel@tonic-gate 	int			i, j, len;
16400Sstevel@tonic-gate 	char			*cp, *cp2, *end;
16410Sstevel@tonic-gate 	char			*tcp = NULL;
16420Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
16430Sstevel@tonic-gate 	char			tbuf[100], *ptbuf;
16440Sstevel@tonic-gate 	char			*sid, *origA, **mapA;
16450Sstevel@tonic-gate 	char			**attr;
16460Sstevel@tonic-gate 	time_t			tm;
16470Sstevel@tonic-gate 	int 			free_memory, exitrc;
16480Sstevel@tonic-gate 	char			**p;
16490Sstevel@tonic-gate 
16500Sstevel@tonic-gate 	/* Find ParamIndexType default configuration data */
16510Sstevel@tonic-gate 	def = get_defconfig(ptr, type);
16520Sstevel@tonic-gate 	if (def == NULL) {
16530Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
16545025Siz202018 		    gettext("Unable to set value: "
16555025Siz202018 		    "invalid ParamIndexType (%d)"), type);
16560Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
16575025Siz202018 		    NULL);
16580Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
16590Sstevel@tonic-gate 	}
16600Sstevel@tonic-gate 
16610Sstevel@tonic-gate 	(void) memset(&conf, 0, sizeof (conf));
16620Sstevel@tonic-gate 
16630Sstevel@tonic-gate 	/* data is actually const char */
16640Sstevel@tonic-gate 	cp = (char *)data;
16650Sstevel@tonic-gate 
16660Sstevel@tonic-gate 	/* eat up beginning quote, if any */
16670Sstevel@tonic-gate 	while (cp && (*cp == QUOTETOK || *cp == SPACETOK))
16680Sstevel@tonic-gate 		cp++;
16690Sstevel@tonic-gate 
16700Sstevel@tonic-gate 	/* eat up space/quote at end of value */
16710Sstevel@tonic-gate 	end = cp2 = cp + strlen(cp) - 1;
16720Sstevel@tonic-gate 	for (; cp2 > cp && (*cp2 == SPACETOK || *cp2 == QUOTETOK); cp2--)
16730Sstevel@tonic-gate 		;
16740Sstevel@tonic-gate 	/* data is const, must duplicate */
16750Sstevel@tonic-gate 	if (cp2 != end) {
16760Sstevel@tonic-gate 		tcp = (char *)calloc((int)(cp2 - cp + 2), sizeof (char));
16770Sstevel@tonic-gate 		if (tcp == NULL)
16780Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
16790Sstevel@tonic-gate 		end = cp2;
16800Sstevel@tonic-gate 		cp2 = tcp;
16810Sstevel@tonic-gate 		while (cp <= end) {
16820Sstevel@tonic-gate 			*cp2++ = *cp++;
16830Sstevel@tonic-gate 		}
16840Sstevel@tonic-gate 		*cp2 = '\0';
16850Sstevel@tonic-gate 		cp = tcp;
16860Sstevel@tonic-gate 	}
16870Sstevel@tonic-gate 
16880Sstevel@tonic-gate 	/* Parse data according to type */
16890Sstevel@tonic-gate 	switch (def->data_type) {
16900Sstevel@tonic-gate 	case INT:
16910Sstevel@tonic-gate 		switch (def->index) {
16920Sstevel@tonic-gate 		case NS_LDAP_PREF_ONLY_P:
16930Sstevel@tonic-gate 		case NS_LDAP_SEARCH_REF_P:
16940Sstevel@tonic-gate 		case NS_LDAP_SEARCH_SCOPE_P:
16958821SMichen.Chang@Sun.COM 		case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
16960Sstevel@tonic-gate 			i = __s_get_enum_value(ptr, cp, def->index);
16970Sstevel@tonic-gate 			if (i < 0) {
16980Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
16995025Siz202018 				    gettext("Unable to set value: "
17005025Siz202018 				    "invalid %s (%d)"), def->name,
17015025Siz202018 				    def->index);
17020Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
17035025Siz202018 				    strdup(errstr), NULL);
17040Sstevel@tonic-gate 				if (tcp != NULL)
17050Sstevel@tonic-gate 					free(tcp);
17060Sstevel@tonic-gate 				return (NS_LDAP_CONFIG);
17070Sstevel@tonic-gate 			}
17080Sstevel@tonic-gate 			conf.ns_i = i;
17090Sstevel@tonic-gate 			break;
17100Sstevel@tonic-gate 		case NS_LDAP_TRANSPORT_SEC_P:	/* ignore TRANSPORT_SEC */
17110Sstevel@tonic-gate 			break;
17120Sstevel@tonic-gate 		default:
17130Sstevel@tonic-gate 			cp2 = cp;
17140Sstevel@tonic-gate 			if ((*cp2 == '+') || (*cp2 == '-'))
17150Sstevel@tonic-gate 				cp2++;
17160Sstevel@tonic-gate 			for (/* empty */; *cp2; cp2++) {
17170Sstevel@tonic-gate 				if (isdigit(*cp2))
17180Sstevel@tonic-gate 					continue;
17190Sstevel@tonic-gate 
17200Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
17215025Siz202018 				    gettext("Unable to set value: "
17225025Siz202018 				    "invalid %s (%d)"), def->name,
17235025Siz202018 				    def->index);
17240Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
17255025Siz202018 				    strdup(errstr), NULL);
17260Sstevel@tonic-gate 				if (tcp != NULL)
17270Sstevel@tonic-gate 					free(tcp);
17280Sstevel@tonic-gate 				return (NS_LDAP_CONFIG);
17290Sstevel@tonic-gate 			}
17300Sstevel@tonic-gate 			i = atoi(cp);
17310Sstevel@tonic-gate 			conf.ns_i = i;
17320Sstevel@tonic-gate 			break;
17330Sstevel@tonic-gate 		}
17340Sstevel@tonic-gate 		break;
17350Sstevel@tonic-gate 	case TIMET:
17360Sstevel@tonic-gate 		/* Do nothing with a TIMET.  Initialize it below */
17370Sstevel@tonic-gate 		break;
17380Sstevel@tonic-gate 	case CHARPTR:
17390Sstevel@tonic-gate 		conf.ns_pc = (char *)strdup(cp);
17400Sstevel@tonic-gate 		if (conf.ns_pc == NULL) {
17410Sstevel@tonic-gate 			if (tcp != NULL)
17420Sstevel@tonic-gate 				free(tcp);
17430Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
17440Sstevel@tonic-gate 		}
17450Sstevel@tonic-gate 		break;
17460Sstevel@tonic-gate 	case SAMLIST:
17470Sstevel@tonic-gate 		/* first check to see if colon (:) is there */
17480Sstevel@tonic-gate 		if ((strchr(cp, COLONTOK)) == NULL) {
17490Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
17505025Siz202018 			    gettext("Unable to set value: "
17515025Siz202018 			    "invalid serviceAuthenticationMethod (%s)"),
17525025Siz202018 			    cp);
17530Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
17545025Siz202018 			    strdup(errstr), NULL);
17550Sstevel@tonic-gate 			if (tcp != NULL)
17560Sstevel@tonic-gate 				free(tcp);
17570Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
17580Sstevel@tonic-gate 		}
17590Sstevel@tonic-gate 		/* Appends an entry to the existing list */
17600Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ptype != SAMLIST) {
17610Sstevel@tonic-gate 			conf.ns_ppc = (char **)calloc(2, sizeof (char *));
17620Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
17630Sstevel@tonic-gate 				if (tcp != NULL)
17640Sstevel@tonic-gate 					free(tcp);
17650Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17660Sstevel@tonic-gate 			}
17670Sstevel@tonic-gate 			conf.ns_acnt = 1;
17680Sstevel@tonic-gate 			conf.ns_ppc[0] = (char *)strdup(cp);
17690Sstevel@tonic-gate 			if (conf.ns_ppc[0] == NULL) {
17700Sstevel@tonic-gate 				free(conf.ns_ppc);
17710Sstevel@tonic-gate 				if (tcp != NULL)
17720Sstevel@tonic-gate 					free(tcp);
17730Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17740Sstevel@tonic-gate 			}
17750Sstevel@tonic-gate 		} else {
17760Sstevel@tonic-gate 			char *dp, *dpend;
17770Sstevel@tonic-gate 			int fnd = 0;
17780Sstevel@tonic-gate 
17790Sstevel@tonic-gate 			/* Attempt to replace if possible */
17800Sstevel@tonic-gate 			dpend = strchr(cp, COLONTOK);
17810Sstevel@tonic-gate 			len = dpend - cp;
17820Sstevel@tonic-gate 			dp = (char *)malloc(len+1);
17830Sstevel@tonic-gate 			if (dp == NULL) {
17840Sstevel@tonic-gate 				if (tcp != NULL)
17850Sstevel@tonic-gate 					free(tcp);
17860Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
17870Sstevel@tonic-gate 			}
17880Sstevel@tonic-gate 			(void) strlcpy(dp, cp, len+1);
17890Sstevel@tonic-gate 			fnd = 0;
17900Sstevel@tonic-gate 			for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
17910Sstevel@tonic-gate 				dpend = strchr(ptr->paramList[type].ns_ppc[j],
17925025Siz202018 				    COLONTOK);
17930Sstevel@tonic-gate 				if (dpend == NULL)
17940Sstevel@tonic-gate 					continue;
17950Sstevel@tonic-gate 				i = dpend - ptr->paramList[type].ns_ppc[j];
17960Sstevel@tonic-gate 				if (i != len)
17970Sstevel@tonic-gate 					continue;
17980Sstevel@tonic-gate 				if (strncmp(ptr->paramList[type].ns_ppc[j],
17995025Siz202018 				    dp, len) == 0) {
18000Sstevel@tonic-gate 					conf.ns_acnt =
18015025Siz202018 					    ptr->paramList[type].ns_acnt;
18020Sstevel@tonic-gate 					conf.ns_ppc =
18035025Siz202018 					    ptr->paramList[type].ns_ppc;
18040Sstevel@tonic-gate 					ptr->paramList[type].ns_ppc = NULL;
18050Sstevel@tonic-gate 					free(conf.ns_ppc[j]);
18060Sstevel@tonic-gate 					conf.ns_ppc[j] = (char *)strdup(cp);
18070Sstevel@tonic-gate 					if (conf.ns_ppc[j] == NULL) {
18080Sstevel@tonic-gate 						free(dp);
18090Sstevel@tonic-gate 						__s_api_free2dArray
18105025Siz202018 						    (conf.ns_ppc);
18110Sstevel@tonic-gate 						if (tcp != NULL)
18120Sstevel@tonic-gate 							free(tcp);
18130Sstevel@tonic-gate 						return (NS_LDAP_MEMORY);
18140Sstevel@tonic-gate 					}
18150Sstevel@tonic-gate 					fnd = 1;
18160Sstevel@tonic-gate 					break;
18170Sstevel@tonic-gate 				}
18180Sstevel@tonic-gate 			}
18190Sstevel@tonic-gate 			free(dp);
18200Sstevel@tonic-gate 
18210Sstevel@tonic-gate 			if (fnd)
18220Sstevel@tonic-gate 				break;	/* Replaced completed */
18230Sstevel@tonic-gate 
18240Sstevel@tonic-gate 			/* Append */
18250Sstevel@tonic-gate 			len = ptr->paramList[type].ns_acnt + 1;
18260Sstevel@tonic-gate 			if (len > 1) {
18270Sstevel@tonic-gate 				p = (char **)dupParam(&ptr->paramList[type]);
18280Sstevel@tonic-gate 				if (p == NULL) {
18290Sstevel@tonic-gate 					if (tcp != NULL)
18300Sstevel@tonic-gate 						free(tcp);
18310Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
18320Sstevel@tonic-gate 				}
18330Sstevel@tonic-gate 			} else
18340Sstevel@tonic-gate 				p = NULL;
18350Sstevel@tonic-gate 			conf.ns_ppc =
18365025Siz202018 			    (char **)realloc(p, (len+1) * sizeof (char *));
18370Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
18380Sstevel@tonic-gate 				__s_api_free2dArray(p);
18390Sstevel@tonic-gate 				if (tcp != NULL)
18400Sstevel@tonic-gate 					free(tcp);
18410Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18420Sstevel@tonic-gate 			}
18430Sstevel@tonic-gate 			conf.ns_acnt = len;
18440Sstevel@tonic-gate 			conf.ns_ppc[len-1] = (char *)strdup(cp);
18450Sstevel@tonic-gate 			if (conf.ns_ppc[len-1] == NULL) {
18460Sstevel@tonic-gate 				__s_api_free2dArray(conf.ns_ppc);
18470Sstevel@tonic-gate 				if (tcp != NULL)
18480Sstevel@tonic-gate 					free(tcp);
18490Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18500Sstevel@tonic-gate 			}
18510Sstevel@tonic-gate 			conf.ns_ppc[len] = NULL;
18520Sstevel@tonic-gate 		}
18530Sstevel@tonic-gate 		break;
18540Sstevel@tonic-gate 	case SCLLIST:
18550Sstevel@tonic-gate 		/* first check to see if colon (:) is there */
18560Sstevel@tonic-gate 		if ((strchr(cp, COLONTOK)) == NULL) {
18570Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
18585025Siz202018 			    gettext("Unable to set value: "
18595025Siz202018 			    "invalid serviceCredentialLevel (%s)"),
18605025Siz202018 			    cp);
18610Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
18625025Siz202018 			    strdup(errstr), NULL);
18630Sstevel@tonic-gate 			if (tcp != NULL)
18640Sstevel@tonic-gate 				free(tcp);
18650Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
18660Sstevel@tonic-gate 		}
18670Sstevel@tonic-gate 		/* Appends an entry to the existing list */
18680Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ptype != SCLLIST) {
18690Sstevel@tonic-gate 			conf.ns_ppc = (char **)calloc(2, sizeof (char *));
18700Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
18710Sstevel@tonic-gate 				if (tcp != NULL)
18720Sstevel@tonic-gate 					free(tcp);
18730Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18740Sstevel@tonic-gate 			}
18750Sstevel@tonic-gate 			conf.ns_acnt = 1;
18760Sstevel@tonic-gate 			conf.ns_ppc[0] = (char *)strdup(cp);
18770Sstevel@tonic-gate 			if (conf.ns_ppc[0] == NULL) {
18780Sstevel@tonic-gate 				free(conf.ns_ppc);
18790Sstevel@tonic-gate 				if (tcp != NULL)
18800Sstevel@tonic-gate 					free(tcp);
18810Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18820Sstevel@tonic-gate 			}
18830Sstevel@tonic-gate 		} else {
18840Sstevel@tonic-gate 			char *dp, *dpend;
18850Sstevel@tonic-gate 			int fnd = 0;
18860Sstevel@tonic-gate 
18870Sstevel@tonic-gate 			/* Attempt to replace if possible */
18880Sstevel@tonic-gate 			dpend = strchr(cp, COLONTOK);
18890Sstevel@tonic-gate 			len = dpend - cp;
18900Sstevel@tonic-gate 			dp = (char *)malloc(len+1);
18910Sstevel@tonic-gate 			if (dp == NULL) {
18920Sstevel@tonic-gate 				if (tcp != NULL)
18930Sstevel@tonic-gate 					free(tcp);
18940Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
18950Sstevel@tonic-gate 			}
18960Sstevel@tonic-gate 			(void) strlcpy(dp, cp, len+1);
18970Sstevel@tonic-gate 			fnd = 0;
18980Sstevel@tonic-gate 			for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
18990Sstevel@tonic-gate 				dpend = strchr(ptr->paramList[type].ns_ppc[j],
19005025Siz202018 				    COLONTOK);
19010Sstevel@tonic-gate 				if (dpend == NULL)
19020Sstevel@tonic-gate 					continue;
19030Sstevel@tonic-gate 				i = dpend - ptr->paramList[type].ns_ppc[j];
19040Sstevel@tonic-gate 				if (i != len)
19050Sstevel@tonic-gate 					continue;
19060Sstevel@tonic-gate 				if (strncmp(ptr->paramList[type].ns_ppc[j],
19075025Siz202018 				    dp, len) == 0) {
19080Sstevel@tonic-gate 					conf.ns_acnt =
19095025Siz202018 					    ptr->paramList[type].ns_acnt;
19100Sstevel@tonic-gate 					conf.ns_ppc =
19115025Siz202018 					    ptr->paramList[type].ns_ppc;
19120Sstevel@tonic-gate 					ptr->paramList[type].ns_ppc = NULL;
19130Sstevel@tonic-gate 					free(conf.ns_ppc[j]);
19140Sstevel@tonic-gate 					conf.ns_ppc[j] = (char *)strdup(cp);
19150Sstevel@tonic-gate 					if (conf.ns_ppc[j] == NULL) {
19160Sstevel@tonic-gate 						free(dp);
19170Sstevel@tonic-gate 						__s_api_free2dArray
19185025Siz202018 						    (conf.ns_ppc);
19190Sstevel@tonic-gate 						if (tcp != NULL)
19200Sstevel@tonic-gate 							free(tcp);
19210Sstevel@tonic-gate 						return (NS_LDAP_MEMORY);
19220Sstevel@tonic-gate 					}
19230Sstevel@tonic-gate 					fnd = 1;
19240Sstevel@tonic-gate 					break;
19250Sstevel@tonic-gate 				}
19260Sstevel@tonic-gate 			}
19270Sstevel@tonic-gate 			free(dp);
19280Sstevel@tonic-gate 
19290Sstevel@tonic-gate 			if (fnd)
19300Sstevel@tonic-gate 				break;	/* Replaced completed */
19310Sstevel@tonic-gate 
19320Sstevel@tonic-gate 			/* Append */
19330Sstevel@tonic-gate 			len = ptr->paramList[type].ns_acnt + 1;
19340Sstevel@tonic-gate 			if (len > 1) {
19350Sstevel@tonic-gate 				p = (char **)dupParam(&ptr->paramList[type]);
19360Sstevel@tonic-gate 				if (p == NULL) {
19370Sstevel@tonic-gate 					if (tcp != NULL)
19380Sstevel@tonic-gate 						free(tcp);
19390Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
19400Sstevel@tonic-gate 				}
19410Sstevel@tonic-gate 			} else
19420Sstevel@tonic-gate 				p = NULL;
19430Sstevel@tonic-gate 			conf.ns_ppc =
19445025Siz202018 			    (char **)realloc(p, (len+1) * sizeof (char *));
19450Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
19460Sstevel@tonic-gate 				__s_api_free2dArray(p);
19470Sstevel@tonic-gate 				if (tcp != NULL)
19480Sstevel@tonic-gate 					free(tcp);
19490Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19500Sstevel@tonic-gate 			}
19510Sstevel@tonic-gate 			conf.ns_acnt = len;
19520Sstevel@tonic-gate 			conf.ns_ppc[len-1] = (char *)strdup(cp);
19530Sstevel@tonic-gate 			if (conf.ns_ppc[len-1] == NULL) {
19540Sstevel@tonic-gate 				__s_api_free2dArray(conf.ns_ppc);
19550Sstevel@tonic-gate 				if (tcp != NULL)
19560Sstevel@tonic-gate 					free(tcp);
19570Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19580Sstevel@tonic-gate 			}
19590Sstevel@tonic-gate 			conf.ns_ppc[len] = NULL;
19600Sstevel@tonic-gate 		}
19610Sstevel@tonic-gate 		break;
19620Sstevel@tonic-gate 	case SSDLIST:
19630Sstevel@tonic-gate 		/*
19640Sstevel@tonic-gate 		 * first check to see if colon (:) is there,
19650Sstevel@tonic-gate 		 * if so, make sure the serviceId is specified,
19660Sstevel@tonic-gate 		 * i.e., colon is not the first character
19670Sstevel@tonic-gate 		 */
19680Sstevel@tonic-gate 		if ((strchr(cp, COLONTOK)) == NULL || *cp == COLONTOK) {
19690Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
19705025Siz202018 			    gettext("Unable to set value: "
19715025Siz202018 			    "invalid serviceSearchDescriptor (%s)"),
19725025Siz202018 			    cp);
19730Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
19745025Siz202018 			    strdup(errstr), NULL);
19750Sstevel@tonic-gate 			if (tcp != NULL)
19760Sstevel@tonic-gate 				free(tcp);
19770Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
19780Sstevel@tonic-gate 		}
19790Sstevel@tonic-gate 		/* Appends an entry to the existing list */
19800Sstevel@tonic-gate 		if (ptr->paramList[type].ns_ptype != SSDLIST) {
19810Sstevel@tonic-gate 			conf.ns_ppc = (char **)calloc(2, sizeof (char *));
19820Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
19830Sstevel@tonic-gate 				if (tcp != NULL)
19840Sstevel@tonic-gate 					free(tcp);
19850Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19860Sstevel@tonic-gate 			}
19870Sstevel@tonic-gate 			conf.ns_acnt = 1;
19880Sstevel@tonic-gate 			conf.ns_ppc[0] = (char *)strdup(cp);
19890Sstevel@tonic-gate 			if (conf.ns_ppc[0] == NULL) {
19900Sstevel@tonic-gate 				free(conf.ns_ppc);
19910Sstevel@tonic-gate 				if (tcp != NULL)
19920Sstevel@tonic-gate 					free(tcp);
19930Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
19940Sstevel@tonic-gate 			}
19950Sstevel@tonic-gate 		} else {
19960Sstevel@tonic-gate 			char *dp, *dpend;
19970Sstevel@tonic-gate 			int fnd = 0;
19980Sstevel@tonic-gate 
19990Sstevel@tonic-gate 			/* Attempt to replace if possible */
20000Sstevel@tonic-gate 			dpend = strchr(cp, COLONTOK);
20010Sstevel@tonic-gate 			len = dpend - cp;
20020Sstevel@tonic-gate 			dp = (char *)malloc(len+1);
20030Sstevel@tonic-gate 			if (dp == NULL) {
20040Sstevel@tonic-gate 				if (tcp != NULL)
20050Sstevel@tonic-gate 					free(tcp);
20060Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
20070Sstevel@tonic-gate 			}
20080Sstevel@tonic-gate 			(void) strlcpy(dp, cp, len+1);
20090Sstevel@tonic-gate 			fnd = 0;
20100Sstevel@tonic-gate 			for (j = 0; j < ptr->paramList[type].ns_acnt; j++) {
20110Sstevel@tonic-gate 				dpend = strchr(ptr->paramList[type].ns_ppc[j],
20125025Siz202018 				    COLONTOK);
20130Sstevel@tonic-gate 				if (dpend == NULL)
20140Sstevel@tonic-gate 					continue;
20150Sstevel@tonic-gate 				i = dpend - ptr->paramList[type].ns_ppc[j];
20160Sstevel@tonic-gate 				if (i != len)
20170Sstevel@tonic-gate 					continue;
20180Sstevel@tonic-gate 				if (strncmp(ptr->paramList[type].ns_ppc[j],
20195025Siz202018 				    dp, len) == 0) {
20200Sstevel@tonic-gate 					conf.ns_acnt =
20215025Siz202018 					    ptr->paramList[type].ns_acnt;
20220Sstevel@tonic-gate 					conf.ns_ppc =
20235025Siz202018 					    ptr->paramList[type].ns_ppc;
20240Sstevel@tonic-gate 					ptr->paramList[type].ns_ppc = NULL;
20250Sstevel@tonic-gate 					free(conf.ns_ppc[j]);
20260Sstevel@tonic-gate 					conf.ns_ppc[j] = (char *)strdup(cp);
20270Sstevel@tonic-gate 					if (conf.ns_ppc[j] == NULL) {
20280Sstevel@tonic-gate 						free(dp);
20290Sstevel@tonic-gate 						__s_api_free2dArray
20305025Siz202018 						    (conf.ns_ppc);
20310Sstevel@tonic-gate 						if (tcp != NULL)
20320Sstevel@tonic-gate 							free(tcp);
20330Sstevel@tonic-gate 						return (NS_LDAP_MEMORY);
20340Sstevel@tonic-gate 					}
20350Sstevel@tonic-gate 					fnd = 1;
20360Sstevel@tonic-gate 					break;
20370Sstevel@tonic-gate 				}
20380Sstevel@tonic-gate 			}
20390Sstevel@tonic-gate 			free(dp);
20400Sstevel@tonic-gate 
20410Sstevel@tonic-gate 			if (fnd)
20420Sstevel@tonic-gate 				break;	/* Replaced completed */
20430Sstevel@tonic-gate 
20440Sstevel@tonic-gate 			/* Append */
20450Sstevel@tonic-gate 			len = ptr->paramList[type].ns_acnt + 1;
20460Sstevel@tonic-gate 			if (len > 1) {
20470Sstevel@tonic-gate 				p = (char **)dupParam(&ptr->paramList[type]);
20480Sstevel@tonic-gate 				if (p == NULL) {
20490Sstevel@tonic-gate 					if (tcp != NULL)
20500Sstevel@tonic-gate 						free(tcp);
20510Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
20520Sstevel@tonic-gate 				}
20530Sstevel@tonic-gate 			} else
20540Sstevel@tonic-gate 				p = NULL;
20550Sstevel@tonic-gate 			conf.ns_ppc =
20565025Siz202018 			    (char **)realloc(p, (len+1) * sizeof (char *));
20570Sstevel@tonic-gate 			if (conf.ns_ppc == NULL) {
20580Sstevel@tonic-gate 				__s_api_free2dArray(p);
20590Sstevel@tonic-gate 				if (tcp != NULL)
20600Sstevel@tonic-gate 					free(tcp);
20610Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
20620Sstevel@tonic-gate 			}
20630Sstevel@tonic-gate 			conf.ns_acnt = len;
20640Sstevel@tonic-gate 			conf.ns_ppc[len-1] = (char *)strdup(cp);
20650Sstevel@tonic-gate 			if (conf.ns_ppc[len-1] == NULL) {
20660Sstevel@tonic-gate 				__s_api_free2dArray(conf.ns_ppc);
20670Sstevel@tonic-gate 				if (tcp != NULL)
20680Sstevel@tonic-gate 					free(tcp);
20690Sstevel@tonic-gate 				return (NS_LDAP_MEMORY);
20700Sstevel@tonic-gate 			}
20710Sstevel@tonic-gate 			conf.ns_ppc[len] = NULL;
20720Sstevel@tonic-gate 		}
20730Sstevel@tonic-gate 		break;
20740Sstevel@tonic-gate 	case ARRAYCP:
20750Sstevel@tonic-gate 		len = 0;
20760Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
20770Sstevel@tonic-gate 			if (*cp2 == COMMATOK)
20780Sstevel@tonic-gate 				len++;
20790Sstevel@tonic-gate 		}
20800Sstevel@tonic-gate 		if (cp != cp2)
20810Sstevel@tonic-gate 			len++;
20820Sstevel@tonic-gate 		if (len == 0) {
20830Sstevel@tonic-gate 			conf.ns_ppc = (char **)NULL;
20840Sstevel@tonic-gate 			conf.ns_acnt = 0;
20850Sstevel@tonic-gate 			break;
20860Sstevel@tonic-gate 		}
20870Sstevel@tonic-gate 		conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
20880Sstevel@tonic-gate 		if (conf.ns_ppc == NULL) {
20890Sstevel@tonic-gate 			if (tcp != NULL)
20900Sstevel@tonic-gate 				free(tcp);
20910Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
20920Sstevel@tonic-gate 		}
20930Sstevel@tonic-gate 		conf.ns_acnt = len;
20940Sstevel@tonic-gate 		i = 0;
20950Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
20960Sstevel@tonic-gate 			if (*cp2 == COMMATOK) {
20970Sstevel@tonic-gate 				j = cp2 - cp + 1;
20980Sstevel@tonic-gate 				conf.ns_ppc[i] = (char *)malloc(j + 1);
20990Sstevel@tonic-gate 				if (conf.ns_ppc[i] == NULL) {
21000Sstevel@tonic-gate 					__s_api_free2dArray(conf.ns_ppc);
21010Sstevel@tonic-gate 					if (tcp != NULL)
21020Sstevel@tonic-gate 						free(tcp);
21030Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
21040Sstevel@tonic-gate 				}
21050Sstevel@tonic-gate 				(void) strlcpy(conf.ns_ppc[i], cp, j);
21060Sstevel@tonic-gate 				cp = cp2+1;
21070Sstevel@tonic-gate 				while (*cp == SPACETOK || *cp == COMMATOK)
21080Sstevel@tonic-gate 					cp++;
21090Sstevel@tonic-gate 				cp2 = cp - 1;
21100Sstevel@tonic-gate 				i++;
21110Sstevel@tonic-gate 			}
21120Sstevel@tonic-gate 		}
21130Sstevel@tonic-gate 		j = cp2 - cp + 1;
21140Sstevel@tonic-gate 		conf.ns_ppc[i] = (char *)malloc(j + 1);
21150Sstevel@tonic-gate 		if (conf.ns_ppc[i] == NULL) {
21160Sstevel@tonic-gate 			__s_api_free2dArray(conf.ns_ppc);
21170Sstevel@tonic-gate 			if (tcp != NULL)
21180Sstevel@tonic-gate 				free(tcp);
21190Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
21200Sstevel@tonic-gate 		}
21210Sstevel@tonic-gate 		(void) strlcpy(conf.ns_ppc[i], cp, j);
21220Sstevel@tonic-gate 		break;
21230Sstevel@tonic-gate 	case SERVLIST:
21240Sstevel@tonic-gate 		len = 0;
21250Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
21260Sstevel@tonic-gate 			if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
21270Sstevel@tonic-gate 				len++;
21280Sstevel@tonic-gate 				for (; *(cp2 + 1) == SPACETOK ||
21295025Siz202018 				    *(cp2 +1) == COMMATOK; cp2++)
21300Sstevel@tonic-gate 					;
21310Sstevel@tonic-gate 			}
21320Sstevel@tonic-gate 		}
21330Sstevel@tonic-gate 		if (cp != cp2)
21340Sstevel@tonic-gate 			len++;
21350Sstevel@tonic-gate 		if (len == 0) {
21360Sstevel@tonic-gate 			conf.ns_ppc = (char **)NULL;
21370Sstevel@tonic-gate 			conf.ns_acnt = 0;
21380Sstevel@tonic-gate 			break;
21390Sstevel@tonic-gate 		}
21400Sstevel@tonic-gate 		conf.ns_ppc = (char **)calloc(len + 1, sizeof (char *));
21410Sstevel@tonic-gate 		if (conf.ns_ppc == NULL) {
21420Sstevel@tonic-gate 			if (tcp != NULL)
21430Sstevel@tonic-gate 				free(tcp);
21440Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
21450Sstevel@tonic-gate 		}
21460Sstevel@tonic-gate 		conf.ns_acnt = len;
21470Sstevel@tonic-gate 		i = 0;
21480Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
21490Sstevel@tonic-gate 			if (*cp2 == SPACETOK || *cp2 == COMMATOK) {
21500Sstevel@tonic-gate 				j = cp2 - cp + 1;
21510Sstevel@tonic-gate 				conf.ns_ppc[i] = (char *)malloc(j + 1);
21520Sstevel@tonic-gate 				if (conf.ns_ppc[i] == NULL) {
21530Sstevel@tonic-gate 					__s_api_free2dArray(conf.ns_ppc);
21540Sstevel@tonic-gate 					if (tcp != NULL)
21550Sstevel@tonic-gate 						free(tcp);
21560Sstevel@tonic-gate 					return (NS_LDAP_MEMORY);
21570Sstevel@tonic-gate 				}
21580Sstevel@tonic-gate 				(void) strlcpy(conf.ns_ppc[i], cp, j);
21590Sstevel@tonic-gate 				cp = cp2+1;
21600Sstevel@tonic-gate 				while (*cp == SPACETOK || *cp == COMMATOK)
21610Sstevel@tonic-gate 					cp++;
21620Sstevel@tonic-gate 				cp2 = cp - 1;
21630Sstevel@tonic-gate 				i++;
21640Sstevel@tonic-gate 			}
21650Sstevel@tonic-gate 		}
21660Sstevel@tonic-gate 		j = cp2 - cp + 1;
21670Sstevel@tonic-gate 		conf.ns_ppc[i] = (char *)malloc(j + 1);
21680Sstevel@tonic-gate 		if (conf.ns_ppc[i] == NULL) {
21690Sstevel@tonic-gate 			__s_api_free2dArray(conf.ns_ppc);
21700Sstevel@tonic-gate 			if (tcp != NULL)
21710Sstevel@tonic-gate 				free(tcp);
21720Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
21730Sstevel@tonic-gate 		}
21740Sstevel@tonic-gate 		(void) strlcpy(conf.ns_ppc[i], cp, j);
21750Sstevel@tonic-gate 		break;
21760Sstevel@tonic-gate 	case ARRAYAUTH:
21770Sstevel@tonic-gate 		len = 0;
21780Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
21790Sstevel@tonic-gate 			if (*cp2 == SEMITOK || *cp2 == COMMATOK)
21800Sstevel@tonic-gate 				len++;
21810Sstevel@tonic-gate 		}
21820Sstevel@tonic-gate 		if (cp != cp2)
21830Sstevel@tonic-gate 			len++;
21840Sstevel@tonic-gate 		if (len == 0) {
21850Sstevel@tonic-gate 			conf.ns_pi = (int *)NULL;
21860Sstevel@tonic-gate 			conf.ns_acnt = 0;
21870Sstevel@tonic-gate 			break;
21880Sstevel@tonic-gate 		}
21890Sstevel@tonic-gate 		conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
21900Sstevel@tonic-gate 		if (conf.ns_pi == NULL) {
21910Sstevel@tonic-gate 			if (tcp != NULL)
21920Sstevel@tonic-gate 				free(tcp);
21930Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
21940Sstevel@tonic-gate 		}
21950Sstevel@tonic-gate 		conf.ns_acnt = len;
21960Sstevel@tonic-gate 		i = 0;
21970Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
21980Sstevel@tonic-gate 			if (*cp2 == SEMITOK || *cp2 == COMMATOK) {
21990Sstevel@tonic-gate 				j = cp2 - cp + 1;
22000Sstevel@tonic-gate 				if (j > sizeof (tbuf)) {
22010Sstevel@tonic-gate 					j = -1;
22020Sstevel@tonic-gate 					ptbuf = cp;
22030Sstevel@tonic-gate 				} else {
22040Sstevel@tonic-gate 					(void) strlcpy(tbuf, cp, j);
22050Sstevel@tonic-gate 					j = __s_get_enum_value(ptr, tbuf,
22065025Siz202018 					    def->index);
22070Sstevel@tonic-gate 					ptbuf = tbuf;
22080Sstevel@tonic-gate 				}
22090Sstevel@tonic-gate 				if (j < 0) {
22100Sstevel@tonic-gate 					(void) snprintf(errstr, sizeof (errstr),
22115025Siz202018 					    gettext("Unable to set value: "
22125025Siz202018 					    "invalid "
22135025Siz202018 					    "authenticationMethod (%s)"),
22145025Siz202018 					    ptbuf);
22150Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
22165025Siz202018 					    NS_CONFIG_SYNTAX,
22175025Siz202018 					    strdup(errstr), NULL);
22180Sstevel@tonic-gate 					free(conf.ns_pi);
22190Sstevel@tonic-gate 					if (tcp != NULL)
22200Sstevel@tonic-gate 						free(tcp);
22210Sstevel@tonic-gate 					return (NS_LDAP_CONFIG);
22220Sstevel@tonic-gate 				}
22230Sstevel@tonic-gate 				conf.ns_pi[i] = j;
22240Sstevel@tonic-gate 				cp = cp2+1;
22250Sstevel@tonic-gate 				i++;
22260Sstevel@tonic-gate 			}
22270Sstevel@tonic-gate 		}
22280Sstevel@tonic-gate 		j = cp2 - cp + 1;
22290Sstevel@tonic-gate 		if (j > sizeof (tbuf)) {
22300Sstevel@tonic-gate 			j = -1;
22310Sstevel@tonic-gate 			ptbuf = cp;
22320Sstevel@tonic-gate 		} else {
22330Sstevel@tonic-gate 			(void) strlcpy(tbuf, cp, j);
22340Sstevel@tonic-gate 			j = __s_get_enum_value(ptr, tbuf, def->index);
22350Sstevel@tonic-gate 			ptbuf = tbuf;
22360Sstevel@tonic-gate 		}
22370Sstevel@tonic-gate 		if (j < 0) {
22380Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
22395025Siz202018 			    gettext("Unable to set value: "
22405025Siz202018 			    "invalid authenticationMethod (%s)"), ptbuf);
22410Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
22425025Siz202018 			    strdup(errstr), NULL);
22430Sstevel@tonic-gate 			if (tcp != NULL)
22440Sstevel@tonic-gate 				free(tcp);
22450Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
22460Sstevel@tonic-gate 		}
22470Sstevel@tonic-gate 		conf.ns_pi[i] = j;
22480Sstevel@tonic-gate 		break;
22490Sstevel@tonic-gate 	case ARRAYCRED:
22500Sstevel@tonic-gate 		len = 0;
22510Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
22520Sstevel@tonic-gate 			if (*cp2 == SPACETOK)
22530Sstevel@tonic-gate 				len++;
22540Sstevel@tonic-gate 		}
22550Sstevel@tonic-gate 		if (cp != cp2)
22560Sstevel@tonic-gate 			len++;
22570Sstevel@tonic-gate 		if (len == 0) {
22580Sstevel@tonic-gate 			conf.ns_pi = (int *)NULL;
22590Sstevel@tonic-gate 			conf.ns_acnt = 0;
22600Sstevel@tonic-gate 			break;
22610Sstevel@tonic-gate 		}
22620Sstevel@tonic-gate 		conf.ns_pi = (int *)calloc(len + 1, sizeof (int));
22630Sstevel@tonic-gate 		if (conf.ns_pi == NULL) {
22640Sstevel@tonic-gate 			if (tcp != NULL)
22650Sstevel@tonic-gate 				free(tcp);
22660Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
22670Sstevel@tonic-gate 		}
22680Sstevel@tonic-gate 		conf.ns_acnt = len;
22690Sstevel@tonic-gate 		i = 0;
22700Sstevel@tonic-gate 		for (cp2 = cp; *cp2; cp2++) {
22710Sstevel@tonic-gate 			if (*cp2 == SPACETOK) {
22720Sstevel@tonic-gate 				j = cp2 - cp + 1;
22730Sstevel@tonic-gate 				if (j > sizeof (tbuf)) {
22740Sstevel@tonic-gate 					j = -1;
22750Sstevel@tonic-gate 					ptbuf = cp;
22760Sstevel@tonic-gate 				} else {
22770Sstevel@tonic-gate 					(void) strlcpy(tbuf, cp, j);
22780Sstevel@tonic-gate 					j = __s_get_enum_value(ptr, tbuf,
22795025Siz202018 					    def->index);
22800Sstevel@tonic-gate 					ptbuf = tbuf;
22810Sstevel@tonic-gate 				}
22820Sstevel@tonic-gate 				if (j < 0) {
22830Sstevel@tonic-gate 					(void) snprintf(errstr, sizeof (errstr),
22845025Siz202018 					    gettext("Unable to set value: "
22855025Siz202018 					    "invalid credentialLevel (%s)"),
22865025Siz202018 					    ptbuf);
22870Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
22885025Siz202018 					    NS_CONFIG_SYNTAX,
22895025Siz202018 					    strdup(errstr), NULL);
22900Sstevel@tonic-gate 					free(conf.ns_pi);
22910Sstevel@tonic-gate 					if (tcp != NULL)
22920Sstevel@tonic-gate 						free(tcp);
22930Sstevel@tonic-gate 					return (NS_LDAP_CONFIG);
22940Sstevel@tonic-gate 				}
22950Sstevel@tonic-gate 				conf.ns_pi[i] = j;
22960Sstevel@tonic-gate 				cp = cp2+1;
22970Sstevel@tonic-gate 				i++;
22980Sstevel@tonic-gate 			}
22990Sstevel@tonic-gate 		}
23000Sstevel@tonic-gate 		j = cp2 - cp + 1;
23010Sstevel@tonic-gate 		if (j > sizeof (tbuf)) {
23020Sstevel@tonic-gate 			j = -1;
23030Sstevel@tonic-gate 			ptbuf = cp;
23040Sstevel@tonic-gate 		} else {
23050Sstevel@tonic-gate 			(void) strlcpy(tbuf, cp, j);
23060Sstevel@tonic-gate 			j = __s_get_enum_value(ptr, tbuf, def->index);
23070Sstevel@tonic-gate 			ptbuf = tbuf;
23080Sstevel@tonic-gate 		}
23090Sstevel@tonic-gate 		if (j < 0) {
23100Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
23115025Siz202018 			    gettext("Unable to set value: "
23125025Siz202018 			    "invalid credentialLevel (%s)"), ptbuf);
23130Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
23145025Siz202018 			    strdup(errstr), NULL);
23150Sstevel@tonic-gate 			if (tcp != NULL)
23160Sstevel@tonic-gate 				free(tcp);
23170Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
23180Sstevel@tonic-gate 		}
23190Sstevel@tonic-gate 		conf.ns_pi[i] = j;
23200Sstevel@tonic-gate 		break;
23210Sstevel@tonic-gate 	case ATTRMAP:
23220Sstevel@tonic-gate 	case OBJMAP:
23230Sstevel@tonic-gate 		i = __s_api_parse_map(cp, &sid, &origA, &mapA);
23240Sstevel@tonic-gate 		if (i != NS_HASH_RC_SUCCESS) {
23250Sstevel@tonic-gate 			if (i == NS_HASH_RC_NO_MEMORY) {
23260Sstevel@tonic-gate 				exitrc = NS_LDAP_MEMORY;
23270Sstevel@tonic-gate 			} else {
23280Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
23290Sstevel@tonic-gate 				gettext("Unable to set value: "
23300Sstevel@tonic-gate 				"invalid schema mapping (%s)"), cp);
23310Sstevel@tonic-gate 				exitrc = NS_LDAP_CONFIG;
23320Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
23335025Siz202018 				    strdup(errstr), NULL);
23340Sstevel@tonic-gate 			}
23350Sstevel@tonic-gate 			if (tcp)
23360Sstevel@tonic-gate 				free(tcp);
23370Sstevel@tonic-gate 			return (exitrc);
23380Sstevel@tonic-gate 		}
23390Sstevel@tonic-gate 
23400Sstevel@tonic-gate 		/*
23410Sstevel@tonic-gate 		 * Add reverse map first.
23420Sstevel@tonic-gate 		 * There could be more than one.
23430Sstevel@tonic-gate 		 */
23440Sstevel@tonic-gate 		for (attr = mapA; *attr; attr++) {
23450Sstevel@tonic-gate 
23460Sstevel@tonic-gate 			free_memory = 1;
23470Sstevel@tonic-gate 			exitrc = NS_LDAP_MEMORY;
23480Sstevel@tonic-gate 
23490Sstevel@tonic-gate 			rmap = (ns_mapping_t *)calloc(1,
23505025Siz202018 			    sizeof (ns_mapping_t));
23510Sstevel@tonic-gate 			if (rmap) {
23520Sstevel@tonic-gate 				rmap->service = strdup(sid);
23530Sstevel@tonic-gate 				if (rmap->service) {
23540Sstevel@tonic-gate 					rmap->orig = strdup(*attr);
23550Sstevel@tonic-gate 					if (rmap->orig) {
23560Sstevel@tonic-gate 						rmap->map = (char **)calloc(2,
23575025Siz202018 						    sizeof (char *));
23580Sstevel@tonic-gate 						if (rmap->map) {
23590Sstevel@tonic-gate 							(rmap->map)[0] =
23605025Siz202018 							    strdup(origA);
23610Sstevel@tonic-gate 							if ((rmap->map)[0])
23620Sstevel@tonic-gate 								free_memory = 0;
23630Sstevel@tonic-gate 						}
23640Sstevel@tonic-gate 					}
23650Sstevel@tonic-gate 				}
23660Sstevel@tonic-gate 			}
23670Sstevel@tonic-gate 
23680Sstevel@tonic-gate 			if (free_memory == 0) {
23690Sstevel@tonic-gate 				if (def->data_type == ATTRMAP) {
23700Sstevel@tonic-gate 					rmap->type = NS_ATTR_MAP;
23710Sstevel@tonic-gate 					i = __s_api_add_map2hash(ptr,
23725025Siz202018 					    NS_HASH_RAMAP, rmap);
23730Sstevel@tonic-gate 				} else {
23740Sstevel@tonic-gate 					rmap->type = NS_OBJ_MAP;
23750Sstevel@tonic-gate 					i = __s_api_add_map2hash(ptr,
23765025Siz202018 					    NS_HASH_ROMAP, rmap);
23770Sstevel@tonic-gate 				}
23780Sstevel@tonic-gate 
23790Sstevel@tonic-gate 				if (i != NS_HASH_RC_SUCCESS) {
23800Sstevel@tonic-gate 					switch (i) {
23810Sstevel@tonic-gate 					case NS_HASH_RC_CONFIG_ERROR:
23820Sstevel@tonic-gate 						exitrc = NS_LDAP_INTERNAL;
23830Sstevel@tonic-gate 						(void) snprintf(errstr,
23845025Siz202018 						    sizeof (errstr),
23855025Siz202018 						    gettext(
23865025Siz202018 						    "Unable to set value: "
23875025Siz202018 						    "no configuration info "
23885025Siz202018 						    "for schema map "
23895025Siz202018 						    "update (%s)"), cp);
23900Sstevel@tonic-gate 						MKERROR(LOG_ERR, *error,
23915025Siz202018 						    NS_LDAP_INTERNAL,
23925025Siz202018 						    strdup(errstr),
23935025Siz202018 						    NULL);
23940Sstevel@tonic-gate 						break;
23950Sstevel@tonic-gate 					case NS_HASH_RC_EXISTED:
23960Sstevel@tonic-gate 						exitrc = NS_LDAP_CONFIG;
23970Sstevel@tonic-gate 						(void) snprintf(errstr,
23985025Siz202018 						    sizeof (errstr),
23995025Siz202018 						    gettext(
24005025Siz202018 						    "Unable to set value: "
24015025Siz202018 						    "schema map "
24025025Siz202018 						    "already existed for "
24035025Siz202018 						    "(%s, %s)."),
24045025Siz202018 						    *attr, origA);
24050Sstevel@tonic-gate 						MKERROR(LOG_ERR, *error,
24065025Siz202018 						    NS_CONFIG_SYNTAX,
24075025Siz202018 						    strdup(errstr),
24085025Siz202018 						    NULL);
24090Sstevel@tonic-gate 						break;
24100Sstevel@tonic-gate 					case NS_HASH_RC_NO_MEMORY:
24110Sstevel@tonic-gate 						exitrc = NS_LDAP_MEMORY;
24120Sstevel@tonic-gate 						break;
24130Sstevel@tonic-gate 					}
24140Sstevel@tonic-gate 					free_memory = 1;
24150Sstevel@tonic-gate 				}
24160Sstevel@tonic-gate 			}
24170Sstevel@tonic-gate 
24180Sstevel@tonic-gate 			if (free_memory) {
24190Sstevel@tonic-gate 				if (tcp)
24200Sstevel@tonic-gate 					free(tcp);
24210Sstevel@tonic-gate 				free(sid);
24220Sstevel@tonic-gate 				free(origA);
24230Sstevel@tonic-gate 				__s_api_free2dArray(mapA);
24240Sstevel@tonic-gate 				if (rmap) {
24250Sstevel@tonic-gate 					if (rmap->service)
24260Sstevel@tonic-gate 						free(rmap->service);
24270Sstevel@tonic-gate 					if (rmap->orig)
24280Sstevel@tonic-gate 						free(rmap->orig);
24290Sstevel@tonic-gate 					if (rmap->map) {
24300Sstevel@tonic-gate 						if ((rmap->map)[0])
24310Sstevel@tonic-gate 							free((rmap->map)[0]);
24320Sstevel@tonic-gate 						free(rmap->map);
24330Sstevel@tonic-gate 					}
24340Sstevel@tonic-gate 					free(rmap);
24350Sstevel@tonic-gate 				}
24360Sstevel@tonic-gate 				return (exitrc);
24370Sstevel@tonic-gate 			}
24380Sstevel@tonic-gate 		}
24390Sstevel@tonic-gate 
24400Sstevel@tonic-gate 		/*
24410Sstevel@tonic-gate 		 * For performance gain,
24420Sstevel@tonic-gate 		 * add a "schema mapping existed" indicator
24430Sstevel@tonic-gate 		 * for the given service if not already added.
24440Sstevel@tonic-gate 		 * This dummy map needs not be removed, if
24450Sstevel@tonic-gate 		 * the next real map add operation fails.
24460Sstevel@tonic-gate 		 * since the caller, e.g. ldap_cachemgr.
24470Sstevel@tonic-gate 		 * should exit anyway.
24480Sstevel@tonic-gate 		 */
24490Sstevel@tonic-gate 		free_memory = 1;
24500Sstevel@tonic-gate 		exitrc = NS_LDAP_MEMORY;
24510Sstevel@tonic-gate 
24520Sstevel@tonic-gate 		map = (ns_mapping_t *)calloc(1,
24535025Siz202018 		    sizeof (ns_mapping_t));
24540Sstevel@tonic-gate 		if (map) {
24550Sstevel@tonic-gate 			map->service = strdup(sid);
24560Sstevel@tonic-gate 			if (map->service) {
24570Sstevel@tonic-gate 				map->orig = strdup(
24585025Siz202018 				    NS_HASH_SCHEMA_MAPPING_EXISTED);
24590Sstevel@tonic-gate 				if (map->orig) {
24600Sstevel@tonic-gate 					map->map = (char **)calloc(2,
24615025Siz202018 					    sizeof (char *));
24620Sstevel@tonic-gate 					if (map->map) {
24630Sstevel@tonic-gate 						(map->map)[0] =
24645025Siz202018 						    strdup(sid);
24650Sstevel@tonic-gate 						if ((map->map)[0])
24660Sstevel@tonic-gate 							free_memory = 0;
24670Sstevel@tonic-gate 					}
24680Sstevel@tonic-gate 				}
24690Sstevel@tonic-gate 			}
24700Sstevel@tonic-gate 		}
24710Sstevel@tonic-gate 
24720Sstevel@tonic-gate 		if (free_memory == 0) {
24730Sstevel@tonic-gate 			map->type = NS_ATTR_MAP;
24740Sstevel@tonic-gate 			/*
24750Sstevel@tonic-gate 			 * add to reverse map,
24760Sstevel@tonic-gate 			 * so that "ldapclient list"
24770Sstevel@tonic-gate 			 * would not show it
24780Sstevel@tonic-gate 			 */
24790Sstevel@tonic-gate 			i = __s_api_add_map2hash(ptr,
24805025Siz202018 			    NS_HASH_RAMAP, map);
24810Sstevel@tonic-gate 
24820Sstevel@tonic-gate 			/*
24830Sstevel@tonic-gate 			 * ignore "map already existed" error,
24840Sstevel@tonic-gate 			 * just need one per service.
24850Sstevel@tonic-gate 			 * Need however to free memory allocated
24860Sstevel@tonic-gate 			 * for map.
24870Sstevel@tonic-gate 			 */
24880Sstevel@tonic-gate 			if (i != NS_HASH_RC_SUCCESS &&
24895025Siz202018 			    i != NS_HASH_RC_EXISTED) {
24900Sstevel@tonic-gate 				switch (i) {
24910Sstevel@tonic-gate 				case NS_HASH_RC_CONFIG_ERROR:
24920Sstevel@tonic-gate 					exitrc = NS_LDAP_INTERNAL;
24930Sstevel@tonic-gate 					(void) snprintf(errstr,
24945025Siz202018 					    sizeof (errstr),
24955025Siz202018 					    gettext(
24965025Siz202018 					    "Unable to set value: "
24975025Siz202018 					    "no configuration info "
24985025Siz202018 					    "for schema map "
24995025Siz202018 					    "update (%s)"), cp);
25000Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
25015025Siz202018 					    NS_LDAP_INTERNAL,
25025025Siz202018 					    strdup(errstr),
25035025Siz202018 					    NULL);
25040Sstevel@tonic-gate 					break;
25050Sstevel@tonic-gate 				case NS_HASH_RC_NO_MEMORY:
25060Sstevel@tonic-gate 					exitrc = NS_LDAP_MEMORY;
25070Sstevel@tonic-gate 					break;
25080Sstevel@tonic-gate 				}
25090Sstevel@tonic-gate 				free_memory = 1;
25100Sstevel@tonic-gate 			} else if (i == NS_HASH_RC_EXISTED) {
25110Sstevel@tonic-gate 				if (map->service)
25120Sstevel@tonic-gate 					free(map->service);
25130Sstevel@tonic-gate 				if (map->orig)
25140Sstevel@tonic-gate 					free(map->orig);
25150Sstevel@tonic-gate 				if (map->map) {
25160Sstevel@tonic-gate 					if ((map->map)[0])
25170Sstevel@tonic-gate 						free((map->map)[0]);
25180Sstevel@tonic-gate 					free(map->map);
25190Sstevel@tonic-gate 				}
25200Sstevel@tonic-gate 				free(map);
25210Sstevel@tonic-gate 				map = NULL;
25220Sstevel@tonic-gate 			}
25230Sstevel@tonic-gate 		}
25240Sstevel@tonic-gate 
25250Sstevel@tonic-gate 		if (free_memory) {
25260Sstevel@tonic-gate 			if (tcp)
25270Sstevel@tonic-gate 				free(tcp);
25280Sstevel@tonic-gate 			free(sid);
25290Sstevel@tonic-gate 			free(origA);
25300Sstevel@tonic-gate 			__s_api_free2dArray(mapA);
25310Sstevel@tonic-gate 			if (map) {
25320Sstevel@tonic-gate 				if (map->service)
25330Sstevel@tonic-gate 					free(map->service);
25340Sstevel@tonic-gate 				if (map->orig)
25350Sstevel@tonic-gate 					free(map->orig);
25360Sstevel@tonic-gate 				if (map->map) {
25370Sstevel@tonic-gate 					if ((map->map)[0])
25380Sstevel@tonic-gate 						free((map->map)[0]);
25390Sstevel@tonic-gate 					free(map->map);
25400Sstevel@tonic-gate 				}
25410Sstevel@tonic-gate 				free(map);
25420Sstevel@tonic-gate 			}
25430Sstevel@tonic-gate 			return (exitrc);
25440Sstevel@tonic-gate 		}
25450Sstevel@tonic-gate 
25460Sstevel@tonic-gate 		/*
25470Sstevel@tonic-gate 		 * add the real schema map
25480Sstevel@tonic-gate 		 */
25490Sstevel@tonic-gate 		free_memory = 1;
25500Sstevel@tonic-gate 		exitrc = NS_LDAP_MEMORY;
25510Sstevel@tonic-gate 		map = (ns_mapping_t *)calloc(1, sizeof (ns_mapping_t));
25520Sstevel@tonic-gate 		if (map) {
25530Sstevel@tonic-gate 			map->service = sid;
25540Sstevel@tonic-gate 			map->orig = origA;
25550Sstevel@tonic-gate 			map->map = mapA;
25560Sstevel@tonic-gate 
25570Sstevel@tonic-gate 			if (def->data_type == ATTRMAP) {
25580Sstevel@tonic-gate 				map->type = NS_ATTR_MAP;
25590Sstevel@tonic-gate 				i = __s_api_add_map2hash(ptr,
25605025Siz202018 				    NS_HASH_AMAP, map);
25610Sstevel@tonic-gate 			} else {
25620Sstevel@tonic-gate 				map->type = NS_OBJ_MAP;
25630Sstevel@tonic-gate 				i = __s_api_add_map2hash(ptr,
25645025Siz202018 				    NS_HASH_OMAP, map);
25650Sstevel@tonic-gate 			}
25660Sstevel@tonic-gate 
25670Sstevel@tonic-gate 			if (i != NS_HASH_RC_SUCCESS) {
25680Sstevel@tonic-gate 				switch (i) {
25690Sstevel@tonic-gate 				case NS_HASH_RC_CONFIG_ERROR:
25700Sstevel@tonic-gate 					exitrc = NS_LDAP_INTERNAL;
25710Sstevel@tonic-gate 					(void) snprintf(errstr,
25725025Siz202018 					    sizeof (errstr),
25735025Siz202018 					    gettext(
25745025Siz202018 					    "Unable to set value: "
25755025Siz202018 					    "no configuration info "
25765025Siz202018 					    "for schema map "
25775025Siz202018 					    "update (%s)"), cp);
25780Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
25795025Siz202018 					    NS_LDAP_INTERNAL,
25805025Siz202018 					    strdup(errstr),
25815025Siz202018 					    NULL);
25820Sstevel@tonic-gate 					break;
25830Sstevel@tonic-gate 				case NS_HASH_RC_EXISTED:
25840Sstevel@tonic-gate 					exitrc = NS_LDAP_CONFIG;
25850Sstevel@tonic-gate 					(void) snprintf(errstr,
25865025Siz202018 					    sizeof (errstr),
25875025Siz202018 					    gettext(
25885025Siz202018 					    "Unable to set value: "
25895025Siz202018 					    "schema map "
25905025Siz202018 					    "already existed for "
25915025Siz202018 					    "'%s'."), origA);
25920Sstevel@tonic-gate 					MKERROR(LOG_ERR, *error,
25935025Siz202018 					    NS_CONFIG_SYNTAX,
25945025Siz202018 					    strdup(errstr),
25955025Siz202018 					    NULL);
25960Sstevel@tonic-gate 					break;
25970Sstevel@tonic-gate 				case NS_HASH_RC_NO_MEMORY:
25980Sstevel@tonic-gate 					exitrc = NS_LDAP_MEMORY;
25990Sstevel@tonic-gate 					break;
26000Sstevel@tonic-gate 				}
26010Sstevel@tonic-gate 				free_memory = 1;
26020Sstevel@tonic-gate 			} else
26030Sstevel@tonic-gate 				free_memory = 0;
26040Sstevel@tonic-gate 		}
26050Sstevel@tonic-gate 
26060Sstevel@tonic-gate 		if (free_memory) {
26070Sstevel@tonic-gate 			if (tcp)
26080Sstevel@tonic-gate 				free(tcp);
26090Sstevel@tonic-gate 			free(sid);
26100Sstevel@tonic-gate 			free(origA);
26110Sstevel@tonic-gate 			__s_api_free2dArray(mapA);
26120Sstevel@tonic-gate 			if (map)
26130Sstevel@tonic-gate 				free(map);
26140Sstevel@tonic-gate 			return (exitrc);
26150Sstevel@tonic-gate 		}
26160Sstevel@tonic-gate 
26170Sstevel@tonic-gate 		break;
26180Sstevel@tonic-gate 	default:
26190Sstevel@tonic-gate 		/* This should never happen. */
26200Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
26215025Siz202018 		    gettext("Unable to set value: invalid configuration "
26225025Siz202018 		    "type (%d)"), def->data_type);
26230Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
26245025Siz202018 		    NULL);
26250Sstevel@tonic-gate 		if (tcp != NULL)
26260Sstevel@tonic-gate 			free(tcp);
26270Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
26280Sstevel@tonic-gate 	}
26290Sstevel@tonic-gate 	conf.ns_ptype = def->data_type;
26300Sstevel@tonic-gate 	if (tcp != NULL)
26310Sstevel@tonic-gate 		free(tcp);
26320Sstevel@tonic-gate 
26330Sstevel@tonic-gate 	/* Individually written verify routines here can replace */
26340Sstevel@tonic-gate 	/* verify_value.  Verify conf (data) as appropriate here */
26350Sstevel@tonic-gate 	if (def->ns_verify != NULL) {
26360Sstevel@tonic-gate 		if ((*def->ns_verify)(type, def, &conf, errstr) != NS_SUCCESS) {
26370Sstevel@tonic-gate 			ns_param_t sav_conf;
26380Sstevel@tonic-gate 
26390Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
26405025Siz202018 			    gettext("%s"), errstr);
26410Sstevel@tonic-gate 			MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX,
26425025Siz202018 			    strdup(errstr), NULL);
26430Sstevel@tonic-gate 
26440Sstevel@tonic-gate 			sav_conf = ptr->paramList[type];
26450Sstevel@tonic-gate 			ptr->paramList[type] = conf;
26460Sstevel@tonic-gate 			destroy_param(ptr, type);
26470Sstevel@tonic-gate 			ptr->paramList[type] = sav_conf;
26480Sstevel@tonic-gate 
26490Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
26500Sstevel@tonic-gate 		}
26510Sstevel@tonic-gate 	}
26520Sstevel@tonic-gate 
26530Sstevel@tonic-gate 	/* post evaluate the data */
26540Sstevel@tonic-gate 
26550Sstevel@tonic-gate 	/*
26560Sstevel@tonic-gate 	 * if this is for setting a password,
26570Sstevel@tonic-gate 	 * encrypt the password first.
26580Sstevel@tonic-gate 	 * NOTE evalue() is smart and will just return
26590Sstevel@tonic-gate 	 * the value passed if it is already encrypted.
26600Sstevel@tonic-gate 	 *
26610Sstevel@tonic-gate 	 * Init NS_LDAP_EXP_P here when CACHETTL is updated
26620Sstevel@tonic-gate 	 */
26638821SMichen.Chang@Sun.COM 	if (type == NS_LDAP_BINDPASSWD_P ||
26648821SMichen.Chang@Sun.COM 	    type == NS_LDAP_ADMIN_BINDPASSWD_P) {
26650Sstevel@tonic-gate 		cp = conf.ns_pc;
26660Sstevel@tonic-gate 		cp2 = evalue((char *)cp);
26670Sstevel@tonic-gate 		conf.ns_pc = cp2;
26680Sstevel@tonic-gate 		free(cp);
26690Sstevel@tonic-gate 		cp = NULL;
26700Sstevel@tonic-gate 	} else if (type == NS_LDAP_FILE_VERSION_P) {
26710Sstevel@tonic-gate 		ptr->version = NS_LDAP_V1;
26720Sstevel@tonic-gate 		if (strcasecmp(conf.ns_pc, NS_LDAP_VERSION_2) == 0) {
26730Sstevel@tonic-gate 			ptr->version = NS_LDAP_V2;
26740Sstevel@tonic-gate 		}
26750Sstevel@tonic-gate 	} else if (type == NS_LDAP_CACHETTL_P) {
26760Sstevel@tonic-gate 		cp = conf.ns_pc;
26770Sstevel@tonic-gate 		tm = conv_time(cp);
26780Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_ptype = TIMET;
26790Sstevel@tonic-gate 		if (tm != 0) {
26800Sstevel@tonic-gate 			tm += time(NULL);
26810Sstevel@tonic-gate 		}
26820Sstevel@tonic-gate 		ptr->paramList[NS_LDAP_EXP_P].ns_tm = tm;
26830Sstevel@tonic-gate 	}
26840Sstevel@tonic-gate 
26850Sstevel@tonic-gate 	/* Everything checks out move new values into param */
26860Sstevel@tonic-gate 	destroy_param(ptr, type);
26870Sstevel@tonic-gate 	/* Assign new/updated value into paramList */
26880Sstevel@tonic-gate 	ptr->paramList[type] = conf;
26890Sstevel@tonic-gate 
26900Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
26910Sstevel@tonic-gate }
26920Sstevel@tonic-gate 
26930Sstevel@tonic-gate 
26940Sstevel@tonic-gate /*
26950Sstevel@tonic-gate  * Set a parameter value in the 'config' configuration structure
26960Sstevel@tonic-gate  * Lock as appropriate
26970Sstevel@tonic-gate  */
26980Sstevel@tonic-gate 
26990Sstevel@tonic-gate int
__ns_ldap_setParam(const ParamIndexType type,const void * data,ns_ldap_error_t ** error)27000Sstevel@tonic-gate __ns_ldap_setParam(const ParamIndexType type,
27010Sstevel@tonic-gate 		const void *data, ns_ldap_error_t **error)
27020Sstevel@tonic-gate {
27030Sstevel@tonic-gate 	ns_ldap_error_t		*errorp;
27040Sstevel@tonic-gate 	int			ret;
27050Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
27060Sstevel@tonic-gate 	ns_config_t		*cfg;
27076842Sth160488 	ns_config_t		*cfg_g = (ns_config_t *)-1;
27080Sstevel@tonic-gate 	ns_config_t		*new_cfg;
27096842Sth160488 	boolean_t		reinit_connmgmt = B_FALSE;
27100Sstevel@tonic-gate 
27110Sstevel@tonic-gate 	/* We want to refresh only one configuration at a time */
27120Sstevel@tonic-gate 	(void) mutex_lock(&ns_loadrefresh_lock);
27130Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
27140Sstevel@tonic-gate 
27150Sstevel@tonic-gate 	if (cache_server == TRUE) {
27160Sstevel@tonic-gate 		if (cfg == NULL) {
27175025Siz202018 			__ns_ldap_default_config();
27185025Siz202018 			cfg = __s_api_get_default_config();
27195025Siz202018 			if (cfg == NULL) {
27205025Siz202018 				(void) mutex_unlock(&ns_loadrefresh_lock);
27215025Siz202018 				return (NS_LDAP_MEMORY);
27225025Siz202018 			}
27230Sstevel@tonic-gate 		}
27240Sstevel@tonic-gate 	} else {
27250Sstevel@tonic-gate 		/*
27260Sstevel@tonic-gate 		 * This code always return error here on client side,
27270Sstevel@tonic-gate 		 * this needs to change once libsldap is used by more
27280Sstevel@tonic-gate 		 * applications that need to set parameters.
27290Sstevel@tonic-gate 		 */
27300Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
27315025Siz202018 		    gettext("Unable to set parameter from a client in "
27325025Siz202018 		    "__ns_ldap_setParam()"));
27330Sstevel@tonic-gate 		MKERROR(LOG_WARNING, *error, NS_CONFIG_SYNTAX, strdup(errstr),
27345025Siz202018 		    NULL);
27350Sstevel@tonic-gate 		if (cfg != NULL)
27360Sstevel@tonic-gate 			__s_api_release_config(cfg);
27370Sstevel@tonic-gate 		(void) mutex_unlock(&ns_loadrefresh_lock);
27380Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
27390Sstevel@tonic-gate 	}
27400Sstevel@tonic-gate 
27410Sstevel@tonic-gate 	/* (re)initialize configuration if necessary */
27426842Sth160488 	if (!__s_api_isStandalone() &&
27436842Sth160488 	    cache_server == FALSE && timetorefresh(cfg))
27446842Sth160488 		cfg_g = __s_api_get_default_config_global();
27456842Sth160488 	/* only (re)initialize the global configuration */
27466842Sth160488 	if (cfg == cfg_g) {
27476842Sth160488 		if (cfg_g != NULL)
27486842Sth160488 			__s_api_release_config(cfg_g);
27496842Sth160488 		new_cfg = LoadCacheConfiguration(cfg, &errorp);
27506842Sth160488 		if (new_cfg != cfg)
27516842Sth160488 			__s_api_release_config(cfg);
27520Sstevel@tonic-gate 		if (new_cfg == NULL) {
27530Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
27545025Siz202018 			    gettext("Unable to load configuration '%s' "
27555025Siz202018 			    "('%s')."), NSCONFIGFILE,
27565025Siz202018 			    errorp != NULL && errorp->message != NULL ?
27575025Siz202018 			    errorp->message : "");
27580Sstevel@tonic-gate 			MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
27595025Siz202018 			    strdup(errstr), NULL);
27600Sstevel@tonic-gate 			if (errorp != NULL)
27610Sstevel@tonic-gate 				(void) __ns_ldap_freeError(&errorp);
27620Sstevel@tonic-gate 			(void) mutex_unlock(&ns_loadrefresh_lock);
27630Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
27640Sstevel@tonic-gate 		}
27656842Sth160488 		if (new_cfg != cfg) {
27666842Sth160488 			set_curr_config_global(new_cfg);
27676842Sth160488 			cfg = new_cfg;
27686842Sth160488 			reinit_connmgmt = B_TRUE;
27696842Sth160488 		}
27700Sstevel@tonic-gate 	}
27710Sstevel@tonic-gate 	(void) mutex_unlock(&ns_loadrefresh_lock);
27720Sstevel@tonic-gate 
27736842Sth160488 	if (reinit_connmgmt == B_TRUE)
27746842Sth160488 		__s_api_reinit_conn_mgmt_new_config(cfg);
27756842Sth160488 
27760Sstevel@tonic-gate 	/* translate input and save in the parameter list */
27770Sstevel@tonic-gate 	ret = __ns_ldap_setParamValue(cfg, type, data, error);
27780Sstevel@tonic-gate 
27790Sstevel@tonic-gate 	__s_api_release_config(cfg);
27800Sstevel@tonic-gate 
27810Sstevel@tonic-gate 	return (ret);
27820Sstevel@tonic-gate }
27830Sstevel@tonic-gate 
27840Sstevel@tonic-gate 
27850Sstevel@tonic-gate /*
27860Sstevel@tonic-gate  * Make a copy of a parameter entry
27870Sstevel@tonic-gate  */
27880Sstevel@tonic-gate 
27890Sstevel@tonic-gate static void **
dupParam(ns_param_t * ptr)27900Sstevel@tonic-gate dupParam(ns_param_t *ptr)
27910Sstevel@tonic-gate {
27920Sstevel@tonic-gate 	int		count, i;
27930Sstevel@tonic-gate 	void		**dupdata, *ret;
27940Sstevel@tonic-gate 	int		*intptr;
27950Sstevel@tonic-gate 	char		*cp, tmbuf[32];
27960Sstevel@tonic-gate 	static time_t	expire = 0;
27970Sstevel@tonic-gate 	ns_auth_t	*ap;
27980Sstevel@tonic-gate 
27990Sstevel@tonic-gate 	switch (ptr->ns_ptype) {
28000Sstevel@tonic-gate 	case ARRAYAUTH:
28010Sstevel@tonic-gate 	case ARRAYCRED:
28020Sstevel@tonic-gate 	case SAMLIST:
28030Sstevel@tonic-gate 	case SCLLIST:
28040Sstevel@tonic-gate 	case SSDLIST:
28050Sstevel@tonic-gate 	case SERVLIST:
28060Sstevel@tonic-gate 	case ARRAYCP:
28070Sstevel@tonic-gate 		count = ptr->ns_acnt;
28080Sstevel@tonic-gate 		if (count == 0)
28090Sstevel@tonic-gate 			return (NULL);
28100Sstevel@tonic-gate 		break;
28110Sstevel@tonic-gate 	case CHARPTR:
28120Sstevel@tonic-gate 	case INT:
28130Sstevel@tonic-gate 	case TIMET:
28140Sstevel@tonic-gate 		count = 1;
28150Sstevel@tonic-gate 	}
28160Sstevel@tonic-gate 
28170Sstevel@tonic-gate 	dupdata = (void **)calloc((count + 1), sizeof (void *));
28180Sstevel@tonic-gate 	if (dupdata == NULL)
28190Sstevel@tonic-gate 		return (NULL);
28200Sstevel@tonic-gate 
28210Sstevel@tonic-gate 	switch (ptr->ns_ptype) {
28220Sstevel@tonic-gate 	case ARRAYAUTH:
28230Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
28240Sstevel@tonic-gate 			ap = __s_api_AuthEnumtoStruct(
28255025Siz202018 			    (EnumAuthType_t)ptr->ns_pi[i]);
28260Sstevel@tonic-gate 			if (ap == NULL) {
28270Sstevel@tonic-gate 				free(dupdata);
28280Sstevel@tonic-gate 				return (NULL);
28290Sstevel@tonic-gate 			}
28300Sstevel@tonic-gate 			dupdata[i] = ap;
28310Sstevel@tonic-gate 		}
28320Sstevel@tonic-gate 		break;
28330Sstevel@tonic-gate 	case ARRAYCRED:
28340Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
28350Sstevel@tonic-gate 			intptr = (int *)malloc(sizeof (int));
28360Sstevel@tonic-gate 			if (intptr == NULL) {
28370Sstevel@tonic-gate 				free(dupdata);
28380Sstevel@tonic-gate 				return (NULL);
28390Sstevel@tonic-gate 			}
28400Sstevel@tonic-gate 			dupdata[i] = (void *)intptr;
28410Sstevel@tonic-gate 			*intptr = ptr->ns_pi[i];
28420Sstevel@tonic-gate 		}
28430Sstevel@tonic-gate 		break;
28440Sstevel@tonic-gate 	case SAMLIST:
28450Sstevel@tonic-gate 	case SCLLIST:
28460Sstevel@tonic-gate 	case SSDLIST:
28470Sstevel@tonic-gate 	case SERVLIST:
28480Sstevel@tonic-gate 	case ARRAYCP:
28490Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
28500Sstevel@tonic-gate 			ret = (void *)strdup(ptr->ns_ppc[i]);
28510Sstevel@tonic-gate 			if (ret == NULL) {
28520Sstevel@tonic-gate 				free(dupdata);
28530Sstevel@tonic-gate 				return (NULL);
28540Sstevel@tonic-gate 			}
28550Sstevel@tonic-gate 			dupdata[i] = ret;
28560Sstevel@tonic-gate 		}
28570Sstevel@tonic-gate 		break;
28580Sstevel@tonic-gate 	case CHARPTR:
28590Sstevel@tonic-gate 		if (ptr->ns_pc == NULL) {
28600Sstevel@tonic-gate 			free(dupdata);
28610Sstevel@tonic-gate 			return (NULL);
28620Sstevel@tonic-gate 		}
28630Sstevel@tonic-gate 		ret = (void *)strdup(ptr->ns_pc);
28640Sstevel@tonic-gate 		if (ret == NULL) {
28650Sstevel@tonic-gate 			free(dupdata);
28660Sstevel@tonic-gate 			return (NULL);
28670Sstevel@tonic-gate 		}
28680Sstevel@tonic-gate 		dupdata[0] = ret;
28690Sstevel@tonic-gate 		break;
28700Sstevel@tonic-gate 	case INT:
28710Sstevel@tonic-gate 		intptr = (int *)malloc(sizeof (int));
28720Sstevel@tonic-gate 		if (intptr == NULL) {
28730Sstevel@tonic-gate 			free(dupdata);
28740Sstevel@tonic-gate 			return (NULL);
28750Sstevel@tonic-gate 		}
28760Sstevel@tonic-gate 		*intptr = ptr->ns_i;
28770Sstevel@tonic-gate 		dupdata[0] = (void *)intptr;
28780Sstevel@tonic-gate 		break;
28790Sstevel@tonic-gate 	case TIMET:
28800Sstevel@tonic-gate 		expire = ptr->ns_tm;
28810Sstevel@tonic-gate 		tmbuf[31] = '\0';
28820Sstevel@tonic-gate 		cp = lltostr((long)expire, &tmbuf[31]);
28830Sstevel@tonic-gate 		ret = (void *)strdup(cp);
28840Sstevel@tonic-gate 		if (ret == NULL) {
28850Sstevel@tonic-gate 			free(dupdata);
28860Sstevel@tonic-gate 			return (NULL);
28870Sstevel@tonic-gate 		}
28880Sstevel@tonic-gate 		dupdata[0] = ret;
28890Sstevel@tonic-gate 		break;
28900Sstevel@tonic-gate 	}
28910Sstevel@tonic-gate 	return (dupdata);
28920Sstevel@tonic-gate }
28930Sstevel@tonic-gate 
28940Sstevel@tonic-gate int
__ns_ldap_freeParam(void *** data)28950Sstevel@tonic-gate __ns_ldap_freeParam(void ***data)
28960Sstevel@tonic-gate {
28970Sstevel@tonic-gate 	void	**tmp;
28980Sstevel@tonic-gate 	int	i = 0;
28990Sstevel@tonic-gate 
29000Sstevel@tonic-gate 	if (*data == NULL)
29010Sstevel@tonic-gate 		return (NS_LDAP_SUCCESS);
29020Sstevel@tonic-gate 
29030Sstevel@tonic-gate 	for (i = 0, tmp = *data; tmp[i] != NULL; i++)
29040Sstevel@tonic-gate 		free(tmp[i]);
29050Sstevel@tonic-gate 
29060Sstevel@tonic-gate 	free(*data);
29070Sstevel@tonic-gate 
29080Sstevel@tonic-gate 	*data = NULL;
29090Sstevel@tonic-gate 
29100Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
29110Sstevel@tonic-gate }
29120Sstevel@tonic-gate 
29130Sstevel@tonic-gate /*
29140Sstevel@tonic-gate  * Get the internal format for a parameter value.  This
29150Sstevel@tonic-gate  * routine makes a copy of an internal param value from
29160Sstevel@tonic-gate  * the currently active parameter list and returns it.
29170Sstevel@tonic-gate  */
29180Sstevel@tonic-gate 
29190Sstevel@tonic-gate int
__ns_ldap_getParam(const ParamIndexType Param,void *** data,ns_ldap_error_t ** error)29200Sstevel@tonic-gate __ns_ldap_getParam(const ParamIndexType Param,
29210Sstevel@tonic-gate 		void ***data, ns_ldap_error_t **error)
29220Sstevel@tonic-gate {
29230Sstevel@tonic-gate 	char			errstr[2 * MAXERROR];
29240Sstevel@tonic-gate 	ns_ldap_error_t		*errorp;
29250Sstevel@tonic-gate 	ns_default_config	*def;
29260Sstevel@tonic-gate 	ns_config_t		*cfg;
29276842Sth160488 	ns_config_t		*cfg_g = (ns_config_t *)-1;
29280Sstevel@tonic-gate 	ns_config_t		*new_cfg;
29296842Sth160488 	boolean_t		reinit_connmgmt = B_FALSE;
29300Sstevel@tonic-gate 
29310Sstevel@tonic-gate 	if (data == NULL)
29320Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
29330Sstevel@tonic-gate 
29340Sstevel@tonic-gate 	*data = NULL;
29350Sstevel@tonic-gate 
29360Sstevel@tonic-gate 	/* We want to refresh only one configuration at a time */
29370Sstevel@tonic-gate 	(void) mutex_lock(&ns_loadrefresh_lock);
29380Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
29390Sstevel@tonic-gate 
29400Sstevel@tonic-gate 	/* (re)initialize configuration if necessary */
29416842Sth160488 	if (!__s_api_isStandalone() &&
29426842Sth160488 	    cache_server == FALSE && timetorefresh(cfg))
29436842Sth160488 		cfg_g = __s_api_get_default_config_global();
29446842Sth160488 	/* only (re)initialize the global configuration */
29456842Sth160488 	if (cfg == cfg_g) {
29466842Sth160488 		if (cfg_g != NULL)
29476842Sth160488 			__s_api_release_config(cfg_g);
29486842Sth160488 		new_cfg = LoadCacheConfiguration(cfg, &errorp);
29496842Sth160488 		if (new_cfg != cfg)
29506842Sth160488 			__s_api_release_config(cfg);
29510Sstevel@tonic-gate 		if (new_cfg == NULL) {
29520Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
29535025Siz202018 			    gettext("Unable to load configuration "
29545025Siz202018 			    "'%s' ('%s')."),
29555025Siz202018 			    NSCONFIGFILE,
29565025Siz202018 			    errorp != NULL && errorp->message != NULL ?
29575025Siz202018 			    errorp->message : "");
29580Sstevel@tonic-gate 			MKERROR(LOG_WARNING, *error, NS_CONFIG_NOTLOADED,
29595025Siz202018 			    strdup(errstr), NULL);
29600Sstevel@tonic-gate 			if (errorp != NULL)
29610Sstevel@tonic-gate 				(void) __ns_ldap_freeError(&errorp);
29620Sstevel@tonic-gate 			(void) mutex_unlock(&ns_loadrefresh_lock);
29630Sstevel@tonic-gate 			return (NS_LDAP_CONFIG);
29640Sstevel@tonic-gate 		}
29656842Sth160488 		if (new_cfg != cfg) {
29666842Sth160488 			set_curr_config_global(new_cfg);
29676842Sth160488 			cfg = new_cfg;
29686842Sth160488 			reinit_connmgmt = B_TRUE;
29696842Sth160488 		}
29700Sstevel@tonic-gate 	}
29710Sstevel@tonic-gate 	(void) mutex_unlock(&ns_loadrefresh_lock);
29720Sstevel@tonic-gate 
29736842Sth160488 	if (reinit_connmgmt == B_TRUE)
29746842Sth160488 		__s_api_reinit_conn_mgmt_new_config(cfg);
29756842Sth160488 
29760Sstevel@tonic-gate 	if (cfg == NULL) {
29770Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
29780Sstevel@tonic-gate 		    gettext("No configuration information available."));
29790Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_NOTLOADED,
29805025Siz202018 		    strdup(errstr), NULL);
29810Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
29820Sstevel@tonic-gate 	}
29830Sstevel@tonic-gate 
29840Sstevel@tonic-gate 	if (Param == NS_LDAP_DOMAIN_P) {
29850Sstevel@tonic-gate 		*data = (void **)calloc(2, sizeof (void *));
29860Sstevel@tonic-gate 		if (*data == NULL) {
29870Sstevel@tonic-gate 			__s_api_release_config(cfg);
29880Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
29890Sstevel@tonic-gate 		}
29900Sstevel@tonic-gate 		(*data)[0] = (void *)strdup(cfg->domainName);
29910Sstevel@tonic-gate 		if ((*data)[0] == NULL) {
29920Sstevel@tonic-gate 			free(*data);
29930Sstevel@tonic-gate 			__s_api_release_config(cfg);
29940Sstevel@tonic-gate 			return (NS_LDAP_MEMORY);
29950Sstevel@tonic-gate 		}
29960Sstevel@tonic-gate 	} else if (cfg->paramList[Param].ns_ptype == NS_UNKNOWN) {
29970Sstevel@tonic-gate 		/* get default */
29980Sstevel@tonic-gate 		def = get_defconfig(cfg, Param);
29990Sstevel@tonic-gate 		if (def != NULL)
30000Sstevel@tonic-gate 			*data = dupParam(&def->defval);
30010Sstevel@tonic-gate 	} else {
30020Sstevel@tonic-gate 		*data = dupParam(&(cfg->paramList[Param]));
30030Sstevel@tonic-gate 	}
30040Sstevel@tonic-gate 	__s_api_release_config(cfg);
30050Sstevel@tonic-gate 
30060Sstevel@tonic-gate 	return (NS_LDAP_SUCCESS);
30070Sstevel@tonic-gate }
30080Sstevel@tonic-gate 
30090Sstevel@tonic-gate /*
30100Sstevel@tonic-gate  * This routine takes a parameter in internal format and
30110Sstevel@tonic-gate  * translates it into a variety of string formats for various
30120Sstevel@tonic-gate  * outputs (doors/file/ldif).  This routine would be better
30130Sstevel@tonic-gate  * named: __ns_ldap_translateParam2String
30140Sstevel@tonic-gate  */
30150Sstevel@tonic-gate 
30160Sstevel@tonic-gate char *
__s_api_strValue(ns_config_t * cfg,ParamIndexType index,ns_strfmt_t fmt)3017*10132SMilan.Jurik@Sun.COM __s_api_strValue(ns_config_t *cfg, ParamIndexType index, ns_strfmt_t fmt)
30180Sstevel@tonic-gate {
30190Sstevel@tonic-gate 	ns_default_config *def = NULL;
30200Sstevel@tonic-gate 	ns_param_t	*ptr;
30210Sstevel@tonic-gate 	ns_hash_t	*hptr;
30220Sstevel@tonic-gate 	ns_mapping_t	*mptr;
3023*10132SMilan.Jurik@Sun.COM 	char		ibuf[14];
30240Sstevel@tonic-gate 	char		abuf[64], **cpp;
3025*10132SMilan.Jurik@Sun.COM 	int		count, i;
3026*10132SMilan.Jurik@Sun.COM 	boolean_t	first = B_TRUE;
3027*10132SMilan.Jurik@Sun.COM 	LineBuf		lbuf;
3028*10132SMilan.Jurik@Sun.COM 	LineBuf		*buffer = &lbuf;
3029*10132SMilan.Jurik@Sun.COM 	char		*retstring;
3030*10132SMilan.Jurik@Sun.COM 	char		*sepstr;
3031*10132SMilan.Jurik@Sun.COM 
3032*10132SMilan.Jurik@Sun.COM 	if (cfg == NULL)
30330Sstevel@tonic-gate 		return (NULL);
30340Sstevel@tonic-gate 
30350Sstevel@tonic-gate 	/* NS_LDAP_EXP and TRANSPORT_SEC are not exported externally */
30360Sstevel@tonic-gate 	if (index == NS_LDAP_EXP_P || index == NS_LDAP_TRANSPORT_SEC_P)
30370Sstevel@tonic-gate 		return (NULL);
30380Sstevel@tonic-gate 
30390Sstevel@tonic-gate 	/* Return nothing if the value is the default */
30400Sstevel@tonic-gate 	if (cfg->paramList[index].ns_ptype == NS_UNKNOWN)
30410Sstevel@tonic-gate 		return (NULL);
30420Sstevel@tonic-gate 
3043*10132SMilan.Jurik@Sun.COM 	(void) memset((char *)buffer, 0, sizeof (LineBuf));
3044*10132SMilan.Jurik@Sun.COM 
30450Sstevel@tonic-gate 	ptr = &(cfg->paramList[index]);
30460Sstevel@tonic-gate 
30470Sstevel@tonic-gate 	abuf[0] = '\0';
30480Sstevel@tonic-gate 
30490Sstevel@tonic-gate 	/* get default */
30500Sstevel@tonic-gate 	def = get_defconfig(cfg, index);
30510Sstevel@tonic-gate 	if (def == NULL)
30520Sstevel@tonic-gate 		return (NULL);
30530Sstevel@tonic-gate 
30540Sstevel@tonic-gate 	switch (fmt) {
30550Sstevel@tonic-gate 	case NS_DOOR_FMT:
30560Sstevel@tonic-gate 		(void) strlcpy(abuf, def->name, sizeof (abuf));
30570Sstevel@tonic-gate 		(void) strlcat(abuf, EQUALSEP, sizeof (abuf));
30580Sstevel@tonic-gate 		break;
30590Sstevel@tonic-gate 	case NS_FILE_FMT:
30600Sstevel@tonic-gate 		(void) strlcpy(abuf, def->name, sizeof (abuf));
30610Sstevel@tonic-gate 		(void) strlcat(abuf, EQUSPSEP, sizeof (abuf));
30620Sstevel@tonic-gate 		break;
30630Sstevel@tonic-gate 	case NS_LDIF_FMT:
30640Sstevel@tonic-gate 		/* If no LDIF attr exists ignore the entry */
30650Sstevel@tonic-gate 		if (def->profile_name == NULL)
30660Sstevel@tonic-gate 			return (NULL);
30670Sstevel@tonic-gate 		(void) strlcpy(abuf, def->profile_name, sizeof (abuf));
30680Sstevel@tonic-gate 		(void) strlcat(abuf, COLSPSEP, sizeof (abuf));
30690Sstevel@tonic-gate 		break;
30700Sstevel@tonic-gate 	default:
30710Sstevel@tonic-gate 		break;
30720Sstevel@tonic-gate 	}
3073*10132SMilan.Jurik@Sun.COM 
3074*10132SMilan.Jurik@Sun.COM 	if (__print2buf(buffer, abuf, NULL))
3075*10132SMilan.Jurik@Sun.COM 		goto strValueError;
30760Sstevel@tonic-gate 
30770Sstevel@tonic-gate 	switch (ptr->ns_ptype) {
30780Sstevel@tonic-gate 	case ARRAYAUTH:
30790Sstevel@tonic-gate 		count = ptr->ns_acnt;
30800Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3081*10132SMilan.Jurik@Sun.COM 			sepstr = NULL;
30820Sstevel@tonic-gate 			if (i != count-1) {
3083*10132SMilan.Jurik@Sun.COM 				if (cfg->version == NS_LDAP_V1) {
3084*10132SMilan.Jurik@Sun.COM 					sepstr = COMMASEP;
3085*10132SMilan.Jurik@Sun.COM 				} else {
3086*10132SMilan.Jurik@Sun.COM 					sepstr = SEMISEP;
3087*10132SMilan.Jurik@Sun.COM 				}
30880Sstevel@tonic-gate 			}
3089*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, __s_get_auth_name(cfg,
3090*10132SMilan.Jurik@Sun.COM 			    (AuthType_t)(ptr->ns_pi[i])), sepstr))
3091*10132SMilan.Jurik@Sun.COM 				goto strValueError;
30920Sstevel@tonic-gate 		}
30930Sstevel@tonic-gate 		break;
30940Sstevel@tonic-gate 	case ARRAYCRED:
30950Sstevel@tonic-gate 		count = ptr->ns_acnt;
30960Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3097*10132SMilan.Jurik@Sun.COM 			sepstr = NULL;
30980Sstevel@tonic-gate 			if (i != count-1) {
3099*10132SMilan.Jurik@Sun.COM 				sepstr = SPACESEP;
31000Sstevel@tonic-gate 			}
3101*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, __s_get_credlvl_name(cfg,
3102*10132SMilan.Jurik@Sun.COM 			    (CredLevel_t)ptr->ns_pi[i]), sepstr))
3103*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31040Sstevel@tonic-gate 		}
31050Sstevel@tonic-gate 		break;
31060Sstevel@tonic-gate 	case SAMLIST:
31070Sstevel@tonic-gate 	case SCLLIST:
31080Sstevel@tonic-gate 	case SSDLIST:
31090Sstevel@tonic-gate 		count = ptr->ns_acnt;
31100Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3111*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, ptr->ns_ppc[i], NULL))
3112*10132SMilan.Jurik@Sun.COM 				goto strValueError;
3113*10132SMilan.Jurik@Sun.COM 
3114*10132SMilan.Jurik@Sun.COM 			if (i == count-1)
3115*10132SMilan.Jurik@Sun.COM 				continue;
3116*10132SMilan.Jurik@Sun.COM 
3117*10132SMilan.Jurik@Sun.COM 			/* Separate items */
3118*10132SMilan.Jurik@Sun.COM 			switch (fmt) {
3119*10132SMilan.Jurik@Sun.COM 			case NS_DOOR_FMT:
3120*10132SMilan.Jurik@Sun.COM 				if (__print2buf(buffer, DOORLINESEP, NULL) ||
3121*10132SMilan.Jurik@Sun.COM 				    __print2buf(buffer, def->name, EQUALSEP))
3122*10132SMilan.Jurik@Sun.COM 					goto strValueError;
3123*10132SMilan.Jurik@Sun.COM 				break;
3124*10132SMilan.Jurik@Sun.COM 			case NS_FILE_FMT:
3125*10132SMilan.Jurik@Sun.COM 				if (__print2buf(buffer, "\n", NULL) ||
3126*10132SMilan.Jurik@Sun.COM 				    __print2buf(buffer, def->name, EQUSPSEP))
3127*10132SMilan.Jurik@Sun.COM 					goto strValueError;
3128*10132SMilan.Jurik@Sun.COM 				break;
3129*10132SMilan.Jurik@Sun.COM 			case NS_LDIF_FMT:
3130*10132SMilan.Jurik@Sun.COM 				if (__print2buf(buffer, "\n", NULL) ||
3131*10132SMilan.Jurik@Sun.COM 				    __print2buf(buffer, def->profile_name,
3132*10132SMilan.Jurik@Sun.COM 				    COLSPSEP))
3133*10132SMilan.Jurik@Sun.COM 					goto strValueError;
3134*10132SMilan.Jurik@Sun.COM 				break;
31350Sstevel@tonic-gate 			}
31360Sstevel@tonic-gate 		}
31370Sstevel@tonic-gate 		break;
31380Sstevel@tonic-gate 	case ARRAYCP:
31390Sstevel@tonic-gate 		count = ptr->ns_acnt;
31400Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3141*10132SMilan.Jurik@Sun.COM 			sepstr = NULL;
31420Sstevel@tonic-gate 			if (i != count-1) {
3143*10132SMilan.Jurik@Sun.COM 				sepstr = COMMASEP;
31440Sstevel@tonic-gate 			}
3145*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
3146*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31470Sstevel@tonic-gate 		}
31480Sstevel@tonic-gate 		break;
31490Sstevel@tonic-gate 	case SERVLIST:
31500Sstevel@tonic-gate 		count = ptr->ns_acnt;
31510Sstevel@tonic-gate 		for (i = 0; i < count; i++) {
3152*10132SMilan.Jurik@Sun.COM 			sepstr = NULL;
31530Sstevel@tonic-gate 			if (i != count-1) {
3154*10132SMilan.Jurik@Sun.COM 				if (fmt == NS_LDIF_FMT) {
3155*10132SMilan.Jurik@Sun.COM 					sepstr = SPACESEP;
3156*10132SMilan.Jurik@Sun.COM 				} else {
3157*10132SMilan.Jurik@Sun.COM 					sepstr = COMMASEP;
3158*10132SMilan.Jurik@Sun.COM 				}
31590Sstevel@tonic-gate 			}
3160*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, ptr->ns_ppc[i], sepstr))
3161*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31620Sstevel@tonic-gate 		}
31630Sstevel@tonic-gate 		break;
31640Sstevel@tonic-gate 	case CHARPTR:
31650Sstevel@tonic-gate 		if (ptr->ns_pc == NULL)
31660Sstevel@tonic-gate 			break;
3167*10132SMilan.Jurik@Sun.COM 		if (__print2buf(buffer, ptr->ns_pc, NULL))
3168*10132SMilan.Jurik@Sun.COM 			goto strValueError;
31690Sstevel@tonic-gate 		break;
31700Sstevel@tonic-gate 	case INT:
31710Sstevel@tonic-gate 		switch (def->index) {
31720Sstevel@tonic-gate 		case NS_LDAP_PREF_ONLY_P:
3173*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer,
3174*10132SMilan.Jurik@Sun.COM 			    __s_get_pref_name((PrefOnly_t)ptr->ns_i), NULL))
3175*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31760Sstevel@tonic-gate 			break;
31770Sstevel@tonic-gate 		case NS_LDAP_SEARCH_REF_P:
3178*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, __s_get_searchref_name(cfg,
3179*10132SMilan.Jurik@Sun.COM 			    (SearchRef_t)ptr->ns_i), NULL))
3180*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31810Sstevel@tonic-gate 			break;
31820Sstevel@tonic-gate 		case NS_LDAP_SEARCH_SCOPE_P:
3183*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer,  __s_get_scope_name(cfg,
3184*10132SMilan.Jurik@Sun.COM 			    (ScopeType_t)ptr->ns_i), NULL))
3185*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31860Sstevel@tonic-gate 			break;
31878821SMichen.Chang@Sun.COM 		case NS_LDAP_ENABLE_SHADOW_UPDATE_P:
3188*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, __s_get_shadowupdate_name(
3189*10132SMilan.Jurik@Sun.COM 			    (enableShadowUpdate_t)ptr->ns_i), NULL))
3190*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31918821SMichen.Chang@Sun.COM 			break;
31920Sstevel@tonic-gate 		default:
31930Sstevel@tonic-gate 			(void) snprintf(ibuf, sizeof (ibuf),
31945025Siz202018 			    "%d", ptr->ns_i);
3195*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, ibuf, NULL))
3196*10132SMilan.Jurik@Sun.COM 				goto strValueError;
31970Sstevel@tonic-gate 			break;
31980Sstevel@tonic-gate 		}
31990Sstevel@tonic-gate 		break;
32000Sstevel@tonic-gate 	case ATTRMAP:
32010Sstevel@tonic-gate 		for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
32020Sstevel@tonic-gate 			if (hptr->h_type != NS_HASH_AMAP) {
32030Sstevel@tonic-gate 				continue;
32040Sstevel@tonic-gate 			}
32050Sstevel@tonic-gate 			if (!first) {
3206*10132SMilan.Jurik@Sun.COM 				/* print abuf as "separator" */
3207*10132SMilan.Jurik@Sun.COM 				if (fmt == NS_DOOR_FMT) {
3208*10132SMilan.Jurik@Sun.COM 					if (__print2buf(buffer, DOORLINESEP,
3209*10132SMilan.Jurik@Sun.COM 					    abuf))
3210*10132SMilan.Jurik@Sun.COM 						goto strValueError;
3211*10132SMilan.Jurik@Sun.COM 				} else {
3212*10132SMilan.Jurik@Sun.COM 					if (__print2buf(buffer, "\n", abuf))
3213*10132SMilan.Jurik@Sun.COM 						goto strValueError;
3214*10132SMilan.Jurik@Sun.COM 				}
32150Sstevel@tonic-gate 			}
32160Sstevel@tonic-gate 			mptr = hptr->h_map;
3217*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, mptr->service, COLONSEP) ||
3218*10132SMilan.Jurik@Sun.COM 			    __print2buf(buffer, mptr->orig, EQUALSEP))
3219*10132SMilan.Jurik@Sun.COM 				goto strValueError;
32200Sstevel@tonic-gate 			for (cpp = mptr->map; cpp && *cpp; cpp++) {
3221*10132SMilan.Jurik@Sun.COM 				/* print *cpp as "separator" */
3222*10132SMilan.Jurik@Sun.COM 				sepstr = "";
32230Sstevel@tonic-gate 				if (cpp != mptr->map)
3224*10132SMilan.Jurik@Sun.COM 					sepstr = SPACESEP;
3225*10132SMilan.Jurik@Sun.COM 				if (__print2buf(buffer, sepstr, *cpp))
3226*10132SMilan.Jurik@Sun.COM 					goto strValueError;
32270Sstevel@tonic-gate 			}
3228*10132SMilan.Jurik@Sun.COM 			first = B_FALSE;
32290Sstevel@tonic-gate 		}
32300Sstevel@tonic-gate 		break;
32310Sstevel@tonic-gate 	case OBJMAP:
32320Sstevel@tonic-gate 		for (hptr = cfg->llHead; hptr; hptr = hptr->h_llnext) {
32330Sstevel@tonic-gate 			if (hptr->h_type != NS_HASH_OMAP) {
32340Sstevel@tonic-gate 				continue;
32350Sstevel@tonic-gate 			}
32360Sstevel@tonic-gate 			if (!first) {
3237*10132SMilan.Jurik@Sun.COM 				/* print abuf as "separator" */
3238*10132SMilan.Jurik@Sun.COM 				if (fmt == NS_DOOR_FMT) {
3239*10132SMilan.Jurik@Sun.COM 					if (__print2buf(buffer, DOORLINESEP,
3240*10132SMilan.Jurik@Sun.COM 					    abuf))
3241*10132SMilan.Jurik@Sun.COM 						goto strValueError;
3242*10132SMilan.Jurik@Sun.COM 				} else {
3243*10132SMilan.Jurik@Sun.COM 					if (__print2buf(buffer, "\n", abuf))
3244*10132SMilan.Jurik@Sun.COM 						goto strValueError;
3245*10132SMilan.Jurik@Sun.COM 				}
32460Sstevel@tonic-gate 			}
32470Sstevel@tonic-gate 			mptr = hptr->h_map;
3248*10132SMilan.Jurik@Sun.COM 			if (__print2buf(buffer, mptr->service, COLONSEP) ||
3249*10132SMilan.Jurik@Sun.COM 			    __print2buf(buffer, mptr->orig, EQUALSEP))
3250*10132SMilan.Jurik@Sun.COM 				goto strValueError;
32510Sstevel@tonic-gate 			for (cpp = mptr->map; cpp && *cpp; cpp++) {
3252*10132SMilan.Jurik@Sun.COM 				/* print *cpp as "separator" */
3253*10132SMilan.Jurik@Sun.COM 				sepstr = "";
32540Sstevel@tonic-gate 				if (cpp != mptr->map)
3255*10132SMilan.Jurik@Sun.COM 					sepstr = SPACESEP;
3256*10132SMilan.Jurik@Sun.COM 				if (__print2buf(buffer, sepstr, *cpp))
3257*10132SMilan.Jurik@Sun.COM 					goto strValueError;
32580Sstevel@tonic-gate 			}
3259*10132SMilan.Jurik@Sun.COM 			first = B_FALSE;
32600Sstevel@tonic-gate 		}
32610Sstevel@tonic-gate 		break;
32620Sstevel@tonic-gate 	}
3263*10132SMilan.Jurik@Sun.COM 
3264*10132SMilan.Jurik@Sun.COM 	retstring = buffer->str;
3265*10132SMilan.Jurik@Sun.COM 	return (retstring);
3266*10132SMilan.Jurik@Sun.COM 
3267*10132SMilan.Jurik@Sun.COM strValueError:
3268*10132SMilan.Jurik@Sun.COM 	if (buffer->len > 0)
3269*10132SMilan.Jurik@Sun.COM 		free(buffer->str);
3270*10132SMilan.Jurik@Sun.COM 	return (NULL);
32710Sstevel@tonic-gate }
32720Sstevel@tonic-gate 
32739576SJulian.Pullen@Sun.COM /* shared by __door_getldapconfig() and __door_getadmincred() */
32749576SJulian.Pullen@Sun.COM int
__door_getconf(char ** buffer,int * buflen,ns_ldap_error_t ** error,int callnumber)32759576SJulian.Pullen@Sun.COM __door_getconf(char **buffer, int *buflen, ns_ldap_error_t **error,
32769576SJulian.Pullen@Sun.COM 		    int callnumber)
32770Sstevel@tonic-gate {
32780Sstevel@tonic-gate 	typedef union {
32790Sstevel@tonic-gate 		ldap_data_t	s_d;
32800Sstevel@tonic-gate 		char		s_b[DOORBUFFERSIZE];
32810Sstevel@tonic-gate 	} space_t;
32825025Siz202018 	space_t			*space;
32835025Siz202018 
32845025Siz202018 	ldap_data_t		*sptr;
32855025Siz202018 	int			ndata;
32865025Siz202018 	int			adata;
32875025Siz202018 	char			errstr[MAXERROR];
32885025Siz202018 	char			*domainname;
32895025Siz202018 	ns_ldap_return_code	retCode;
32906842Sth160488 	ldap_config_out_t	*cfghdr;
32915025Siz202018 
32925025Siz202018 	*error = NULL;
32930Sstevel@tonic-gate 
32940Sstevel@tonic-gate 	domainname = __getdomainname();
32950Sstevel@tonic-gate 	if (domainname == NULL || buffer == NULL || buflen == NULL ||
32960Sstevel@tonic-gate 	    (strlen(domainname) >= (sizeof (space_t)
32975025Siz202018 	    - sizeof (space->s_d.ldap_call.ldap_callnumber)))) {
32980Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
32990Sstevel@tonic-gate 	}
33000Sstevel@tonic-gate 
33010Sstevel@tonic-gate 	space = (space_t *)calloc(1, sizeof (space_t));
33020Sstevel@tonic-gate 	if (space == NULL)
33035025Siz202018 		return (NS_LDAP_MEMORY);
33040Sstevel@tonic-gate 
33050Sstevel@tonic-gate 	adata = (sizeof (ldap_call_t) + strlen(domainname) +1);
33060Sstevel@tonic-gate 	ndata = sizeof (space_t);
33079576SJulian.Pullen@Sun.COM 	space->s_d.ldap_call.ldap_callnumber = callnumber;
33080Sstevel@tonic-gate 	(void) strcpy(space->s_d.ldap_call.ldap_u.domainname, domainname);
33090Sstevel@tonic-gate 	free(domainname);
33100Sstevel@tonic-gate 	domainname = NULL;
33110Sstevel@tonic-gate 	sptr = &space->s_d;
33120Sstevel@tonic-gate 
33130Sstevel@tonic-gate 	switch (__ns_ldap_trydoorcall(&sptr, &ndata, &adata)) {
33146842Sth160488 	case NS_CACHE_SUCCESS:
33150Sstevel@tonic-gate 		break;
33166842Sth160488 	case NS_CACHE_NOTFOUND:
33170Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
33185025Siz202018 		    gettext("Door call to "
33195025Siz202018 		    "ldap_cachemgr failed - error: %d."),
33205025Siz202018 		    space->s_d.ldap_ret.ldap_errno);
33210Sstevel@tonic-gate 		MKERROR(LOG_WARNING, *error, NS_CONFIG_CACHEMGR,
33225025Siz202018 		    strdup(errstr), NULL);
33230Sstevel@tonic-gate 		free(space);
33240Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
33250Sstevel@tonic-gate 	default:
33260Sstevel@tonic-gate 		free(space);
33270Sstevel@tonic-gate 		return (NS_LDAP_OP_FAILED);
33280Sstevel@tonic-gate 	}
33290Sstevel@tonic-gate 
33305025Siz202018 	retCode = NS_LDAP_SUCCESS;
33315025Siz202018 
33320Sstevel@tonic-gate 	/* copy info from door call to buffer here */
33336842Sth160488 	cfghdr = &sptr->ldap_ret.ldap_u.config_str;
33346842Sth160488 	*buflen = offsetof(ldap_config_out_t, config_str) +
33356842Sth160488 	    cfghdr->data_size + 1;
33360Sstevel@tonic-gate 	*buffer = calloc(*buflen, sizeof (char));
33370Sstevel@tonic-gate 	if (*buffer == NULL) {
33385025Siz202018 		retCode = NS_LDAP_MEMORY;
33396842Sth160488 	} else
33406842Sth160488 		(void) memcpy(*buffer, cfghdr, *buflen - 1);
33410Sstevel@tonic-gate 
33420Sstevel@tonic-gate 	if (sptr != &space->s_d) {
33430Sstevel@tonic-gate 		(void) munmap((char *)sptr, ndata);
33440Sstevel@tonic-gate 	}
33455025Siz202018 	free(space);
33465025Siz202018 
33475025Siz202018 	return (retCode);
33480Sstevel@tonic-gate }
33490Sstevel@tonic-gate 
33509576SJulian.Pullen@Sun.COM static int
__door_getldapconfig(char ** buffer,int * buflen,ns_ldap_error_t ** error)33519576SJulian.Pullen@Sun.COM __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error)
33529576SJulian.Pullen@Sun.COM {
33539576SJulian.Pullen@Sun.COM 	return (__door_getconf(buffer, buflen, error, GETLDAPCONFIGV1));
33549576SJulian.Pullen@Sun.COM }
33559576SJulian.Pullen@Sun.COM 
33569576SJulian.Pullen@Sun.COM /*
33579576SJulian.Pullen@Sun.COM  * SetDoorInfoToUnixCred parses ldapcachemgr configuration information
33589576SJulian.Pullen@Sun.COM  * for Admin credentials.
33599576SJulian.Pullen@Sun.COM  */
33609576SJulian.Pullen@Sun.COM int
SetDoorInfoToUnixCred(char * buffer,ns_ldap_error_t ** errorp,UnixCred_t ** cred)33619576SJulian.Pullen@Sun.COM SetDoorInfoToUnixCred(char *buffer, ns_ldap_error_t **errorp,
33629576SJulian.Pullen@Sun.COM 	UnixCred_t **cred)
33639576SJulian.Pullen@Sun.COM {
33649576SJulian.Pullen@Sun.COM 	UnixCred_t	*ptr;
33659576SJulian.Pullen@Sun.COM 	char		errstr[MAXERROR];
33669576SJulian.Pullen@Sun.COM 	char		*name, *value, valbuf[BUFSIZE];
33679576SJulian.Pullen@Sun.COM 	char		*bufptr = buffer;
33689576SJulian.Pullen@Sun.COM 	char		*strptr;
33699576SJulian.Pullen@Sun.COM 	char		*rest;
33709576SJulian.Pullen@Sun.COM 	ParamIndexType	index = 0;
33719576SJulian.Pullen@Sun.COM 	ldap_config_out_t	*cfghdr;
33729576SJulian.Pullen@Sun.COM 
33739576SJulian.Pullen@Sun.COM 	if (errorp == NULL || cred == NULL || *cred == NULL)
33749576SJulian.Pullen@Sun.COM 		return (NS_LDAP_INVALID_PARAM);
33759576SJulian.Pullen@Sun.COM 	*errorp = NULL;
33769576SJulian.Pullen@Sun.COM 
33779576SJulian.Pullen@Sun.COM 	ptr = *cred;
33789576SJulian.Pullen@Sun.COM 
33799576SJulian.Pullen@Sun.COM 	cfghdr = (ldap_config_out_t *)bufptr;
33809576SJulian.Pullen@Sun.COM 	bufptr = (char *)cfghdr->config_str;
33819576SJulian.Pullen@Sun.COM 
33829576SJulian.Pullen@Sun.COM 	strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
33839576SJulian.Pullen@Sun.COM 	for (; ; ) {
33849576SJulian.Pullen@Sun.COM 		if (strptr == NULL)
33859576SJulian.Pullen@Sun.COM 			break;
33869576SJulian.Pullen@Sun.COM 		(void) strlcpy(valbuf, strptr, sizeof (valbuf));
33879576SJulian.Pullen@Sun.COM 		__s_api_split_key_value(valbuf, &name, &value);
33889576SJulian.Pullen@Sun.COM 		if (__ns_ldap_getParamType(name, &index) != 0) {
33899576SJulian.Pullen@Sun.COM 			(void) snprintf(errstr, MAXERROR,
33909576SJulian.Pullen@Sun.COM 			    gettext("SetDoorInfoToUnixCred: "
33919576SJulian.Pullen@Sun.COM 			    "Unknown keyword encountered '%s'."), name);
33929576SJulian.Pullen@Sun.COM 			MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
33939576SJulian.Pullen@Sun.COM 			    strdup(errstr), NULL);
33949576SJulian.Pullen@Sun.COM 			return (NS_LDAP_CONFIG);
33959576SJulian.Pullen@Sun.COM 		}
33969576SJulian.Pullen@Sun.COM 		switch (index) {
33979576SJulian.Pullen@Sun.COM 		case NS_LDAP_ADMIN_BINDDN_P:
33989576SJulian.Pullen@Sun.COM 			ptr->userID = (char *)strdup(value);
33999576SJulian.Pullen@Sun.COM 			break;
34009576SJulian.Pullen@Sun.COM 		case NS_LDAP_ADMIN_BINDPASSWD_P:
34019576SJulian.Pullen@Sun.COM 			ptr->passwd = (char *)strdup(value);
34029576SJulian.Pullen@Sun.COM 			break;
34039576SJulian.Pullen@Sun.COM 		default:
34049576SJulian.Pullen@Sun.COM 			(void) snprintf(errstr, MAXERROR,
34059576SJulian.Pullen@Sun.COM 			    gettext("SetDoorInfoToUnixCred: "
34069576SJulian.Pullen@Sun.COM 			    "Unknown index encountered '%d'."), index);
34079576SJulian.Pullen@Sun.COM 			MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
34089576SJulian.Pullen@Sun.COM 			    strdup(errstr), NULL);
34099576SJulian.Pullen@Sun.COM 			return (NS_LDAP_CONFIG);
34109576SJulian.Pullen@Sun.COM 		}
34119576SJulian.Pullen@Sun.COM 		strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
34129576SJulian.Pullen@Sun.COM 	}
34139576SJulian.Pullen@Sun.COM 
34149576SJulian.Pullen@Sun.COM 	return (NS_LDAP_SUCCESS);
34159576SJulian.Pullen@Sun.COM }
34169576SJulian.Pullen@Sun.COM 
34170Sstevel@tonic-gate /*
34180Sstevel@tonic-gate  * SetDoorInfo parses ldapcachemgr configuration information
34190Sstevel@tonic-gate  * and verifies that the profile is version 1 or version 2 based.
34200Sstevel@tonic-gate  * version 2 profiles must have a version number as the first profile
34210Sstevel@tonic-gate  * attribute in the configuration.
34220Sstevel@tonic-gate  */
34230Sstevel@tonic-gate static ns_config_t *
SetDoorInfo(char * buffer,ns_ldap_error_t ** errorp)34240Sstevel@tonic-gate SetDoorInfo(char *buffer, ns_ldap_error_t **errorp)
34250Sstevel@tonic-gate {
34260Sstevel@tonic-gate 	ns_config_t	*ptr;
34270Sstevel@tonic-gate 	char		errstr[MAXERROR], errbuf[MAXERROR];
34280Sstevel@tonic-gate 	char		*name, *value, valbuf[BUFSIZE];
34290Sstevel@tonic-gate 	char		*strptr;
34300Sstevel@tonic-gate 	char		*rest;
34310Sstevel@tonic-gate 	char		*bufptr = buffer;
34320Sstevel@tonic-gate 	ParamIndexType	i;
34330Sstevel@tonic-gate 	int		ret;
34340Sstevel@tonic-gate 	int		first = 1;
34350Sstevel@tonic-gate 	int		errfnd = 0;
34366842Sth160488 	ldap_config_out_t *cfghdr;
34370Sstevel@tonic-gate 
34380Sstevel@tonic-gate 	if (errorp == NULL)
34390Sstevel@tonic-gate 		return (NULL);
34400Sstevel@tonic-gate 	*errorp = NULL;
34410Sstevel@tonic-gate 
34420Sstevel@tonic-gate 	ptr = __s_api_create_config();
34430Sstevel@tonic-gate 	if (ptr == NULL) {
34440Sstevel@tonic-gate 		return (NULL);
34450Sstevel@tonic-gate 	}
34460Sstevel@tonic-gate 
34476842Sth160488 	/* get config cookie from the header */
34486842Sth160488 	cfghdr = (ldap_config_out_t *)bufptr;
34496842Sth160488 	ptr->config_cookie = cfghdr->cookie;
34506842Sth160488 	bufptr = (char *)cfghdr->config_str;
34516842Sth160488 
34520Sstevel@tonic-gate 	strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest);
34530Sstevel@tonic-gate 	for (; ; ) {
34540Sstevel@tonic-gate 		if (strptr == NULL)
34550Sstevel@tonic-gate 			break;
34560Sstevel@tonic-gate 		(void) strlcpy(valbuf, strptr, sizeof (valbuf));
34570Sstevel@tonic-gate 		__s_api_split_key_value(valbuf, &name, &value);
34580Sstevel@tonic-gate 		/* Use get_versiontype and check for V1 vs V2 prototypes */
34590Sstevel@tonic-gate 		if (__s_api_get_versiontype(ptr, name, &i) < 0) {
34600Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
34615025Siz202018 			    "%s (%s)\n",
34625025Siz202018 			    gettext("Illegal profile entry "
34635025Siz202018 			    "line in configuration."),
34645025Siz202018 			    name);
34650Sstevel@tonic-gate 			errfnd++;
34660Sstevel@tonic-gate 		/* Write verify routines and get rid of verify_value here */
34670Sstevel@tonic-gate 		} else if (verify_value(ptr, name,
34685025Siz202018 		    value, errbuf) != NS_SUCCESS) {
34690Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
34705025Siz202018 			    gettext("%s\n"), errbuf);
34710Sstevel@tonic-gate 			errfnd++;
34720Sstevel@tonic-gate 		} else if (!first && i == NS_LDAP_FILE_VERSION_P) {
34730Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
34745025Siz202018 			    gettext("Illegal NS_LDAP_FILE_VERSION "
34755025Siz202018 			    "line in configuration.\n"));
34760Sstevel@tonic-gate 			errfnd++;
34770Sstevel@tonic-gate 		}
34780Sstevel@tonic-gate 		if (errfnd) {
34790Sstevel@tonic-gate 			MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX,
34805025Siz202018 			    strdup(errstr), NULL);
34810Sstevel@tonic-gate 		} else {
34820Sstevel@tonic-gate 			ret = set_default_value(ptr, name, value, errorp);
34830Sstevel@tonic-gate 		}
34840Sstevel@tonic-gate 		if (errfnd || ret != NS_SUCCESS) {
34850Sstevel@tonic-gate 			__s_api_destroy_config(ptr);
34860Sstevel@tonic-gate 			return (NULL);
34870Sstevel@tonic-gate 		}
34880Sstevel@tonic-gate 		first = 0;
34890Sstevel@tonic-gate 
34900Sstevel@tonic-gate 		strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest);
34910Sstevel@tonic-gate 	}
34920Sstevel@tonic-gate 
34930Sstevel@tonic-gate 	if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
34940Sstevel@tonic-gate 		__s_api_destroy_config(ptr);
34950Sstevel@tonic-gate 		MKERROR(LOG_WARNING, *errorp, NS_CONFIG_SYNTAX, strdup(errstr),
34965025Siz202018 		    NULL);
34970Sstevel@tonic-gate 		return (NULL);
34980Sstevel@tonic-gate 	}
34990Sstevel@tonic-gate 
35000Sstevel@tonic-gate 	return (ptr);
35010Sstevel@tonic-gate }
35020Sstevel@tonic-gate 
35030Sstevel@tonic-gate static ns_config_t *
LoadCacheConfiguration(ns_config_t * oldcfg,ns_ldap_error_t ** error)35046842Sth160488 LoadCacheConfiguration(ns_config_t *oldcfg, ns_ldap_error_t **error)
35050Sstevel@tonic-gate {
35060Sstevel@tonic-gate 	char		*buffer = NULL;
35070Sstevel@tonic-gate 	int		buflen = 0;
35080Sstevel@tonic-gate 	int		ret;
35090Sstevel@tonic-gate 	ns_config_t	*cfg;
35106842Sth160488 	ldap_config_out_t *cfghdr;
35116842Sth160488 	ldap_get_chg_cookie_t old_cookie;
35126842Sth160488 	ldap_get_chg_cookie_t new_cookie;
35130Sstevel@tonic-gate 
35140Sstevel@tonic-gate 	*error = NULL;
35150Sstevel@tonic-gate 	ret = __door_getldapconfig(&buffer, &buflen, error);
35160Sstevel@tonic-gate 
35170Sstevel@tonic-gate 	if (ret != NS_LDAP_SUCCESS) {
35180Sstevel@tonic-gate 		if (*error != NULL && (*error)->message != NULL)
35190Sstevel@tonic-gate 			syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
35200Sstevel@tonic-gate 		return (NULL);
35210Sstevel@tonic-gate 	}
35220Sstevel@tonic-gate 
35236842Sth160488 	/* No need to reload configuration if config cookie is the same */
35246842Sth160488 	cfghdr = (ldap_config_out_t *)buffer;
35256842Sth160488 	new_cookie = cfghdr->cookie;
35266842Sth160488 	if (oldcfg != NULL)
35276842Sth160488 		old_cookie = oldcfg->config_cookie;
35286842Sth160488 
35296842Sth160488 	if (oldcfg != NULL && old_cookie.mgr_pid == new_cookie.mgr_pid &&
35306842Sth160488 	    old_cookie.seq_num == new_cookie.seq_num) {
35316842Sth160488 		free(buffer);
35326842Sth160488 		return (oldcfg);
35336842Sth160488 	}
35346842Sth160488 
35350Sstevel@tonic-gate 	/* now convert from door format */
35360Sstevel@tonic-gate 	cfg = SetDoorInfo(buffer, error);
35370Sstevel@tonic-gate 	free(buffer);
35380Sstevel@tonic-gate 
35390Sstevel@tonic-gate 	if (cfg == NULL && *error != NULL && (*error)->message != NULL)
35400Sstevel@tonic-gate 		syslog(LOG_WARNING, "libsldap: %s", (*error)->message);
35410Sstevel@tonic-gate 	return (cfg);
35420Sstevel@tonic-gate }
35430Sstevel@tonic-gate 
35440Sstevel@tonic-gate /*
35450Sstevel@tonic-gate  * converts the time string into seconds.  The time string can be specified
35460Sstevel@tonic-gate  * using one of the following time units:
35470Sstevel@tonic-gate  * 	#s (# of seconds)
35480Sstevel@tonic-gate  *	#m (# of minutes)
35490Sstevel@tonic-gate  *	#h (# of hours)
35500Sstevel@tonic-gate  *	#d (# of days)
35510Sstevel@tonic-gate  *	#w (# of weeks)
35520Sstevel@tonic-gate  * NOTE: you can only specify one the above.  No combination of the above
35530Sstevel@tonic-gate  * units is allowed.  If no unit specified, it will default to "seconds".
35540Sstevel@tonic-gate  */
35550Sstevel@tonic-gate static time_t
conv_time(char * s)35560Sstevel@tonic-gate conv_time(char *s)
35570Sstevel@tonic-gate {
35580Sstevel@tonic-gate 	time_t t;
35590Sstevel@tonic-gate 	char c;
35600Sstevel@tonic-gate 	int l, m;
35610Sstevel@tonic-gate 	long tot;
35620Sstevel@tonic-gate 
35630Sstevel@tonic-gate 	l = strlen(s);
35640Sstevel@tonic-gate 	if (l == 0)
35650Sstevel@tonic-gate 		return (0);
35660Sstevel@tonic-gate 	c = s[--l];
35670Sstevel@tonic-gate 	m = 0;
35680Sstevel@tonic-gate 	switch (c) {
35690Sstevel@tonic-gate 	case 'w': /* weeks */
35700Sstevel@tonic-gate 		m = 604800;
35710Sstevel@tonic-gate 		break;
35720Sstevel@tonic-gate 	case 'd': /* days */
35730Sstevel@tonic-gate 		m = 86400;
35740Sstevel@tonic-gate 		break;
35750Sstevel@tonic-gate 	case 'h': /* hours */
35760Sstevel@tonic-gate 		m = 3600;
35770Sstevel@tonic-gate 		break;
35780Sstevel@tonic-gate 	case 'm': /* minutes */
35790Sstevel@tonic-gate 		m = 60;
35800Sstevel@tonic-gate 		break;
35810Sstevel@tonic-gate 	case 's': /* seconds */
35820Sstevel@tonic-gate 		m = 1;
35830Sstevel@tonic-gate 		break;
35840Sstevel@tonic-gate 	/* the default case is set to "second" */
35850Sstevel@tonic-gate 	}
35860Sstevel@tonic-gate 	if (m != 0)
35870Sstevel@tonic-gate 		s[l] = '\0';
35880Sstevel@tonic-gate 	else
35890Sstevel@tonic-gate 		m = 1;
35900Sstevel@tonic-gate 	errno = 0;
35910Sstevel@tonic-gate 	tot = atol(s);
35920Sstevel@tonic-gate 	if ((0 == tot) && (EINVAL == errno))
35930Sstevel@tonic-gate 		return (0);
35940Sstevel@tonic-gate 	if (((LONG_MAX == tot) || (LONG_MIN == tot)) && (EINVAL == errno))
35950Sstevel@tonic-gate 		return (0);
35960Sstevel@tonic-gate 
35970Sstevel@tonic-gate 	tot = tot * m;
35980Sstevel@tonic-gate 	t = (time_t)tot;
35990Sstevel@tonic-gate 	return (t);
36000Sstevel@tonic-gate }
36010Sstevel@tonic-gate 
36020Sstevel@tonic-gate 
36030Sstevel@tonic-gate ns_auth_t *
__s_api_AuthEnumtoStruct(const EnumAuthType_t i)36040Sstevel@tonic-gate __s_api_AuthEnumtoStruct(const EnumAuthType_t i)
36050Sstevel@tonic-gate {
36060Sstevel@tonic-gate 	ns_auth_t *ap;
36070Sstevel@tonic-gate 
36080Sstevel@tonic-gate 	ap = (ns_auth_t *)calloc(1, sizeof (ns_auth_t));
36090Sstevel@tonic-gate 	if (ap == NULL)
36100Sstevel@tonic-gate 		return (NULL);
36110Sstevel@tonic-gate 	switch (i) {
36120Sstevel@tonic-gate 		case NS_LDAP_EA_NONE:
36130Sstevel@tonic-gate 			break;
36140Sstevel@tonic-gate 		case NS_LDAP_EA_SIMPLE:
36150Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SIMPLE;
36160Sstevel@tonic-gate 			break;
36170Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_CRAM_MD5:
36180Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
36190Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
36200Sstevel@tonic-gate 			break;
36210Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_DIGEST_MD5:
36220Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
36230Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36240Sstevel@tonic-gate 			break;
36250Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_DIGEST_MD5_INT:
36260Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
36270Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36280Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_INT;
36290Sstevel@tonic-gate 			break;
36300Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_DIGEST_MD5_CONF:
36310Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
36320Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36330Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_PRIV;
36340Sstevel@tonic-gate 			break;
36350Sstevel@tonic-gate 		case NS_LDAP_EA_SASL_EXTERNAL:
36360Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_SASL;
36370Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_EXTERNAL;
36380Sstevel@tonic-gate 			break;
36392830Sdjl 		case NS_LDAP_EA_SASL_GSSAPI:
36402830Sdjl 			ap->type = NS_LDAP_AUTH_SASL;
36412830Sdjl 			ap->saslmech = NS_LDAP_SASL_GSSAPI;
36422830Sdjl 			ap->saslopt = NS_LDAP_SASLOPT_INT |
36435025Siz202018 			    NS_LDAP_SASLOPT_PRIV;
36442830Sdjl 			break;
36450Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_NONE:
36460Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36470Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_NONE;
36480Sstevel@tonic-gate 			break;
36490Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SIMPLE:
36500Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36510Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SIMPLE;
36520Sstevel@tonic-gate 			break;
36530Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_CRAM_MD5:
36540Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36550Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36560Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_CRAM_MD5;
36570Sstevel@tonic-gate 			break;
36580Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5:
36590Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36600Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36610Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36620Sstevel@tonic-gate 			break;
36630Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_INT:
36640Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36650Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36660Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36670Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_INT;
36680Sstevel@tonic-gate 			break;
36690Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_DIGEST_MD5_CONF:
36700Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36710Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36720Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_DIGEST_MD5;
36730Sstevel@tonic-gate 			ap->saslopt = NS_LDAP_SASLOPT_PRIV;
36740Sstevel@tonic-gate 			break;
36750Sstevel@tonic-gate 		case NS_LDAP_EA_TLS_SASL_EXTERNAL:
36760Sstevel@tonic-gate 			ap->type = NS_LDAP_AUTH_TLS;
36770Sstevel@tonic-gate 			ap->tlstype = NS_LDAP_TLS_SASL;
36780Sstevel@tonic-gate 			ap->saslmech = NS_LDAP_SASL_EXTERNAL;
36790Sstevel@tonic-gate 			break;
36800Sstevel@tonic-gate 		default:
36810Sstevel@tonic-gate 			/* should never get here */
36820Sstevel@tonic-gate 			free(ap);
36830Sstevel@tonic-gate 			return (NULL);
36840Sstevel@tonic-gate 	}
36850Sstevel@tonic-gate 	return (ap);
36860Sstevel@tonic-gate }
36870Sstevel@tonic-gate 
36880Sstevel@tonic-gate 
36890Sstevel@tonic-gate /*
36900Sstevel@tonic-gate  * Parameter Index Type validation routines
36910Sstevel@tonic-gate  */
36920Sstevel@tonic-gate 
36930Sstevel@tonic-gate /* Validate a positive integer */
36940Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
36950Sstevel@tonic-gate /* ARGSUSED */
36960Sstevel@tonic-gate static int
__s_val_postime(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)36970Sstevel@tonic-gate __s_val_postime(ParamIndexType i, ns_default_config *def,
36980Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
36990Sstevel@tonic-gate {
37000Sstevel@tonic-gate 	char	*cp;
37010Sstevel@tonic-gate 	long	tot;
37020Sstevel@tonic-gate 
37030Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR && param->ns_pc) {
37040Sstevel@tonic-gate 		for (cp = param->ns_pc; cp && *cp; cp++) {
37050Sstevel@tonic-gate 			if (*cp >= '0' && *cp <= '9')
37060Sstevel@tonic-gate 				continue;
37070Sstevel@tonic-gate 			switch (*cp) {
37080Sstevel@tonic-gate 			case 'w': /* weeks */
37090Sstevel@tonic-gate 			case 'd': /* days */
37100Sstevel@tonic-gate 			case 'h': /* hours */
37110Sstevel@tonic-gate 			case 'm': /* minutes */
37120Sstevel@tonic-gate 			case 's': /* seconds */
37130Sstevel@tonic-gate 				if (*(cp+1) == '\0') {
37140Sstevel@tonic-gate 					break;
37150Sstevel@tonic-gate 				}
37160Sstevel@tonic-gate 			default:
37170Sstevel@tonic-gate 				(void) strcpy(errbuf, "Illegal time value");
37180Sstevel@tonic-gate 				return (NS_PARSE_ERR);
37190Sstevel@tonic-gate 			}
37200Sstevel@tonic-gate 		}
37210Sstevel@tonic-gate 		/* Valid form:  [0-9][0-9]*[wdhms]* */
37220Sstevel@tonic-gate 		tot = atol(param->ns_pc);	/* check overflow */
37230Sstevel@tonic-gate 		if (tot >= 0)
37240Sstevel@tonic-gate 			return (NS_SUCCESS);
37250Sstevel@tonic-gate 	}
37260Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
37275025Siz202018 	    gettext("Illegal time value in %s"), def->name);
37280Sstevel@tonic-gate 	return (NS_PARSE_ERR);
37290Sstevel@tonic-gate }
37300Sstevel@tonic-gate 
37310Sstevel@tonic-gate 
37320Sstevel@tonic-gate /* Validate the Base DN */
37330Sstevel@tonic-gate /* It can be empty (RootDSE request) or needs to have an '=' */
37340Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
37350Sstevel@tonic-gate /* ARGSUSED */
37360Sstevel@tonic-gate static int
__s_val_basedn(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)37370Sstevel@tonic-gate __s_val_basedn(ParamIndexType i, ns_default_config *def,
37380Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
37390Sstevel@tonic-gate {
37400Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR &&
37410Sstevel@tonic-gate 	    i == NS_LDAP_SEARCH_BASEDN_P &&
37425025Siz202018 	    ((param->ns_pc == NULL) || 		/* empty */
37435025Siz202018 	    (*(param->ns_pc) == '\0') ||		/* empty */
37445025Siz202018 	    (strchr(param->ns_pc, '=') != NULL)))	/* '=' */
37450Sstevel@tonic-gate 	{
37460Sstevel@tonic-gate 		return (NS_SUCCESS);
37470Sstevel@tonic-gate 	}
37480Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
37495025Siz202018 	    gettext("Non-existent or invalid DN in %s"),
37505025Siz202018 	    def->name);
37510Sstevel@tonic-gate 	return (NS_PARSE_ERR);
37520Sstevel@tonic-gate }
37530Sstevel@tonic-gate 
37540Sstevel@tonic-gate 
37550Sstevel@tonic-gate /* Validate the serverList */
37560Sstevel@tonic-gate /* For each server in list, check if valid IP or hostname */
37570Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
37580Sstevel@tonic-gate /* ARGSUSED */
37590Sstevel@tonic-gate static int
__s_val_serverList(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)37600Sstevel@tonic-gate __s_val_serverList(ParamIndexType i, ns_default_config *def,
37610Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
37620Sstevel@tonic-gate {
37630Sstevel@tonic-gate 	for (i = 0; i < param->ns_acnt; i++) {
37640Sstevel@tonic-gate 		if ((__s_api_isipv4(param->ns_ppc[i])) ||
37655025Siz202018 		    (__s_api_isipv6(param->ns_ppc[i])) ||
37665025Siz202018 		    (__s_api_ishost(param->ns_ppc[i]))) {
37670Sstevel@tonic-gate 			continue;
37680Sstevel@tonic-gate 		}
37690Sstevel@tonic-gate 		/* err */
37700Sstevel@tonic-gate 		(void) snprintf(errbuf, MAXERROR,
37715025Siz202018 		    gettext("Invalid server (%s) in %s"),
37725025Siz202018 		    param->ns_ppc[i], def->name);
37730Sstevel@tonic-gate 		return (NS_PARSE_ERR);
37740Sstevel@tonic-gate 	}
37750Sstevel@tonic-gate 
37760Sstevel@tonic-gate 	return (NS_SUCCESS);
37770Sstevel@tonic-gate }
37780Sstevel@tonic-gate 
37790Sstevel@tonic-gate 
37800Sstevel@tonic-gate /* Check for a BINDDN */
37810Sstevel@tonic-gate /* It can not be empty and needs to have an '=' */
37820Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
37830Sstevel@tonic-gate /* ARGSUSED */
37840Sstevel@tonic-gate static int
__s_val_binddn(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)37850Sstevel@tonic-gate __s_val_binddn(ParamIndexType i, ns_default_config *def,
37860Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
37870Sstevel@tonic-gate {
37888821SMichen.Chang@Sun.COM 	char *dntype;
37898821SMichen.Chang@Sun.COM 
37900Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR &&
37918821SMichen.Chang@Sun.COM 	    (i == NS_LDAP_BINDDN_P || i == NS_LDAP_ADMIN_BINDDN_P) &&
37925025Siz202018 	    ((param->ns_pc == NULL) ||
37935025Siz202018 	    ((*(param->ns_pc) != '\0') &&
37945025Siz202018 	    (strchr(param->ns_pc, '=') != NULL)))) {
37950Sstevel@tonic-gate 		return (NS_SUCCESS);
37960Sstevel@tonic-gate 	}
37978821SMichen.Chang@Sun.COM 	if (i == NS_LDAP_BINDDN_P)
37988821SMichen.Chang@Sun.COM 		dntype = "proxy";
37998821SMichen.Chang@Sun.COM 	else
38008821SMichen.Chang@Sun.COM 		dntype = "update";
38010Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
38028821SMichen.Chang@Sun.COM 	    gettext("NULL or invalid %s bind DN"), dntype);
38030Sstevel@tonic-gate 	return (NS_PARSE_ERR);
38040Sstevel@tonic-gate }
38050Sstevel@tonic-gate 
38060Sstevel@tonic-gate 
38070Sstevel@tonic-gate /* Check for a BINDPASSWD */
38080Sstevel@tonic-gate /* The string can not be NULL or empty */
38090Sstevel@tonic-gate /* Size of errbuf needs to be MAXERROR */
38100Sstevel@tonic-gate /* ARGSUSED */
38110Sstevel@tonic-gate static int
__s_val_bindpw(ParamIndexType i,ns_default_config * def,ns_param_t * param,char * errbuf)38120Sstevel@tonic-gate __s_val_bindpw(ParamIndexType i, ns_default_config *def,
38130Sstevel@tonic-gate 		ns_param_t *param, char *errbuf)
38140Sstevel@tonic-gate {
38158821SMichen.Chang@Sun.COM 	char *pwtype;
38168821SMichen.Chang@Sun.COM 
38170Sstevel@tonic-gate 	if (param && param->ns_ptype == CHARPTR &&
38188821SMichen.Chang@Sun.COM 	    (i == NS_LDAP_BINDPASSWD_P || i == NS_LDAP_ADMIN_BINDPASSWD_P) &&
38195025Siz202018 	    ((param->ns_pc == NULL) ||
38205025Siz202018 	    (*(param->ns_pc) != '\0'))) {
38210Sstevel@tonic-gate 		return (NS_SUCCESS);
38220Sstevel@tonic-gate 	}
38238821SMichen.Chang@Sun.COM 	if (i == NS_LDAP_BINDPASSWD_P)
38248821SMichen.Chang@Sun.COM 		pwtype = "proxy";
38258821SMichen.Chang@Sun.COM 	else
38268821SMichen.Chang@Sun.COM 		pwtype = "admin";
38270Sstevel@tonic-gate 	(void) snprintf(errbuf, MAXERROR,
38288821SMichen.Chang@Sun.COM 	    gettext("NULL %s bind password"), pwtype);
38290Sstevel@tonic-gate 	return (NS_PARSE_ERR);
38300Sstevel@tonic-gate }
38310Sstevel@tonic-gate 
38320Sstevel@tonic-gate /*
38330Sstevel@tonic-gate  * __s_get_hostcertpath returns either the configured host certificate path
38340Sstevel@tonic-gate  * or, if none, the default host certificate path (/var/ldap). Note that this
38350Sstevel@tonic-gate  * does not use __ns_ldap_getParam because it may be called during connection
38360Sstevel@tonic-gate  * setup. This can fail due to insufficient memory.
38370Sstevel@tonic-gate  */
38380Sstevel@tonic-gate 
38390Sstevel@tonic-gate char *
__s_get_hostcertpath(void)38400Sstevel@tonic-gate __s_get_hostcertpath(void)
38410Sstevel@tonic-gate {
38420Sstevel@tonic-gate 	ns_config_t		*cfg;
38430Sstevel@tonic-gate 	ns_param_t		*param;
38440Sstevel@tonic-gate 	char			*ret = NULL;
38450Sstevel@tonic-gate 
38460Sstevel@tonic-gate 	cfg = __s_api_get_default_config();
38470Sstevel@tonic-gate 	if (cfg != NULL) {
38480Sstevel@tonic-gate 		param = &cfg->paramList[NS_LDAP_HOST_CERTPATH_P];
38490Sstevel@tonic-gate 		if (param->ns_ptype == CHARPTR)
38500Sstevel@tonic-gate 			ret = strdup(param->ns_pc);
38510Sstevel@tonic-gate 		__s_api_release_config(cfg);
38520Sstevel@tonic-gate 	}
38530Sstevel@tonic-gate 	if (ret == NULL)
38540Sstevel@tonic-gate 		ret = strdup(NSLDAPDIRECTORY);
38550Sstevel@tonic-gate 	return (ret);
38560Sstevel@tonic-gate }
38570Sstevel@tonic-gate 
38580Sstevel@tonic-gate static void
_free_config()38590Sstevel@tonic-gate _free_config()
38600Sstevel@tonic-gate {
38610Sstevel@tonic-gate 	if (current_config != NULL)
38620Sstevel@tonic-gate 		destroy_config(current_config);
38630Sstevel@tonic-gate 
38640Sstevel@tonic-gate 	current_config = NULL;
38650Sstevel@tonic-gate }
3866