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