xref: /onnv-gate/usr/src/cmd/idmap/idmapd/init.c (revision 8361:9c6ec36a5ee9)
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 /*
225908Sjp151216  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
234520Snw141292  * Use is subject to license terms.
244520Snw141292  */
254520Snw141292 
264520Snw141292 /*
274520Snw141292  * Initialization routines
284520Snw141292  */
294520Snw141292 
304520Snw141292 #include "idmapd.h"
314520Snw141292 #include <signal.h>
324520Snw141292 #include <thread.h>
334520Snw141292 #include <string.h>
344520Snw141292 #include <errno.h>
354520Snw141292 #include <assert.h>
364520Snw141292 #include <unistd.h>
374520Snw141292 #include <sys/types.h>
384520Snw141292 #include <sys/stat.h>
394695Sbaban #include <rpcsvc/daemon_utils.h>
404520Snw141292 
414520Snw141292 
424520Snw141292 int
435908Sjp151216 init_mapping_system()
445908Sjp151216 {
454695Sbaban 	int rc = 0;
464695Sbaban 
474520Snw141292 	if (rwlock_init(&_idmapdstate.rwlk_cfg, USYNC_THREAD, NULL) != 0)
484520Snw141292 		return (-1);
495731Sbaban 	if ((rc = load_config()) < 0)
505731Sbaban 		return (rc);
514695Sbaban 
524695Sbaban 	(void) setegid(DAEMON_GID);
534695Sbaban 	(void) seteuid(DAEMON_UID);
544520Snw141292 	if (init_dbs() < 0) {
554695Sbaban 		rc = -1;
564520Snw141292 		fini_mapping_system();
574520Snw141292 	}
584695Sbaban 	(void) seteuid(0);
594695Sbaban 	(void) setegid(0);
604695Sbaban 
614695Sbaban 	return (rc);
624520Snw141292 }
634520Snw141292 
644520Snw141292 void
655908Sjp151216 fini_mapping_system()
665908Sjp151216 {
674520Snw141292 	fini_dbs();
684520Snw141292 }
694520Snw141292 
704520Snw141292 int
715908Sjp151216 load_config()
725908Sjp151216 {
735447Snw141292 	int rc;
744520Snw141292 	if ((_idmapdstate.cfg = idmap_cfg_init()) == NULL) {
756097Snw141292 		degrade_svc(0, "failed to initialize config");
764520Snw141292 		return (-1);
774520Snw141292 	}
785317Sjp151216 
796097Snw141292 	rc = idmap_cfg_load(_idmapdstate.cfg, 0);
805447Snw141292 	if (rc < -1) {
815447Snw141292 		/* Total failure */
826097Snw141292 		degrade_svc(0, "fatal error while loading configuration");
835731Sbaban 		return (rc);
844520Snw141292 	}
855317Sjp151216 
865447Snw141292 	if (rc != 0)
875447Snw141292 		/* Partial failure */
886017Snw141292 		idmapdlog(LOG_ERR, "Various errors occurred while loading "
896017Snw141292 		    "the configuration; check the logs");
905447Snw141292 
915968Snw141292 	if ((rc = idmap_cfg_start_updates()) < 0) {
925968Snw141292 		/* Total failure */
936097Snw141292 		degrade_svc(0, "could not start config updater");
945968Snw141292 		return (rc);
955968Snw141292 	}
965447Snw141292 
976017Snw141292 	idmapdlog(LOG_DEBUG, "Initial configuration loaded");
985447Snw141292 
995317Sjp151216 	return (0);
1005317Sjp151216 }
1015317Sjp151216 
1025317Sjp151216 
1036097Snw141292 void
1045908Sjp151216 reload_ad()
1055908Sjp151216 {
106*8361SJulian.Pullen@Sun.COM 	int		i, j;
107*8361SJulian.Pullen@Sun.COM 	adutils_ad_t	**new_ads = NULL;
108*8361SJulian.Pullen@Sun.COM 	adutils_ad_t	**old_ads;
109*8361SJulian.Pullen@Sun.COM 	int		new_num_ads;
110*8361SJulian.Pullen@Sun.COM 	int		old_num_ads;
1115317Sjp151216 	idmap_pg_config_t *pgcfg = &_idmapdstate.cfg->pgcfg;
112*8361SJulian.Pullen@Sun.COM 	idmap_trustedforest_t *trustfor = pgcfg->trusted_forests;
113*8361SJulian.Pullen@Sun.COM 	int		num_trustfor = pgcfg->num_trusted_forests;
114*8361SJulian.Pullen@Sun.COM 	ad_disc_domainsinforest_t *domain_in_forest;
1155317Sjp151216 
1166097Snw141292 	if (pgcfg->global_catalog == NULL ||
1176097Snw141292 	    pgcfg->global_catalog[0].host[0] == '\0') {
1186097Snw141292 		/*
1196097Snw141292 		 * No GCs.  Continue to use the previous AD config in case
1206097Snw141292 		 * that's still good but auto-discovery had a transient failure.
1216097Snw141292 		 * If that stops working we'll go into degraded mode anyways
1226097Snw141292 		 * when it does.
1236097Snw141292 		 */
1246097Snw141292 		degrade_svc(0,
1256097Snw141292 		    "Global Catalog servers not configured/discoverable");
1266097Snw141292 		return;
1274520Snw141292 	}
1285317Sjp151216 
129*8361SJulian.Pullen@Sun.COM 	old_ads = _idmapdstate.ads;
130*8361SJulian.Pullen@Sun.COM 	old_num_ads = _idmapdstate.num_ads;
1315317Sjp151216 
132*8361SJulian.Pullen@Sun.COM 	new_num_ads = 1 + num_trustfor;
133*8361SJulian.Pullen@Sun.COM 	new_ads = calloc(new_num_ads, sizeof (adutils_ad_t *));
134*8361SJulian.Pullen@Sun.COM 	if (new_ads == NULL) {
135*8361SJulian.Pullen@Sun.COM 		degrade_svc(0, "could not allocate AD context array "
136*8361SJulian.Pullen@Sun.COM 		    "(out of memory)");
137*8361SJulian.Pullen@Sun.COM 		return;
138*8361SJulian.Pullen@Sun.COM 	}
139*8361SJulian.Pullen@Sun.COM 
140*8361SJulian.Pullen@Sun.COM 	if (adutils_ad_alloc(&new_ads[0], pgcfg->default_domain,
1418040SBaban.Kenkre@Sun.COM 	    ADUTILS_AD_GLOBAL_CATALOG) != ADUTILS_SUCCESS) {
142*8361SJulian.Pullen@Sun.COM 		free(new_ads);
143*8361SJulian.Pullen@Sun.COM 		degrade_svc(0, "could not initialize AD context "
144*8361SJulian.Pullen@Sun.COM 		    "(out of memory)");
1456097Snw141292 		return;
1464520Snw141292 	}
1475317Sjp151216 
1485317Sjp151216 	for (i = 0; pgcfg->global_catalog[i].host[0] != '\0'; i++) {
149*8361SJulian.Pullen@Sun.COM 		if (idmap_add_ds(new_ads[0],
1505317Sjp151216 		    pgcfg->global_catalog[i].host,
1515317Sjp151216 		    pgcfg->global_catalog[i].port) != 0) {
152*8361SJulian.Pullen@Sun.COM 			adutils_ad_free(&new_ads[0]);
153*8361SJulian.Pullen@Sun.COM 			free(new_ads);
154*8361SJulian.Pullen@Sun.COM 			degrade_svc(0, "could not set AD hosts "
155*8361SJulian.Pullen@Sun.COM 			    "(out of memory)");
1566097Snw141292 			return;
1575317Sjp151216 		}
1585317Sjp151216 	}
1595317Sjp151216 
160*8361SJulian.Pullen@Sun.COM 	if (pgcfg->domains_in_forest != NULL) {
161*8361SJulian.Pullen@Sun.COM 		for (i = 0; pgcfg->domains_in_forest[i].domain[0] != '\0';
162*8361SJulian.Pullen@Sun.COM 		    i++) {
163*8361SJulian.Pullen@Sun.COM 			if (adutils_add_domain(new_ads[0],
164*8361SJulian.Pullen@Sun.COM 			    pgcfg->domains_in_forest[i].domain,
165*8361SJulian.Pullen@Sun.COM 			    pgcfg->domains_in_forest[i].sid) != 0) {
166*8361SJulian.Pullen@Sun.COM 				adutils_ad_free(&new_ads[0]);
167*8361SJulian.Pullen@Sun.COM 				free(new_ads);
168*8361SJulian.Pullen@Sun.COM 				degrade_svc(0, "could not set AD domains "
169*8361SJulian.Pullen@Sun.COM 				    "(out of memory)");
170*8361SJulian.Pullen@Sun.COM 				return;
171*8361SJulian.Pullen@Sun.COM 			}
172*8361SJulian.Pullen@Sun.COM 		}
173*8361SJulian.Pullen@Sun.COM 	}
1745317Sjp151216 
175*8361SJulian.Pullen@Sun.COM 	for (i = 0; i < num_trustfor; i++) {
176*8361SJulian.Pullen@Sun.COM 		if (adutils_ad_alloc(&new_ads[i + 1], NULL,
177*8361SJulian.Pullen@Sun.COM 		    ADUTILS_AD_GLOBAL_CATALOG) != ADUTILS_SUCCESS) {
178*8361SJulian.Pullen@Sun.COM 			degrade_svc(0, "could not initialize trusted AD "
179*8361SJulian.Pullen@Sun.COM 			    "context (out of memory)");
180*8361SJulian.Pullen@Sun.COM 				new_num_ads = i + 1;
181*8361SJulian.Pullen@Sun.COM 				goto out;
182*8361SJulian.Pullen@Sun.COM 		}
183*8361SJulian.Pullen@Sun.COM 		for (j = 0; trustfor[i].global_catalog[j].host[0] != '\0';
184*8361SJulian.Pullen@Sun.COM 		    j++) {
185*8361SJulian.Pullen@Sun.COM 			if (idmap_add_ds(new_ads[i + 1],
186*8361SJulian.Pullen@Sun.COM 			    trustfor[i].global_catalog[j].host,
187*8361SJulian.Pullen@Sun.COM 			    trustfor[i].global_catalog[j].port) != 0) {
188*8361SJulian.Pullen@Sun.COM 				adutils_ad_free(&new_ads[i + 1]);
189*8361SJulian.Pullen@Sun.COM 				degrade_svc(0, "could not set trusted "
190*8361SJulian.Pullen@Sun.COM 				    "AD hosts (out of memory)");
191*8361SJulian.Pullen@Sun.COM 				new_num_ads = i + 1;
192*8361SJulian.Pullen@Sun.COM 				goto out;
193*8361SJulian.Pullen@Sun.COM 			}
194*8361SJulian.Pullen@Sun.COM 		}
195*8361SJulian.Pullen@Sun.COM 		for (j = 0; trustfor[i].domains_in_forest[j].domain[0] != '\0';
196*8361SJulian.Pullen@Sun.COM 		    j++) {
197*8361SJulian.Pullen@Sun.COM 			domain_in_forest = &trustfor[i].domains_in_forest[j];
198*8361SJulian.Pullen@Sun.COM 			/* Only add domains which are marked */
199*8361SJulian.Pullen@Sun.COM 			if (domain_in_forest->trusted) {
200*8361SJulian.Pullen@Sun.COM 				if (adutils_add_domain(new_ads[i + 1],
201*8361SJulian.Pullen@Sun.COM 				    domain_in_forest->domain,
202*8361SJulian.Pullen@Sun.COM 				    domain_in_forest->sid) != 0) {
203*8361SJulian.Pullen@Sun.COM 					adutils_ad_free(&new_ads[i + 1]);
204*8361SJulian.Pullen@Sun.COM 					degrade_svc(0, "could not set trusted "
205*8361SJulian.Pullen@Sun.COM 					    "AD domains (out of memory)");
206*8361SJulian.Pullen@Sun.COM 					new_num_ads = i + 1;
207*8361SJulian.Pullen@Sun.COM 					goto out;
208*8361SJulian.Pullen@Sun.COM 				}
209*8361SJulian.Pullen@Sun.COM 			}
210*8361SJulian.Pullen@Sun.COM 		}
211*8361SJulian.Pullen@Sun.COM 	}
212*8361SJulian.Pullen@Sun.COM 
213*8361SJulian.Pullen@Sun.COM out:
214*8361SJulian.Pullen@Sun.COM 	_idmapdstate.ads = new_ads;
215*8361SJulian.Pullen@Sun.COM 	_idmapdstate.num_ads = new_num_ads;
216*8361SJulian.Pullen@Sun.COM 
217*8361SJulian.Pullen@Sun.COM 
218*8361SJulian.Pullen@Sun.COM 	if (old_ads != NULL) {
219*8361SJulian.Pullen@Sun.COM 		for (i = 0; i < old_num_ads; i++)
220*8361SJulian.Pullen@Sun.COM 			adutils_ad_free(&old_ads[i]);
221*8361SJulian.Pullen@Sun.COM 		free(old_ads);
222*8361SJulian.Pullen@Sun.COM 	}
2234520Snw141292 }
2244520Snw141292 
2255317Sjp151216 
2264520Snw141292 void
2275908Sjp151216 print_idmapdstate()
2285908Sjp151216 {
229*8361SJulian.Pullen@Sun.COM 	int i, j;
2305731Sbaban 	idmap_pg_config_t *pgcfg;
231*8361SJulian.Pullen@Sun.COM 	idmap_trustedforest_t *tf;
2325317Sjp151216 
2334520Snw141292 	RDLOCK_CONFIG();
2344520Snw141292 
2355317Sjp151216 	if (_idmapdstate.cfg == NULL) {
2366017Snw141292 		idmapdlog(LOG_INFO, "Null configuration");
2375317Sjp151216 		UNLOCK_CONFIG();
2385317Sjp151216 		return;
2394520Snw141292 	}
2405317Sjp151216 
2415731Sbaban 	pgcfg = &_idmapdstate.cfg->pgcfg;
2425731Sbaban 
2436017Snw141292 	idmapdlog(LOG_DEBUG, "list_size_limit=%llu", pgcfg->list_size_limit);
2446017Snw141292 	idmapdlog(LOG_DEBUG, "default_domain=%s",
2455317Sjp151216 	    CHECK_NULL(pgcfg->default_domain));
2466017Snw141292 	idmapdlog(LOG_DEBUG, "domain_name=%s", CHECK_NULL(pgcfg->domain_name));
2476017Snw141292 	idmapdlog(LOG_DEBUG, "machine_sid=%s", CHECK_NULL(pgcfg->machine_sid));
2485317Sjp151216 	if (pgcfg->domain_controller == NULL ||
2495317Sjp151216 	    pgcfg->domain_controller[0].host[0] == '\0') {
2506017Snw141292 		idmapdlog(LOG_DEBUG, "No domain controllers known");
2515317Sjp151216 	} else {
2525317Sjp151216 		for (i = 0; pgcfg->domain_controller[i].host[0] != '\0'; i++)
2536017Snw141292 			idmapdlog(LOG_DEBUG, "domain_controller=%s port=%d",
2546017Snw141292 			    pgcfg->domain_controller[i].host,
2555317Sjp151216 			    pgcfg->domain_controller[i].port);
2565317Sjp151216 	}
2576017Snw141292 	idmapdlog(LOG_DEBUG, "forest_name=%s", CHECK_NULL(pgcfg->forest_name));
2586017Snw141292 	idmapdlog(LOG_DEBUG, "site_name=%s", CHECK_NULL(pgcfg->site_name));
2595317Sjp151216 	if (pgcfg->global_catalog == NULL ||
2605317Sjp151216 	    pgcfg->global_catalog[0].host[0] == '\0') {
2616017Snw141292 		idmapdlog(LOG_DEBUG, "No global catalog servers known");
2625317Sjp151216 	} else {
2635317Sjp151216 		for (i = 0; pgcfg->global_catalog[i].host[0] != '\0'; i++)
2646017Snw141292 			idmapdlog(LOG_DEBUG, "global_catalog=%s port=%d",
2655317Sjp151216 			    pgcfg->global_catalog[i].host,
2665317Sjp151216 			    pgcfg->global_catalog[i].port);
2675317Sjp151216 	}
268*8361SJulian.Pullen@Sun.COM 	if (pgcfg->domains_in_forest == NULL ||
269*8361SJulian.Pullen@Sun.COM 	    pgcfg->domains_in_forest[0].domain[0] == '\0') {
270*8361SJulian.Pullen@Sun.COM 		idmapdlog(LOG_DEBUG, "No domains in forest %s known",
271*8361SJulian.Pullen@Sun.COM 		    CHECK_NULL(pgcfg->forest_name));
272*8361SJulian.Pullen@Sun.COM 	} else {
273*8361SJulian.Pullen@Sun.COM 		for (i = 0; pgcfg->domains_in_forest[i].domain[0] != '\0'; i++)
274*8361SJulian.Pullen@Sun.COM 			idmapdlog(LOG_DEBUG, "domains in forest %s = %s",
275*8361SJulian.Pullen@Sun.COM 			    CHECK_NULL(pgcfg->forest_name),
276*8361SJulian.Pullen@Sun.COM 			    pgcfg->domains_in_forest[i].domain);
277*8361SJulian.Pullen@Sun.COM 	}
278*8361SJulian.Pullen@Sun.COM 	if (pgcfg->trusted_domains == NULL ||
279*8361SJulian.Pullen@Sun.COM 	    pgcfg->trusted_domains[0].domain[0] == '\0') {
280*8361SJulian.Pullen@Sun.COM 		idmapdlog(LOG_DEBUG, "No trusted domains known");
281*8361SJulian.Pullen@Sun.COM 	} else {
282*8361SJulian.Pullen@Sun.COM 		for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++)
283*8361SJulian.Pullen@Sun.COM 			idmapdlog(LOG_DEBUG, "trusted domain = %s",
284*8361SJulian.Pullen@Sun.COM 			    pgcfg->trusted_domains[i].domain);
285*8361SJulian.Pullen@Sun.COM 	}
286*8361SJulian.Pullen@Sun.COM 
287*8361SJulian.Pullen@Sun.COM 	for (i = 0; i < pgcfg->num_trusted_forests; i++) {
288*8361SJulian.Pullen@Sun.COM 		tf = &pgcfg->trusted_forests[i];
289*8361SJulian.Pullen@Sun.COM 		for (j = 0; tf->global_catalog[j].host[0] != '\0'; j++)
290*8361SJulian.Pullen@Sun.COM 			idmapdlog(LOG_DEBUG,
291*8361SJulian.Pullen@Sun.COM 			    "trusted forest %s global_catalog=%s port=%d",
292*8361SJulian.Pullen@Sun.COM 			    tf->forest_name,
293*8361SJulian.Pullen@Sun.COM 			    tf->global_catalog[j].host,
294*8361SJulian.Pullen@Sun.COM 			    tf->global_catalog[j].port);
295*8361SJulian.Pullen@Sun.COM 		for (j = 0; tf->domains_in_forest[j].domain[0] != '\0'; j++) {
296*8361SJulian.Pullen@Sun.COM 			if (tf->domains_in_forest[j].trusted) {
297*8361SJulian.Pullen@Sun.COM 				idmapdlog(LOG_DEBUG,
298*8361SJulian.Pullen@Sun.COM 				    "trusted forest %s domain=%s",
299*8361SJulian.Pullen@Sun.COM 				    tf->forest_name,
300*8361SJulian.Pullen@Sun.COM 				    tf->domains_in_forest[j].domain);
301*8361SJulian.Pullen@Sun.COM 			}
302*8361SJulian.Pullen@Sun.COM 		}
303*8361SJulian.Pullen@Sun.COM 	}
304*8361SJulian.Pullen@Sun.COM 
3056017Snw141292 	idmapdlog(LOG_DEBUG, "ds_name_mapping_enabled=%s",
3065731Sbaban 	    (pgcfg->ds_name_mapping_enabled == TRUE) ? "true" : "false");
3076017Snw141292 	idmapdlog(LOG_DEBUG, "ad_unixuser_attr=%s",
3085731Sbaban 	    CHECK_NULL(pgcfg->ad_unixuser_attr));
3096017Snw141292 	idmapdlog(LOG_DEBUG, "ad_unixgroup_attr=%s",
3105731Sbaban 	    CHECK_NULL(pgcfg->ad_unixgroup_attr));
3116017Snw141292 	idmapdlog(LOG_DEBUG, "nldap_winname_attr=%s",
3125731Sbaban 	    CHECK_NULL(pgcfg->nldap_winname_attr));
3135317Sjp151216 
3144520Snw141292 	UNLOCK_CONFIG();
3154520Snw141292 }
3164520Snw141292 
3174520Snw141292 int
3185908Sjp151216 create_directory(const char *path, uid_t uid, gid_t gid)
3195908Sjp151216 {
3204520Snw141292 	int	rc;
3214520Snw141292 
3224520Snw141292 	if ((rc = mkdir(path, 0700)) < 0 && errno != EEXIST) {
3236017Snw141292 		idmapdlog(LOG_ERR, "Error creating directory %s (%s)",
3246017Snw141292 		    path, strerror(errno));
3254520Snw141292 		return (-1);
3264520Snw141292 	}
3274520Snw141292 
3284520Snw141292 	if (lchown(path, uid, gid) < 0) {
3296017Snw141292 		idmapdlog(LOG_ERR, "Error creating directory %s (%s)",
3306017Snw141292 		    path, strerror(errno));
3314520Snw141292 		if (rc == 0)
3324520Snw141292 			(void) rmdir(path);
3334520Snw141292 		return (-1);
3344520Snw141292 	}
3354520Snw141292 	return (0);
3364520Snw141292 }
337