xref: /onnv-gate/usr/src/cmd/idmap/idmapd/idmap_config.c (revision 12508:edb7861a1533)
14520Snw141292 /*
24520Snw141292  * CDDL HEADER START
34520Snw141292  *
44520Snw141292  * The contents of this file are subject to the terms of the
54520Snw141292  * Common Development and Distribution License (the "License").
64520Snw141292  * You may not use this file except in compliance with the License.
74520Snw141292  *
84520Snw141292  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94520Snw141292  * or http://www.opensolaris.org/os/licensing.
104520Snw141292  * See the License for the specific language governing permissions
114520Snw141292  * and limitations under the License.
124520Snw141292  *
134520Snw141292  * When distributing Covered Code, include this CDDL HEADER in each
144520Snw141292  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154520Snw141292  * If applicable, add the following below this CDDL HEADER, with the
164520Snw141292  * fields enclosed by brackets "[]" replaced with your own identifying
174520Snw141292  * information: Portions Copyright [yyyy] [name of copyright owner]
184520Snw141292  *
194520Snw141292  * CDDL HEADER END
204520Snw141292  */
214520Snw141292 /*
2212065SKeyur.Desai@Sun.COM  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
234520Snw141292  */
244520Snw141292 
254520Snw141292 
264520Snw141292 /*
274520Snw141292  * Config routines common to idmap(1M) and idmapd(1M)
284520Snw141292  */
294520Snw141292 
304520Snw141292 #include <stdlib.h>
314520Snw141292 #include <strings.h>
324520Snw141292 #include <libintl.h>
334520Snw141292 #include <ctype.h>
344520Snw141292 #include <errno.h>
354644Sbaban #include "idmapd.h"
364520Snw141292 #include <stdio.h>
374520Snw141292 #include <stdarg.h>
384695Sbaban #include <uuid/uuid.h>
395317Sjp151216 #include <pthread.h>
405317Sjp151216 #include <port.h>
415968Snw141292 #include <net/route.h>
428361SJulian.Pullen@Sun.COM #include <sys/u8_textprep.h>
43*12508Samw@Sun.COM #include <note.h>
445317Sjp151216 #include "addisc.h"
454520Snw141292 
467031Snw141292 #define	MACHINE_SID_LEN		(9 + 3 * 11)
475968Snw141292 #define	FMRI_BASE		"svc:/system/idmap"
485968Snw141292 #define	CONFIG_PG		"config"
49*12508Samw@Sun.COM #define	DEBUG_PG		"debug"
505968Snw141292 #define	RECONFIGURE		1
515968Snw141292 #define	POKE_AUTO_DISCOVERY	2
524520Snw141292 
5312065SKeyur.Desai@Sun.COM enum event_type {
5412065SKeyur.Desai@Sun.COM 	EVENT_NOTHING,	/* Woke up for no good reason */
5512065SKeyur.Desai@Sun.COM 	EVENT_TIMEOUT,	/* Timeout expired */
5612065SKeyur.Desai@Sun.COM 	EVENT_ROUTING,	/* An interesting routing event happened */
5712065SKeyur.Desai@Sun.COM 	EVENT_DEGRADE,	/* An error occurred in the mainline */
5812065SKeyur.Desai@Sun.COM 	EVENT_REFRESH,	/* SMF refresh */
5912065SKeyur.Desai@Sun.COM };
6012065SKeyur.Desai@Sun.COM 
615317Sjp151216 
625317Sjp151216 
635317Sjp151216 static pthread_t update_thread_handle = 0;
645317Sjp151216 
655968Snw141292 static int idmapd_ev_port = -1;
665968Snw141292 static int rt_sock = -1;
675317Sjp151216 
6810504SKeyur.Desai@Sun.COM struct enum_lookup_map directory_mapping_map[] = {
6910504SKeyur.Desai@Sun.COM 	{ DIRECTORY_MAPPING_NONE, "none" },
7010504SKeyur.Desai@Sun.COM 	{ DIRECTORY_MAPPING_NAME, "name" },
7110504SKeyur.Desai@Sun.COM 	{ DIRECTORY_MAPPING_IDMU, "idmu" },
7210504SKeyur.Desai@Sun.COM 	{ 0, NULL },
7310504SKeyur.Desai@Sun.COM };
7410504SKeyur.Desai@Sun.COM 
75*12508Samw@Sun.COM struct enum_lookup_map trust_dir_map[] = {
76*12508Samw@Sun.COM 	{ 1, "they trust us" },
77*12508Samw@Sun.COM 	{ 2, "we trust them" },
78*12508Samw@Sun.COM 	{ 3, "we trust each other" },
79*12508Samw@Sun.COM 	{ 0, NULL },
80*12508Samw@Sun.COM };
81*12508Samw@Sun.COM 
824695Sbaban static int
generate_machine_sid(char ** machine_sid)835908Sjp151216 generate_machine_sid(char **machine_sid)
845908Sjp151216 {
854695Sbaban 	char *p;
864695Sbaban 	uuid_t uu;
874695Sbaban 	int i, j, len, rlen;
884695Sbaban 	uint32_t rid;
894695Sbaban 
904695Sbaban 	/*
917031Snw141292 	 * Generate and split 128-bit UUID into three 32-bit RIDs The
927031Snw141292 	 * machine_sid will be of the form S-1-5-21-N1-N2-N3 (that's
937031Snw141292 	 * four RIDs altogether).
947031Snw141292 	 *
9510504SKeyur.Desai@Sun.COM 	 * Technically we could use up to 14 random RIDs here, but it
967031Snw141292 	 * turns out that with some versions of Windows using SIDs with
977031Snw141292 	 * more than  five RIDs in security descriptors causes problems.
984695Sbaban 	 */
994695Sbaban 
1004695Sbaban 	*machine_sid = calloc(1, MACHINE_SID_LEN);
1014695Sbaban 	if (*machine_sid == NULL) {
1026017Snw141292 		idmapdlog(LOG_ERR, "Out of memory");
1034695Sbaban 		return (-1);
1044695Sbaban 	}
1054695Sbaban 	(void) strcpy(*machine_sid, "S-1-5-21");
1064695Sbaban 	p = *machine_sid + strlen("S-1-5-21");
1074695Sbaban 	len = MACHINE_SID_LEN - strlen("S-1-5-21");
1084695Sbaban 
1094695Sbaban 	uuid_clear(uu);
1104695Sbaban 	uuid_generate_random(uu);
1114695Sbaban 
1127031Snw141292 #if UUID_LEN != 16
1137031Snw141292 #error UUID size is not 16!
1147031Snw141292 #endif
1157031Snw141292 
1167031Snw141292 	for (i = 0; i < 3; i++) {
1174695Sbaban 		j = i * 4;
1184695Sbaban 		rid = (uu[j] << 24) | (uu[j + 1] << 16) |
1195908Sjp151216 		    (uu[j + 2] << 8) | (uu[j + 3]);
1204695Sbaban 		rlen = snprintf(p, len, "-%u", rid);
1214695Sbaban 		p += rlen;
1224695Sbaban 		len -= rlen;
1234695Sbaban 	}
1244695Sbaban 
1254695Sbaban 	return (0);
1264695Sbaban }
1274695Sbaban 
1286616Sdm199847 
1296616Sdm199847 /* In the case of error, exists is set to FALSE anyway */
1306616Sdm199847 static int
prop_exists(idmap_cfg_handles_t * handles,const char * name,boolean_t * exists)13110504SKeyur.Desai@Sun.COM prop_exists(idmap_cfg_handles_t *handles, const char *name, boolean_t *exists)
1326017Snw141292 {
1336616Sdm199847 
1346616Sdm199847 	scf_property_t *scf_prop;
135*12508Samw@Sun.COM 
136*12508Samw@Sun.COM 	*exists = B_FALSE;
137*12508Samw@Sun.COM 
138*12508Samw@Sun.COM 	scf_prop = scf_property_create(handles->main);
139*12508Samw@Sun.COM 	if (scf_prop == NULL) {
140*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "scf_property_create() failed: %s",
141*12508Samw@Sun.COM 		    scf_strerror(scf_error()));
142*12508Samw@Sun.COM 		return (-1);
143*12508Samw@Sun.COM 	}
144*12508Samw@Sun.COM 
145*12508Samw@Sun.COM 	if (scf_pg_get_property(handles->config_pg, name, scf_prop) == 0)
146*12508Samw@Sun.COM 		*exists = B_TRUE;
147*12508Samw@Sun.COM 
148*12508Samw@Sun.COM 	scf_property_destroy(scf_prop);
149*12508Samw@Sun.COM 
150*12508Samw@Sun.COM 	return (0);
151*12508Samw@Sun.COM }
152*12508Samw@Sun.COM 
153*12508Samw@Sun.COM static int
get_debug(idmap_cfg_handles_t * handles,const char * name)154*12508Samw@Sun.COM get_debug(idmap_cfg_handles_t *handles, const char *name)
155*12508Samw@Sun.COM {
156*12508Samw@Sun.COM 	int64_t i64 = 0;
157*12508Samw@Sun.COM 
158*12508Samw@Sun.COM 	scf_property_t *scf_prop;
1596616Sdm199847 	scf_value_t *value;
1606616Sdm199847 
161*12508Samw@Sun.COM 	scf_prop = scf_property_create(handles->main);
162*12508Samw@Sun.COM 	if (scf_prop == NULL) {
163*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "scf_property_create() failed: %s",
164*12508Samw@Sun.COM 		    scf_strerror(scf_error()));
165*12508Samw@Sun.COM 		abort();
166*12508Samw@Sun.COM 	}
167*12508Samw@Sun.COM 	value = scf_value_create(handles->main);
168*12508Samw@Sun.COM 	if (value == NULL) {
169*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "scf_value_create() failed: %s",
170*12508Samw@Sun.COM 		    scf_strerror(scf_error()));
171*12508Samw@Sun.COM 		abort();
172*12508Samw@Sun.COM 	}
173*12508Samw@Sun.COM 
174*12508Samw@Sun.COM 	if (scf_pg_get_property(handles->debug_pg, name, scf_prop) < 0) {
175*12508Samw@Sun.COM 		/* this is OK: the property is just undefined */
176*12508Samw@Sun.COM 		goto destruction;
177*12508Samw@Sun.COM 	}
178*12508Samw@Sun.COM 
179*12508Samw@Sun.COM 
180*12508Samw@Sun.COM 	if (scf_property_get_value(scf_prop, value) < 0) {
181*12508Samw@Sun.COM 		/* It is still OK when a property doesn't have any value */
182*12508Samw@Sun.COM 		goto destruction;
183*12508Samw@Sun.COM 	}
184*12508Samw@Sun.COM 
185*12508Samw@Sun.COM 	if (scf_value_get_integer(value, &i64) != 0) {
186*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "Can not retrieve %s/%s:  %s",
187*12508Samw@Sun.COM 		    DEBUG_PG, name, scf_strerror(scf_error()));
188*12508Samw@Sun.COM 		abort();
189*12508Samw@Sun.COM 	}
190*12508Samw@Sun.COM 
191*12508Samw@Sun.COM destruction:
192*12508Samw@Sun.COM 	scf_value_destroy(value);
193*12508Samw@Sun.COM 	scf_property_destroy(scf_prop);
194*12508Samw@Sun.COM 
195*12508Samw@Sun.COM 	return ((int)i64);
196*12508Samw@Sun.COM }
197*12508Samw@Sun.COM 
198*12508Samw@Sun.COM static int
get_val_bool(idmap_cfg_handles_t * handles,const char * name,boolean_t * val,boolean_t default_val)199*12508Samw@Sun.COM get_val_bool(idmap_cfg_handles_t *handles, const char *name,
200*12508Samw@Sun.COM 	boolean_t *val, boolean_t default_val)
201*12508Samw@Sun.COM {
202*12508Samw@Sun.COM 	int rc = 0;
203*12508Samw@Sun.COM 
204*12508Samw@Sun.COM 	scf_property_t *scf_prop;
205*12508Samw@Sun.COM 	scf_value_t *value;
206*12508Samw@Sun.COM 
207*12508Samw@Sun.COM 	*val = default_val;
2086017Snw141292 
2096616Sdm199847 	scf_prop = scf_property_create(handles->main);
2106616Sdm199847 	if (scf_prop == NULL) {
2116616Sdm199847 		idmapdlog(LOG_ERR, "scf_property_create() failed: %s",
2126616Sdm199847 		    scf_strerror(scf_error()));
2136616Sdm199847 		return (-1);
2146616Sdm199847 	}
2156616Sdm199847 	value = scf_value_create(handles->main);
2166616Sdm199847 	if (value == NULL) {
2176616Sdm199847 		idmapdlog(LOG_ERR, "scf_value_create() failed: %s",
2186616Sdm199847 		    scf_strerror(scf_error()));
2196616Sdm199847 		scf_property_destroy(scf_prop);
2206616Sdm199847 		return (-1);
2216616Sdm199847 	}
2226017Snw141292 
223*12508Samw@Sun.COM 	/* It is OK if the property is undefined */
224*12508Samw@Sun.COM 	if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0)
225*12508Samw@Sun.COM 		goto destruction;
226*12508Samw@Sun.COM 
2276017Snw141292 
228*12508Samw@Sun.COM 	/* It is still OK when a property doesn't have any value */
229*12508Samw@Sun.COM 	if (scf_property_get_value(scf_prop, value) < 0)
230*12508Samw@Sun.COM 		goto destruction;
231*12508Samw@Sun.COM 
232*12508Samw@Sun.COM 	uint8_t b;
233*12508Samw@Sun.COM 	rc = scf_value_get_boolean(value, &b);
234*12508Samw@Sun.COM 
235*12508Samw@Sun.COM 	if (rc == 0)
236*12508Samw@Sun.COM 		*val = (boolean_t)b;
237*12508Samw@Sun.COM 
238*12508Samw@Sun.COM destruction:
2396017Snw141292 	scf_value_destroy(value);
2406017Snw141292 	scf_property_destroy(scf_prop);
2416017Snw141292 
242*12508Samw@Sun.COM 	return (rc);
2436017Snw141292 }
2446017Snw141292 
2454520Snw141292 static int
get_val_int(idmap_cfg_handles_t * handles,const char * name,void * val,scf_type_t type)24610504SKeyur.Desai@Sun.COM get_val_int(idmap_cfg_handles_t *handles, const char *name,
2475317Sjp151216 	void *val, scf_type_t type)
2484520Snw141292 {
2494520Snw141292 	int rc = 0;
2504520Snw141292 
2516616Sdm199847 	scf_property_t *scf_prop;
2526616Sdm199847 	scf_value_t *value;
2536616Sdm199847 
2547031Snw141292 	switch (type) {
2557031Snw141292 	case SCF_TYPE_COUNT:
2567031Snw141292 		*(uint64_t *)val = 0;
2577031Snw141292 		break;
2587031Snw141292 	case SCF_TYPE_INTEGER:
2597031Snw141292 		*(int64_t *)val = 0;
2607031Snw141292 		break;
2617031Snw141292 	default:
2627031Snw141292 		idmapdlog(LOG_ERR, "Invalid scf integer type (%d)",
2637031Snw141292 		    type);
2647031Snw141292 		abort();
2657031Snw141292 	}
2667031Snw141292 
2676616Sdm199847 	scf_prop = scf_property_create(handles->main);
2686616Sdm199847 	if (scf_prop == NULL) {
2696616Sdm199847 		idmapdlog(LOG_ERR, "scf_property_create() failed: %s",
2706616Sdm199847 		    scf_strerror(scf_error()));
2716616Sdm199847 		return (-1);
2726616Sdm199847 	}
2736616Sdm199847 	value = scf_value_create(handles->main);
2746616Sdm199847 	if (value == NULL) {
2756616Sdm199847 		idmapdlog(LOG_ERR, "scf_value_create() failed: %s",
2766616Sdm199847 		    scf_strerror(scf_error()));
2776616Sdm199847 		scf_property_destroy(scf_prop);
2786616Sdm199847 		return (-1);
2796616Sdm199847 	}
2804520Snw141292 
2815317Sjp151216 	if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0)
2824520Snw141292 	/* this is OK: the property is just undefined */
2834520Snw141292 		goto destruction;
2844520Snw141292 
2854520Snw141292 
2865317Sjp151216 	if (scf_property_get_value(scf_prop, value) < 0)
2874520Snw141292 	/* It is still OK when a property doesn't have any value */
2884520Snw141292 		goto destruction;
2894520Snw141292 
2904520Snw141292 	switch (type) {
2914520Snw141292 	case SCF_TYPE_COUNT:
2924520Snw141292 		rc = scf_value_get_count(value, val);
2934520Snw141292 		break;
2944520Snw141292 	case SCF_TYPE_INTEGER:
2954520Snw141292 		rc = scf_value_get_integer(value, val);
2964520Snw141292 		break;
29710504SKeyur.Desai@Sun.COM 	default:
29810504SKeyur.Desai@Sun.COM 		abort();	/* tested above */
29910504SKeyur.Desai@Sun.COM 		/* NOTREACHED */
3004520Snw141292 	}
3014520Snw141292 
30210504SKeyur.Desai@Sun.COM 	if (rc != 0) {
30310504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR, "Can not retrieve config/%s:  %s",
30410504SKeyur.Desai@Sun.COM 		    name, scf_strerror(scf_error()));
30510504SKeyur.Desai@Sun.COM 	}
3064520Snw141292 
3074520Snw141292 destruction:
3084520Snw141292 	scf_value_destroy(value);
3094520Snw141292 	scf_property_destroy(scf_prop);
3104520Snw141292 
3114520Snw141292 	return (rc);
3124520Snw141292 }
3134520Snw141292 
3144520Snw141292 static char *
scf_value2string(const char * name,scf_value_t * value)31510504SKeyur.Desai@Sun.COM scf_value2string(const char *name, scf_value_t *value)
3165908Sjp151216 {
31710504SKeyur.Desai@Sun.COM 	static size_t max_val = 0;
3184520Snw141292 
31910504SKeyur.Desai@Sun.COM 	if (max_val == 0)
32010504SKeyur.Desai@Sun.COM 		max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH);
3214520Snw141292 
32210504SKeyur.Desai@Sun.COM 	char buf[max_val + 1];
32310504SKeyur.Desai@Sun.COM 	if (scf_value_get_astring(value, buf, max_val + 1) < 0) {
32410504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR, "Can not retrieve config/%s:  %s",
32510504SKeyur.Desai@Sun.COM 		    name, scf_strerror(scf_error()));
32610504SKeyur.Desai@Sun.COM 		return (NULL);
3274520Snw141292 	}
3284520Snw141292 
32910504SKeyur.Desai@Sun.COM 	char *s = strdup(buf);
33010504SKeyur.Desai@Sun.COM 	if (s == NULL)
33110504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR, "Out of memory");
3324520Snw141292 
33310504SKeyur.Desai@Sun.COM 	return (s);
3344520Snw141292 }
3354520Snw141292 
3365317Sjp151216 static int
get_val_ds(idmap_cfg_handles_t * handles,const char * name,int defport,idmap_ad_disc_ds_t ** val)3375317Sjp151216 get_val_ds(idmap_cfg_handles_t *handles, const char *name, int defport,
3386616Sdm199847 		idmap_ad_disc_ds_t **val)
3395317Sjp151216 {
3406616Sdm199847 	idmap_ad_disc_ds_t *servers = NULL;
3415317Sjp151216 	scf_property_t *scf_prop;
3425317Sjp151216 	scf_value_t *value;
3435317Sjp151216 	scf_iter_t *iter;
3445317Sjp151216 	char *host, *portstr;
3455447Snw141292 	int len, i;
3465317Sjp151216 	int count = 0;
3475447Snw141292 	int rc = -1;
3485317Sjp151216 
3495317Sjp151216 	*val = NULL;
3505317Sjp151216 
3515317Sjp151216 restart:
3525317Sjp151216 	scf_prop = scf_property_create(handles->main);
3536616Sdm199847 	if (scf_prop == NULL) {
3546616Sdm199847 		idmapdlog(LOG_ERR, "scf_property_create() failed: %s",
3556616Sdm199847 		    scf_strerror(scf_error()));
3566616Sdm199847 		return (-1);
3576616Sdm199847 	}
3586616Sdm199847 
3595317Sjp151216 	value = scf_value_create(handles->main);
3606616Sdm199847 	if (value == NULL) {
3616616Sdm199847 		idmapdlog(LOG_ERR, "scf_value_create() failed: %s",
3626616Sdm199847 		    scf_strerror(scf_error()));
3636616Sdm199847 		scf_property_destroy(scf_prop);
3646616Sdm199847 		return (-1);
3656616Sdm199847 	}
3666616Sdm199847 
3675317Sjp151216 	iter = scf_iter_create(handles->main);
3686616Sdm199847 	if (iter == NULL) {
3696616Sdm199847 		idmapdlog(LOG_ERR, "scf_iter_create() failed: %s",
3706616Sdm199847 		    scf_strerror(scf_error()));
3716616Sdm199847 		scf_value_destroy(value);
3726616Sdm199847 		scf_property_destroy(scf_prop);
3736616Sdm199847 		return (-1);
3746616Sdm199847 	}
3755317Sjp151216 
3765447Snw141292 	if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) {
3775317Sjp151216 		/* this is OK: the property is just undefined */
3785447Snw141292 		rc = 0;
3795317Sjp151216 		goto destruction;
3805447Snw141292 	}
3815317Sjp151216 
3825317Sjp151216 	if (scf_iter_property_values(iter, scf_prop) < 0) {
3835317Sjp151216 		idmapdlog(LOG_ERR,
3846017Snw141292 		    "scf_iter_property_values(%s) failed: %s",
3856017Snw141292 		    name, scf_strerror(scf_error()));
3865317Sjp151216 		goto destruction;
3875317Sjp151216 	}
3885317Sjp151216 
3895317Sjp151216 	/* Workaround scf bugs -- can't reset an iteration */
3905317Sjp151216 	if (count == 0) {
3915317Sjp151216 		while (scf_iter_next_value(iter, value) > 0)
3925317Sjp151216 			count++;
3935317Sjp151216 
3945447Snw141292 		if (count == 0) {
3955317Sjp151216 			/* no values */
3965447Snw141292 			rc = 0;
3975317Sjp151216 			goto destruction;
3985447Snw141292 		}
3995317Sjp151216 
4005317Sjp151216 		scf_value_destroy(value);
4015317Sjp151216 		scf_iter_destroy(iter);
4025317Sjp151216 		scf_property_destroy(scf_prop);
4035317Sjp151216 		goto restart;
4045317Sjp151216 	}
4055317Sjp151216 
4065317Sjp151216 	if ((servers = calloc(count + 1, sizeof (*servers))) == NULL) {
4076017Snw141292 		idmapdlog(LOG_ERR, "Out of memory");
4085317Sjp151216 		goto destruction;
4095317Sjp151216 	}
4105317Sjp151216 
4115447Snw141292 	i = 0;
4125447Snw141292 	while (i < count && scf_iter_next_value(iter, value) > 0) {
4135447Snw141292 		servers[i].priority = 0;
4145447Snw141292 		servers[i].weight = 100;
4155447Snw141292 		servers[i].port = defport;
41610504SKeyur.Desai@Sun.COM 		if ((host = scf_value2string(name, value)) == NULL) {
4175317Sjp151216 			goto destruction;
4185317Sjp151216 		}
4195317Sjp151216 		if ((portstr = strchr(host, ':')) != NULL) {
4205317Sjp151216 			*portstr++ = '\0';
4215447Snw141292 			servers[i].port = strtol(portstr,
4225317Sjp151216 			    (char **)NULL, 10);
4235447Snw141292 			if (servers[i].port == 0)
4245447Snw141292 				servers[i].port = defport;
4255317Sjp151216 		}
4265447Snw141292 		len = strlcpy(servers[i].host, host,
4275317Sjp151216 		    sizeof (servers->host));
4285317Sjp151216 
4295317Sjp151216 		free(host);
4305317Sjp151216 
4315317Sjp151216 		/* Ignore this server if the hostname is too long */
4325317Sjp151216 		if (len < sizeof (servers->host))
4335447Snw141292 			i++;
4345317Sjp151216 	}
4355317Sjp151216 
4365317Sjp151216 	*val = servers;
4375317Sjp151216 
4385447Snw141292 	rc = 0;
4395447Snw141292 
4405317Sjp151216 destruction:
4415317Sjp151216 	scf_value_destroy(value);
4425317Sjp151216 	scf_iter_destroy(iter);
4435317Sjp151216 	scf_property_destroy(scf_prop);
4445317Sjp151216 
4455317Sjp151216 	if (rc < 0) {
4465317Sjp151216 		if (servers)
4475317Sjp151216 			free(servers);
4485317Sjp151216 		*val = NULL;
4495317Sjp151216 	}
4505317Sjp151216 
4515317Sjp151216 	return (rc);
4525317Sjp151216 }
4535317Sjp151216 
4544520Snw141292 
4554520Snw141292 static int
get_val_astring(idmap_cfg_handles_t * handles,const char * name,char ** val)45610504SKeyur.Desai@Sun.COM get_val_astring(idmap_cfg_handles_t *handles, const char *name, char **val)
4574520Snw141292 {
4584520Snw141292 	int rc = 0;
4594520Snw141292 
4606616Sdm199847 	scf_property_t *scf_prop;
4616616Sdm199847 	scf_value_t *value;
4626616Sdm199847 
4636616Sdm199847 	scf_prop = scf_property_create(handles->main);
4646616Sdm199847 	if (scf_prop == NULL) {
4656616Sdm199847 		idmapdlog(LOG_ERR, "scf_property_create() failed: %s",
4666616Sdm199847 		    scf_strerror(scf_error()));
4676616Sdm199847 		return (-1);
4686616Sdm199847 	}
4696616Sdm199847 	value = scf_value_create(handles->main);
4706616Sdm199847 	if (value == NULL) {
4716616Sdm199847 		idmapdlog(LOG_ERR, "scf_value_create() failed: %s",
4726616Sdm199847 		    scf_strerror(scf_error()));
4736616Sdm199847 		scf_property_destroy(scf_prop);
4746616Sdm199847 		return (-1);
4756616Sdm199847 	}
4764520Snw141292 
4775317Sjp151216 	*val = NULL;
4784520Snw141292 
4795317Sjp151216 	if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0)
4804520Snw141292 	/* this is OK: the property is just undefined */
4814520Snw141292 		goto destruction;
4824520Snw141292 
4835317Sjp151216 	if (scf_property_get_value(scf_prop, value) < 0) {
4844644Sbaban 		idmapdlog(LOG_ERR,
4856017Snw141292 		    "scf_property_get_value(%s) failed: %s",
4866017Snw141292 		    name, scf_strerror(scf_error()));
4874520Snw141292 		rc = -1;
4884520Snw141292 		goto destruction;
4894520Snw141292 	}
4904520Snw141292 
49110504SKeyur.Desai@Sun.COM 	*val = scf_value2string(name, value);
49210504SKeyur.Desai@Sun.COM 	if (*val == NULL)
4934520Snw141292 		rc = -1;
4944520Snw141292 
4954520Snw141292 destruction:
4964520Snw141292 	scf_value_destroy(value);
4974520Snw141292 	scf_property_destroy(scf_prop);
4984520Snw141292 
4994520Snw141292 	if (rc < 0) {
5004520Snw141292 		if (*val)
5014520Snw141292 			free(*val);
5024520Snw141292 		*val = NULL;
5034520Snw141292 	}
5044520Snw141292 
5054520Snw141292 	return (rc);
5064520Snw141292 }
5074520Snw141292 
5085317Sjp151216 
5094695Sbaban static int
del_val(idmap_cfg_handles_t * handles,scf_propertygroup_t * pg,const char * name)510*12508Samw@Sun.COM del_val(
511*12508Samw@Sun.COM     idmap_cfg_handles_t *handles,
512*12508Samw@Sun.COM     scf_propertygroup_t *pg,
513*12508Samw@Sun.COM     const char *name)
51410504SKeyur.Desai@Sun.COM {
51510504SKeyur.Desai@Sun.COM 	int			rc = -1;
51610504SKeyur.Desai@Sun.COM 	int			ret;
51710504SKeyur.Desai@Sun.COM 	scf_transaction_t	*tx = NULL;
51810504SKeyur.Desai@Sun.COM 	scf_transaction_entry_t	*ent = NULL;
51910504SKeyur.Desai@Sun.COM 
52010504SKeyur.Desai@Sun.COM 	if ((tx = scf_transaction_create(handles->main)) == NULL) {
52110504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR,
52210504SKeyur.Desai@Sun.COM 		    "scf_transaction_create() failed: %s",
52310504SKeyur.Desai@Sun.COM 		    scf_strerror(scf_error()));
52410504SKeyur.Desai@Sun.COM 		goto destruction;
52510504SKeyur.Desai@Sun.COM 	}
52610504SKeyur.Desai@Sun.COM 	if ((ent = scf_entry_create(handles->main)) == NULL) {
52710504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR,
52810504SKeyur.Desai@Sun.COM 		    "scf_entry_create() failed: %s",
52910504SKeyur.Desai@Sun.COM 		    scf_strerror(scf_error()));
53010504SKeyur.Desai@Sun.COM 		goto destruction;
53110504SKeyur.Desai@Sun.COM 	}
53210504SKeyur.Desai@Sun.COM 
53310504SKeyur.Desai@Sun.COM 	do {
534*12508Samw@Sun.COM 		if (scf_pg_update(pg) == -1) {
53510504SKeyur.Desai@Sun.COM 			idmapdlog(LOG_ERR,
53610504SKeyur.Desai@Sun.COM 			    "scf_pg_update(%s) failed: %s",
53710504SKeyur.Desai@Sun.COM 			    name, scf_strerror(scf_error()));
53810504SKeyur.Desai@Sun.COM 			goto destruction;
53910504SKeyur.Desai@Sun.COM 		}
540*12508Samw@Sun.COM 		if (scf_transaction_start(tx, pg) != 0) {
54110504SKeyur.Desai@Sun.COM 			idmapdlog(LOG_ERR,
54210504SKeyur.Desai@Sun.COM 			    "scf_transaction_start(%s) failed: %s",
54310504SKeyur.Desai@Sun.COM 			    name, scf_strerror(scf_error()));
54410504SKeyur.Desai@Sun.COM 			goto destruction;
54510504SKeyur.Desai@Sun.COM 		}
54610504SKeyur.Desai@Sun.COM 
54710504SKeyur.Desai@Sun.COM 		if (scf_transaction_property_delete(tx, ent, name) != 0) {
54810504SKeyur.Desai@Sun.COM 			/* Don't complain if it already doesn't exist. */
54910504SKeyur.Desai@Sun.COM 			if (scf_error() != SCF_ERROR_NOT_FOUND) {
55010504SKeyur.Desai@Sun.COM 				idmapdlog(LOG_ERR,
55110504SKeyur.Desai@Sun.COM 				    "scf_transaction_property_delete() failed:"
55210504SKeyur.Desai@Sun.COM 				    " %s",
55310504SKeyur.Desai@Sun.COM 				    scf_strerror(scf_error()));
55410504SKeyur.Desai@Sun.COM 			}
55510504SKeyur.Desai@Sun.COM 			goto destruction;
55610504SKeyur.Desai@Sun.COM 		}
55710504SKeyur.Desai@Sun.COM 
55810504SKeyur.Desai@Sun.COM 		ret = scf_transaction_commit(tx);
55910504SKeyur.Desai@Sun.COM 
56010504SKeyur.Desai@Sun.COM 		if (ret == 0)
56110504SKeyur.Desai@Sun.COM 			scf_transaction_reset(tx);
56210504SKeyur.Desai@Sun.COM 	} while (ret == 0);
56310504SKeyur.Desai@Sun.COM 
56410504SKeyur.Desai@Sun.COM 	if (ret == -1) {
56510504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR,
56610504SKeyur.Desai@Sun.COM 		    "scf_transaction_commit(%s) failed: %s",
56710504SKeyur.Desai@Sun.COM 		    name, scf_strerror(scf_error()));
56810504SKeyur.Desai@Sun.COM 		goto destruction;
56910504SKeyur.Desai@Sun.COM 	}
57010504SKeyur.Desai@Sun.COM 
57110504SKeyur.Desai@Sun.COM 	rc = 0;
57210504SKeyur.Desai@Sun.COM 
57310504SKeyur.Desai@Sun.COM destruction:
57410504SKeyur.Desai@Sun.COM 	if (ent != NULL)
57510504SKeyur.Desai@Sun.COM 		scf_entry_destroy(ent);
57610504SKeyur.Desai@Sun.COM 	if (tx != NULL)
57710504SKeyur.Desai@Sun.COM 		scf_transaction_destroy(tx);
57810504SKeyur.Desai@Sun.COM 	return (rc);
57910504SKeyur.Desai@Sun.COM }
58010504SKeyur.Desai@Sun.COM 
58110504SKeyur.Desai@Sun.COM 
58210504SKeyur.Desai@Sun.COM static int
set_val(idmap_cfg_handles_t * handles,scf_propertygroup_t * pg,const char * name,scf_value_t * value)583*12508Samw@Sun.COM set_val(
584*12508Samw@Sun.COM     idmap_cfg_handles_t *handles,
585*12508Samw@Sun.COM     scf_propertygroup_t *pg,
586*12508Samw@Sun.COM     const char *name,
587*12508Samw@Sun.COM     scf_value_t *value)
5884695Sbaban {
5895447Snw141292 	int			rc = -1;
5905447Snw141292 	int			i;
591*12508Samw@Sun.COM 	scf_property_t		*prop = NULL;
5924695Sbaban 	scf_transaction_t	*tx = NULL;
5934695Sbaban 	scf_transaction_entry_t	*ent = NULL;
5944695Sbaban 
595*12508Samw@Sun.COM 	if ((prop = scf_property_create(handles->main)) == NULL ||
5965317Sjp151216 	    (tx = scf_transaction_create(handles->main)) == NULL ||
5975317Sjp151216 	    (ent = scf_entry_create(handles->main)) == NULL) {
5986017Snw141292 		idmapdlog(LOG_ERR, "Unable to set property %s",
5996017Snw141292 		    name, scf_strerror(scf_error()));
6004695Sbaban 		goto destruction;
6014695Sbaban 	}
6024695Sbaban 
603*12508Samw@Sun.COM 	for (i = 0; i < MAX_TRIES; i++) {
604*12508Samw@Sun.COM 		int ret;
605*12508Samw@Sun.COM 
606*12508Samw@Sun.COM 		if (scf_pg_update(pg) == -1) {
607*12508Samw@Sun.COM 			idmapdlog(LOG_ERR,
608*12508Samw@Sun.COM 			    "scf_pg_update() failed: %s",
609*12508Samw@Sun.COM 			    scf_strerror(scf_error()));
610*12508Samw@Sun.COM 			goto destruction;
611*12508Samw@Sun.COM 		}
612*12508Samw@Sun.COM 
613*12508Samw@Sun.COM 		if (scf_transaction_start(tx, pg) == -1) {
6144695Sbaban 			idmapdlog(LOG_ERR,
6156017Snw141292 			    "scf_transaction_start(%s) failed: %s",
6166017Snw141292 			    name, scf_strerror(scf_error()));
6174695Sbaban 			goto destruction;
6184695Sbaban 		}
6194695Sbaban 
620*12508Samw@Sun.COM 		ret = scf_pg_get_property(pg, name, prop);
621*12508Samw@Sun.COM 		if (ret == SCF_SUCCESS) {
622*12508Samw@Sun.COM 			if (scf_transaction_property_change_type(tx, ent, name,
623*12508Samw@Sun.COM 			    scf_value_type(value)) < 0) {
624*12508Samw@Sun.COM 				idmapdlog(LOG_ERR,
625*12508Samw@Sun.COM 				    "scf_transaction_property_change_type(%s)"
626*12508Samw@Sun.COM 				    " failed: %s",
627*12508Samw@Sun.COM 				    name, scf_strerror(scf_error()));
628*12508Samw@Sun.COM 				goto destruction;
629*12508Samw@Sun.COM 			}
630*12508Samw@Sun.COM 		} else if (scf_error() == SCF_ERROR_NOT_FOUND) {
631*12508Samw@Sun.COM 			if (scf_transaction_property_new(tx, ent, name,
632*12508Samw@Sun.COM 			    scf_value_type(value)) < 0) {
633*12508Samw@Sun.COM 				idmapdlog(LOG_ERR,
634*12508Samw@Sun.COM 				    "scf_transaction_property_new() failed: %s",
635*12508Samw@Sun.COM 				    scf_strerror(scf_error()));
636*12508Samw@Sun.COM 				goto destruction;
637*12508Samw@Sun.COM 			}
638*12508Samw@Sun.COM 		} else {
6394695Sbaban 			idmapdlog(LOG_ERR,
640*12508Samw@Sun.COM 			    "scf_pg_get_property(%s) failed: %s",
641*12508Samw@Sun.COM 			    name, scf_strerror(scf_error()));
6424695Sbaban 			goto destruction;
6434695Sbaban 		}
6444695Sbaban 
6454695Sbaban 		if (scf_entry_add_value(ent, value) == -1) {
6464695Sbaban 			idmapdlog(LOG_ERR,
6476017Snw141292 			    "scf_entry_add_value() failed: %s",
6486017Snw141292 			    scf_strerror(scf_error()));
6494695Sbaban 			goto destruction;
6504695Sbaban 		}
6514695Sbaban 
652*12508Samw@Sun.COM 		ret = scf_transaction_commit(tx);
653*12508Samw@Sun.COM 		if (ret == 0) {
6544695Sbaban 			/*
6554695Sbaban 			 * Property group set in scf_transaction_start()
6564695Sbaban 			 * is not the most recent. Update pg, reset tx and
6574695Sbaban 			 * retry tx.
6584695Sbaban 			 */
6594695Sbaban 			idmapdlog(LOG_WARNING,
660*12508Samw@Sun.COM 			    "scf_transaction_commit(%s) failed: %s",
661*12508Samw@Sun.COM 			    name, scf_strerror(scf_error()));
662*12508Samw@Sun.COM 			scf_transaction_reset(tx);
663*12508Samw@Sun.COM 			continue;
664*12508Samw@Sun.COM 		}
665*12508Samw@Sun.COM 		if (ret != 1) {
666*12508Samw@Sun.COM 			idmapdlog(LOG_ERR,
667*12508Samw@Sun.COM 			    "scf_transaction_commit(%s) failed: %s",
6686017Snw141292 			    name, scf_strerror(scf_error()));
669*12508Samw@Sun.COM 			goto destruction;
6704695Sbaban 		}
671*12508Samw@Sun.COM 		/* Success! */
672*12508Samw@Sun.COM 		rc = 0;
673*12508Samw@Sun.COM 		break;
6744695Sbaban 	}
6754695Sbaban 
676*12508Samw@Sun.COM destruction:
677*12508Samw@Sun.COM 	scf_entry_destroy(ent);
678*12508Samw@Sun.COM 	scf_transaction_destroy(tx);
679*12508Samw@Sun.COM 	scf_property_destroy(prop);
680*12508Samw@Sun.COM 	return (rc);
681*12508Samw@Sun.COM }
682*12508Samw@Sun.COM 
683*12508Samw@Sun.COM static int
set_val_integer(idmap_cfg_handles_t * handles,scf_propertygroup_t * pg,const char * name,int64_t val)684*12508Samw@Sun.COM set_val_integer(
685*12508Samw@Sun.COM     idmap_cfg_handles_t *handles,
686*12508Samw@Sun.COM     scf_propertygroup_t *pg,
687*12508Samw@Sun.COM     const char *name,
688*12508Samw@Sun.COM     int64_t val)
689*12508Samw@Sun.COM {
690*12508Samw@Sun.COM 	scf_value_t		*value = NULL;
691*12508Samw@Sun.COM 	int			rc;
692*12508Samw@Sun.COM 
693*12508Samw@Sun.COM 	if ((value = scf_value_create(handles->main)) == NULL) {
694*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "Unable to set property %s",
695*12508Samw@Sun.COM 		    name, scf_strerror(scf_error()));
696*12508Samw@Sun.COM 		return (-1);
697*12508Samw@Sun.COM 	}
698*12508Samw@Sun.COM 
699*12508Samw@Sun.COM 	scf_value_set_integer(value, val);
700*12508Samw@Sun.COM 
701*12508Samw@Sun.COM 	rc = set_val(handles, pg, name, value);
702*12508Samw@Sun.COM 
703*12508Samw@Sun.COM 	scf_value_destroy(value);
704*12508Samw@Sun.COM 
705*12508Samw@Sun.COM 	return (rc);
706*12508Samw@Sun.COM }
707*12508Samw@Sun.COM 
7085447Snw141292 
709*12508Samw@Sun.COM static int
set_val_astring(idmap_cfg_handles_t * handles,scf_propertygroup_t * pg,const char * name,const char * val)710*12508Samw@Sun.COM set_val_astring(
711*12508Samw@Sun.COM     idmap_cfg_handles_t *handles,
712*12508Samw@Sun.COM     scf_propertygroup_t *pg,
713*12508Samw@Sun.COM     const char *name,
714*12508Samw@Sun.COM     const char *val)
715*12508Samw@Sun.COM {
716*12508Samw@Sun.COM 	scf_value_t		*value = NULL;
717*12508Samw@Sun.COM 	int			rc = -1;
718*12508Samw@Sun.COM 
719*12508Samw@Sun.COM 	if ((value = scf_value_create(handles->main)) == NULL) {
720*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "Unable to set property %s",
7216017Snw141292 		    name, scf_strerror(scf_error()));
722*12508Samw@Sun.COM 		goto out;
723*12508Samw@Sun.COM 	}
7244695Sbaban 
725*12508Samw@Sun.COM 	if (scf_value_set_astring(value, val) == -1) {
726*12508Samw@Sun.COM 		idmapdlog(LOG_ERR,
727*12508Samw@Sun.COM 		    "scf_value_set_astring() failed: %s",
728*12508Samw@Sun.COM 		    scf_strerror(scf_error()));
729*12508Samw@Sun.COM 		goto out;
730*12508Samw@Sun.COM 	}
731*12508Samw@Sun.COM 
732*12508Samw@Sun.COM 	rc = set_val(handles, pg, name, value);
733*12508Samw@Sun.COM 
734*12508Samw@Sun.COM out:
7354695Sbaban 	scf_value_destroy(value);
7364695Sbaban 	return (rc);
7374695Sbaban }
7384695Sbaban 
7398361SJulian.Pullen@Sun.COM 
7408361SJulian.Pullen@Sun.COM 
7418361SJulian.Pullen@Sun.COM /*
7428361SJulian.Pullen@Sun.COM  * This function updates a boolean value.
7438361SJulian.Pullen@Sun.COM  * If nothing has changed it returns 0 else 1
7448361SJulian.Pullen@Sun.COM  */
7455317Sjp151216 static int
update_bool(boolean_t * value,boolean_t * new,char * name)7468671SJulian.Pullen@Sun.COM update_bool(boolean_t *value, boolean_t *new, char *name)
7477031Snw141292 {
7487031Snw141292 	if (*value == *new)
7497031Snw141292 		return (0);
7507031Snw141292 
751*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
752*12508Samw@Sun.COM 		idmapdlog(LOG_INFO, "change %s=%s", name,
753*12508Samw@Sun.COM 		    *new ? "true" : "false");
754*12508Samw@Sun.COM 	}
755*12508Samw@Sun.COM 
7567031Snw141292 	*value = *new;
7577031Snw141292 	return (1);
7587031Snw141292 }
7597031Snw141292 
7608361SJulian.Pullen@Sun.COM /*
7618361SJulian.Pullen@Sun.COM  * This function updates a string value.
7628361SJulian.Pullen@Sun.COM  * If nothing has changed it returns 0 else 1
7638361SJulian.Pullen@Sun.COM  */
7647031Snw141292 static int
update_string(char ** value,char ** new,char * name)7657031Snw141292 update_string(char **value, char **new, char *name)
7664520Snw141292 {
767*12508Samw@Sun.COM 	int changed;
7684520Snw141292 
769*12508Samw@Sun.COM 	if (*new == NULL && *value != NULL)
770*12508Samw@Sun.COM 		changed = 1;
771*12508Samw@Sun.COM 	else if (*new != NULL && *value == NULL)
772*12508Samw@Sun.COM 		changed = 1;
773*12508Samw@Sun.COM 	else if (*new != NULL && *value != NULL && strcmp(*new, *value) != 0)
774*12508Samw@Sun.COM 		changed = 1;
775*12508Samw@Sun.COM 	else
776*12508Samw@Sun.COM 		changed = 0;
7774520Snw141292 
778*12508Samw@Sun.COM 	/*
779*12508Samw@Sun.COM 	 * Note that even if unchanged we can't just return; we must free one
780*12508Samw@Sun.COM 	 * of the values.
781*12508Samw@Sun.COM 	 */
782*12508Samw@Sun.COM 
783*12508Samw@Sun.COM 	if (DBG(CONFIG, 1) && changed)
784*12508Samw@Sun.COM 		idmapdlog(LOG_INFO, "change %s=%s", name, CHECK_NULL(*new));
785*12508Samw@Sun.COM 
786*12508Samw@Sun.COM 	free(*value);
7875317Sjp151216 	*value = *new;
7885317Sjp151216 	*new = NULL;
789*12508Samw@Sun.COM 	return (changed);
7905317Sjp151216 }
7915317Sjp151216 
79210504SKeyur.Desai@Sun.COM static int
update_enum(int * value,int * new,char * name,struct enum_lookup_map * map)79310504SKeyur.Desai@Sun.COM update_enum(int *value, int *new, char *name, struct enum_lookup_map *map)
79410504SKeyur.Desai@Sun.COM {
79510504SKeyur.Desai@Sun.COM 	if (*value == *new)
79610504SKeyur.Desai@Sun.COM 		return (0);
79710504SKeyur.Desai@Sun.COM 
798*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
799*12508Samw@Sun.COM 		idmapdlog(LOG_INFO, "change %s=%s", name,
800*12508Samw@Sun.COM 		    enum_lookup(*new, map));
801*12508Samw@Sun.COM 	}
80210504SKeyur.Desai@Sun.COM 
80310504SKeyur.Desai@Sun.COM 	*value = *new;
80410504SKeyur.Desai@Sun.COM 
80510504SKeyur.Desai@Sun.COM 	return (1);
80610504SKeyur.Desai@Sun.COM }
8078361SJulian.Pullen@Sun.COM 
8088361SJulian.Pullen@Sun.COM /*
8098361SJulian.Pullen@Sun.COM  * This function updates a directory service structure.
8108361SJulian.Pullen@Sun.COM  * If nothing has changed it returns 0 else 1
8118361SJulian.Pullen@Sun.COM  */
8125317Sjp151216 static int
update_dirs(idmap_ad_disc_ds_t ** value,idmap_ad_disc_ds_t ** new,char * name)8136616Sdm199847 update_dirs(idmap_ad_disc_ds_t **value, idmap_ad_disc_ds_t **new, char *name)
8145317Sjp151216 {
8155317Sjp151216 	int i;
8165317Sjp151216 
8175968Snw141292 	if (*value == *new)
8185968Snw141292 		/* Nothing to do */
8196097Snw141292 		return (0);
8205317Sjp151216 
8215968Snw141292 	if (*value != NULL && *new != NULL &&
8225968Snw141292 	    ad_disc_compare_ds(*value, *new) == 0) {
8235317Sjp151216 		free(*new);
8245317Sjp151216 		*new = NULL;
8256097Snw141292 		return (0);
8264520Snw141292 	}
8274520Snw141292 
8288361SJulian.Pullen@Sun.COM 	if (*value != NULL)
8295317Sjp151216 		free(*value);
8305317Sjp151216 
8315317Sjp151216 	*value = *new;
8325317Sjp151216 	*new = NULL;
8335968Snw141292 
8345968Snw141292 	if (*value == NULL) {
8355968Snw141292 		/* We're unsetting this DS property */
836*12508Samw@Sun.COM 		if (DBG(CONFIG, 1))
837*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=<none>", name);
8386097Snw141292 		return (1);
8395968Snw141292 	}
8405968Snw141292 
841*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
842*12508Samw@Sun.COM 		/* List all the new DSs */
843*12508Samw@Sun.COM 		for (i = 0; (*value)[i].host[0] != '\0'; i++) {
844*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=%s port=%d", name,
845*12508Samw@Sun.COM 			    (*value)[i].host, (*value)[i].port);
846*12508Samw@Sun.COM 		}
847*12508Samw@Sun.COM 	}
8486097Snw141292 	return (1);
8495317Sjp151216 }
8505317Sjp151216 
8518361SJulian.Pullen@Sun.COM /*
8528361SJulian.Pullen@Sun.COM  * This function updates a trusted domains structure.
8538361SJulian.Pullen@Sun.COM  * If nothing has changed it returns 0 else 1
8548361SJulian.Pullen@Sun.COM  */
8558361SJulian.Pullen@Sun.COM static int
update_trusted_domains(ad_disc_trusteddomains_t ** value,ad_disc_trusteddomains_t ** new,char * name)8568361SJulian.Pullen@Sun.COM update_trusted_domains(ad_disc_trusteddomains_t **value,
8578361SJulian.Pullen@Sun.COM 			ad_disc_trusteddomains_t **new, char *name)
8588361SJulian.Pullen@Sun.COM {
8598361SJulian.Pullen@Sun.COM 	int i;
8608361SJulian.Pullen@Sun.COM 
8618361SJulian.Pullen@Sun.COM 	if (*value == *new)
8628361SJulian.Pullen@Sun.COM 		/* Nothing to do */
8638361SJulian.Pullen@Sun.COM 		return (0);
8648361SJulian.Pullen@Sun.COM 
8658361SJulian.Pullen@Sun.COM 	if (*value != NULL && *new != NULL &&
8668361SJulian.Pullen@Sun.COM 	    ad_disc_compare_trusteddomains(*value, *new) == 0) {
8678361SJulian.Pullen@Sun.COM 		free(*new);
8688361SJulian.Pullen@Sun.COM 		*new = NULL;
8698361SJulian.Pullen@Sun.COM 		return (0);
8708361SJulian.Pullen@Sun.COM 	}
8718361SJulian.Pullen@Sun.COM 
8728361SJulian.Pullen@Sun.COM 	if (*value != NULL)
8738361SJulian.Pullen@Sun.COM 		free(*value);
8748361SJulian.Pullen@Sun.COM 
8758361SJulian.Pullen@Sun.COM 	*value = *new;
8768361SJulian.Pullen@Sun.COM 	*new = NULL;
8778361SJulian.Pullen@Sun.COM 
8788361SJulian.Pullen@Sun.COM 	if (*value == NULL) {
8798361SJulian.Pullen@Sun.COM 		/* We're unsetting this DS property */
880*12508Samw@Sun.COM 		if (DBG(CONFIG, 1))
881*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=<none>", name);
8828361SJulian.Pullen@Sun.COM 		return (1);
8838361SJulian.Pullen@Sun.COM 	}
8848361SJulian.Pullen@Sun.COM 
885*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
886*12508Samw@Sun.COM 		/* List all the new domains */
887*12508Samw@Sun.COM 		for (i = 0; (*value)[i].domain[0] != '\0'; i++) {
888*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=%s direction=%s", name,
889*12508Samw@Sun.COM 			    (*value)[i].domain,
890*12508Samw@Sun.COM 			    enum_lookup((*value)[i].direction, trust_dir_map));
891*12508Samw@Sun.COM 		}
892*12508Samw@Sun.COM 	}
8938361SJulian.Pullen@Sun.COM 	return (1);
8948361SJulian.Pullen@Sun.COM }
8958361SJulian.Pullen@Sun.COM 
8968361SJulian.Pullen@Sun.COM 
8978361SJulian.Pullen@Sun.COM /*
8988361SJulian.Pullen@Sun.COM  * This function updates a domains in a forest structure.
8998361SJulian.Pullen@Sun.COM  * If nothing has changed it returns 0 else 1
9008361SJulian.Pullen@Sun.COM  */
9018361SJulian.Pullen@Sun.COM static int
update_domains_in_forest(ad_disc_domainsinforest_t ** value,ad_disc_domainsinforest_t ** new,char * name)9028361SJulian.Pullen@Sun.COM update_domains_in_forest(ad_disc_domainsinforest_t **value,
9038361SJulian.Pullen@Sun.COM 			ad_disc_domainsinforest_t **new, char *name)
9048361SJulian.Pullen@Sun.COM {
9058361SJulian.Pullen@Sun.COM 	int i;
9068361SJulian.Pullen@Sun.COM 
9078361SJulian.Pullen@Sun.COM 	if (*value == *new)
9088361SJulian.Pullen@Sun.COM 		/* Nothing to do */
9098361SJulian.Pullen@Sun.COM 		return (0);
9108361SJulian.Pullen@Sun.COM 
9118361SJulian.Pullen@Sun.COM 	if (*value != NULL && *new != NULL &&
9128361SJulian.Pullen@Sun.COM 	    ad_disc_compare_domainsinforest(*value, *new) == 0) {
9138361SJulian.Pullen@Sun.COM 		free(*new);
9148361SJulian.Pullen@Sun.COM 		*new = NULL;
9158361SJulian.Pullen@Sun.COM 		return (0);
9168361SJulian.Pullen@Sun.COM 	}
9178361SJulian.Pullen@Sun.COM 
9188361SJulian.Pullen@Sun.COM 	if (*value != NULL)
9198361SJulian.Pullen@Sun.COM 		free(*value);
9208361SJulian.Pullen@Sun.COM 
9218361SJulian.Pullen@Sun.COM 	*value = *new;
9228361SJulian.Pullen@Sun.COM 	*new = NULL;
9238361SJulian.Pullen@Sun.COM 
9248361SJulian.Pullen@Sun.COM 	if (*value == NULL) {
9258361SJulian.Pullen@Sun.COM 		/* We're unsetting this DS property */
926*12508Samw@Sun.COM 		if (DBG(CONFIG, 1))
927*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=<none>", name);
9288361SJulian.Pullen@Sun.COM 		return (1);
9298361SJulian.Pullen@Sun.COM 	}
9308361SJulian.Pullen@Sun.COM 
931*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
932*12508Samw@Sun.COM 		/* List all the new domains */
933*12508Samw@Sun.COM 		for (i = 0; (*value)[i].domain[0] != '\0'; i++) {
934*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=%s", name,
935*12508Samw@Sun.COM 			    (*value)[i].domain);
936*12508Samw@Sun.COM 		}
937*12508Samw@Sun.COM 	}
9388361SJulian.Pullen@Sun.COM 	return (1);
9398361SJulian.Pullen@Sun.COM }
9408361SJulian.Pullen@Sun.COM 
9418361SJulian.Pullen@Sun.COM 
9428361SJulian.Pullen@Sun.COM static void
free_trusted_forests(idmap_trustedforest_t ** value,int * num_values)9438361SJulian.Pullen@Sun.COM free_trusted_forests(idmap_trustedforest_t **value, int *num_values)
9448361SJulian.Pullen@Sun.COM {
9458361SJulian.Pullen@Sun.COM 	int i;
9468361SJulian.Pullen@Sun.COM 
9478361SJulian.Pullen@Sun.COM 	for (i = 0; i < *num_values; i++) {
9488361SJulian.Pullen@Sun.COM 		free((*value)[i].forest_name);
9498361SJulian.Pullen@Sun.COM 		free((*value)[i].global_catalog);
9508361SJulian.Pullen@Sun.COM 		free((*value)[i].domains_in_forest);
9518361SJulian.Pullen@Sun.COM 	}
9528361SJulian.Pullen@Sun.COM 	free(*value);
9538361SJulian.Pullen@Sun.COM 	*value = NULL;
9548361SJulian.Pullen@Sun.COM 	*num_values = 0;
9558361SJulian.Pullen@Sun.COM }
9568361SJulian.Pullen@Sun.COM 
9578361SJulian.Pullen@Sun.COM 
9588361SJulian.Pullen@Sun.COM static int
compare_trusteddomainsinforest(ad_disc_domainsinforest_t * df1,ad_disc_domainsinforest_t * df2)9598361SJulian.Pullen@Sun.COM compare_trusteddomainsinforest(ad_disc_domainsinforest_t *df1,
9608361SJulian.Pullen@Sun.COM 			ad_disc_domainsinforest_t *df2)
9618361SJulian.Pullen@Sun.COM {
9628671SJulian.Pullen@Sun.COM 	int		i, j;
9638671SJulian.Pullen@Sun.COM 	int		num_df1 = 0;
9648671SJulian.Pullen@Sun.COM 	int		num_df2 = 0;
9658671SJulian.Pullen@Sun.COM 	boolean_t	match;
9668361SJulian.Pullen@Sun.COM 
9678361SJulian.Pullen@Sun.COM 	for (i = 0; df1[i].domain[0] != '\0'; i++)
9688361SJulian.Pullen@Sun.COM 		if (df1[i].trusted)
9698361SJulian.Pullen@Sun.COM 			num_df1++;
9708361SJulian.Pullen@Sun.COM 
9718361SJulian.Pullen@Sun.COM 	for (j = 0; df2[j].domain[0] != '\0'; j++)
9728361SJulian.Pullen@Sun.COM 		if (df2[j].trusted)
9738361SJulian.Pullen@Sun.COM 			num_df2++;
9748361SJulian.Pullen@Sun.COM 
9758361SJulian.Pullen@Sun.COM 	if (num_df1 != num_df2)
9768361SJulian.Pullen@Sun.COM 		return (1);
9778361SJulian.Pullen@Sun.COM 
9788361SJulian.Pullen@Sun.COM 	for (i = 0; df1[i].domain[0] != '\0'; i++) {
9798361SJulian.Pullen@Sun.COM 		if (df1[i].trusted) {
9808671SJulian.Pullen@Sun.COM 			match = B_FALSE;
9818361SJulian.Pullen@Sun.COM 			for (j = 0; df2[j].domain[0] != '\0'; j++) {
9828361SJulian.Pullen@Sun.COM 				if (df2[j].trusted &&
98310122SJordan.Brown@Sun.COM 				    domain_eq(df1[i].domain, df2[j].domain) &&
98410122SJordan.Brown@Sun.COM 				    strcmp(df1[i].sid, df2[j].sid) == 0) {
9858671SJulian.Pullen@Sun.COM 					match = B_TRUE;
9868361SJulian.Pullen@Sun.COM 					break;
9878361SJulian.Pullen@Sun.COM 				}
9888361SJulian.Pullen@Sun.COM 			}
9898361SJulian.Pullen@Sun.COM 			if (!match)
9908361SJulian.Pullen@Sun.COM 				return (1);
9918361SJulian.Pullen@Sun.COM 		}
9928361SJulian.Pullen@Sun.COM 	}
9938361SJulian.Pullen@Sun.COM 	return (0);
9948361SJulian.Pullen@Sun.COM }
9958361SJulian.Pullen@Sun.COM 
9968361SJulian.Pullen@Sun.COM 
9978361SJulian.Pullen@Sun.COM 
9988361SJulian.Pullen@Sun.COM /*
9998361SJulian.Pullen@Sun.COM  * This function updates trusted forest structure.
10008361SJulian.Pullen@Sun.COM  * If nothing has changed it returns 0 else 1
10018361SJulian.Pullen@Sun.COM  */
10028361SJulian.Pullen@Sun.COM static int
update_trusted_forest(idmap_trustedforest_t ** value,int * num_value,idmap_trustedforest_t ** new,int * num_new,char * name)10038361SJulian.Pullen@Sun.COM update_trusted_forest(idmap_trustedforest_t **value, int *num_value,
10048361SJulian.Pullen@Sun.COM 			idmap_trustedforest_t **new, int *num_new, char *name)
10058361SJulian.Pullen@Sun.COM {
10068361SJulian.Pullen@Sun.COM 	int i, j;
10078671SJulian.Pullen@Sun.COM 	boolean_t match;
10088361SJulian.Pullen@Sun.COM 
10098361SJulian.Pullen@Sun.COM 	if (*value == *new)
10108361SJulian.Pullen@Sun.COM 		/* Nothing to do */
10118361SJulian.Pullen@Sun.COM 		return (0);
10128361SJulian.Pullen@Sun.COM 
10138361SJulian.Pullen@Sun.COM 	if (*value != NULL && *new != NULL) {
10148361SJulian.Pullen@Sun.COM 		if (*num_value != *num_new)
10158361SJulian.Pullen@Sun.COM 			goto not_equal;
10168361SJulian.Pullen@Sun.COM 		for (i = 0; i < *num_value; i++) {
10178671SJulian.Pullen@Sun.COM 			match = B_FALSE;
10188361SJulian.Pullen@Sun.COM 			for (j = 0; j < *num_new; j++) {
10198361SJulian.Pullen@Sun.COM 				if (strcmp((*value)[i].forest_name,
10208361SJulian.Pullen@Sun.COM 				    (*new)[j].forest_name) == 0 &&
10218361SJulian.Pullen@Sun.COM 				    ad_disc_compare_ds(
10228361SJulian.Pullen@Sun.COM 				    (*value)[i].global_catalog,
102310122SJordan.Brown@Sun.COM 				    (*new)[j].global_catalog) == 0 &&
10248361SJulian.Pullen@Sun.COM 				    compare_trusteddomainsinforest(
10258361SJulian.Pullen@Sun.COM 				    (*value)[i].domains_in_forest,
102610122SJordan.Brown@Sun.COM 				    (*new)[j].domains_in_forest) == 0) {
10278671SJulian.Pullen@Sun.COM 					match = B_TRUE;
10288361SJulian.Pullen@Sun.COM 					break;
10298361SJulian.Pullen@Sun.COM 				}
10308361SJulian.Pullen@Sun.COM 			}
10318361SJulian.Pullen@Sun.COM 			if (!match)
10328361SJulian.Pullen@Sun.COM 				goto not_equal;
10338361SJulian.Pullen@Sun.COM 		}
10348361SJulian.Pullen@Sun.COM 		free_trusted_forests(new, num_new);
10358361SJulian.Pullen@Sun.COM 		return (0);
10368361SJulian.Pullen@Sun.COM 	}
10378361SJulian.Pullen@Sun.COM not_equal:
10388361SJulian.Pullen@Sun.COM 	if (*value != NULL)
10398361SJulian.Pullen@Sun.COM 		free_trusted_forests(value, num_value);
10408361SJulian.Pullen@Sun.COM 	*value = *new;
10418361SJulian.Pullen@Sun.COM 	*num_value = *num_new;
10428361SJulian.Pullen@Sun.COM 	*new = NULL;
10438361SJulian.Pullen@Sun.COM 	*num_new = 0;
10448361SJulian.Pullen@Sun.COM 
10458361SJulian.Pullen@Sun.COM 	if (*value == NULL) {
10468361SJulian.Pullen@Sun.COM 		/* We're unsetting this DS property */
1047*12508Samw@Sun.COM 		if (DBG(CONFIG, 1))
1048*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change %s=<none>", name);
10498361SJulian.Pullen@Sun.COM 		return (1);
10508361SJulian.Pullen@Sun.COM 	}
10518361SJulian.Pullen@Sun.COM 
1052*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
1053*12508Samw@Sun.COM 		/* List all the trusted forests */
1054*12508Samw@Sun.COM 		for (i = 0; i < *num_value; i++) {
1055*12508Samw@Sun.COM 			idmap_trustedforest_t *f = &(*value)[i];
1056*12508Samw@Sun.COM 			for (j = 0;
1057*12508Samw@Sun.COM 			    f->domains_in_forest[j].domain[0] != '\0';
1058*12508Samw@Sun.COM 			    j++) {
1059*12508Samw@Sun.COM 				/* List trusted Domains in the forest. */
1060*12508Samw@Sun.COM 				if (f->domains_in_forest[j].trusted)
1061*12508Samw@Sun.COM 					idmapdlog(LOG_INFO,
1062*12508Samw@Sun.COM 					    "change %s=%s domain=%s",
1063*12508Samw@Sun.COM 					    name, f->forest_name,
1064*12508Samw@Sun.COM 					    f->domains_in_forest[j].domain);
1065*12508Samw@Sun.COM 			}
1066*12508Samw@Sun.COM 			/* List the hosts */
1067*12508Samw@Sun.COM 			for (j = 0;
1068*12508Samw@Sun.COM 			    f->global_catalog[j].host[0] != '\0';
1069*12508Samw@Sun.COM 			    j++) {
1070*12508Samw@Sun.COM 				idmapdlog(LOG_INFO,
1071*12508Samw@Sun.COM 				    "change %s=%s host=%s port=%d",
1072*12508Samw@Sun.COM 				    name, f->forest_name,
1073*12508Samw@Sun.COM 				    f->global_catalog[j].host,
1074*12508Samw@Sun.COM 				    f->global_catalog[j].port);
1075*12508Samw@Sun.COM 			}
10768361SJulian.Pullen@Sun.COM 		}
10778361SJulian.Pullen@Sun.COM 	}
10788361SJulian.Pullen@Sun.COM 	return (1);
10798361SJulian.Pullen@Sun.COM }
10808361SJulian.Pullen@Sun.COM 
108110504SKeyur.Desai@Sun.COM const char *
enum_lookup(int value,struct enum_lookup_map * map)108210504SKeyur.Desai@Sun.COM enum_lookup(int value, struct enum_lookup_map *map)
108310504SKeyur.Desai@Sun.COM {
108410504SKeyur.Desai@Sun.COM 	for (; map->string != NULL; map++) {
108510504SKeyur.Desai@Sun.COM 		if (value == map->value) {
108610504SKeyur.Desai@Sun.COM 			return (map->string);
108710504SKeyur.Desai@Sun.COM 		}
108810504SKeyur.Desai@Sun.COM 	}
108910504SKeyur.Desai@Sun.COM 	return ("(invalid)");
109010504SKeyur.Desai@Sun.COM }
10915317Sjp151216 
10925317Sjp151216 /*
10935968Snw141292  * Returns 1 if the PF_ROUTE socket event indicates that we should rescan the
10945968Snw141292  * interfaces.
10955317Sjp151216  *
10965968Snw141292  * Shamelessly based on smb_nics_changed() and other PF_ROUTE uses in ON.
10975968Snw141292  */
10985968Snw141292 static
109912065SKeyur.Desai@Sun.COM boolean_t
pfroute_event_is_interesting(int rt_sock)11005968Snw141292 pfroute_event_is_interesting(int rt_sock)
11015968Snw141292 {
11025968Snw141292 	int nbytes;
11035968Snw141292 	int64_t msg[2048 / 8];
11045968Snw141292 	struct rt_msghdr *rtm;
110512065SKeyur.Desai@Sun.COM 	boolean_t is_interesting = B_FALSE;
11065968Snw141292 
11075968Snw141292 	for (;;) {
11085968Snw141292 		if ((nbytes = read(rt_sock, msg, sizeof (msg))) <= 0)
11095968Snw141292 			break;
11105968Snw141292 		rtm = (struct rt_msghdr *)msg;
11115968Snw141292 		if (rtm->rtm_version != RTM_VERSION)
11125968Snw141292 			continue;
11135968Snw141292 		if (nbytes < rtm->rtm_msglen)
11145968Snw141292 			continue;
11155968Snw141292 		switch (rtm->rtm_type) {
11165968Snw141292 		case RTM_NEWADDR:
11175968Snw141292 		case RTM_DELADDR:
11185968Snw141292 		case RTM_IFINFO:
111912065SKeyur.Desai@Sun.COM 			is_interesting = B_TRUE;
11205968Snw141292 			break;
11215968Snw141292 		default:
11225968Snw141292 			break;
11235968Snw141292 		}
11245968Snw141292 	}
11255968Snw141292 	return (is_interesting);
11265968Snw141292 }
11275968Snw141292 
11285968Snw141292 /*
112912065SKeyur.Desai@Sun.COM  * Wait for an event, and report what kind of event occurred.
11305968Snw141292  *
113112065SKeyur.Desai@Sun.COM  * Note that there are cases where we are awoken but don't care about
113212065SKeyur.Desai@Sun.COM  * the lower-level event.  We can't just loop here because we can't
113312065SKeyur.Desai@Sun.COM  * readily calculate how long to sleep the next time.  We return
113412065SKeyur.Desai@Sun.COM  * EVENT_NOTHING and let the caller loop.
11355317Sjp151216  */
11365317Sjp151216 static
113712065SKeyur.Desai@Sun.COM enum event_type
wait_for_event(struct timespec * timeoutp)113812065SKeyur.Desai@Sun.COM wait_for_event(struct timespec *timeoutp)
11395317Sjp151216 {
11405317Sjp151216 	port_event_t pe;
11415317Sjp151216 
1142*12508Samw@Sun.COM 	(void) memset(&pe, 0, sizeof (pe));
11436097Snw141292 	if (port_get(idmapd_ev_port, &pe, timeoutp) != 0) {
11445317Sjp151216 		switch (errno) {
11455317Sjp151216 		case EINTR:
114612065SKeyur.Desai@Sun.COM 			return (EVENT_NOTHING);
11475317Sjp151216 		case ETIME:
11485317Sjp151216 			/* Timeout */
114912065SKeyur.Desai@Sun.COM 			return (EVENT_TIMEOUT);
11505317Sjp151216 		default:
11515968Snw141292 			/* EBADF, EBADFD, EFAULT, EINVAL (end of time?)? */
11525968Snw141292 			idmapdlog(LOG_ERR, "Event port failed: %s",
11535968Snw141292 			    strerror(errno));
11545968Snw141292 			exit(1);
11555968Snw141292 			/* NOTREACHED */
11564520Snw141292 		}
11574520Snw141292 	}
11584520Snw141292 
115912065SKeyur.Desai@Sun.COM 
116012065SKeyur.Desai@Sun.COM 	switch (pe.portev_source) {
116112065SKeyur.Desai@Sun.COM 	case 0:
116212065SKeyur.Desai@Sun.COM 		/*
116312065SKeyur.Desai@Sun.COM 		 * This isn't documented, but seems to be what you get if
116412065SKeyur.Desai@Sun.COM 		 * the timeout is zero seconds and there are no events
116512065SKeyur.Desai@Sun.COM 		 * pending.
116612065SKeyur.Desai@Sun.COM 		 */
116712065SKeyur.Desai@Sun.COM 		return (EVENT_TIMEOUT);
116812065SKeyur.Desai@Sun.COM 
116912065SKeyur.Desai@Sun.COM 	case PORT_SOURCE_USER:
117012065SKeyur.Desai@Sun.COM 		if (pe.portev_events == POKE_AUTO_DISCOVERY)
117112065SKeyur.Desai@Sun.COM 			return (EVENT_DEGRADE);
117212065SKeyur.Desai@Sun.COM 		if (pe.portev_events == RECONFIGURE)
117312065SKeyur.Desai@Sun.COM 			return (EVENT_REFRESH);
117412065SKeyur.Desai@Sun.COM 		break;
11755317Sjp151216 
117612065SKeyur.Desai@Sun.COM 	case PORT_SOURCE_FD:
117712065SKeyur.Desai@Sun.COM 		if (pe.portev_object == rt_sock) {
117812065SKeyur.Desai@Sun.COM 			/*
117912065SKeyur.Desai@Sun.COM 			 * PF_ROUTE socket read event:
118012065SKeyur.Desai@Sun.COM 			 *    re-associate fd
118112065SKeyur.Desai@Sun.COM 			 *    handle event
118212065SKeyur.Desai@Sun.COM 			 */
118312065SKeyur.Desai@Sun.COM 			if (port_associate(idmapd_ev_port, PORT_SOURCE_FD,
118412065SKeyur.Desai@Sun.COM 			    rt_sock, POLLIN, NULL) != 0) {
118512065SKeyur.Desai@Sun.COM 				idmapdlog(LOG_ERR, "Failed to re-associate the "
118612065SKeyur.Desai@Sun.COM 				    "routing socket with the event port: %s",
118712065SKeyur.Desai@Sun.COM 				    strerror(errno));
118812065SKeyur.Desai@Sun.COM 				abort();
118912065SKeyur.Desai@Sun.COM 			}
119012065SKeyur.Desai@Sun.COM 			/*
119112065SKeyur.Desai@Sun.COM 			 * The network configuration may still be in flux.
119212065SKeyur.Desai@Sun.COM 			 * No matter, the resolver will re-transmit and
119312065SKeyur.Desai@Sun.COM 			 * timeout if need be.
119412065SKeyur.Desai@Sun.COM 			 */
119512065SKeyur.Desai@Sun.COM 			if (pfroute_event_is_interesting(rt_sock)) {
1196*12508Samw@Sun.COM 				if (DBG(CONFIG, 1)) {
1197*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG,
1198*12508Samw@Sun.COM 					    "Interesting routing event");
1199*12508Samw@Sun.COM 				}
120012065SKeyur.Desai@Sun.COM 				return (EVENT_ROUTING);
120112065SKeyur.Desai@Sun.COM 			} else {
1202*12508Samw@Sun.COM 				if (DBG(CONFIG, 2)) {
1203*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG,
1204*12508Samw@Sun.COM 					    "Boring routing event");
1205*12508Samw@Sun.COM 				}
120612065SKeyur.Desai@Sun.COM 				return (EVENT_NOTHING);
120712065SKeyur.Desai@Sun.COM 			}
12085968Snw141292 		}
120912065SKeyur.Desai@Sun.COM 		/* Event on an FD other than the routing FD? Ignore it. */
121012065SKeyur.Desai@Sun.COM 		break;
12115968Snw141292 	}
12125968Snw141292 
121312065SKeyur.Desai@Sun.COM 	return (EVENT_NOTHING);
12145317Sjp151216 }
12155317Sjp151216 
12165317Sjp151216 void *
idmap_cfg_update_thread(void * arg)12175317Sjp151216 idmap_cfg_update_thread(void *arg)
12185317Sjp151216 {
1219*12508Samw@Sun.COM 	NOTE(ARGUNUSED(arg))
12205317Sjp151216 
122112065SKeyur.Desai@Sun.COM 	const ad_disc_t		ad_ctx = _idmapdstate.cfg->handles.ad_ctx;
12225317Sjp151216 
122312065SKeyur.Desai@Sun.COM 	for (;;) {
122412065SKeyur.Desai@Sun.COM 		struct timespec timeout;
122512065SKeyur.Desai@Sun.COM 		struct timespec	*timeoutp;
122612065SKeyur.Desai@Sun.COM 		int		rc;
122712065SKeyur.Desai@Sun.COM 		int		ttl;
12285968Snw141292 
12295968Snw141292 		(void) ad_disc_SubnetChanged(ad_ctx);
12305317Sjp151216 
123112065SKeyur.Desai@Sun.COM 		rc = idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER);
123212065SKeyur.Desai@Sun.COM 		if (rc < -1) {
12338671SJulian.Pullen@Sun.COM 			idmapdlog(LOG_ERR, "Fatal errors while reading "
12346097Snw141292 			    "SMF properties");
12356097Snw141292 			exit(1);
123612065SKeyur.Desai@Sun.COM 		} else if (rc == -1) {
123712065SKeyur.Desai@Sun.COM 			idmapdlog(LOG_WARNING,
123812065SKeyur.Desai@Sun.COM 			    "Errors re-loading configuration may cause AD "
123912065SKeyur.Desai@Sun.COM 			    "lookups to fail");
12405317Sjp151216 		}
12415317Sjp151216 
124212065SKeyur.Desai@Sun.COM 		/*
124312065SKeyur.Desai@Sun.COM 		 * Wait for an interesting event.  Note that we might get
124412065SKeyur.Desai@Sun.COM 		 * boring events between interesting events.  If so, we loop.
124512065SKeyur.Desai@Sun.COM 		 */
124612065SKeyur.Desai@Sun.COM 		for (;;) {
124712065SKeyur.Desai@Sun.COM 			ttl = ad_disc_get_TTL(ad_ctx);
124812065SKeyur.Desai@Sun.COM 
124912065SKeyur.Desai@Sun.COM 			if (ttl < 0) {
125012065SKeyur.Desai@Sun.COM 				timeoutp = NULL;
125112065SKeyur.Desai@Sun.COM 			} else {
125212065SKeyur.Desai@Sun.COM 				timeoutp = &timeout;
125312065SKeyur.Desai@Sun.COM 				timeout.tv_sec = ttl;
125412065SKeyur.Desai@Sun.COM 				timeout.tv_nsec = 0;
125512065SKeyur.Desai@Sun.COM 			}
125612065SKeyur.Desai@Sun.COM 
125712065SKeyur.Desai@Sun.COM 			switch (wait_for_event(timeoutp)) {
125812065SKeyur.Desai@Sun.COM 			case EVENT_NOTHING:
1259*12508Samw@Sun.COM 				if (DBG(CONFIG, 2))
1260*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG, "Boring event.");
126112065SKeyur.Desai@Sun.COM 				continue;
126212065SKeyur.Desai@Sun.COM 			case EVENT_REFRESH:
1263*12508Samw@Sun.COM 				if (DBG(CONFIG, 1))
1264*12508Samw@Sun.COM 					idmapdlog(LOG_INFO, "SMF refresh");
126512065SKeyur.Desai@Sun.COM 				/*
126612065SKeyur.Desai@Sun.COM 				 * Blow away the ccache, we might have
126712065SKeyur.Desai@Sun.COM 				 * re-joined the domain or joined a new one
126812065SKeyur.Desai@Sun.COM 				 */
126912065SKeyur.Desai@Sun.COM 				(void) unlink(IDMAP_CACHEDIR "/ccache");
127012065SKeyur.Desai@Sun.COM 				break;
127112065SKeyur.Desai@Sun.COM 			case EVENT_DEGRADE:
1272*12508Samw@Sun.COM 				if (DBG(CONFIG, 1)) {
1273*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG,
1274*12508Samw@Sun.COM 					    "Service degraded");
1275*12508Samw@Sun.COM 				}
127612065SKeyur.Desai@Sun.COM 				break;
127712065SKeyur.Desai@Sun.COM 			case EVENT_TIMEOUT:
1278*12508Samw@Sun.COM 				if (DBG(CONFIG, 1))
1279*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG, "TTL expired");
128012065SKeyur.Desai@Sun.COM 				break;
128112065SKeyur.Desai@Sun.COM 			case EVENT_ROUTING:
128212065SKeyur.Desai@Sun.COM 				/* Already logged to DEBUG */
128312065SKeyur.Desai@Sun.COM 				break;
128412065SKeyur.Desai@Sun.COM 			}
128512065SKeyur.Desai@Sun.COM 			/* An interesting event! */
128612065SKeyur.Desai@Sun.COM 			break;
128712065SKeyur.Desai@Sun.COM 		}
12885317Sjp151216 	}
128912065SKeyur.Desai@Sun.COM 	/*
129012065SKeyur.Desai@Sun.COM 	 * Lint isn't happy with the concept of a function declared to
129112065SKeyur.Desai@Sun.COM 	 * return something, that doesn't return.  Of course, merely adding
129212065SKeyur.Desai@Sun.COM 	 * the return isn't enough, because it's never reached...
129312065SKeyur.Desai@Sun.COM 	 */
12945317Sjp151216 	/*NOTREACHED*/
12955317Sjp151216 	return (NULL);
12965317Sjp151216 }
12975317Sjp151216 
12985968Snw141292 int
idmap_cfg_start_updates(void)12995968Snw141292 idmap_cfg_start_updates(void)
13005968Snw141292 {
13015968Snw141292 	if ((idmapd_ev_port = port_create()) < 0) {
13026017Snw141292 		idmapdlog(LOG_ERR, "Failed to create event port: %s",
13036017Snw141292 		    strerror(errno));
13045968Snw141292 		return (-1);
13055968Snw141292 	}
13065968Snw141292 
13075968Snw141292 	if ((rt_sock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) {
13086017Snw141292 		idmapdlog(LOG_ERR, "Failed to open routing socket: %s",
13096017Snw141292 		    strerror(errno));
13105968Snw141292 		(void) close(idmapd_ev_port);
13115968Snw141292 		return (-1);
13125968Snw141292 	}
13135317Sjp151216 
13145968Snw141292 	if (fcntl(rt_sock, F_SETFL, O_NDELAY|O_NONBLOCK) < 0) {
13156017Snw141292 		idmapdlog(LOG_ERR, "Failed to set routing socket flags: %s",
13166017Snw141292 		    strerror(errno));
13175968Snw141292 		(void) close(rt_sock);
13185968Snw141292 		(void) close(idmapd_ev_port);
13194520Snw141292 		return (-1);
13205968Snw141292 	}
13215968Snw141292 
13225968Snw141292 	if (port_associate(idmapd_ev_port, PORT_SOURCE_FD,
13235968Snw141292 	    rt_sock, POLLIN, NULL) != 0) {
13246017Snw141292 		idmapdlog(LOG_ERR, "Failed to associate the routing "
13256017Snw141292 		    "socket with the event port: %s", strerror(errno));
13265968Snw141292 		(void) close(rt_sock);
13275968Snw141292 		(void) close(idmapd_ev_port);
13285968Snw141292 		return (-1);
13295968Snw141292 	}
13305968Snw141292 
13315968Snw141292 	if ((errno = pthread_create(&update_thread_handle, NULL,
13325968Snw141292 	    idmap_cfg_update_thread, NULL)) != 0) {
13336017Snw141292 		idmapdlog(LOG_ERR, "Failed to start update thread: %s",
13346017Snw141292 		    strerror(errno));
13355968Snw141292 		(void) port_dissociate(idmapd_ev_port, PORT_SOURCE_FD, rt_sock);
13365968Snw141292 		(void) close(rt_sock);
13375968Snw141292 		(void) close(idmapd_ev_port);
13385968Snw141292 		return (-1);
13395968Snw141292 	}
13405968Snw141292 
13415968Snw141292 	return (0);
13425317Sjp151216 }
13435317Sjp151216 
13446097Snw141292 /*
13456616Sdm199847  * Reject attribute names with invalid characters.
13466616Sdm199847  */
13476616Sdm199847 static
13486616Sdm199847 int
valid_ldap_attr(const char * attr)13496616Sdm199847 valid_ldap_attr(const char *attr) {
13506616Sdm199847 	for (; *attr; attr++) {
13516616Sdm199847 		if (!isalnum(*attr) && *attr != '-' &&
13526616Sdm199847 		    *attr != '_' && *attr != '.' && *attr != ';')
13536616Sdm199847 			return (0);
13546616Sdm199847 	}
13556616Sdm199847 	return (1);
13566616Sdm199847 }
13576616Sdm199847 
135810504SKeyur.Desai@Sun.COM static
1359*12508Samw@Sun.COM void
idmapd_set_debug(idmap_cfg_handles_t * handles,enum idmapd_debug item,const char * name)1360*12508Samw@Sun.COM idmapd_set_debug(
1361*12508Samw@Sun.COM     idmap_cfg_handles_t *handles,
1362*12508Samw@Sun.COM     enum idmapd_debug item,
1363*12508Samw@Sun.COM     const char *name)
1364*12508Samw@Sun.COM {
1365*12508Samw@Sun.COM 	int val;
1366*12508Samw@Sun.COM 
1367*12508Samw@Sun.COM 	if (item < 0 || item > IDMAPD_DEBUG_MAX)
1368*12508Samw@Sun.COM 		return;
1369*12508Samw@Sun.COM 
1370*12508Samw@Sun.COM 	val = get_debug(handles, name);
1371*12508Samw@Sun.COM 
1372*12508Samw@Sun.COM 	if (val != _idmapdstate.debug[item])
1373*12508Samw@Sun.COM 		idmapdlog(LOG_DEBUG, "%s/%s = %d", DEBUG_PG, name, val);
1374*12508Samw@Sun.COM 
1375*12508Samw@Sun.COM 	_idmapdstate.debug[item] = val;
1376*12508Samw@Sun.COM }
1377*12508Samw@Sun.COM 
1378*12508Samw@Sun.COM static
1379*12508Samw@Sun.COM void
check_smf_debug_mode(idmap_cfg_handles_t * handles)138010504SKeyur.Desai@Sun.COM check_smf_debug_mode(idmap_cfg_handles_t *handles)
138110504SKeyur.Desai@Sun.COM {
1382*12508Samw@Sun.COM 	idmapd_set_debug(handles, IDMAPD_DEBUG_ALL, "all");
1383*12508Samw@Sun.COM 	idmapd_set_debug(handles, IDMAPD_DEBUG_CONFIG, "config");
1384*12508Samw@Sun.COM 	idmapd_set_debug(handles, IDMAPD_DEBUG_MAPPING, "mapping");
1385*12508Samw@Sun.COM 	idmapd_set_debug(handles, IDMAPD_DEBUG_DISC, "discovery");
1386*12508Samw@Sun.COM 	idmapd_set_debug(handles, IDMAPD_DEBUG_DNS, "dns");
1387*12508Samw@Sun.COM 	idmapd_set_debug(handles, IDMAPD_DEBUG_LDAP, "ldap");
138810504SKeyur.Desai@Sun.COM 
1389*12508Samw@Sun.COM 	adutils_set_debug(AD_DEBUG_ALL, _idmapdstate.debug[IDMAPD_DEBUG_ALL]);
1390*12508Samw@Sun.COM 	adutils_set_debug(AD_DEBUG_DISC, _idmapdstate.debug[IDMAPD_DEBUG_DISC]);
1391*12508Samw@Sun.COM 	adutils_set_debug(AD_DEBUG_DNS, _idmapdstate.debug[IDMAPD_DEBUG_DNS]);
1392*12508Samw@Sun.COM 	adutils_set_debug(AD_DEBUG_LDAP, _idmapdstate.debug[IDMAPD_DEBUG_LDAP]);
139310504SKeyur.Desai@Sun.COM }
139410504SKeyur.Desai@Sun.COM 
13956616Sdm199847 /*
13966097Snw141292  * This is the half of idmap_cfg_load() that loads property values from
13976097Snw141292  * SMF (using the config/ property group of the idmap FMRI).
13986097Snw141292  *
13996097Snw141292  * Return values: 0 -> success, -1 -> failure, -2 -> hard failures
14006616Sdm199847  *               -3 -> hard smf config failures
14016097Snw141292  * reading from SMF.
14026097Snw141292  */
14036097Snw141292 static
14045317Sjp151216 int
idmap_cfg_load_smf(idmap_cfg_handles_t * handles,idmap_pg_config_t * pgcfg,int * const errors)14056097Snw141292 idmap_cfg_load_smf(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg,
140610504SKeyur.Desai@Sun.COM 	int * const errors)
14075317Sjp151216 {
14085447Snw141292 	int rc;
140910504SKeyur.Desai@Sun.COM 	char *s;
141010504SKeyur.Desai@Sun.COM 
141110504SKeyur.Desai@Sun.COM 	*errors = 0;
14125317Sjp151216 
14135317Sjp151216 	if (scf_pg_update(handles->config_pg) < 0) {
14146017Snw141292 		idmapdlog(LOG_ERR, "scf_pg_update() failed: %s",
14156017Snw141292 		    scf_strerror(scf_error()));
14166097Snw141292 		return (-2);
14175317Sjp151216 	}
14185317Sjp151216 
1419*12508Samw@Sun.COM 	if (scf_pg_update(handles->debug_pg) < 0) {
14206017Snw141292 		idmapdlog(LOG_ERR, "scf_pg_update() failed: %s",
14216017Snw141292 		    scf_strerror(scf_error()));
14226097Snw141292 		return (-2);
14235317Sjp151216 	}
14245317Sjp151216 
1425*12508Samw@Sun.COM 	check_smf_debug_mode(handles);
1426*12508Samw@Sun.COM 
1427*12508Samw@Sun.COM 	rc = get_val_bool(handles, "unresolvable_sid_mapping",
1428*12508Samw@Sun.COM 	    &pgcfg->eph_map_unres_sids, B_TRUE);
14296616Sdm199847 	if (rc != 0)
143010504SKeyur.Desai@Sun.COM 		(*errors)++;
14316017Snw141292 
1432*12508Samw@Sun.COM 	rc = get_val_bool(handles, "use_lsa",
1433*12508Samw@Sun.COM 	    &pgcfg->use_lsa, B_TRUE);
1434*12508Samw@Sun.COM 	if (rc != 0)
1435*12508Samw@Sun.COM 		(*errors)++;
1436*12508Samw@Sun.COM 
1437*12508Samw@Sun.COM 	rc = get_val_bool(handles, "disable_cross_forest_trusts",
1438*12508Samw@Sun.COM 	    &pgcfg->disable_cross_forest_trusts, B_TRUE);
14397031Snw141292 	if (rc != 0)
144010504SKeyur.Desai@Sun.COM 		(*errors)++;
144110504SKeyur.Desai@Sun.COM 
144210504SKeyur.Desai@Sun.COM 	rc = get_val_astring(handles, "directory_based_mapping", &s);
144310504SKeyur.Desai@Sun.COM 	if (rc != 0)
144410504SKeyur.Desai@Sun.COM 		(*errors)++;
144510504SKeyur.Desai@Sun.COM 	else if (s == NULL || strcasecmp(s, "none") == 0)
144610504SKeyur.Desai@Sun.COM 		pgcfg->directory_based_mapping = DIRECTORY_MAPPING_NONE;
144710504SKeyur.Desai@Sun.COM 	else if (strcasecmp(s, "name") == 0)
144810504SKeyur.Desai@Sun.COM 		pgcfg->directory_based_mapping = DIRECTORY_MAPPING_NAME;
144910504SKeyur.Desai@Sun.COM 	else if (strcasecmp(s, "idmu") == 0)
145010504SKeyur.Desai@Sun.COM 		pgcfg->directory_based_mapping = DIRECTORY_MAPPING_IDMU;
145110504SKeyur.Desai@Sun.COM 	else {
145210504SKeyur.Desai@Sun.COM 		pgcfg->directory_based_mapping = DIRECTORY_MAPPING_NONE;
145310504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_ERR,
145410504SKeyur.Desai@Sun.COM 		"config/directory_based_mapping:  invalid value \"%s\" ignored",
145510504SKeyur.Desai@Sun.COM 		    s);
145610504SKeyur.Desai@Sun.COM 		(*errors)++;
145710504SKeyur.Desai@Sun.COM 	}
145810504SKeyur.Desai@Sun.COM 	free(s);
14597031Snw141292 
14605317Sjp151216 	rc = get_val_int(handles, "list_size_limit",
14615317Sjp151216 	    &pgcfg->list_size_limit, SCF_TYPE_COUNT);
14627031Snw141292 	if (rc != 0)
146310504SKeyur.Desai@Sun.COM 		(*errors)++;
14645317Sjp151216 
14655317Sjp151216 	rc = get_val_astring(handles, "domain_name",
14665317Sjp151216 	    &pgcfg->domain_name);
14675447Snw141292 	if (rc != 0)
146810504SKeyur.Desai@Sun.COM 		(*errors)++;
14698361SJulian.Pullen@Sun.COM 	else {
1470*12508Samw@Sun.COM 		if (pgcfg->domain_name != NULL &&
1471*12508Samw@Sun.COM 		    pgcfg->domain_name[0] == '\0') {
1472*12508Samw@Sun.COM 			free(pgcfg->domain_name);
1473*12508Samw@Sun.COM 			pgcfg->domain_name = NULL;
1474*12508Samw@Sun.COM 		}
14756097Snw141292 		(void) ad_disc_set_DomainName(handles->ad_ctx,
14766097Snw141292 		    pgcfg->domain_name);
14778671SJulian.Pullen@Sun.COM 		pgcfg->domain_name_auto_disc = B_FALSE;
14788361SJulian.Pullen@Sun.COM 	}
14795317Sjp151216 
14805317Sjp151216 	rc = get_val_astring(handles, "default_domain",
14815317Sjp151216 	    &pgcfg->default_domain);
14825317Sjp151216 	if (rc != 0) {
14835447Snw141292 		/*
14845447Snw141292 		 * SCF failures fetching config/default_domain we treat
14855447Snw141292 		 * as fatal as they may leave ID mapping rules that
14865447Snw141292 		 * match unqualified winnames flapping in the wind.
14875447Snw141292 		 */
14886097Snw141292 		return (-2);
14895317Sjp151216 	}
14905317Sjp151216 
149110504SKeyur.Desai@Sun.COM 	if (pgcfg->default_domain == NULL && pgcfg->domain_name != NULL) {
149210504SKeyur.Desai@Sun.COM 		pgcfg->default_domain = strdup(pgcfg->domain_name);
14934695Sbaban 	}
14944520Snw141292 
14955317Sjp151216 	rc = get_val_astring(handles, "machine_sid", &pgcfg->machine_sid);
14965447Snw141292 	if (rc != 0)
149710504SKeyur.Desai@Sun.COM 		(*errors)++;
14985317Sjp151216 	if (pgcfg->machine_sid == NULL) {
14995317Sjp151216 		/* If machine_sid not configured, generate one */
15006097Snw141292 		if (generate_machine_sid(&pgcfg->machine_sid) < 0)
15016097Snw141292 			return (-2);
1502*12508Samw@Sun.COM 		rc = set_val_astring(handles, handles->config_pg,
1503*12508Samw@Sun.COM 		    "machine_sid", pgcfg->machine_sid);
15045447Snw141292 		if (rc != 0)
150510504SKeyur.Desai@Sun.COM 			(*errors)++;
15065317Sjp151216 	}
15075317Sjp151216 
15085317Sjp151216 	rc = get_val_ds(handles, "domain_controller", 389,
15095317Sjp151216 	    &pgcfg->domain_controller);
15105447Snw141292 	if (rc != 0)
151110504SKeyur.Desai@Sun.COM 		(*errors)++;
15128361SJulian.Pullen@Sun.COM 	else {
15136097Snw141292 		(void) ad_disc_set_DomainController(handles->ad_ctx,
15145447Snw141292 		    pgcfg->domain_controller);
15158671SJulian.Pullen@Sun.COM 		pgcfg->domain_controller_auto_disc = B_FALSE;
15168361SJulian.Pullen@Sun.COM 	}
15175317Sjp151216 
15185317Sjp151216 	rc = get_val_astring(handles, "forest_name", &pgcfg->forest_name);
15195447Snw141292 	if (rc != 0)
152010504SKeyur.Desai@Sun.COM 		(*errors)++;
15218361SJulian.Pullen@Sun.COM 	else {
15226097Snw141292 		(void) ad_disc_set_ForestName(handles->ad_ctx,
15236097Snw141292 		    pgcfg->forest_name);
15248671SJulian.Pullen@Sun.COM 		pgcfg->forest_name_auto_disc = B_FALSE;
15258361SJulian.Pullen@Sun.COM 	}
15265317Sjp151216 
15275317Sjp151216 	rc = get_val_astring(handles, "site_name", &pgcfg->site_name);
15285447Snw141292 	if (rc != 0)
152910504SKeyur.Desai@Sun.COM 		(*errors)++;
15305447Snw141292 	else
15316097Snw141292 		(void) ad_disc_set_SiteName(handles->ad_ctx, pgcfg->site_name);
15325317Sjp151216 
15335317Sjp151216 	rc = get_val_ds(handles, "global_catalog", 3268,
15345317Sjp151216 	    &pgcfg->global_catalog);
15355447Snw141292 	if (rc != 0)
153610504SKeyur.Desai@Sun.COM 		(*errors)++;
15378361SJulian.Pullen@Sun.COM 	else {
15386097Snw141292 		(void) ad_disc_set_GlobalCatalog(handles->ad_ctx,
15396097Snw141292 		    pgcfg->global_catalog);
15408671SJulian.Pullen@Sun.COM 		pgcfg->global_catalog_auto_disc = B_FALSE;
15418361SJulian.Pullen@Sun.COM 	}
15425447Snw141292 
154310504SKeyur.Desai@Sun.COM 	/* Unless we're doing directory-based name mapping, we're done. */
154410504SKeyur.Desai@Sun.COM 	if (pgcfg->directory_based_mapping != DIRECTORY_MAPPING_NAME)
154510504SKeyur.Desai@Sun.COM 		return (0);
15466097Snw141292 
15476097Snw141292 	rc = get_val_astring(handles, "ad_unixuser_attr",
15486097Snw141292 	    &pgcfg->ad_unixuser_attr);
15496097Snw141292 	if (rc != 0)
15506097Snw141292 		return (-2);
15516616Sdm199847 	if (pgcfg->ad_unixuser_attr != NULL &&
15526616Sdm199847 	    !valid_ldap_attr(pgcfg->ad_unixuser_attr)) {
15536616Sdm199847 		idmapdlog(LOG_ERR, "config/ad_unixuser_attr=%s is not a "
15546616Sdm199847 		    "valid LDAP attribute name", pgcfg->ad_unixuser_attr);
15556616Sdm199847 		return (-3);
15566616Sdm199847 	}
15576097Snw141292 
15586097Snw141292 	rc = get_val_astring(handles, "ad_unixgroup_attr",
15596097Snw141292 	    &pgcfg->ad_unixgroup_attr);
15606097Snw141292 	if (rc != 0)
15616097Snw141292 		return (-2);
15626616Sdm199847 	if (pgcfg->ad_unixgroup_attr != NULL &&
15636616Sdm199847 	    !valid_ldap_attr(pgcfg->ad_unixgroup_attr)) {
15646616Sdm199847 		idmapdlog(LOG_ERR, "config/ad_unixgroup_attr=%s is not a "
15656616Sdm199847 		    "valid LDAP attribute name", pgcfg->ad_unixgroup_attr);
15666616Sdm199847 		return (-3);
15676616Sdm199847 	}
15685731Sbaban 
15696097Snw141292 	rc = get_val_astring(handles, "nldap_winname_attr",
15706097Snw141292 	    &pgcfg->nldap_winname_attr);
15716097Snw141292 	if (rc != 0)
15726097Snw141292 		return (-2);
15736616Sdm199847 	if (pgcfg->nldap_winname_attr != NULL &&
15746616Sdm199847 	    !valid_ldap_attr(pgcfg->nldap_winname_attr)) {
15756616Sdm199847 		idmapdlog(LOG_ERR, "config/nldap_winname_attr=%s is not a "
15766616Sdm199847 		    "valid LDAP attribute name", pgcfg->nldap_winname_attr);
15776097Snw141292 		return (-3);
15786097Snw141292 	}
15796097Snw141292 	if (pgcfg->ad_unixuser_attr == NULL &&
15806616Sdm199847 	    pgcfg->ad_unixgroup_attr == NULL &&
15816616Sdm199847 	    pgcfg->nldap_winname_attr == NULL) {
15826097Snw141292 		idmapdlog(LOG_ERR,
158310504SKeyur.Desai@Sun.COM 		    "If config/directory_based_mapping property is set to "
158410504SKeyur.Desai@Sun.COM 		    "\"name\" then at least one of the following name mapping "
15856097Snw141292 		    "attributes must be specified. (config/ad_unixuser_attr OR "
15866616Sdm199847 		    "config/ad_unixgroup_attr OR config/nldap_winname_attr)");
15876097Snw141292 		return (-3);
15885731Sbaban 	}
15895731Sbaban 
15906097Snw141292 	return (rc);
15915447Snw141292 
15926097Snw141292 }
15935317Sjp151216 
15946097Snw141292 static
15956097Snw141292 void
log_if_unable(const void * val,const char * what)1596*12508Samw@Sun.COM log_if_unable(const void *val, const char *what)
15976097Snw141292 {
1598*12508Samw@Sun.COM 	if (val == NULL) {
1599*12508Samw@Sun.COM 		idmapdlog(LOG_DEBUG, "unable to discover %s", what);
1600*12508Samw@Sun.COM 	}
1601*12508Samw@Sun.COM }
1602*12508Samw@Sun.COM 
1603*12508Samw@Sun.COM static
1604*12508Samw@Sun.COM void
discover_trusted_domains(idmap_pg_config_t * pgcfg,ad_disc_t ad_ctx)1605*12508Samw@Sun.COM discover_trusted_domains(idmap_pg_config_t *pgcfg, ad_disc_t ad_ctx)
1606*12508Samw@Sun.COM {
16078361SJulian.Pullen@Sun.COM 	ad_disc_t trusted_ctx;
16088361SJulian.Pullen@Sun.COM 	int i, j, k, l;
16098361SJulian.Pullen@Sun.COM 	char *forestname;
16108361SJulian.Pullen@Sun.COM 	int num_trusteddomains;
16118671SJulian.Pullen@Sun.COM 	boolean_t new_forest;
16128361SJulian.Pullen@Sun.COM 	char *trusteddomain;
16138361SJulian.Pullen@Sun.COM 	idmap_ad_disc_ds_t *globalcatalog;
16148361SJulian.Pullen@Sun.COM 	idmap_trustedforest_t *trustedforests;
16158361SJulian.Pullen@Sun.COM 	ad_disc_domainsinforest_t *domainsinforest;
16166097Snw141292 
16178361SJulian.Pullen@Sun.COM 	pgcfg->trusted_domains =
16188361SJulian.Pullen@Sun.COM 	    ad_disc_get_TrustedDomains(ad_ctx, NULL);
16198361SJulian.Pullen@Sun.COM 
16208361SJulian.Pullen@Sun.COM 	if (pgcfg->forest_name != NULL && pgcfg->trusted_domains != NULL &&
16218361SJulian.Pullen@Sun.COM 	    pgcfg->trusted_domains[0].domain[0] != '\0') {
16228361SJulian.Pullen@Sun.COM 		/*
16238361SJulian.Pullen@Sun.COM 		 * We have trusted domains.  We need to go through every
16248361SJulian.Pullen@Sun.COM 		 * one and find its forest. If it is a new forest we then need
16258361SJulian.Pullen@Sun.COM 		 * to find its Global Catalog and the domains in the forest
16268361SJulian.Pullen@Sun.COM 		 */
16278361SJulian.Pullen@Sun.COM 		for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++)
16288361SJulian.Pullen@Sun.COM 			continue;
16298361SJulian.Pullen@Sun.COM 		num_trusteddomains = i;
16308361SJulian.Pullen@Sun.COM 
16318361SJulian.Pullen@Sun.COM 		trustedforests = calloc(num_trusteddomains,
16328361SJulian.Pullen@Sun.COM 		    sizeof (idmap_trustedforest_t));
16338361SJulian.Pullen@Sun.COM 		j = 0;
16348361SJulian.Pullen@Sun.COM 		for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++) {
16358361SJulian.Pullen@Sun.COM 			trusteddomain = pgcfg->trusted_domains[i].domain;
16368361SJulian.Pullen@Sun.COM 			trusted_ctx = ad_disc_init();
1637*12508Samw@Sun.COM 			(void) ad_disc_set_DomainName(trusted_ctx,
16388361SJulian.Pullen@Sun.COM 			    trusteddomain);
16398361SJulian.Pullen@Sun.COM 			forestname =
16408361SJulian.Pullen@Sun.COM 			    ad_disc_get_ForestName(trusted_ctx, NULL);
16418361SJulian.Pullen@Sun.COM 			if (forestname == NULL) {
1642*12508Samw@Sun.COM 				if (DBG(CONFIG, 1)) {
1643*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG,
1644*12508Samw@Sun.COM 					    "unable to discover Forest Name"
1645*12508Samw@Sun.COM 					    " for the trusted domain %s",
1646*12508Samw@Sun.COM 					    trusteddomain);
1647*12508Samw@Sun.COM 				}
16488361SJulian.Pullen@Sun.COM 				ad_disc_fini(trusted_ctx);
16498361SJulian.Pullen@Sun.COM 				continue;
16508361SJulian.Pullen@Sun.COM 			}
16518361SJulian.Pullen@Sun.COM 
16528361SJulian.Pullen@Sun.COM 			if (strcasecmp(forestname, pgcfg->forest_name) == 0) {
16538361SJulian.Pullen@Sun.COM 				/*
16548361SJulian.Pullen@Sun.COM 				 * Ignore the domain as it is part of
16558361SJulian.Pullen@Sun.COM 				 * the primary forest
16568361SJulian.Pullen@Sun.COM 				 */
16578361SJulian.Pullen@Sun.COM 				free(forestname);
16588361SJulian.Pullen@Sun.COM 				ad_disc_fini(trusted_ctx);
16598361SJulian.Pullen@Sun.COM 				continue;
16608361SJulian.Pullen@Sun.COM 			}
16618361SJulian.Pullen@Sun.COM 
16628361SJulian.Pullen@Sun.COM 			/* Is this a new forest? */
16638671SJulian.Pullen@Sun.COM 			new_forest = B_TRUE;
16648361SJulian.Pullen@Sun.COM 			for (k = 0; k < j; k++) {
16658361SJulian.Pullen@Sun.COM 				if (strcasecmp(forestname,
16668361SJulian.Pullen@Sun.COM 				    trustedforests[k].forest_name) == 0) {
16678671SJulian.Pullen@Sun.COM 					new_forest = B_FALSE;
16688361SJulian.Pullen@Sun.COM 					domainsinforest =
16698361SJulian.Pullen@Sun.COM 					    trustedforests[k].domains_in_forest;
16708361SJulian.Pullen@Sun.COM 					break;
16718361SJulian.Pullen@Sun.COM 				}
16728361SJulian.Pullen@Sun.COM 			}
16738361SJulian.Pullen@Sun.COM 			if (!new_forest) {
16748361SJulian.Pullen@Sun.COM 				/* Mark the domain as trusted */
16758361SJulian.Pullen@Sun.COM 				for (l = 0;
16768361SJulian.Pullen@Sun.COM 				    domainsinforest[l].domain[0] != '\0'; l++) {
167710122SJordan.Brown@Sun.COM 					if (domain_eq(trusteddomain,
167810122SJordan.Brown@Sun.COM 					    domainsinforest[l].domain)) {
16798361SJulian.Pullen@Sun.COM 						domainsinforest[l].trusted =
16808361SJulian.Pullen@Sun.COM 						    TRUE;
16818361SJulian.Pullen@Sun.COM 						break;
16828361SJulian.Pullen@Sun.COM 					}
16838361SJulian.Pullen@Sun.COM 				}
16848361SJulian.Pullen@Sun.COM 				free(forestname);
16858361SJulian.Pullen@Sun.COM 				ad_disc_fini(trusted_ctx);
16868361SJulian.Pullen@Sun.COM 				continue;
16878361SJulian.Pullen@Sun.COM 			}
16888361SJulian.Pullen@Sun.COM 
16898361SJulian.Pullen@Sun.COM 			/*
16908361SJulian.Pullen@Sun.COM 			 * Get the Global Catalog and the domains in
16918361SJulian.Pullen@Sun.COM 			 * this new forest.
16928361SJulian.Pullen@Sun.COM 			 */
16938361SJulian.Pullen@Sun.COM 			globalcatalog =
16948361SJulian.Pullen@Sun.COM 			    ad_disc_get_GlobalCatalog(trusted_ctx,
16958361SJulian.Pullen@Sun.COM 			    AD_DISC_PREFER_SITE, NULL);
16968361SJulian.Pullen@Sun.COM 			if (globalcatalog == NULL) {
1697*12508Samw@Sun.COM 				if (DBG(CONFIG, 1)) {
1698*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG,
1699*12508Samw@Sun.COM 					    "unable to discover Global Catalog"
1700*12508Samw@Sun.COM 					    " for the trusted domain %s",
1701*12508Samw@Sun.COM 					    trusteddomain);
1702*12508Samw@Sun.COM 				}
17038361SJulian.Pullen@Sun.COM 				free(forestname);
17048361SJulian.Pullen@Sun.COM 				ad_disc_fini(trusted_ctx);
17058361SJulian.Pullen@Sun.COM 				continue;
17068361SJulian.Pullen@Sun.COM 			}
17078361SJulian.Pullen@Sun.COM 			domainsinforest =
17088361SJulian.Pullen@Sun.COM 			    ad_disc_get_DomainsInForest(trusted_ctx,
17098361SJulian.Pullen@Sun.COM 			    NULL);
17108361SJulian.Pullen@Sun.COM 			if (domainsinforest == NULL) {
1711*12508Samw@Sun.COM 				if (DBG(CONFIG, 1)) {
1712*12508Samw@Sun.COM 					idmapdlog(LOG_DEBUG,
1713*12508Samw@Sun.COM 					    "unable to discover Domains in the"
1714*12508Samw@Sun.COM 					    " Forest for the trusted domain %s",
1715*12508Samw@Sun.COM 					    trusteddomain);
1716*12508Samw@Sun.COM 				}
17178361SJulian.Pullen@Sun.COM 				free(globalcatalog);
17188361SJulian.Pullen@Sun.COM 				free(forestname);
17198361SJulian.Pullen@Sun.COM 				ad_disc_fini(trusted_ctx);
17208361SJulian.Pullen@Sun.COM 				continue;
17218361SJulian.Pullen@Sun.COM 			}
17228361SJulian.Pullen@Sun.COM 
17238361SJulian.Pullen@Sun.COM 			trustedforests[j].forest_name = forestname;
17248361SJulian.Pullen@Sun.COM 			trustedforests[j].global_catalog = globalcatalog;
17258361SJulian.Pullen@Sun.COM 			trustedforests[j].domains_in_forest = domainsinforest;
17268361SJulian.Pullen@Sun.COM 			j++;
17278361SJulian.Pullen@Sun.COM 			/* Mark the domain as trusted */
17288361SJulian.Pullen@Sun.COM 			for (l = 0; domainsinforest[l].domain[0] != '\0';
17298361SJulian.Pullen@Sun.COM 			    l++) {
173010122SJordan.Brown@Sun.COM 				if (domain_eq(trusteddomain,
173110122SJordan.Brown@Sun.COM 				    domainsinforest[l].domain)) {
17328361SJulian.Pullen@Sun.COM 					domainsinforest[l].trusted = TRUE;
17338361SJulian.Pullen@Sun.COM 					break;
17348361SJulian.Pullen@Sun.COM 				}
17358361SJulian.Pullen@Sun.COM 			}
17368361SJulian.Pullen@Sun.COM 			ad_disc_fini(trusted_ctx);
17378361SJulian.Pullen@Sun.COM 		}
17388361SJulian.Pullen@Sun.COM 		if (j > 0) {
17398361SJulian.Pullen@Sun.COM 			pgcfg->num_trusted_forests = j;
17408361SJulian.Pullen@Sun.COM 			pgcfg->trusted_forests = trustedforests;
174110122SJordan.Brown@Sun.COM 		} else {
174210122SJordan.Brown@Sun.COM 			free(trustedforests);
17438361SJulian.Pullen@Sun.COM 		}
17448361SJulian.Pullen@Sun.COM 	}
1745*12508Samw@Sun.COM }
17466097Snw141292 
1747*12508Samw@Sun.COM /*
1748*12508Samw@Sun.COM  * This is the half of idmap_cfg_load() that auto-discovers values of
1749*12508Samw@Sun.COM  * discoverable properties that weren't already set via SMF properties.
1750*12508Samw@Sun.COM  *
1751*12508Samw@Sun.COM  * idmap_cfg_discover() is called *after* idmap_cfg_load_smf(), so it
1752*12508Samw@Sun.COM  * needs to be careful not to overwrite any properties set in SMF.
1753*12508Samw@Sun.COM  */
1754*12508Samw@Sun.COM static
1755*12508Samw@Sun.COM void
idmap_cfg_discover(idmap_cfg_handles_t * handles,idmap_pg_config_t * pgcfg)1756*12508Samw@Sun.COM idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg)
1757*12508Samw@Sun.COM {
1758*12508Samw@Sun.COM 	ad_disc_t ad_ctx = handles->ad_ctx;
1759*12508Samw@Sun.COM 
1760*12508Samw@Sun.COM 	if (DBG(CONFIG, 1))
1761*12508Samw@Sun.COM 		idmapdlog(LOG_DEBUG, "Running discovery.");
1762*12508Samw@Sun.COM 
1763*12508Samw@Sun.COM 	ad_disc_refresh(ad_ctx);
1764*12508Samw@Sun.COM 
1765*12508Samw@Sun.COM 	if (pgcfg->domain_name == NULL) {
1766*12508Samw@Sun.COM 		idmapdlog(LOG_DEBUG, "No domain name specified.");
1767*12508Samw@Sun.COM 	} else {
1768*12508Samw@Sun.COM 		if (pgcfg->domain_controller == NULL)
1769*12508Samw@Sun.COM 			pgcfg->domain_controller =
1770*12508Samw@Sun.COM 			    ad_disc_get_DomainController(ad_ctx,
1771*12508Samw@Sun.COM 			    AD_DISC_PREFER_SITE,
1772*12508Samw@Sun.COM 			    &pgcfg->domain_controller_auto_disc);
1773*12508Samw@Sun.COM 
1774*12508Samw@Sun.COM 		if (pgcfg->forest_name == NULL)
1775*12508Samw@Sun.COM 			pgcfg->forest_name = ad_disc_get_ForestName(ad_ctx,
1776*12508Samw@Sun.COM 			    &pgcfg->forest_name_auto_disc);
1777*12508Samw@Sun.COM 
1778*12508Samw@Sun.COM 		if (pgcfg->site_name == NULL)
1779*12508Samw@Sun.COM 			pgcfg->site_name = ad_disc_get_SiteName(ad_ctx,
1780*12508Samw@Sun.COM 			    &pgcfg->site_name_auto_disc);
1781*12508Samw@Sun.COM 
1782*12508Samw@Sun.COM 		if (pgcfg->global_catalog == NULL)
1783*12508Samw@Sun.COM 			pgcfg->global_catalog =
1784*12508Samw@Sun.COM 			    ad_disc_get_GlobalCatalog(ad_ctx,
1785*12508Samw@Sun.COM 			    AD_DISC_PREFER_SITE,
1786*12508Samw@Sun.COM 			    &pgcfg->global_catalog_auto_disc);
1787*12508Samw@Sun.COM 
1788*12508Samw@Sun.COM 		pgcfg->domains_in_forest =
1789*12508Samw@Sun.COM 		    ad_disc_get_DomainsInForest(ad_ctx, NULL);
1790*12508Samw@Sun.COM 
1791*12508Samw@Sun.COM 		if (!pgcfg->disable_cross_forest_trusts)
1792*12508Samw@Sun.COM 			discover_trusted_domains(pgcfg, ad_ctx);
1793*12508Samw@Sun.COM 
1794*12508Samw@Sun.COM 		if (DBG(CONFIG, 1)) {
1795*12508Samw@Sun.COM 			log_if_unable(pgcfg->domain_name, "Domain Name");
1796*12508Samw@Sun.COM 			log_if_unable(pgcfg->domain_controller,
1797*12508Samw@Sun.COM 			    "Domain Controller");
1798*12508Samw@Sun.COM 			log_if_unable(pgcfg->forest_name, "Forest Name");
1799*12508Samw@Sun.COM 			log_if_unable(pgcfg->site_name, "Site Name");
1800*12508Samw@Sun.COM 			log_if_unable(pgcfg->global_catalog, "Global Catalog");
1801*12508Samw@Sun.COM 			log_if_unable(pgcfg->domains_in_forest,
1802*12508Samw@Sun.COM 			    "Domains in the Forest");
1803*12508Samw@Sun.COM 			if (!pgcfg->disable_cross_forest_trusts) {
1804*12508Samw@Sun.COM 				log_if_unable(pgcfg->trusted_domains,
1805*12508Samw@Sun.COM 				    "Trusted Domains");
1806*12508Samw@Sun.COM 			}
1807*12508Samw@Sun.COM 		}
1808*12508Samw@Sun.COM 	}
180912065SKeyur.Desai@Sun.COM 
181012065SKeyur.Desai@Sun.COM 	ad_disc_done(ad_ctx);
1811*12508Samw@Sun.COM 
1812*12508Samw@Sun.COM 	if (DBG(CONFIG, 1))
1813*12508Samw@Sun.COM 		idmapdlog(LOG_DEBUG, "Discovery done.");
18146097Snw141292 }
18155317Sjp151216 
18168361SJulian.Pullen@Sun.COM 
18176097Snw141292 /*
18186097Snw141292  * idmap_cfg_load() is called at startup, and periodically via the
18196097Snw141292  * update thread when the auto-discovery TTLs expire, as well as part of
18206097Snw141292  * the refresh method, to update the current configuration.  It always
18216097Snw141292  * reads from SMF, but you still have to refresh the service after
18226097Snw141292  * changing the config pg in order for the changes to take effect.
18236097Snw141292  *
1824*12508Samw@Sun.COM  * There is one flag:
18256097Snw141292  *
18266097Snw141292  *  - CFG_DISCOVER
18276097Snw141292  *
18286097Snw141292  * If CFG_DISCOVER is set then idmap_cfg_load() calls
18296097Snw141292  * idmap_cfg_discover() to discover, via DNS and LDAP lookups, property
18306097Snw141292  * values that weren't set in SMF.
18316097Snw141292  *
1832*12508Samw@Sun.COM  * idmap_cfg_load() will log (to LOG_NOTICE) whether the configuration
1833*12508Samw@Sun.COM  * changed.
18346097Snw141292  *
18356097Snw141292  * Return values: 0 -> success, -1 -> failure, -2 -> hard failures
18366097Snw141292  * reading from SMF.
18376097Snw141292  */
18386097Snw141292 int
idmap_cfg_load(idmap_cfg_t * cfg,int flags)18396097Snw141292 idmap_cfg_load(idmap_cfg_t *cfg, int flags)
18406097Snw141292 {
18416097Snw141292 	int rc = 0;
184210504SKeyur.Desai@Sun.COM 	int errors;
18436097Snw141292 	int changed = 0;
18448361SJulian.Pullen@Sun.COM 	int ad_reload_required = 0;
18456097Snw141292 	idmap_pg_config_t new_pgcfg, *live_pgcfg;
18466097Snw141292 
1847*12508Samw@Sun.COM 	if (DBG(CONFIG, 1))
1848*12508Samw@Sun.COM 		idmapdlog(LOG_DEBUG, "Loading configuration.");
1849*12508Samw@Sun.COM 
18506097Snw141292 	live_pgcfg = &cfg->pgcfg;
18516097Snw141292 	(void) memset(&new_pgcfg, 0, sizeof (new_pgcfg));
18526097Snw141292 
1853*12508Samw@Sun.COM 	(void) pthread_mutex_lock(&cfg->handles.mutex);
18546097Snw141292 
18556097Snw141292 	if ((rc = idmap_cfg_load_smf(&cfg->handles, &new_pgcfg, &errors)) < -1)
18566097Snw141292 		goto err;
18576097Snw141292 
18586097Snw141292 	if (flags & CFG_DISCOVER)
18596097Snw141292 		idmap_cfg_discover(&cfg->handles, &new_pgcfg);
18606097Snw141292 
18616097Snw141292 	WRLOCK_CONFIG();
18626097Snw141292 	if (live_pgcfg->list_size_limit != new_pgcfg.list_size_limit) {
1863*12508Samw@Sun.COM 		if (DBG(CONFIG, 1)) {
1864*12508Samw@Sun.COM 			idmapdlog(LOG_INFO, "change list_size=%d",
1865*12508Samw@Sun.COM 			    new_pgcfg.list_size_limit);
1866*12508Samw@Sun.COM 		}
18676097Snw141292 		live_pgcfg->list_size_limit = new_pgcfg.list_size_limit;
18685317Sjp151216 	}
18695317Sjp151216 
18706097Snw141292 	/* Non-discoverable props updated here */
18717031Snw141292 	changed += update_string(&live_pgcfg->machine_sid,
18726097Snw141292 	    &new_pgcfg.machine_sid, "machine_sid");
18736097Snw141292 
18747031Snw141292 	changed += update_bool(&live_pgcfg->eph_map_unres_sids,
18757031Snw141292 	    &new_pgcfg.eph_map_unres_sids, "unresolvable_sid_mapping");
18767031Snw141292 
1877*12508Samw@Sun.COM 	changed += update_bool(&live_pgcfg->use_lsa,
1878*12508Samw@Sun.COM 	    &new_pgcfg.use_lsa, "use_lsa");
1879*12508Samw@Sun.COM 
1880*12508Samw@Sun.COM 	changed += update_bool(&live_pgcfg->disable_cross_forest_trusts,
1881*12508Samw@Sun.COM 	    &new_pgcfg.disable_cross_forest_trusts,
1882*12508Samw@Sun.COM 	    "disable_cross_forest_trusts");
1883*12508Samw@Sun.COM 
188410504SKeyur.Desai@Sun.COM 	changed += update_enum(&live_pgcfg->directory_based_mapping,
188510504SKeyur.Desai@Sun.COM 	    &new_pgcfg.directory_based_mapping, "directory_based_mapping",
188610504SKeyur.Desai@Sun.COM 	    directory_mapping_map);
18876097Snw141292 
18887031Snw141292 	changed += update_string(&live_pgcfg->ad_unixuser_attr,
18896097Snw141292 	    &new_pgcfg.ad_unixuser_attr, "ad_unixuser_attr");
18906097Snw141292 
18917031Snw141292 	changed += update_string(&live_pgcfg->ad_unixgroup_attr,
18926097Snw141292 	    &new_pgcfg.ad_unixgroup_attr, "ad_unixgroup_attr");
18936097Snw141292 
18947031Snw141292 	changed += update_string(&live_pgcfg->nldap_winname_attr,
18956097Snw141292 	    &new_pgcfg.nldap_winname_attr, "nldap_winname_attr");
18966097Snw141292 
18976097Snw141292 	/* Props that can be discovered and set in SMF updated here */
189810504SKeyur.Desai@Sun.COM 	changed += update_string(&live_pgcfg->default_domain,
189910504SKeyur.Desai@Sun.COM 	    &new_pgcfg.default_domain, "default_domain");
19006097Snw141292 
19017031Snw141292 	changed += update_string(&live_pgcfg->domain_name,
19026097Snw141292 	    &new_pgcfg.domain_name, "domain_name");
19038361SJulian.Pullen@Sun.COM 	live_pgcfg->domain_name_auto_disc = new_pgcfg.domain_name_auto_disc;
19046097Snw141292 
19056097Snw141292 	changed += update_dirs(&live_pgcfg->domain_controller,
19066097Snw141292 	    &new_pgcfg.domain_controller, "domain_controller");
19078361SJulian.Pullen@Sun.COM 	live_pgcfg->domain_controller_auto_disc =
19088361SJulian.Pullen@Sun.COM 	    new_pgcfg.domain_controller_auto_disc;
19096097Snw141292 
19107031Snw141292 	changed += update_string(&live_pgcfg->forest_name,
19116097Snw141292 	    &new_pgcfg.forest_name, "forest_name");
19128361SJulian.Pullen@Sun.COM 	live_pgcfg->forest_name_auto_disc = new_pgcfg.forest_name_auto_disc;
19136097Snw141292 
19147031Snw141292 	changed += update_string(&live_pgcfg->site_name,
19156097Snw141292 	    &new_pgcfg.site_name, "site_name");
19168361SJulian.Pullen@Sun.COM 	live_pgcfg->site_name_auto_disc = new_pgcfg.site_name_auto_disc;
19176097Snw141292 
19186097Snw141292 	if (update_dirs(&live_pgcfg->global_catalog,
19196097Snw141292 	    &new_pgcfg.global_catalog, "global_catalog")) {
19206097Snw141292 		changed++;
19216097Snw141292 		if (live_pgcfg->global_catalog != NULL &&
19226097Snw141292 		    live_pgcfg->global_catalog[0].host[0] != '\0')
19238361SJulian.Pullen@Sun.COM 			ad_reload_required = TRUE;
19248361SJulian.Pullen@Sun.COM 	}
19258361SJulian.Pullen@Sun.COM 	live_pgcfg->global_catalog_auto_disc =
19268361SJulian.Pullen@Sun.COM 	    new_pgcfg.global_catalog_auto_disc;
19278361SJulian.Pullen@Sun.COM 
19288361SJulian.Pullen@Sun.COM 	if (update_domains_in_forest(&live_pgcfg->domains_in_forest,
19298361SJulian.Pullen@Sun.COM 	    &new_pgcfg.domains_in_forest, "domains_in_forest")) {
19308361SJulian.Pullen@Sun.COM 		changed++;
19318361SJulian.Pullen@Sun.COM 		ad_reload_required = TRUE;
19325317Sjp151216 	}
19335317Sjp151216 
19348361SJulian.Pullen@Sun.COM 	if (update_trusted_domains(&live_pgcfg->trusted_domains,
19358361SJulian.Pullen@Sun.COM 	    &new_pgcfg.trusted_domains, "trusted_domains")) {
19368361SJulian.Pullen@Sun.COM 		changed++;
19378361SJulian.Pullen@Sun.COM 		if (live_pgcfg->trusted_domains != NULL &&
19388361SJulian.Pullen@Sun.COM 		    live_pgcfg->trusted_domains[0].domain[0] != '\0')
19398361SJulian.Pullen@Sun.COM 			ad_reload_required = TRUE;
19408361SJulian.Pullen@Sun.COM 	}
19418361SJulian.Pullen@Sun.COM 
19428361SJulian.Pullen@Sun.COM 	if (update_trusted_forest(&live_pgcfg->trusted_forests,
19438361SJulian.Pullen@Sun.COM 	    &live_pgcfg->num_trusted_forests, &new_pgcfg.trusted_forests,
19448361SJulian.Pullen@Sun.COM 	    &new_pgcfg.num_trusted_forests, "trusted_forest")) {
19458361SJulian.Pullen@Sun.COM 		changed++;
19468361SJulian.Pullen@Sun.COM 		if (live_pgcfg->trusted_forests != NULL)
19478361SJulian.Pullen@Sun.COM 			ad_reload_required = TRUE;
19488361SJulian.Pullen@Sun.COM 	}
19498361SJulian.Pullen@Sun.COM 
19508361SJulian.Pullen@Sun.COM 	if (ad_reload_required)
19518361SJulian.Pullen@Sun.COM 		reload_ad();
19528361SJulian.Pullen@Sun.COM 
19536097Snw141292 	idmap_cfg_unload(&new_pgcfg);
19546097Snw141292 
1955*12508Samw@Sun.COM 	if (DBG(CONFIG, 1)) {
1956*12508Samw@Sun.COM 		if (changed)
1957*12508Samw@Sun.COM 			idmapdlog(LOG_NOTICE, "Configuration changed");
1958*12508Samw@Sun.COM 		else
1959*12508Samw@Sun.COM 			idmapdlog(LOG_NOTICE, "Configuration unchanged");
19605317Sjp151216 	}
19615447Snw141292 
19626097Snw141292 	UNLOCK_CONFIG();
19636097Snw141292 
19646097Snw141292 err:
1965*12508Samw@Sun.COM 	(void) pthread_mutex_unlock(&cfg->handles.mutex);
19664520Snw141292 
19675731Sbaban 	if (rc < -1)
19685447Snw141292 		return (rc);
19695447Snw141292 
19705447Snw141292 	return ((errors == 0) ? 0 : -1);
19714520Snw141292 }
19724520Snw141292 
19734644Sbaban /*
19744644Sbaban  * Initialize 'cfg'.
19754644Sbaban  */
19764520Snw141292 idmap_cfg_t *
idmap_cfg_init()19775908Sjp151216 idmap_cfg_init()
19785908Sjp151216 {
19795317Sjp151216 	idmap_cfg_handles_t *handles;
19804520Snw141292 
19814520Snw141292 	/* First the smf repository handles: */
19824520Snw141292 	idmap_cfg_t *cfg = calloc(1, sizeof (idmap_cfg_t));
19834520Snw141292 	if (!cfg) {
19846017Snw141292 		idmapdlog(LOG_ERR, "Out of memory");
19854520Snw141292 		return (NULL);
19864520Snw141292 	}
19875317Sjp151216 	handles = &cfg->handles;
19884520Snw141292 
19895317Sjp151216 	(void) pthread_mutex_init(&handles->mutex, NULL);
19905317Sjp151216 
19915317Sjp151216 	if (!(handles->main = scf_handle_create(SCF_VERSION))) {
19926017Snw141292 		idmapdlog(LOG_ERR, "scf_handle_create() failed: %s",
19936017Snw141292 		    scf_strerror(scf_error()));
19944520Snw141292 		goto error;
19954520Snw141292 	}
19964520Snw141292 
19975317Sjp151216 	if (scf_handle_bind(handles->main) < 0) {
19986017Snw141292 		idmapdlog(LOG_ERR, "scf_handle_bind() failed: %s",
19996017Snw141292 		    scf_strerror(scf_error()));
20004520Snw141292 		goto error;
20014520Snw141292 	}
20024520Snw141292 
20035317Sjp151216 	if (!(handles->service = scf_service_create(handles->main)) ||
20045317Sjp151216 	    !(handles->instance = scf_instance_create(handles->main)) ||
20055317Sjp151216 	    !(handles->config_pg = scf_pg_create(handles->main)) ||
2006*12508Samw@Sun.COM 	    !(handles->debug_pg = scf_pg_create(handles->main))) {
20076017Snw141292 		idmapdlog(LOG_ERR, "scf handle creation failed: %s",
20086017Snw141292 		    scf_strerror(scf_error()));
20094520Snw141292 		goto error;
20104520Snw141292 	}
20114520Snw141292 
20125317Sjp151216 	if (scf_handle_decode_fmri(handles->main,
20135908Sjp151216 	    FMRI_BASE "/:properties/" CONFIG_PG,
20145908Sjp151216 	    NULL,				/* scope */
20155908Sjp151216 	    handles->service,		/* service */
20165908Sjp151216 	    handles->instance,		/* instance */
20175908Sjp151216 	    handles->config_pg,		/* pg */
20185908Sjp151216 	    NULL,				/* prop */
20195908Sjp151216 	    SCF_DECODE_FMRI_EXACT) < 0) {
20206017Snw141292 		idmapdlog(LOG_ERR, "scf_handle_decode_fmri() failed: %s",
20216017Snw141292 		    scf_strerror(scf_error()));
20224520Snw141292 		goto error;
20234520Snw141292 	}
20244520Snw141292 
20255317Sjp151216 	if (scf_service_get_pg(handles->service,
2026*12508Samw@Sun.COM 	    DEBUG_PG, handles->debug_pg) < 0) {
2027*12508Samw@Sun.COM 		idmapdlog(LOG_ERR, "Property group \"%s\": %s",
2028*12508Samw@Sun.COM 		    DEBUG_PG, scf_strerror(scf_error()));
20294520Snw141292 		goto error;
20304520Snw141292 	}
20314520Snw141292 
2032*12508Samw@Sun.COM 	check_smf_debug_mode(handles);
203310504SKeyur.Desai@Sun.COM 
20345317Sjp151216 	/* Initialize AD Auto Discovery context */
20355317Sjp151216 	handles->ad_ctx = ad_disc_init();
20365317Sjp151216 	if (handles->ad_ctx == NULL)
20375317Sjp151216 		goto error;
20385317Sjp151216 
20394520Snw141292 	return (cfg);
20404520Snw141292 
20414520Snw141292 error:
20424520Snw141292 	(void) idmap_cfg_fini(cfg);
20434520Snw141292 	return (NULL);
20444520Snw141292 }
20454520Snw141292 
20465317Sjp151216 void
idmap_cfg_unload(idmap_pg_config_t * pgcfg)20475908Sjp151216 idmap_cfg_unload(idmap_pg_config_t *pgcfg)
20485908Sjp151216 {
20495317Sjp151216 
20505317Sjp151216 	if (pgcfg->default_domain) {
20515317Sjp151216 		free(pgcfg->default_domain);
20525317Sjp151216 		pgcfg->default_domain = NULL;
20535317Sjp151216 	}
20545317Sjp151216 	if (pgcfg->domain_name) {
20555317Sjp151216 		free(pgcfg->domain_name);
20565317Sjp151216 		pgcfg->domain_name = NULL;
20575317Sjp151216 	}
20585317Sjp151216 	if (pgcfg->machine_sid) {
20595317Sjp151216 		free(pgcfg->machine_sid);
20605317Sjp151216 		pgcfg->machine_sid = NULL;
20615317Sjp151216 	}
20625317Sjp151216 	if (pgcfg->domain_controller) {
20635317Sjp151216 		free(pgcfg->domain_controller);
20645317Sjp151216 		pgcfg->domain_controller = NULL;
20655317Sjp151216 	}
20665317Sjp151216 	if (pgcfg->forest_name) {
20675317Sjp151216 		free(pgcfg->forest_name);
20685317Sjp151216 		pgcfg->forest_name = NULL;
20695317Sjp151216 	}
20705317Sjp151216 	if (pgcfg->site_name) {
20715317Sjp151216 		free(pgcfg->site_name);
20725317Sjp151216 		pgcfg->site_name = NULL;
20735317Sjp151216 	}
20745317Sjp151216 	if (pgcfg->global_catalog) {
20754520Snw141292 		free(pgcfg->global_catalog);
20765317Sjp151216 		pgcfg->global_catalog = NULL;
20775317Sjp151216 	}
20788361SJulian.Pullen@Sun.COM 	if (pgcfg->trusted_domains) {
20798361SJulian.Pullen@Sun.COM 		free(pgcfg->trusted_domains);
20808361SJulian.Pullen@Sun.COM 		pgcfg->trusted_domains = NULL;
20818361SJulian.Pullen@Sun.COM 	}
20828361SJulian.Pullen@Sun.COM 	if (pgcfg->trusted_forests)
20838361SJulian.Pullen@Sun.COM 		free_trusted_forests(&pgcfg->trusted_forests,
20848361SJulian.Pullen@Sun.COM 		    &pgcfg->num_trusted_forests);
20858361SJulian.Pullen@Sun.COM 
20865731Sbaban 	if (pgcfg->ad_unixuser_attr) {
20875731Sbaban 		free(pgcfg->ad_unixuser_attr);
20885731Sbaban 		pgcfg->ad_unixuser_attr = NULL;
20895731Sbaban 	}
20905731Sbaban 	if (pgcfg->ad_unixgroup_attr) {
20915731Sbaban 		free(pgcfg->ad_unixgroup_attr);
20925731Sbaban 		pgcfg->ad_unixgroup_attr = NULL;
20935731Sbaban 	}
20945731Sbaban 	if (pgcfg->nldap_winname_attr) {
20955731Sbaban 		free(pgcfg->nldap_winname_attr);
20965731Sbaban 		pgcfg->nldap_winname_attr = NULL;
20975731Sbaban 	}
20984520Snw141292 }
20994520Snw141292 
21004520Snw141292 int
idmap_cfg_fini(idmap_cfg_t * cfg)21014520Snw141292 idmap_cfg_fini(idmap_cfg_t *cfg)
21024520Snw141292 {
21035317Sjp151216 	idmap_cfg_handles_t *handles = &cfg->handles;
21045317Sjp151216 	idmap_cfg_unload(&cfg->pgcfg);
21054520Snw141292 
21065317Sjp151216 	(void) pthread_mutex_destroy(&handles->mutex);
21075317Sjp151216 	scf_pg_destroy(handles->config_pg);
2108*12508Samw@Sun.COM 	if (handles->debug_pg != NULL)
2109*12508Samw@Sun.COM 		scf_pg_destroy(handles->debug_pg);
21105317Sjp151216 	scf_instance_destroy(handles->instance);
21115317Sjp151216 	scf_service_destroy(handles->service);
21125317Sjp151216 	scf_handle_destroy(handles->main);
21135731Sbaban 	if (handles->ad_ctx != NULL)
21145731Sbaban 		ad_disc_fini(handles->ad_ctx);
21154520Snw141292 	free(cfg);
21164520Snw141292 
21174520Snw141292 	return (0);
21184520Snw141292 }
21195968Snw141292 
21205968Snw141292 void
idmap_cfg_poke_updates(void)21215968Snw141292 idmap_cfg_poke_updates(void)
21225968Snw141292 {
21236097Snw141292 	if (idmapd_ev_port != -1)
21246097Snw141292 		(void) port_send(idmapd_ev_port, POKE_AUTO_DISCOVERY, NULL);
21255968Snw141292 }
21265968Snw141292 
21275968Snw141292 /*ARGSUSED*/
21285968Snw141292 void
idmap_cfg_hup_handler(int sig)21296097Snw141292 idmap_cfg_hup_handler(int sig)
21306097Snw141292 {
21315968Snw141292 	if (idmapd_ev_port >= 0)
21325968Snw141292 		(void) port_send(idmapd_ev_port, RECONFIGURE, NULL);
21335968Snw141292 }
213410504SKeyur.Desai@Sun.COM 
213510504SKeyur.Desai@Sun.COM /*
2136*12508Samw@Sun.COM  * Upgrade the debug flags.
2137*12508Samw@Sun.COM  *
2138*12508Samw@Sun.COM  * We're replacing a single debug flag with a fine-grained mechanism that
2139*12508Samw@Sun.COM  * is also capable of considerably more verbosity.  We'll take a stab at
2140*12508Samw@Sun.COM  * producing roughly the same level of output.
2141*12508Samw@Sun.COM  */
2142*12508Samw@Sun.COM static
2143*12508Samw@Sun.COM int
upgrade_debug(idmap_cfg_handles_t * handles)2144*12508Samw@Sun.COM upgrade_debug(idmap_cfg_handles_t *handles)
2145*12508Samw@Sun.COM {
2146*12508Samw@Sun.COM 	boolean_t debug_present;
2147*12508Samw@Sun.COM 	const char DEBUG_PROP[] = "debug";
2148*12508Samw@Sun.COM 	int rc;
2149*12508Samw@Sun.COM 
2150*12508Samw@Sun.COM 	rc = prop_exists(handles, DEBUG_PROP, &debug_present);
2151*12508Samw@Sun.COM 
2152*12508Samw@Sun.COM 	if (rc != 0)
2153*12508Samw@Sun.COM 		return (rc);
2154*12508Samw@Sun.COM 
2155*12508Samw@Sun.COM 	if (!debug_present)
2156*12508Samw@Sun.COM 		return (0);
2157*12508Samw@Sun.COM 
2158*12508Samw@Sun.COM 	idmapdlog(LOG_INFO,
2159*12508Samw@Sun.COM 	    "Upgrading old %s/%s setting to %s/* settings.",
2160*12508Samw@Sun.COM 	    CONFIG_PG, DEBUG_PROP, DEBUG_PG);
2161*12508Samw@Sun.COM 
2162*12508Samw@Sun.COM 	rc = set_val_integer(handles, handles->debug_pg, "config", 1);
2163*12508Samw@Sun.COM 	if (rc != 0)
2164*12508Samw@Sun.COM 		return (rc);
2165*12508Samw@Sun.COM 	rc = set_val_integer(handles, handles->debug_pg, "discovery", 1);
2166*12508Samw@Sun.COM 	if (rc != 0)
2167*12508Samw@Sun.COM 		return (rc);
2168*12508Samw@Sun.COM 
2169*12508Samw@Sun.COM 	rc = del_val(handles, handles->config_pg, DEBUG_PROP);
2170*12508Samw@Sun.COM 	if (rc != 0)
2171*12508Samw@Sun.COM 		return (rc);
2172*12508Samw@Sun.COM 
2173*12508Samw@Sun.COM 	return (0);
2174*12508Samw@Sun.COM }
2175*12508Samw@Sun.COM 
2176*12508Samw@Sun.COM /*
217710504SKeyur.Desai@Sun.COM  * Upgrade the DS mapping flags.
217810504SKeyur.Desai@Sun.COM  *
217910504SKeyur.Desai@Sun.COM  * If the old ds_name_mapping_enabled flag is present, then
218010504SKeyur.Desai@Sun.COM  *     if the new directory_based_mapping value is present, then
218110504SKeyur.Desai@Sun.COM  *         if the two are compatible, delete the old and note it
218210504SKeyur.Desai@Sun.COM  *         else delete the old and warn
218310504SKeyur.Desai@Sun.COM  *     else
218410504SKeyur.Desai@Sun.COM  *         set the new based on the old, and note it
218510504SKeyur.Desai@Sun.COM  *         delete the old
218610504SKeyur.Desai@Sun.COM  */
218710504SKeyur.Desai@Sun.COM static
218810504SKeyur.Desai@Sun.COM int
upgrade_directory_mapping(idmap_cfg_handles_t * handles)218910504SKeyur.Desai@Sun.COM upgrade_directory_mapping(idmap_cfg_handles_t *handles)
219010504SKeyur.Desai@Sun.COM {
219110504SKeyur.Desai@Sun.COM 	boolean_t legacy_ds_name_mapping_present;
219210504SKeyur.Desai@Sun.COM 	const char DS_NAME_MAPPING_ENABLED[] = "ds_name_mapping_enabled";
219310504SKeyur.Desai@Sun.COM 	const char DIRECTORY_BASED_MAPPING[] = "directory_based_mapping";
219410504SKeyur.Desai@Sun.COM 	int rc;
219510504SKeyur.Desai@Sun.COM 
219610504SKeyur.Desai@Sun.COM 	rc = prop_exists(handles, DS_NAME_MAPPING_ENABLED,
219710504SKeyur.Desai@Sun.COM 	    &legacy_ds_name_mapping_present);
219810504SKeyur.Desai@Sun.COM 
219910504SKeyur.Desai@Sun.COM 	if (rc != 0)
220010504SKeyur.Desai@Sun.COM 		return (rc);
220110504SKeyur.Desai@Sun.COM 
220210504SKeyur.Desai@Sun.COM 	if (!legacy_ds_name_mapping_present)
220310504SKeyur.Desai@Sun.COM 		return (0);
220410504SKeyur.Desai@Sun.COM 
220510504SKeyur.Desai@Sun.COM 	boolean_t legacy_ds_name_mapping_enabled;
2206*12508Samw@Sun.COM 	rc = get_val_bool(handles, DS_NAME_MAPPING_ENABLED,
2207*12508Samw@Sun.COM 	    &legacy_ds_name_mapping_enabled, B_FALSE);
220810504SKeyur.Desai@Sun.COM 	if (rc != 0)
220910504SKeyur.Desai@Sun.COM 		return (rc);
221010504SKeyur.Desai@Sun.COM 
221110504SKeyur.Desai@Sun.COM 	char *legacy_mode;
221210504SKeyur.Desai@Sun.COM 	char *legacy_bool_string;
221310504SKeyur.Desai@Sun.COM 	if (legacy_ds_name_mapping_enabled) {
221410504SKeyur.Desai@Sun.COM 		legacy_mode = "name";
221510504SKeyur.Desai@Sun.COM 		legacy_bool_string = "true";
221610504SKeyur.Desai@Sun.COM 	} else {
221710504SKeyur.Desai@Sun.COM 		legacy_mode = "none";
221810504SKeyur.Desai@Sun.COM 		legacy_bool_string = "false";
221910504SKeyur.Desai@Sun.COM 	}
222010504SKeyur.Desai@Sun.COM 
222110504SKeyur.Desai@Sun.COM 	char *directory_based_mapping;
222210504SKeyur.Desai@Sun.COM 	rc = get_val_astring(handles, DIRECTORY_BASED_MAPPING,
222310504SKeyur.Desai@Sun.COM 	    &directory_based_mapping);
222410504SKeyur.Desai@Sun.COM 	if (rc != 0)
222510504SKeyur.Desai@Sun.COM 		return (rc);
222610504SKeyur.Desai@Sun.COM 
222710504SKeyur.Desai@Sun.COM 	if (directory_based_mapping == NULL) {
222810504SKeyur.Desai@Sun.COM 		idmapdlog(LOG_INFO,
222910504SKeyur.Desai@Sun.COM 		    "Upgrading old %s=%s setting\n"
223010504SKeyur.Desai@Sun.COM 		    "to %s=%s.",
223110504SKeyur.Desai@Sun.COM 		    DS_NAME_MAPPING_ENABLED, legacy_bool_string,
223210504SKeyur.Desai@Sun.COM 		    DIRECTORY_BASED_MAPPING, legacy_mode);
2233*12508Samw@Sun.COM 		rc = set_val_astring(handles, handles->config_pg,
2234*12508Samw@Sun.COM 		    DIRECTORY_BASED_MAPPING, legacy_mode);
223510504SKeyur.Desai@Sun.COM 		if (rc != 0)
223610504SKeyur.Desai@Sun.COM 			return (rc);
223710504SKeyur.Desai@Sun.COM 	} else {
223810504SKeyur.Desai@Sun.COM 		boolean_t new_name_mapping;
223910504SKeyur.Desai@Sun.COM 		if (strcasecmp(directory_based_mapping, "name") == 0)
224010504SKeyur.Desai@Sun.COM 			new_name_mapping = B_TRUE;
224110504SKeyur.Desai@Sun.COM 		else
224210504SKeyur.Desai@Sun.COM 			new_name_mapping = B_FALSE;
224310504SKeyur.Desai@Sun.COM 
224410504SKeyur.Desai@Sun.COM 		if (legacy_ds_name_mapping_enabled == new_name_mapping) {
224510504SKeyur.Desai@Sun.COM 			idmapdlog(LOG_INFO,
224610504SKeyur.Desai@Sun.COM 			    "Automatically removing old %s=%s setting\n"
224710504SKeyur.Desai@Sun.COM 			    "in favor of %s=%s.",
224810504SKeyur.Desai@Sun.COM 			    DS_NAME_MAPPING_ENABLED, legacy_bool_string,
224910504SKeyur.Desai@Sun.COM 			    DIRECTORY_BASED_MAPPING, directory_based_mapping);
225010504SKeyur.Desai@Sun.COM 		} else {
225110504SKeyur.Desai@Sun.COM 			idmapdlog(LOG_WARNING,
225210504SKeyur.Desai@Sun.COM 			    "Removing conflicting %s=%s setting\n"
225310504SKeyur.Desai@Sun.COM 			    "in favor of %s=%s.",
225410504SKeyur.Desai@Sun.COM 			    DS_NAME_MAPPING_ENABLED, legacy_bool_string,
225510504SKeyur.Desai@Sun.COM 			    DIRECTORY_BASED_MAPPING, directory_based_mapping);
225610504SKeyur.Desai@Sun.COM 		}
225710504SKeyur.Desai@Sun.COM 		free(directory_based_mapping);
225810504SKeyur.Desai@Sun.COM 	}
225910504SKeyur.Desai@Sun.COM 
2260*12508Samw@Sun.COM 	rc = del_val(handles, handles->config_pg, DS_NAME_MAPPING_ENABLED);
226110504SKeyur.Desai@Sun.COM 	if (rc != 0)
226210504SKeyur.Desai@Sun.COM 		return (rc);
226310504SKeyur.Desai@Sun.COM 
226410504SKeyur.Desai@Sun.COM 	return (0);
226510504SKeyur.Desai@Sun.COM }
226610504SKeyur.Desai@Sun.COM 
226710504SKeyur.Desai@Sun.COM /*
226810504SKeyur.Desai@Sun.COM  * Do whatever is necessary to upgrade idmap's configuration before
226910504SKeyur.Desai@Sun.COM  * we load it.
227010504SKeyur.Desai@Sun.COM  */
227110504SKeyur.Desai@Sun.COM int
idmap_cfg_upgrade(idmap_cfg_t * cfg)227210504SKeyur.Desai@Sun.COM idmap_cfg_upgrade(idmap_cfg_t *cfg)
227310504SKeyur.Desai@Sun.COM {
227410504SKeyur.Desai@Sun.COM 	int rc;
227510504SKeyur.Desai@Sun.COM 
227610504SKeyur.Desai@Sun.COM 	rc = upgrade_directory_mapping(&cfg->handles);
227710504SKeyur.Desai@Sun.COM 	if (rc != 0)
227810504SKeyur.Desai@Sun.COM 		return (rc);
227910504SKeyur.Desai@Sun.COM 
2280*12508Samw@Sun.COM 	rc = upgrade_debug(&cfg->handles);
2281*12508Samw@Sun.COM 	if (rc != 0)
2282*12508Samw@Sun.COM 		return (rc);
2283*12508Samw@Sun.COM 
228410504SKeyur.Desai@Sun.COM 	return (0);
228510504SKeyur.Desai@Sun.COM }
2286