17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5004388ebScasper  * Common Development and Distribution License (the "License").
6004388ebScasper  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22dd1104fbSMichen Chang  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /* libsldap - cachemgr side configuration components */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <stdio.h>
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <libintl.h>
327c478bd9Sstevel@tonic-gate #include <string.h>
337c478bd9Sstevel@tonic-gate #include <ctype.h>
347c478bd9Sstevel@tonic-gate 
357c478bd9Sstevel@tonic-gate #include <sys/stat.h>
367c478bd9Sstevel@tonic-gate #include <fcntl.h>
377c478bd9Sstevel@tonic-gate #include <unistd.h>
387c478bd9Sstevel@tonic-gate #include <syslog.h>
397c478bd9Sstevel@tonic-gate #include <locale.h>
407c478bd9Sstevel@tonic-gate #include <errno.h>
417c478bd9Sstevel@tonic-gate #include <sys/time.h>
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #include "ns_sldap.h"
447c478bd9Sstevel@tonic-gate #include "ns_internal.h"
457c478bd9Sstevel@tonic-gate #include "ns_cache_door.h"
467c478bd9Sstevel@tonic-gate 
477c478bd9Sstevel@tonic-gate #define	ALWAYS		1
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate /*
517c478bd9Sstevel@tonic-gate  * **************************************************************
527c478bd9Sstevel@tonic-gate  * Configuration File Routines
537c478bd9Sstevel@tonic-gate  * **************************************************************
547c478bd9Sstevel@tonic-gate  */
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate 
577c478bd9Sstevel@tonic-gate /* Size of the errstr buffer needs to be MAXERROR */
587c478bd9Sstevel@tonic-gate static int
read_line(FILE * fp,char * buffer,int buflen,char * errstr)597c478bd9Sstevel@tonic-gate read_line(FILE *fp, char *buffer, int buflen, char *errstr)
607c478bd9Sstevel@tonic-gate {
617c478bd9Sstevel@tonic-gate 	int	linelen;
627c478bd9Sstevel@tonic-gate 	char	c;
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate 	*errstr = '\0';
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate 	for (linelen = 0; linelen < buflen; ) {
677c478bd9Sstevel@tonic-gate 		c = getc(fp);
687c478bd9Sstevel@tonic-gate 		if (c == EOF)
697c478bd9Sstevel@tonic-gate 			break;
707c478bd9Sstevel@tonic-gate 		switch (c) {
717c478bd9Sstevel@tonic-gate 		case '\n':
7282c6b8c6Smj 			if (linelen > 0 && buffer[linelen - 1] == '\\') {
7382c6b8c6Smj 				/* Continuation line found */
7482c6b8c6Smj 				--linelen;
7582c6b8c6Smj 			} else {
7682c6b8c6Smj 				/* end of line found */
7782c6b8c6Smj 				buffer[linelen] = '\0';
7882c6b8c6Smj 				return (linelen);
7982c6b8c6Smj 			}
8082c6b8c6Smj 			break;
817c478bd9Sstevel@tonic-gate 		default:
8282c6b8c6Smj 			buffer[linelen++] = c;
837c478bd9Sstevel@tonic-gate 		}
847c478bd9Sstevel@tonic-gate 	}
857c478bd9Sstevel@tonic-gate 
867c478bd9Sstevel@tonic-gate 	if (linelen >= buflen) {
877c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, MAXERROR,
8882c6b8c6Smj 		    gettext("Buffer overflow, line too long."));
897c478bd9Sstevel@tonic-gate 		return (-2);
907c478bd9Sstevel@tonic-gate 	} else if (linelen > 0 && buffer[linelen - 1] == '\\') {
917c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, MAXERROR,
9282c6b8c6Smj 		    gettext("Unterminated continuation line."));
937c478bd9Sstevel@tonic-gate 		return (-2);
947c478bd9Sstevel@tonic-gate 	} else {
957c478bd9Sstevel@tonic-gate 		/* end of file */
967c478bd9Sstevel@tonic-gate 		buffer[linelen] = '\0';
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 	return (linelen > 0 ? linelen : -1);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate static ns_parse_status
read_file(ns_config_t * ptr,int cred_file,ns_ldap_error_t ** error)1037c478bd9Sstevel@tonic-gate read_file(ns_config_t *ptr, int cred_file, ns_ldap_error_t **error)
1047c478bd9Sstevel@tonic-gate {
1057c478bd9Sstevel@tonic-gate 	ParamIndexType	i = 0;
1067c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
1077c478bd9Sstevel@tonic-gate 	char		buffer[BUFSIZE], *name, *value;
1087c478bd9Sstevel@tonic-gate 	int		emptyfile, lineno;
1097c478bd9Sstevel@tonic-gate 	FILE		*fp;
1107c478bd9Sstevel@tonic-gate 	int		ret;
1117c478bd9Sstevel@tonic-gate 	int		linelen;
1127c478bd9Sstevel@tonic-gate 	char		*file;
1137c478bd9Sstevel@tonic-gate 	int		first = 1;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 
1167c478bd9Sstevel@tonic-gate 	if (cred_file) {
1177c478bd9Sstevel@tonic-gate 		file = NSCREDFILE;
1187c478bd9Sstevel@tonic-gate 	} else {
1197c478bd9Sstevel@tonic-gate 		file = NSCONFIGFILE;
1207c478bd9Sstevel@tonic-gate 	}
121004388ebScasper 	fp = fopen(file, "rF");
1227c478bd9Sstevel@tonic-gate 	if (fp == NULL) {
1237c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
12482c6b8c6Smj 		    gettext("Unable to open filename '%s' "
12582c6b8c6Smj 		    "for reading (errno=%d)."), file, errno);
12651b02b29SToomas Soome 		MKERROR(LOG_ERR, *error, NS_CONFIG_FILE, strdup(errstr),
127*81de4da4SToomas Soome 		    NS_PARSE_ERR);
1287c478bd9Sstevel@tonic-gate 		return (NS_NOTFOUND);
1297c478bd9Sstevel@tonic-gate 	}
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate 	emptyfile = 1;
1327c478bd9Sstevel@tonic-gate 	lineno = 0;
1337c478bd9Sstevel@tonic-gate 	for (; ; ) {
1347c478bd9Sstevel@tonic-gate 		if ((linelen = read_line(fp, buffer, sizeof (buffer),
13582c6b8c6Smj 		    errstr)) < 0)
1367c478bd9Sstevel@tonic-gate 			/* End of file */
1377c478bd9Sstevel@tonic-gate 			break;
1387c478bd9Sstevel@tonic-gate 		lineno++;
1397c478bd9Sstevel@tonic-gate 		if (linelen == 0)
1407c478bd9Sstevel@tonic-gate 			continue;
1417c478bd9Sstevel@tonic-gate 		/* get rid of comment lines */
1427c478bd9Sstevel@tonic-gate 		if (buffer[0] == '#')
1437c478bd9Sstevel@tonic-gate 			continue;
1447c478bd9Sstevel@tonic-gate 		emptyfile = 0;
1457c478bd9Sstevel@tonic-gate 		name = NULL;
1467c478bd9Sstevel@tonic-gate 		value = NULL;
1477c478bd9Sstevel@tonic-gate 		__s_api_split_key_value(buffer, &name, &value);
1487c478bd9Sstevel@tonic-gate 		if (name == NULL || value == NULL) {
1497c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
1507c478bd9Sstevel@tonic-gate 			    gettext("Missing Name or Value on line %d."),
15182c6b8c6Smj 			    lineno);
1527c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
153*81de4da4SToomas Soome 			    strdup(errstr), NS_PARSE_ERR);
1547c478bd9Sstevel@tonic-gate 			(void) fclose(fp);
1557c478bd9Sstevel@tonic-gate 			return (NS_PARSE_ERR);
1567c478bd9Sstevel@tonic-gate 		}
1577c478bd9Sstevel@tonic-gate 		if (__s_api_get_versiontype(ptr, name, &i) != 0) {
1587c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
1597c478bd9Sstevel@tonic-gate 			    gettext("Illegal profile type on line %d."),
16082c6b8c6Smj 			    lineno);
1617c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
162*81de4da4SToomas Soome 			    strdup(errstr), NS_PARSE_ERR);
1637c478bd9Sstevel@tonic-gate 			(void) fclose(fp);
1647c478bd9Sstevel@tonic-gate 			return (NS_PARSE_ERR);
1657c478bd9Sstevel@tonic-gate 		}
1667c478bd9Sstevel@tonic-gate 		if (!first && i == NS_LDAP_FILE_VERSION_P) {
1677c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
16882c6b8c6Smj 			    gettext("Illegal NS_LDAP_FILE_VERSION "
16982c6b8c6Smj 			    "on line %d."), lineno);
1707c478bd9Sstevel@tonic-gate 			MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
171*81de4da4SToomas Soome 			    strdup(errstr), NS_PARSE_ERR);
1727c478bd9Sstevel@tonic-gate 			(void) fclose(fp);
1737c478bd9Sstevel@tonic-gate 			return (NS_PARSE_ERR);
1747c478bd9Sstevel@tonic-gate 		}
1757c478bd9Sstevel@tonic-gate 		first = 0;
1767c478bd9Sstevel@tonic-gate 		switch (__s_api_get_configtype(i)) {
1777c478bd9Sstevel@tonic-gate 		case SERVERCONFIG:
1787c478bd9Sstevel@tonic-gate 		case CLIENTCONFIG:
1797c478bd9Sstevel@tonic-gate 			if (cred_file == 0) {
1807c478bd9Sstevel@tonic-gate 				ret = __ns_ldap_setParamValue(ptr, i, value,
18182c6b8c6Smj 				    error);
1827c478bd9Sstevel@tonic-gate 				if (ret != NS_SUCCESS) {
1837c478bd9Sstevel@tonic-gate 					(void) fclose(fp);
1847c478bd9Sstevel@tonic-gate 					return (ret);
1857c478bd9Sstevel@tonic-gate 				}
1867c478bd9Sstevel@tonic-gate 			} else if (i != NS_LDAP_FILE_VERSION_P) {
1877c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
18882c6b8c6Smj 				    gettext("Illegal entry in '%s' on "
18982c6b8c6Smj 				    "line %d"), file, lineno);
1907c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
191*81de4da4SToomas Soome 				    strdup(errstr), NS_PARSE_ERR);
1927c478bd9Sstevel@tonic-gate 				(void) fclose(fp);
1937c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
1947c478bd9Sstevel@tonic-gate 			}
1957c478bd9Sstevel@tonic-gate 			break;
1967c478bd9Sstevel@tonic-gate 		case CREDCONFIG:
1977c478bd9Sstevel@tonic-gate 			if (i == NS_LDAP_FILE_VERSION_P)
1987c478bd9Sstevel@tonic-gate 				break;
1997c478bd9Sstevel@tonic-gate 			if (cred_file) {
2007c478bd9Sstevel@tonic-gate 				ret = __ns_ldap_setParamValue(ptr, i, value,
20182c6b8c6Smj 				    error);
2027c478bd9Sstevel@tonic-gate 				if (ret != NS_SUCCESS) {
2037c478bd9Sstevel@tonic-gate 					(void) fclose(fp);
2047c478bd9Sstevel@tonic-gate 					return (ret);
2057c478bd9Sstevel@tonic-gate 				}
2067c478bd9Sstevel@tonic-gate 			} else {
2077c478bd9Sstevel@tonic-gate 				(void) snprintf(errstr, sizeof (errstr),
20882c6b8c6Smj 				    gettext("Illegal entry in '%s' on "
20982c6b8c6Smj 				    "line %d"), file, lineno);
2107c478bd9Sstevel@tonic-gate 				MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX,
211*81de4da4SToomas Soome 				    strdup(errstr), NS_PARSE_ERR);
2127c478bd9Sstevel@tonic-gate 				(void) fclose(fp);
2137c478bd9Sstevel@tonic-gate 				return (NS_PARSE_ERR);
2147c478bd9Sstevel@tonic-gate 			}
2157c478bd9Sstevel@tonic-gate 		}
2167c478bd9Sstevel@tonic-gate 	}
2177c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
2187c478bd9Sstevel@tonic-gate 	if (!cred_file && emptyfile) {
2197c478bd9Sstevel@tonic-gate 		/* Error in read_line */
2207c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
22182c6b8c6Smj 		    gettext("Empty config file: '%s'"), file);
2227c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
223*81de4da4SToomas Soome 		    NS_PARSE_ERR);
2247c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
2257c478bd9Sstevel@tonic-gate 	}
2267c478bd9Sstevel@tonic-gate 	if (linelen == -2) {
2277c478bd9Sstevel@tonic-gate 		/* Error in read_line */
2287c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
22982c6b8c6Smj 		    gettext("Line too long in '%s'"), file);
2307c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *error, NS_CONFIG_SYNTAX, strdup(errstr),
231*81de4da4SToomas Soome 		    NS_PARSE_ERR);
2327c478bd9Sstevel@tonic-gate 		return (NS_PARSE_ERR);
2337c478bd9Sstevel@tonic-gate 	}
2347c478bd9Sstevel@tonic-gate 	return (NS_SUCCESS);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 
238e1dd0a2fSth static
239e1dd0a2fSth ns_ldap_return_code
set_attr(ns_config_t * config_struct,char * attr_name,char * attr_val,ns_ldap_error_t ** errorp)240*81de4da4SToomas Soome set_attr(ns_config_t *config_struct, char *attr_name, char *attr_val,
241*81de4da4SToomas Soome     ns_ldap_error_t **errorp)
242e1dd0a2fSth {
243e1dd0a2fSth 	ParamIndexType	idx;
244e1dd0a2fSth 	char		errmsg[MAXERROR];
245e1dd0a2fSth 
246e1dd0a2fSth 	if (errorp == NULL) {
247e1dd0a2fSth 		return (NS_LDAP_INVALID_PARAM);
248e1dd0a2fSth 	}
249e1dd0a2fSth 
250e1dd0a2fSth 	*errorp = NULL;
251e1dd0a2fSth 
252e1dd0a2fSth 	/*
253e1dd0a2fSth 	 * This double call is made due to the presence of
254e1dd0a2fSth 	 * two sets of LDAP config. attribute names.
255e1dd0a2fSth 	 * An LDAP configuration can be obtained either from a server
256e1dd0a2fSth 	 * or from SMF. The former sends a DUA with attributes' names
257e1dd0a2fSth 	 * styled like "preferredServerList". But local configurations
258e1dd0a2fSth 	 * will have names inherited from the /var/ldap/ldap* files such as
259e1dd0a2fSth 	 * "NS_LDAP_SERVER_PREF".
260e1dd0a2fSth 	 * So, the standalone bits are able to process both sets of
261e1dd0a2fSth 	 * attributes' names.
262e1dd0a2fSth 	 */
263e1dd0a2fSth 	if (__s_api_get_profiletype(attr_name, &idx) < 0 &&
264e1dd0a2fSth 	    __s_api_get_versiontype(config_struct, attr_name, &idx) < 0) {
265e1dd0a2fSth 		(void) snprintf(errmsg, sizeof (errmsg),
266e1dd0a2fSth 		    gettext("Illegal DUAProfile property: <%s>."), attr_name);
26751b02b29SToomas Soome 		MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg),
26851b02b29SToomas Soome 		    NS_LDAP_MEMORY);
269e1dd0a2fSth 		return (NS_LDAP_CONFIG);
270e1dd0a2fSth 	}
271e1dd0a2fSth 
272e1dd0a2fSth 	return (__ns_ldap_setParamValue(config_struct, idx, attr_val, errorp));
273e1dd0a2fSth }
274e1dd0a2fSth 
275e1dd0a2fSth 
276e1dd0a2fSth /*
277e1dd0a2fSth  * This function creates a configuration which will be used
278e1dd0a2fSth  * for all LDAP requests in the Standalone mode.
279e1dd0a2fSth  *
280e1dd0a2fSth  * INPUT:
281e1dd0a2fSth  *     config - a buffer returned by __ns_ldap_getConnectionInfo()'s
282e1dd0a2fSth  *              dua_profile parameter.
283e1dd0a2fSth  *
284e1dd0a2fSth  */
285e1dd0a2fSth ns_config_t *
__s_api_create_config_door_str(char * config,ns_ldap_error_t ** errorp)286e1dd0a2fSth __s_api_create_config_door_str(char *config, ns_ldap_error_t **errorp)
287e1dd0a2fSth {
288e1dd0a2fSth 	char		*attr, *attrName, *attrVal, *rest;
289e1dd0a2fSth 	ns_config_t	*configStruct = NULL;
290e1dd0a2fSth 	char		errmsg[MAXERROR];
291e1dd0a2fSth 
292e1dd0a2fSth 	if (config == NULL || errorp == NULL)
293e1dd0a2fSth 		return (NULL);
294e1dd0a2fSth 
295e1dd0a2fSth 	if ((configStruct = __s_api_create_config()) == NULL) {
296e1dd0a2fSth 		return (NULL);
297e1dd0a2fSth 	}
298e1dd0a2fSth 
299e1dd0a2fSth 	*errorp = NULL;
300e1dd0a2fSth 
301e1dd0a2fSth 	attr = strtok_r(config, DOORLINESEP, &rest);
302e1dd0a2fSth 	if (!attr) {
303e1dd0a2fSth 		__s_api_destroy_config(configStruct);
304e1dd0a2fSth 		(void) snprintf(errmsg, sizeof (errmsg),
305e1dd0a2fSth 		    gettext("DUAProfile received from the server"
306e1dd0a2fSth 		    " has bad format"));
307e1dd0a2fSth 		MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
308e1dd0a2fSth 		return (NULL);
309e1dd0a2fSth 	}
310e1dd0a2fSth 
311e1dd0a2fSth 	do {
312e1dd0a2fSth 		__s_api_split_key_value(attr, &attrName, &attrVal);
313e1dd0a2fSth 
314e1dd0a2fSth 		if (attrName == NULL || attrVal == NULL) {
315e1dd0a2fSth 			__s_api_destroy_config(configStruct);
316e1dd0a2fSth 			(void) snprintf(errmsg, sizeof (errmsg),
317e1dd0a2fSth 			    gettext("Attribute %s is not valid"), attr);
318e1dd0a2fSth 			MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG,
319e1dd0a2fSth 			    strdup(errmsg), NULL);
320e1dd0a2fSth 			return (NULL);
321e1dd0a2fSth 		}
322e1dd0a2fSth 
323e1dd0a2fSth 		/* Get the version of the profile. */
324e1dd0a2fSth 		if (strcasecmp(attrName, "objectclass") == 0) {
325e1dd0a2fSth 			if (strcasecmp(attrVal, _PROFILE2_OBJECTCLASS) == 0) {
326e1dd0a2fSth 				if (__ns_ldap_setParamValue(configStruct,
327e1dd0a2fSth 				    NS_LDAP_FILE_VERSION_P,
328e1dd0a2fSth 				    NS_LDAP_VERSION_2,
329e1dd0a2fSth 				    errorp) != NS_LDAP_SUCCESS) {
330e1dd0a2fSth 					__s_api_destroy_config(configStruct);
331e1dd0a2fSth 					return (NULL);
332e1dd0a2fSth 				}
333dd1104fbSMichen Chang 			} else if (strcasecmp(attrVal,
334dd1104fbSMichen Chang 			    _PROFILE1_OBJECTCLASS) == 0) {
335dd1104fbSMichen Chang 				if (__ns_ldap_setParamValue(configStruct,
336dd1104fbSMichen Chang 				    NS_LDAP_FILE_VERSION_P,
337dd1104fbSMichen Chang 				    NS_LDAP_VERSION_1,
338dd1104fbSMichen Chang 				    errorp) != NS_LDAP_SUCCESS) {
339dd1104fbSMichen Chang 					__s_api_destroy_config(configStruct);
340dd1104fbSMichen Chang 					return (NULL);
341dd1104fbSMichen Chang 				}
342e1dd0a2fSth 			}
343e1dd0a2fSth 			continue;
344e1dd0a2fSth 		}
345e1dd0a2fSth 
346e1dd0a2fSth 		if (set_attr(configStruct, attrName, attrVal, errorp) !=
347e1dd0a2fSth 		    NS_LDAP_SUCCESS) {
348e1dd0a2fSth 			__s_api_destroy_config(configStruct);
349e1dd0a2fSth 			return (NULL);
350e1dd0a2fSth 		}
351e1dd0a2fSth 	} while (attr = strtok_r(NULL, DOORLINESEP, &rest));
352e1dd0a2fSth 
353e1dd0a2fSth 	if (__s_api_crosscheck(configStruct, errmsg, B_FALSE) != NS_SUCCESS) {
354e1dd0a2fSth 		MKERROR(LOG_ERR, *errorp, NS_LDAP_CONFIG, strdup(errmsg), NULL);
355e1dd0a2fSth 		__s_api_destroy_config(configStruct);
356e1dd0a2fSth 		return (NULL);
357e1dd0a2fSth 	}
358e1dd0a2fSth 
359e1dd0a2fSth 	return (configStruct);
360e1dd0a2fSth }
361e1dd0a2fSth 
362e1dd0a2fSth 
3637c478bd9Sstevel@tonic-gate /*
3647c478bd9Sstevel@tonic-gate  * Cache Manager side of configuration file loading
3657c478bd9Sstevel@tonic-gate  */
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_LoadConfiguration()3687c478bd9Sstevel@tonic-gate __ns_ldap_LoadConfiguration()
3697c478bd9Sstevel@tonic-gate {
3707c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*error = NULL;
3717c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = NULL;
3727c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
3737c478bd9Sstevel@tonic-gate 	ns_parse_status	ret;
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate 	ptr = __s_api_create_config();
3777c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
3787c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
37982c6b8c6Smj 		    gettext("__ns_ldap_LoadConfiguration: Out of memory."));
3807c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, error, NS_CONFIG_NOTLOADED,
38182c6b8c6Smj 		    strdup(errstr), NULL);
3827c478bd9Sstevel@tonic-gate 		return (error);
3837c478bd9Sstevel@tonic-gate 	}
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 	/* Load in Configuration file */
3867c478bd9Sstevel@tonic-gate 	ret = read_file(ptr, 0, &error);
3877c478bd9Sstevel@tonic-gate 	if (ret != NS_SUCCESS) {
3887c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(ptr);
3897c478bd9Sstevel@tonic-gate 		return (error);
3907c478bd9Sstevel@tonic-gate 	}
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 	/* Load in Credential file */
3937c478bd9Sstevel@tonic-gate 	ret = read_file(ptr, 1, &error);
3947c478bd9Sstevel@tonic-gate 	if (ret != NS_SUCCESS) {
3957c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(ptr);
3967c478bd9Sstevel@tonic-gate 		return (error);
3977c478bd9Sstevel@tonic-gate 	}
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 	if (__s_api_crosscheck(ptr, errstr, B_TRUE) != NS_SUCCESS) {
4007c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(ptr);
4017c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, error, NS_CONFIG_SYNTAX, strdup(errstr), NULL);
4027c478bd9Sstevel@tonic-gate 		return (error);
4037c478bd9Sstevel@tonic-gate 	}
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	__s_api_init_config(ptr);
4067c478bd9Sstevel@tonic-gate 	return (NULL);
4077c478bd9Sstevel@tonic-gate }
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 
410434c5a06SMilan Jurik int
__print2buf(LineBuf * line,const char * toprint,char * sep)411434c5a06SMilan Jurik __print2buf(LineBuf *line, const char *toprint, char *sep)
4127c478bd9Sstevel@tonic-gate {
4137c478bd9Sstevel@tonic-gate 	int	newsz = 0;
4147c478bd9Sstevel@tonic-gate 	int	newmax = 0;
4157c478bd9Sstevel@tonic-gate 	char	*str;
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	if (line == NULL)
4187c478bd9Sstevel@tonic-gate 		return (-1);
4197c478bd9Sstevel@tonic-gate 
4207c478bd9Sstevel@tonic-gate 	newsz = strlen(toprint) + line->len + 1;
421434c5a06SMilan Jurik 	if (sep != NULL) {
422434c5a06SMilan Jurik 		newsz += strlen(sep);
4237c478bd9Sstevel@tonic-gate 	}
4247c478bd9Sstevel@tonic-gate 	if (line->alloc == 0 || newsz > line->alloc) {
4257c478bd9Sstevel@tonic-gate 		/* Round up to next buffer and add 1 */
4267c478bd9Sstevel@tonic-gate 		newmax = (((newsz+(BUFSIZ-1))/BUFSIZ)+1) * BUFSIZ;
4277c478bd9Sstevel@tonic-gate 		if (line->alloc == 0)
4287c478bd9Sstevel@tonic-gate 			line->str = (char *)calloc(newmax, 1);
4297c478bd9Sstevel@tonic-gate 		else {
4307c478bd9Sstevel@tonic-gate 			/*
4317c478bd9Sstevel@tonic-gate 			 * if realloc() returns NULL,
4327c478bd9Sstevel@tonic-gate 			 * the original buffer is untouched.
4337c478bd9Sstevel@tonic-gate 			 * It needs to be freed.
4347c478bd9Sstevel@tonic-gate 			 */
4357c478bd9Sstevel@tonic-gate 			str = (char *)realloc(line->str, newmax);
4367c478bd9Sstevel@tonic-gate 			if (str == NULL) {
4377c478bd9Sstevel@tonic-gate 				free(line->str);
4387c478bd9Sstevel@tonic-gate 				line->str = NULL;
4397c478bd9Sstevel@tonic-gate 			}
4407c478bd9Sstevel@tonic-gate 			else
4417c478bd9Sstevel@tonic-gate 				line->str = str;
4427c478bd9Sstevel@tonic-gate 		}
4437c478bd9Sstevel@tonic-gate 		line->alloc = newmax;
4447c478bd9Sstevel@tonic-gate 		if (line->str == NULL) {
4457c478bd9Sstevel@tonic-gate 			line->alloc = 0;
4467c478bd9Sstevel@tonic-gate 			line->len = 0;
4477c478bd9Sstevel@tonic-gate 			return (-1);
4487c478bd9Sstevel@tonic-gate 		}
4497c478bd9Sstevel@tonic-gate 	}
4507c478bd9Sstevel@tonic-gate 	/* now add new 'toprint' data to buffer */
4517c478bd9Sstevel@tonic-gate 	(void) strlcat(line->str, toprint, line->alloc);
452434c5a06SMilan Jurik 	if (sep != NULL) {
453434c5a06SMilan Jurik 		(void) strlcat(line->str, sep, line->alloc);
4547c478bd9Sstevel@tonic-gate 	}
4557c478bd9Sstevel@tonic-gate 	line->len = newsz;
4567c478bd9Sstevel@tonic-gate 	return (0);
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 
4607c478bd9Sstevel@tonic-gate /*
4617c478bd9Sstevel@tonic-gate  * __ns_ldap_LoadDoorInfo is a routine used by the ldapcachemgr
4627c478bd9Sstevel@tonic-gate  * to create a configuration buffer to transmit back to a client
4637c478bd9Sstevel@tonic-gate  * domainname is transmitted to ldapcachemgr and ldapcachemgr uses
4647c478bd9Sstevel@tonic-gate  * it to select a configuration to transmit back.  Otherwise it
4657c478bd9Sstevel@tonic-gate  * is essentially unused in sldap.
466b57459abSJulian Pullen  * If cred_only is not 0, then only the credentials for shadow
467b57459abSJulian Pullen  * update are taken care of.
4687c478bd9Sstevel@tonic-gate  */
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_LoadDoorInfo(LineBuf * configinfo,char * domainname,ns_config_t * new,int cred_only)471b57459abSJulian Pullen __ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname,
472*81de4da4SToomas Soome     ns_config_t *new, int cred_only)
4737c478bd9Sstevel@tonic-gate {
4747c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
4757c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
4767c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*errorp;
4777c478bd9Sstevel@tonic-gate 	char		*str;
4787c478bd9Sstevel@tonic-gate 	ParamIndexType	i = 0;
479e1dd0a2fSth 	int		len;
480e1dd0a2fSth 	ldap_config_out_t *cout;
481e1dd0a2fSth 
482e1dd0a2fSth 	/*
483e1dd0a2fSth 	 * If new is NULL, it outputs the flatten data of current default
484e1dd0a2fSth 	 * config, if it's non-NULL, it outputs the flatten data of a temporary
485e1dd0a2fSth 	 * config. It's used to compare the new config data with the current
486e1dd0a2fSth 	 * default config data.
487e1dd0a2fSth 	 */
488e1dd0a2fSth 	if (new == NULL)
489e1dd0a2fSth 		ptr = __s_api_get_default_config();
490e1dd0a2fSth 	else
491e1dd0a2fSth 		ptr = new;
4927c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
4937c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
4947c478bd9Sstevel@tonic-gate 		    gettext("No configuration information available for %s."),
4957c478bd9Sstevel@tonic-gate 		    domainname == NULL ? "<no domain specified>" : domainname);
4967c478bd9Sstevel@tonic-gate 		MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
49782c6b8c6Smj 		    strdup(errstr), NULL);
4987c478bd9Sstevel@tonic-gate 		return (errorp);
4997c478bd9Sstevel@tonic-gate 	}
5007c478bd9Sstevel@tonic-gate 	(void) memset((char *)configinfo, 0, sizeof (LineBuf));
5017c478bd9Sstevel@tonic-gate 	for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
502b57459abSJulian Pullen 		if (cred_only) {
503b57459abSJulian Pullen 			/* only exposed credential for shadow update */
504b57459abSJulian Pullen 			if (i != NS_LDAP_ADMIN_BINDDN_P &&
505b57459abSJulian Pullen 			    i != NS_LDAP_ADMIN_BINDPASSWD_P)
506b57459abSJulian Pullen 				continue;
507b57459abSJulian Pullen 		} else {
508b57459abSJulian Pullen 			/* credential for shadow update is not to be exposed */
509b57459abSJulian Pullen 			if (i == NS_LDAP_ADMIN_BINDDN_P ||
510b57459abSJulian Pullen 			    i == NS_LDAP_ADMIN_BINDPASSWD_P)
511b57459abSJulian Pullen 				continue;
512b57459abSJulian Pullen 		}
513434c5a06SMilan Jurik 		str = __s_api_strValue(ptr, i, NS_DOOR_FMT);
5147c478bd9Sstevel@tonic-gate 		if (str == NULL)
5157c478bd9Sstevel@tonic-gate 			continue;
516434c5a06SMilan Jurik 		if (__print2buf(configinfo, str, DOORLINESEP)) {
5177c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
518434c5a06SMilan Jurik 			    gettext("__print2buf: Out of memory."));
5197c478bd9Sstevel@tonic-gate 			MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
52082c6b8c6Smj 			    strdup(errstr), NULL);
5217c478bd9Sstevel@tonic-gate 			__s_api_release_config(ptr);
5227c478bd9Sstevel@tonic-gate 			free(str);
523434c5a06SMilan Jurik 			return (errorp);
5247c478bd9Sstevel@tonic-gate 		}
525434c5a06SMilan Jurik 		free(str);
5267c478bd9Sstevel@tonic-gate 	}
527e1dd0a2fSth 	if (new == NULL)
528e1dd0a2fSth 		__s_api_release_config(ptr);
529e1dd0a2fSth 
530e1dd0a2fSth 	/*
531e1dd0a2fSth 	 * The new interface of the configuration between ldap_cachemgr
532e1dd0a2fSth 	 * & libsldap contains a header structure ldap_config_out_t.
533e1dd0a2fSth 	 * The flatten configuration data configinfo->str is cloned
534e1dd0a2fSth 	 * to cout->config_str, configinfo->len is saved in
535e1dd0a2fSth 	 * cout->data_size and cout->cookie is set later after this function
536e1dd0a2fSth 	 * is returned in ldap_cachemgr.
537e1dd0a2fSth 	 * configinfo->str & configinfo->len are reused to save info of
538e1dd0a2fSth 	 * header + data.
539e1dd0a2fSth 	 * The format:
540e1dd0a2fSth 	 * [cookie|data_size|config_str .............]
541e1dd0a2fSth 	 */
542e1dd0a2fSth 
543e1dd0a2fSth 	if (configinfo->str) {
544e1dd0a2fSth 		len = sizeof (ldap_config_out_t) - sizeof (int) +
545e1dd0a2fSth 		    configinfo->len;
546e1dd0a2fSth 		if ((cout = calloc(1, len)) == NULL) {
547e1dd0a2fSth 			free(configinfo->str);
548e1dd0a2fSth 			configinfo->str = NULL;
549e1dd0a2fSth 			configinfo->len = 0;
550e1dd0a2fSth 			(void) snprintf(errstr, sizeof (errstr),
551e1dd0a2fSth 			    gettext("calloc: Out of memory."));
552e1dd0a2fSth 			MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
553e1dd0a2fSth 			    strdup(errstr), NULL);
554e1dd0a2fSth 			return (errorp);
555e1dd0a2fSth 		}
556e1dd0a2fSth 		/*
557e1dd0a2fSth 		 * cout->cookie is set by the caller,
558e1dd0a2fSth 		 * which is in ldap_cachemgr.
559e1dd0a2fSth 		 */
560e1dd0a2fSth 		cout->data_size = configinfo->len;
561e1dd0a2fSth 		(void) memcpy(cout->config_str, configinfo->str,
562e1dd0a2fSth 		    configinfo->len);
563e1dd0a2fSth 		free(configinfo->str);
564e1dd0a2fSth 		configinfo->str = (char *)cout;
565e1dd0a2fSth 		configinfo->len = len;
566e1dd0a2fSth 	}
5677c478bd9Sstevel@tonic-gate 	return (NULL);
5687c478bd9Sstevel@tonic-gate }
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_DumpLdif(char * filename)5727c478bd9Sstevel@tonic-gate __ns_ldap_DumpLdif(char *filename)
5737c478bd9Sstevel@tonic-gate {
5747c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
5757c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
5767c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*errorp;
5777c478bd9Sstevel@tonic-gate 	char		*str;
5787c478bd9Sstevel@tonic-gate 	FILE		*fp;
5797c478bd9Sstevel@tonic-gate 	ParamIndexType	i = 0;
5807c478bd9Sstevel@tonic-gate 	char		*profile, *container, *base;
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 	ptr = __s_api_get_default_config();
5837c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
5847c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
5857c478bd9Sstevel@tonic-gate 		    gettext("No configuration information available."));
5867c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
58782c6b8c6Smj 		    NULL);
5887c478bd9Sstevel@tonic-gate 		return (errorp);
5897c478bd9Sstevel@tonic-gate 	}
5907c478bd9Sstevel@tonic-gate 
5917c478bd9Sstevel@tonic-gate 	if (filename == NULL) {
5927c478bd9Sstevel@tonic-gate 		fp = stdout;
5937c478bd9Sstevel@tonic-gate 	} else {
594004388ebScasper 		fp = fopen(filename, "wF");
5957c478bd9Sstevel@tonic-gate 		if (fp == NULL) {
5967c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
59782c6b8c6Smj 			    gettext("Unable to open filename %s for ldif "
59882c6b8c6Smj 			    "dump (errno=%d)."), filename, errno);
5997c478bd9Sstevel@tonic-gate 			MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE,
60082c6b8c6Smj 			    strdup(errstr), NULL);
6017c478bd9Sstevel@tonic-gate 			__s_api_release_config(ptr);
6027c478bd9Sstevel@tonic-gate 			return (errorp);
6037c478bd9Sstevel@tonic-gate 		}
6047c478bd9Sstevel@tonic-gate 		(void) fchmod(fileno(fp), 0444);
6057c478bd9Sstevel@tonic-gate 	}
6067c478bd9Sstevel@tonic-gate 
6077c478bd9Sstevel@tonic-gate 	if (ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_ptype != CHARPTR ||
6087c478bd9Sstevel@tonic-gate 	    ptr->paramList[NS_LDAP_PROFILE_P].ns_ptype != CHARPTR) {
6097c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
61082c6b8c6Smj 		    gettext("Required BaseDN and/or Profile name "
61182c6b8c6Smj 		    "ldif fields not present"));
6127c478bd9Sstevel@tonic-gate 		MKERROR(LOG_WARNING, errorp, NS_CONFIG_FILE, strdup(errstr),
61382c6b8c6Smj 		    NULL);
6147c478bd9Sstevel@tonic-gate 		__s_api_release_config(ptr);
6157c478bd9Sstevel@tonic-gate 		return (errorp);
6167c478bd9Sstevel@tonic-gate 	}
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate 	profile = ptr->paramList[NS_LDAP_PROFILE_P].ns_pc;
6197c478bd9Sstevel@tonic-gate 	base = ptr->paramList[NS_LDAP_SEARCH_BASEDN_P].ns_pc;
6207c478bd9Sstevel@tonic-gate 	container = _PROFILE_CONTAINER;
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 	/*
6237c478bd9Sstevel@tonic-gate 	 * Construct DN, but since this is the profile, there is no need
6247c478bd9Sstevel@tonic-gate 	 * to worry about mapping.  The profile itself can not be mapped
6257c478bd9Sstevel@tonic-gate 	 */
6267c478bd9Sstevel@tonic-gate 	(void) fprintf(fp, "dn: cn=%s,ou=%s,%s\n", profile, container, base);
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	/* dump objectclass names */
6297c478bd9Sstevel@tonic-gate 	if (ptr->version == NS_LDAP_V1) {
63082c6b8c6Smj 		(void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n",
63182c6b8c6Smj 		    _PROFILE1_OBJECTCLASS);
6327c478bd9Sstevel@tonic-gate 	} else {
63382c6b8c6Smj 		(void) fprintf(fp, "ObjectClass: top\nObjectClass: %s\n",
63482c6b8c6Smj 		    _PROFILE2_OBJECTCLASS);
6357c478bd9Sstevel@tonic-gate 	}
6367c478bd9Sstevel@tonic-gate 
6377c478bd9Sstevel@tonic-gate 	/* For each parameter - construct value */
6387c478bd9Sstevel@tonic-gate 	for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
639434c5a06SMilan Jurik 		str = __s_api_strValue(ptr, i, NS_LDIF_FMT);
6407c478bd9Sstevel@tonic-gate 		if (str == NULL)
6417c478bd9Sstevel@tonic-gate 			continue;
6427c478bd9Sstevel@tonic-gate 		/*
643dd1104fbSMichen Chang 		 * don't dump binddn, bind password, admin binddn, admin
644dd1104fbSMichen Chang 		 * bind password, enableShadowUpdate flag, or cert path
645dd1104fbSMichen Chang 		 * as they are not part of version 2 profiles
6467c478bd9Sstevel@tonic-gate 		 */
647dd1104fbSMichen Chang 		if ((i != NS_LDAP_BINDDN_P) &&
648dd1104fbSMichen Chang 		    (i != NS_LDAP_BINDPASSWD_P) &&
649dd1104fbSMichen Chang 		    (i != NS_LDAP_ADMIN_BINDDN_P) &&
650dd1104fbSMichen Chang 		    (i != NS_LDAP_ADMIN_BINDPASSWD_P) &&
651dd1104fbSMichen Chang 		    (i != NS_LDAP_ENABLE_SHADOW_UPDATE_P) &&
65282c6b8c6Smj 		    (i != NS_LDAP_HOST_CERTPATH_P))
6537c478bd9Sstevel@tonic-gate 			(void) fprintf(fp, "%s\n", str);
654434c5a06SMilan Jurik 		free(str);
6557c478bd9Sstevel@tonic-gate 	}
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 	if (filename != NULL)
6587c478bd9Sstevel@tonic-gate 		(void) fclose(fp);
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
6617c478bd9Sstevel@tonic-gate 	return (NULL);
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate /*
6657c478bd9Sstevel@tonic-gate  * This routine can process the configuration  and/or
6667c478bd9Sstevel@tonic-gate  * the credential files at the same time.
6677c478bd9Sstevel@tonic-gate  * files is char *[3] = { "config", "cred", NULL };
6687c478bd9Sstevel@tonic-gate  */
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate static
6717c478bd9Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_DumpConfigFiles(char ** files)6727c478bd9Sstevel@tonic-gate __ns_ldap_DumpConfigFiles(char **files)
6737c478bd9Sstevel@tonic-gate {
6747c478bd9Sstevel@tonic-gate 	char		*filename;
6757c478bd9Sstevel@tonic-gate 	int		fi;
6767c478bd9Sstevel@tonic-gate 	int		docred;
6777c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
6787c478bd9Sstevel@tonic-gate 	char		*str;
6797c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
6807c478bd9Sstevel@tonic-gate 	ParamIndexType	i = 0;
6817c478bd9Sstevel@tonic-gate 	FILE		*fp;
6827c478bd9Sstevel@tonic-gate 	int		rc;
68382c6b8c6Smj 	ns_ldap_error_t	*errorp = NULL;
6847c478bd9Sstevel@tonic-gate 	struct stat	buf;
6857c478bd9Sstevel@tonic-gate 	int		cfgtype;
68682c6b8c6Smj 	boolean_t	file_export_error = B_FALSE;
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	ptr = __s_api_get_default_config();
6897c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
6907c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
69182c6b8c6Smj 		    gettext("No configuration information available."));
6927c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
69382c6b8c6Smj 		    NULL);
6947c478bd9Sstevel@tonic-gate 		return (errorp);
6957c478bd9Sstevel@tonic-gate 	}
6967c478bd9Sstevel@tonic-gate 
6977c478bd9Sstevel@tonic-gate 	for (fi = 0; fi < 2; fi++) {
6987c478bd9Sstevel@tonic-gate 		docred = 0;
6997c478bd9Sstevel@tonic-gate 		filename = files[fi];
7007c478bd9Sstevel@tonic-gate 		if (filename == NULL)
7017c478bd9Sstevel@tonic-gate 			continue;
7027c478bd9Sstevel@tonic-gate 		if (fi == 1)
7037c478bd9Sstevel@tonic-gate 			docred++;
7047c478bd9Sstevel@tonic-gate 		rc = stat(filename, &buf);
705004388ebScasper 		fp = fopen(filename, "wF");
7067c478bd9Sstevel@tonic-gate 		if (fp == NULL) {
7077c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
70882c6b8c6Smj 			    gettext("Unable to open filename %s"
70982c6b8c6Smj 			    " for configuration dump (%s)."),
71082c6b8c6Smj 			    filename, strerror(errno));
71182c6b8c6Smj 			MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE,
71282c6b8c6Smj 			    strdup(errstr), NULL);
7137c478bd9Sstevel@tonic-gate 			__s_api_release_config(ptr);
7147c478bd9Sstevel@tonic-gate 			return (errorp);
7157c478bd9Sstevel@tonic-gate 		}
71682c6b8c6Smj 		if (rc == 0) {
71782c6b8c6Smj 			if (fchmod(fileno(fp), buf.st_mode) != 0) {
71882c6b8c6Smj 				(void) snprintf(errstr, sizeof (errstr),
71982c6b8c6Smj 				    gettext("Unable to set permissions for file"
72082c6b8c6Smj 				    " %s for configuration dump (%s)."),
72182c6b8c6Smj 				    filename, strerror(errno));
72282c6b8c6Smj 				(void) fclose(fp);
72382c6b8c6Smj 				file_export_error = B_TRUE;
72482c6b8c6Smj 				break;
72582c6b8c6Smj 			}
72682c6b8c6Smj 		} else {
72782c6b8c6Smj 			if (fchmod(fileno(fp), 0400) != 0) {
72882c6b8c6Smj 				(void) snprintf(errstr, sizeof (errstr),
72982c6b8c6Smj 				    gettext("Unable to set permissions for file"
73082c6b8c6Smj 				    " %s for configuration dump (%s)."),
73182c6b8c6Smj 				    filename, strerror(errno));
73282c6b8c6Smj 				(void) fclose(fp);
73382c6b8c6Smj 				file_export_error = B_TRUE;
73482c6b8c6Smj 				break;
73582c6b8c6Smj 			}
73682c6b8c6Smj 		}
73782c6b8c6Smj 		if (fprintf(fp, "#\n# %s\n#\n", DONOTEDIT) < 0) {
73882c6b8c6Smj 			(void) snprintf(errstr, sizeof (errstr), gettext(
73982c6b8c6Smj 			    "Writing to file %s for configuration dump failed "
74082c6b8c6Smj 			    "(%s)."), filename, strerror(errno));
74182c6b8c6Smj 			file_export_error = B_TRUE;
74282c6b8c6Smj 		}
7437c478bd9Sstevel@tonic-gate 
7447c478bd9Sstevel@tonic-gate 		/* assume VERSION is set and it outputs first */
7457c478bd9Sstevel@tonic-gate 
7467c478bd9Sstevel@tonic-gate 		/* For each parameter - construct value */
74782c6b8c6Smj 		for (i = 0; !file_export_error && (i <= NS_LDAP_MAX_PIT_P);
74882c6b8c6Smj 		    i++) {
7497c478bd9Sstevel@tonic-gate 			cfgtype = __s_api_get_configtype(i);
7507c478bd9Sstevel@tonic-gate 			if ((docred == 0 && cfgtype == CREDCONFIG) ||
75182c6b8c6Smj 			    (docred == 1 && cfgtype != CREDCONFIG))
7527c478bd9Sstevel@tonic-gate 				continue;
7537c478bd9Sstevel@tonic-gate 
754434c5a06SMilan Jurik 			str = __s_api_strValue(ptr, i, NS_FILE_FMT);
7557c478bd9Sstevel@tonic-gate 			if (str == NULL)
7567c478bd9Sstevel@tonic-gate 				continue;
75782c6b8c6Smj 			if (fprintf(fp, "%s\n", str) < 0) {
75882c6b8c6Smj 				(void) snprintf(errstr, sizeof (errstr),
75982c6b8c6Smj 				    gettext("Writing to file %s for"
76082c6b8c6Smj 				    "configuration dump failed (%s)."),
76182c6b8c6Smj 				    filename, strerror(errno));
76282c6b8c6Smj 				file_export_error = B_TRUE;
76382c6b8c6Smj 			}
76482c6b8c6Smj 
765434c5a06SMilan Jurik 			free(str);
7667c478bd9Sstevel@tonic-gate 		}
76782c6b8c6Smj 		if (fclose(fp) != 0) {
76882c6b8c6Smj 			/* Break if error already hit */
76982c6b8c6Smj 			if (file_export_error)
77082c6b8c6Smj 				break;
77182c6b8c6Smj 
77282c6b8c6Smj 			(void) snprintf(errstr, sizeof (errstr), gettext(
77382c6b8c6Smj 			    "Writing to file %s for configuration dump failed "
77482c6b8c6Smj 			    "during file close (%s)."), filename,
77582c6b8c6Smj 			    strerror(errno));
77682c6b8c6Smj 			file_export_error = B_TRUE;
77782c6b8c6Smj 			break;
77882c6b8c6Smj 		}
77982c6b8c6Smj 
78082c6b8c6Smj 	}
78182c6b8c6Smj 
78282c6b8c6Smj 	if (file_export_error) {
78382c6b8c6Smj 		MKERROR(LOG_ERR, errorp, NS_CONFIG_FILE,
78482c6b8c6Smj 		    strdup(errstr), NULL);
78582c6b8c6Smj 		(void) unlink(filename);
7867c478bd9Sstevel@tonic-gate 	}
7877c478bd9Sstevel@tonic-gate 
7887c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
78982c6b8c6Smj 	return (errorp);
7907c478bd9Sstevel@tonic-gate }
7917c478bd9Sstevel@tonic-gate 
7927c478bd9Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_DumpConfiguration(char * file)7937c478bd9Sstevel@tonic-gate __ns_ldap_DumpConfiguration(char *file)
7947c478bd9Sstevel@tonic-gate {
7957c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*ret;
7967c478bd9Sstevel@tonic-gate 	char		*files[3];
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate 	files[0] = NULL;
7997c478bd9Sstevel@tonic-gate 	files[1] = NULL;
8007c478bd9Sstevel@tonic-gate 	files[2] = NULL;
8017c478bd9Sstevel@tonic-gate 	if (strcmp(file, NSCONFIGFILE) == 0) {
8027c478bd9Sstevel@tonic-gate 		files[0] = file;
8037c478bd9Sstevel@tonic-gate 	} else if (strcmp(file, NSCONFIGREFRESH) == 0) {
8047c478bd9Sstevel@tonic-gate 		files[0] = file;
8057c478bd9Sstevel@tonic-gate 	} else if (strcmp(file, NSCREDFILE) == 0) {
8067c478bd9Sstevel@tonic-gate 		files[1] = file;
8077c478bd9Sstevel@tonic-gate 	} else if (strcmp(file, NSCREDREFRESH) == 0) {
8087c478bd9Sstevel@tonic-gate 		files[1] = file;
8097c478bd9Sstevel@tonic-gate 	}
8107c478bd9Sstevel@tonic-gate 	ret = __ns_ldap_DumpConfigFiles(files);
8117c478bd9Sstevel@tonic-gate 	return (ret);
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate 
8147c478bd9Sstevel@tonic-gate /*
8157c478bd9Sstevel@tonic-gate  * **************************************************************
8167c478bd9Sstevel@tonic-gate  * Misc Routines
8177c478bd9Sstevel@tonic-gate  * **************************************************************
8187c478bd9Sstevel@tonic-gate  */
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate ns_config_t *
__ns_ldap_make_config(ns_ldap_result_t * result)8217c478bd9Sstevel@tonic-gate __ns_ldap_make_config(ns_ldap_result_t *result)
8227c478bd9Sstevel@tonic-gate {
823382f99a9Smj 	int		l, m;
824434c5a06SMilan Jurik 	char		val[BUFSIZE];
825*81de4da4SToomas Soome 	char		*attrname;
8267c478bd9Sstevel@tonic-gate 	ns_ldap_entry_t	*entry;
8277c478bd9Sstevel@tonic-gate 	ns_ldap_attr_t	*attr;
8287c478bd9Sstevel@tonic-gate 	char		**attrval;
8297c478bd9Sstevel@tonic-gate 	ParamIndexType	index;
8307c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
8317c478bd9Sstevel@tonic-gate 	ns_ldap_error_t	*error = NULL;
8327c478bd9Sstevel@tonic-gate 	int		prof_ver;
8337c478bd9Sstevel@tonic-gate 	ns_config_t	*curr_ptr = NULL;
834382f99a9Smj 	char		errstr[MAXERROR];
835382f99a9Smj 	ns_ldap_error_t	*errorp;
836434c5a06SMilan Jurik 	LineBuf		buffer;
837434c5a06SMilan Jurik 	char		*sepstr;
8387c478bd9Sstevel@tonic-gate 
8397c478bd9Sstevel@tonic-gate 	if (result == NULL)
8407c478bd9Sstevel@tonic-gate 		return (NULL);
8417c478bd9Sstevel@tonic-gate 
842382f99a9Smj 	if (result->entries_count > 1) {
843382f99a9Smj 		(void) snprintf(errstr, MAXERROR,
84482c6b8c6Smj 		    gettext("Configuration Error: More than one profile "
84582c6b8c6Smj 		    "found"));
846382f99a9Smj 		MKERROR(LOG_ERR, errorp, NS_PARSE_ERR, strdup(errstr), NULL);
847382f99a9Smj 		(void) __ns_ldap_freeError(&errorp);
848382f99a9Smj 		return (NULL);
849382f99a9Smj 	}
850382f99a9Smj 
8517c478bd9Sstevel@tonic-gate 	ptr = __s_api_create_config();
8527c478bd9Sstevel@tonic-gate 	if (ptr == NULL)
8537c478bd9Sstevel@tonic-gate 		return (NULL);
8547c478bd9Sstevel@tonic-gate 
8557c478bd9Sstevel@tonic-gate 	curr_ptr = __s_api_get_default_config();
8567c478bd9Sstevel@tonic-gate 	if (curr_ptr == NULL) {
8577c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(ptr);
8587c478bd9Sstevel@tonic-gate 		return (NULL);
8597c478bd9Sstevel@tonic-gate 	}
8607c478bd9Sstevel@tonic-gate 
8617c478bd9Sstevel@tonic-gate 	/* Check to see if the profile is version 1 or version 2 */
8627c478bd9Sstevel@tonic-gate 	prof_ver = 1;
8637c478bd9Sstevel@tonic-gate 	entry = result->entry;
864382f99a9Smj 	for (l = 0; l < entry->attr_count; l++) {
865382f99a9Smj 		attr = entry->attr_pair[l];
8667c478bd9Sstevel@tonic-gate 
867382f99a9Smj 		attrname = attr->attrname;
868382f99a9Smj 		if (attrname == NULL)
869382f99a9Smj 			continue;
870382f99a9Smj 		if (strcasecmp(attrname, "objectclass") == 0) {
871382f99a9Smj 			for (m = 0; m < attr->value_count; m++) {
872382f99a9Smj 				if (strcasecmp(_PROFILE2_OBJECTCLASS,
87382c6b8c6Smj 				    attr->attrvalue[m]) == 0) {
874382f99a9Smj 					prof_ver = 2;
875382f99a9Smj 					break;
8767c478bd9Sstevel@tonic-gate 				}
8777c478bd9Sstevel@tonic-gate 			}
8787c478bd9Sstevel@tonic-gate 		}
8797c478bd9Sstevel@tonic-gate 	}
8807c478bd9Sstevel@tonic-gate 	/* update the configuration to accept v1 or v2 attributes */
8817c478bd9Sstevel@tonic-gate 	if (prof_ver == 1) {
8827c478bd9Sstevel@tonic-gate 		(void) strcpy(val, NS_LDAP_VERSION_1);
88382c6b8c6Smj 		(void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P,
88482c6b8c6Smj 		    val, &error);
8857c478bd9Sstevel@tonic-gate 	} else {
8867c478bd9Sstevel@tonic-gate 		(void) strcpy(val, NS_LDAP_VERSION_2);
88782c6b8c6Smj 		(void) __ns_ldap_setParamValue(ptr, NS_LDAP_FILE_VERSION_P,
88882c6b8c6Smj 		    val, &error);
8897c478bd9Sstevel@tonic-gate 	}
8907c478bd9Sstevel@tonic-gate 
891382f99a9Smj 	for (l = 0; l < entry->attr_count; l++) {
892382f99a9Smj 		attr = entry->attr_pair[l];
8937c478bd9Sstevel@tonic-gate 
894382f99a9Smj 		attrname = attr->attrname;
895382f99a9Smj 		if (attrname == NULL)
896382f99a9Smj 			continue;
897382f99a9Smj 		if (__s_api_get_profiletype(attrname, &index) != 0)
898382f99a9Smj 			continue;
8997c478bd9Sstevel@tonic-gate 
900382f99a9Smj 		attrval = attr->attrvalue;
901382f99a9Smj 		switch (index) {
902382f99a9Smj 		case NS_LDAP_SEARCH_DN_P:
903382f99a9Smj 		case NS_LDAP_SERVICE_SEARCH_DESC_P:
904382f99a9Smj 		case NS_LDAP_ATTRIBUTEMAP_P:
905382f99a9Smj 		case NS_LDAP_OBJECTCLASSMAP_P:
906382f99a9Smj 		case NS_LDAP_SERVICE_CRED_LEVEL_P:
907382f99a9Smj 		case NS_LDAP_SERVICE_AUTH_METHOD_P:
908382f99a9Smj 			/* Multiple Value - insert 1 at a time */
909382f99a9Smj 			for (m = 0; m < attr->value_count; m++) {
9107c478bd9Sstevel@tonic-gate 				(void) __ns_ldap_setParamValue(ptr, index,
91182c6b8c6Smj 				    attrval[m], &error);
9127c478bd9Sstevel@tonic-gate 			}
913382f99a9Smj 			break;
914382f99a9Smj 		default:
915434c5a06SMilan Jurik 			(void) memset((void *)&buffer, 0, sizeof (LineBuf));
916434c5a06SMilan Jurik 
917382f99a9Smj 			/* Single or Multiple Value */
918382f99a9Smj 			for (m = 0; m < attr->value_count; m++) {
919434c5a06SMilan Jurik 				sepstr = NULL;
920434c5a06SMilan Jurik 				if (m != attr->value_count - 1) {
921434c5a06SMilan Jurik 					sepstr = SPACESEP;
922382f99a9Smj 				}
923434c5a06SMilan Jurik 				if (__print2buf(&buffer, attrval[m], sepstr))
924434c5a06SMilan Jurik 					goto makeconfigerror;
925434c5a06SMilan Jurik 			}
926434c5a06SMilan Jurik 			(void) __ns_ldap_setParamValue(ptr, index, buffer.str,
927434c5a06SMilan Jurik 			    &error);
928434c5a06SMilan Jurik 			if (buffer.len > 0) {
929434c5a06SMilan Jurik 				free(buffer.str);
930434c5a06SMilan Jurik 				buffer.len = 0;
931382f99a9Smj 			}
932382f99a9Smj 			break;
9337c478bd9Sstevel@tonic-gate 		}
9347c478bd9Sstevel@tonic-gate 	}
9357c478bd9Sstevel@tonic-gate 	if (ptr->version != NS_LDAP_V1) {
936dd1104fbSMichen Chang 		ParamIndexType i;
93782c6b8c6Smj 		if (curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_ptype == CHARPTR) {
93882c6b8c6Smj 			(void) __ns_ldap_setParamValue(ptr, NS_LDAP_BINDDN_P,
93982c6b8c6Smj 			    curr_ptr->paramList[NS_LDAP_BINDDN_P].ns_pc,
94082c6b8c6Smj 			    &error);
94182c6b8c6Smj 		}
94282c6b8c6Smj 		if (curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_ptype ==
94382c6b8c6Smj 		    CHARPTR) {
94482c6b8c6Smj 			(void) __ns_ldap_setParamValue(ptr,
94582c6b8c6Smj 			    NS_LDAP_BINDPASSWD_P,
94682c6b8c6Smj 			    curr_ptr->paramList[NS_LDAP_BINDPASSWD_P].ns_pc,
94782c6b8c6Smj 			    &error);
94882c6b8c6Smj 		}
949dd1104fbSMichen Chang 		i = NS_LDAP_ENABLE_SHADOW_UPDATE_P;
950dd1104fbSMichen Chang 		if (curr_ptr->paramList[i].ns_ptype == INT) {
951434c5a06SMilan Jurik 			char *valt;
952434c5a06SMilan Jurik 			valt = __s_get_shadowupdate_name(
953dd1104fbSMichen Chang 			    curr_ptr->paramList[i].ns_i);
954434c5a06SMilan Jurik 			(void) __ns_ldap_setParamValue(ptr, i, valt, &error);
955dd1104fbSMichen Chang 		}
956dd1104fbSMichen Chang 		if (curr_ptr->paramList[NS_LDAP_ADMIN_BINDDN_P].ns_ptype ==
957dd1104fbSMichen Chang 		    CHARPTR) {
958dd1104fbSMichen Chang 			(void) __ns_ldap_setParamValue(ptr,
959dd1104fbSMichen Chang 			    NS_LDAP_ADMIN_BINDDN_P,
960dd1104fbSMichen Chang 			    curr_ptr->paramList[NS_LDAP_ADMIN_BINDDN_P].ns_pc,
961dd1104fbSMichen Chang 			    &error);
962dd1104fbSMichen Chang 		}
963dd1104fbSMichen Chang 		if (curr_ptr->paramList[NS_LDAP_ADMIN_BINDPASSWD_P].ns_ptype ==
964dd1104fbSMichen Chang 		    CHARPTR) {
965dd1104fbSMichen Chang 			(void) __ns_ldap_setParamValue(ptr,
966dd1104fbSMichen Chang 			    NS_LDAP_ADMIN_BINDPASSWD_P,
967dd1104fbSMichen Chang 			    curr_ptr->
968dd1104fbSMichen Chang 			    paramList[NS_LDAP_ADMIN_BINDPASSWD_P].ns_pc,
969dd1104fbSMichen Chang 			    &error);
970dd1104fbSMichen Chang 		}
97182c6b8c6Smj 		if (curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_ptype ==
97282c6b8c6Smj 		    CHARPTR) {
97382c6b8c6Smj 			(void) __ns_ldap_setParamValue(ptr,
97482c6b8c6Smj 			    NS_LDAP_HOST_CERTPATH_P,
97582c6b8c6Smj 			    curr_ptr->paramList[NS_LDAP_HOST_CERTPATH_P].ns_pc,
97682c6b8c6Smj 			    &error);
97782c6b8c6Smj 		}
9787c478bd9Sstevel@tonic-gate 	}
9797c478bd9Sstevel@tonic-gate 	__s_api_release_config(curr_ptr);
9807c478bd9Sstevel@tonic-gate 	return (ptr);
981434c5a06SMilan Jurik 
982434c5a06SMilan Jurik makeconfigerror:
983434c5a06SMilan Jurik 	if (buffer.len > 0)
984434c5a06SMilan Jurik 		free(buffer.str);
985434c5a06SMilan Jurik 
986434c5a06SMilan Jurik 	__s_api_debug_pause(LOG_ERR, NS_PARSE_ERR,
987434c5a06SMilan Jurik 	    "__ns_ldap_make_config: Not enough memory");
988434c5a06SMilan Jurik 	return (NULL);
9897c478bd9Sstevel@tonic-gate }
9907c478bd9Sstevel@tonic-gate 
9917c478bd9Sstevel@tonic-gate /*
9927c478bd9Sstevel@tonic-gate  * Download a profile into our internal structure.  The calling application
9937c478bd9Sstevel@tonic-gate  * needs to DumpConfig() to save the information to NSCONFIGFILE and NSCREDFILE
9947c478bd9Sstevel@tonic-gate  * if desired.
9957c478bd9Sstevel@tonic-gate  */
9967c478bd9Sstevel@tonic-gate int
__ns_ldap_download(const char * profile,char * addr,char * baseDN,ns_ldap_error_t ** errorp)9977c478bd9Sstevel@tonic-gate __ns_ldap_download(const char *profile, char *addr, char *baseDN,
998*81de4da4SToomas Soome     ns_ldap_error_t **errorp)
9997c478bd9Sstevel@tonic-gate {
1000434c5a06SMilan Jurik 	char filter[BUFSIZE];
10017c478bd9Sstevel@tonic-gate 	int rc;
10027c478bd9Sstevel@tonic-gate 	ns_ldap_result_t *result = NULL;
10037c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr = NULL;
10047c478bd9Sstevel@tonic-gate 	ns_config_t	*new_ptr = NULL;
10057c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
10067c478bd9Sstevel@tonic-gate 
10077c478bd9Sstevel@tonic-gate 	*errorp = NULL;
10087c478bd9Sstevel@tonic-gate 	if (baseDN == NULL)
10097c478bd9Sstevel@tonic-gate 		return (NS_LDAP_INVALID_PARAM);
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate 	ptr = __s_api_get_default_config();
10127c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
10137c478bd9Sstevel@tonic-gate 		(void) snprintf(errstr, sizeof (errstr),
10147c478bd9Sstevel@tonic-gate 		    gettext("No configuration information available."));
10157c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
101651b02b29SToomas Soome 		    NS_LDAP_MEMORY);
10177c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
10187c478bd9Sstevel@tonic-gate 	}
10197c478bd9Sstevel@tonic-gate 
102082c6b8c6Smj 	rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SEARCH_BASEDN_P, baseDN,
102182c6b8c6Smj 	    errorp);
10227c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
10237c478bd9Sstevel@tonic-gate 		__s_api_release_config(ptr);
10247c478bd9Sstevel@tonic-gate 		return (rc);
10257c478bd9Sstevel@tonic-gate 	}
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 	rc = __ns_ldap_setParamValue(ptr, NS_LDAP_SERVERS_P, addr, errorp);
10287c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
10297c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS)
10307c478bd9Sstevel@tonic-gate 		return (rc);
10317c478bd9Sstevel@tonic-gate 
10327c478bd9Sstevel@tonic-gate 	(void) snprintf(filter, sizeof (filter), _PROFILE_FILTER,
103382c6b8c6Smj 	    _PROFILE1_OBJECTCLASS, _PROFILE2_OBJECTCLASS, profile);
10347c478bd9Sstevel@tonic-gate 	rc = __ns_ldap_list(_PROFILE_CONTAINER, (const char *)filter,
103582c6b8c6Smj 	    NULL, NULL, NULL, 0, &result, errorp, NULL, NULL);
10367c478bd9Sstevel@tonic-gate 
10377c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS)
10387c478bd9Sstevel@tonic-gate 		return (rc);
10397c478bd9Sstevel@tonic-gate 
10407c478bd9Sstevel@tonic-gate 	new_ptr = __ns_ldap_make_config(result);
10417c478bd9Sstevel@tonic-gate 	(void) __ns_ldap_freeResult(&result);
10427c478bd9Sstevel@tonic-gate 
1043382f99a9Smj 	if (new_ptr == NULL)
1044382f99a9Smj 		return (NS_LDAP_OP_FAILED);
1045382f99a9Smj 
10467c478bd9Sstevel@tonic-gate 	rc = __s_api_crosscheck(new_ptr, errstr, B_FALSE);
10477c478bd9Sstevel@tonic-gate 	if (rc != NS_LDAP_SUCCESS) {
10487c478bd9Sstevel@tonic-gate 		__s_api_destroy_config(new_ptr);
10497c478bd9Sstevel@tonic-gate 		MKERROR(LOG_ERR, *errorp, NS_CONFIG_NOTLOADED, strdup(errstr),
105051b02b29SToomas Soome 		    NS_LDAP_MEMORY);
10517c478bd9Sstevel@tonic-gate 		return (NS_LDAP_CONFIG);
10527c478bd9Sstevel@tonic-gate 	}
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 	__s_api_init_config(new_ptr);
10557c478bd9Sstevel@tonic-gate 	return (rc);
10567c478bd9Sstevel@tonic-gate }
10577c478bd9Sstevel@tonic-gate 
10587c478bd9Sstevel@tonic-gate /*
10597c478bd9Sstevel@tonic-gate  * **************************************************************
10607c478bd9Sstevel@tonic-gate  * Configuration Printing Routines
10617c478bd9Sstevel@tonic-gate  * **************************************************************
10627c478bd9Sstevel@tonic-gate  */
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate /*
10657c478bd9Sstevel@tonic-gate  * Yes the use of stdio is okay here because all we are doing is sending
10667c478bd9Sstevel@tonic-gate  * output to stdout.  This would not be necessary if we could get to the
10677c478bd9Sstevel@tonic-gate  * configuration pointer outside this file.
10687c478bd9Sstevel@tonic-gate  */
10697c478bd9Sstevel@tonic-gate ns_ldap_error_t *
__ns_ldap_print_config(int verbose)10707c478bd9Sstevel@tonic-gate __ns_ldap_print_config(int verbose)
10717c478bd9Sstevel@tonic-gate {
10727c478bd9Sstevel@tonic-gate 	ns_config_t	*ptr;
10737c478bd9Sstevel@tonic-gate 	char		errstr[MAXERROR];
10747c478bd9Sstevel@tonic-gate 	ns_ldap_error_t *errorp;
10757c478bd9Sstevel@tonic-gate 	char		*str;
10767c478bd9Sstevel@tonic-gate 	int		i;
10777c478bd9Sstevel@tonic-gate 
10787c478bd9Sstevel@tonic-gate 	ptr = __s_api_get_default_config();
10797c478bd9Sstevel@tonic-gate 	if (ptr == NULL) {
10807c478bd9Sstevel@tonic-gate 		errorp = __ns_ldap_LoadConfiguration();
10817c478bd9Sstevel@tonic-gate 		if (errorp != NULL)
10827c478bd9Sstevel@tonic-gate 			return (errorp);
10837c478bd9Sstevel@tonic-gate 		ptr = __s_api_get_default_config();
10847c478bd9Sstevel@tonic-gate 		if (ptr == NULL) {
10857c478bd9Sstevel@tonic-gate 			(void) snprintf(errstr, sizeof (errstr),
10867c478bd9Sstevel@tonic-gate 			    gettext("No configuration information."));
10877c478bd9Sstevel@tonic-gate 			MKERROR(LOG_WARNING, errorp, NS_CONFIG_NOTLOADED,
108882c6b8c6Smj 			    strdup(errstr), NULL);
10897c478bd9Sstevel@tonic-gate 			return (errorp);
10907c478bd9Sstevel@tonic-gate 		}
10917c478bd9Sstevel@tonic-gate 	}
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 	if (verbose && (ptr->domainName != NULL)) {
10947c478bd9Sstevel@tonic-gate 		(void) fputs("ptr->domainName ", stdout);
10957c478bd9Sstevel@tonic-gate 		(void) fputs(ptr->domainName, stdout);
10967c478bd9Sstevel@tonic-gate 		(void) putchar('\n');
10977c478bd9Sstevel@tonic-gate 	}
10987c478bd9Sstevel@tonic-gate 	/* For each parameter - construct value */
10997c478bd9Sstevel@tonic-gate 	for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) {
11007c478bd9Sstevel@tonic-gate 			/*
11017c478bd9Sstevel@tonic-gate 			 * Version 1 skipped this entry because:
11027c478bd9Sstevel@tonic-gate 			 *
11037c478bd9Sstevel@tonic-gate 			 * don't print default cache TTL for now since
11047c478bd9Sstevel@tonic-gate 			 * we don't store it in the ldap_client_file.
11057c478bd9Sstevel@tonic-gate 			 */
11067c478bd9Sstevel@tonic-gate 		if ((i == NS_LDAP_CACHETTL_P) && (ptr->version == NS_LDAP_V1))
11077c478bd9Sstevel@tonic-gate 			continue;
11087c478bd9Sstevel@tonic-gate 
1109dd1104fbSMichen Chang 		/* the credential for shadow update is not to be exposed */
1110dd1104fbSMichen Chang 		if (i == NS_LDAP_ADMIN_BINDDN_P ||
1111dd1104fbSMichen Chang 		    i == NS_LDAP_ADMIN_BINDPASSWD_P)
1112dd1104fbSMichen Chang 			continue;
1113dd1104fbSMichen Chang 
1114434c5a06SMilan Jurik 		str = __s_api_strValue(ptr, i, NS_FILE_FMT);
11157c478bd9Sstevel@tonic-gate 		if (str == NULL)
11167c478bd9Sstevel@tonic-gate 			continue;
11177c478bd9Sstevel@tonic-gate 		if (verbose)
11187c478bd9Sstevel@tonic-gate 			(void) putchar('\t');
11197c478bd9Sstevel@tonic-gate 		(void) fprintf(stdout, "%s\n", str);
1120434c5a06SMilan Jurik 		free(str);
11217c478bd9Sstevel@tonic-gate 	}
11227c478bd9Sstevel@tonic-gate 
11237c478bd9Sstevel@tonic-gate 	__s_api_release_config(ptr);
11247c478bd9Sstevel@tonic-gate 	return (NULL);
11257c478bd9Sstevel@tonic-gate }
1126