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 /* 22*12065SKeyur.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> 435317Sjp151216 #include "addisc.h" 444520Snw141292 457031Snw141292 #define MACHINE_SID_LEN (9 + 3 * 11) 465968Snw141292 #define FMRI_BASE "svc:/system/idmap" 475968Snw141292 #define CONFIG_PG "config" 485968Snw141292 #define GENERAL_PG "general" 495968Snw141292 #define RECONFIGURE 1 505968Snw141292 #define POKE_AUTO_DISCOVERY 2 514520Snw141292 52*12065SKeyur.Desai@Sun.COM enum event_type { 53*12065SKeyur.Desai@Sun.COM EVENT_NOTHING, /* Woke up for no good reason */ 54*12065SKeyur.Desai@Sun.COM EVENT_TIMEOUT, /* Timeout expired */ 55*12065SKeyur.Desai@Sun.COM EVENT_ROUTING, /* An interesting routing event happened */ 56*12065SKeyur.Desai@Sun.COM EVENT_DEGRADE, /* An error occurred in the mainline */ 57*12065SKeyur.Desai@Sun.COM EVENT_REFRESH, /* SMF refresh */ 58*12065SKeyur.Desai@Sun.COM }; 59*12065SKeyur.Desai@Sun.COM 605317Sjp151216 /*LINTLIBRARY*/ 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 754695Sbaban static int 765908Sjp151216 generate_machine_sid(char **machine_sid) 775908Sjp151216 { 784695Sbaban char *p; 794695Sbaban uuid_t uu; 804695Sbaban int i, j, len, rlen; 814695Sbaban uint32_t rid; 824695Sbaban 834695Sbaban /* 847031Snw141292 * Generate and split 128-bit UUID into three 32-bit RIDs The 857031Snw141292 * machine_sid will be of the form S-1-5-21-N1-N2-N3 (that's 867031Snw141292 * four RIDs altogether). 877031Snw141292 * 8810504SKeyur.Desai@Sun.COM * Technically we could use up to 14 random RIDs here, but it 897031Snw141292 * turns out that with some versions of Windows using SIDs with 907031Snw141292 * more than five RIDs in security descriptors causes problems. 914695Sbaban */ 924695Sbaban 934695Sbaban *machine_sid = calloc(1, MACHINE_SID_LEN); 944695Sbaban if (*machine_sid == NULL) { 956017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 964695Sbaban return (-1); 974695Sbaban } 984695Sbaban (void) strcpy(*machine_sid, "S-1-5-21"); 994695Sbaban p = *machine_sid + strlen("S-1-5-21"); 1004695Sbaban len = MACHINE_SID_LEN - strlen("S-1-5-21"); 1014695Sbaban 1024695Sbaban uuid_clear(uu); 1034695Sbaban uuid_generate_random(uu); 1044695Sbaban 1057031Snw141292 #if UUID_LEN != 16 1067031Snw141292 #error UUID size is not 16! 1077031Snw141292 #endif 1087031Snw141292 1097031Snw141292 for (i = 0; i < 3; i++) { 1104695Sbaban j = i * 4; 1114695Sbaban rid = (uu[j] << 24) | (uu[j + 1] << 16) | 1125908Sjp151216 (uu[j + 2] << 8) | (uu[j + 3]); 1134695Sbaban rlen = snprintf(p, len, "-%u", rid); 1144695Sbaban p += rlen; 1154695Sbaban len -= rlen; 1164695Sbaban } 1174695Sbaban 1184695Sbaban return (0); 1194695Sbaban } 1204695Sbaban 1216616Sdm199847 1226616Sdm199847 /* In the case of error, exists is set to FALSE anyway */ 1236616Sdm199847 static int 12410504SKeyur.Desai@Sun.COM prop_exists(idmap_cfg_handles_t *handles, const char *name, boolean_t *exists) 1256017Snw141292 { 1266616Sdm199847 1276616Sdm199847 scf_property_t *scf_prop; 1286616Sdm199847 scf_value_t *value; 1296616Sdm199847 1308671SJulian.Pullen@Sun.COM *exists = B_FALSE; 1316017Snw141292 1326616Sdm199847 scf_prop = scf_property_create(handles->main); 1336616Sdm199847 if (scf_prop == NULL) { 1346616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 1356616Sdm199847 scf_strerror(scf_error())); 1366616Sdm199847 return (-1); 1376616Sdm199847 } 1386616Sdm199847 value = scf_value_create(handles->main); 1396616Sdm199847 if (value == NULL) { 1406616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 1416616Sdm199847 scf_strerror(scf_error())); 1426616Sdm199847 scf_property_destroy(scf_prop); 1436616Sdm199847 return (-1); 1446616Sdm199847 } 1456017Snw141292 1466017Snw141292 if (scf_pg_get_property(handles->config_pg, name, scf_prop) == 0) 1478671SJulian.Pullen@Sun.COM *exists = B_TRUE; 1486017Snw141292 1496017Snw141292 scf_value_destroy(value); 1506017Snw141292 scf_property_destroy(scf_prop); 1516017Snw141292 1526616Sdm199847 return (0); 1536017Snw141292 } 1546017Snw141292 1554520Snw141292 /* Check if in the case of failure the original value of *val is preserved */ 1564520Snw141292 static int 15710504SKeyur.Desai@Sun.COM get_val_int(idmap_cfg_handles_t *handles, const char *name, 1585317Sjp151216 void *val, scf_type_t type) 1594520Snw141292 { 1604520Snw141292 int rc = 0; 1614520Snw141292 1626616Sdm199847 scf_property_t *scf_prop; 1636616Sdm199847 scf_value_t *value; 16410504SKeyur.Desai@Sun.COM uint8_t b; 1656616Sdm199847 1667031Snw141292 switch (type) { 1677031Snw141292 case SCF_TYPE_BOOLEAN: 16810504SKeyur.Desai@Sun.COM *(boolean_t *)val = B_FALSE; 1697031Snw141292 break; 1707031Snw141292 case SCF_TYPE_COUNT: 1717031Snw141292 *(uint64_t *)val = 0; 1727031Snw141292 break; 1737031Snw141292 case SCF_TYPE_INTEGER: 1747031Snw141292 *(int64_t *)val = 0; 1757031Snw141292 break; 1767031Snw141292 default: 1777031Snw141292 idmapdlog(LOG_ERR, "Invalid scf integer type (%d)", 1787031Snw141292 type); 1797031Snw141292 abort(); 1807031Snw141292 } 1817031Snw141292 1826616Sdm199847 scf_prop = scf_property_create(handles->main); 1836616Sdm199847 if (scf_prop == NULL) { 1846616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 1856616Sdm199847 scf_strerror(scf_error())); 1866616Sdm199847 return (-1); 1876616Sdm199847 } 1886616Sdm199847 value = scf_value_create(handles->main); 1896616Sdm199847 if (value == NULL) { 1906616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 1916616Sdm199847 scf_strerror(scf_error())); 1926616Sdm199847 scf_property_destroy(scf_prop); 1936616Sdm199847 return (-1); 1946616Sdm199847 } 1954520Snw141292 1965317Sjp151216 if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) 1974520Snw141292 /* this is OK: the property is just undefined */ 1984520Snw141292 goto destruction; 1994520Snw141292 2004520Snw141292 2015317Sjp151216 if (scf_property_get_value(scf_prop, value) < 0) 2024520Snw141292 /* It is still OK when a property doesn't have any value */ 2034520Snw141292 goto destruction; 2044520Snw141292 2054520Snw141292 switch (type) { 2064520Snw141292 case SCF_TYPE_BOOLEAN: 20710504SKeyur.Desai@Sun.COM rc = scf_value_get_boolean(value, &b); 20810504SKeyur.Desai@Sun.COM *(boolean_t *)val = b; 2094520Snw141292 break; 2104520Snw141292 case SCF_TYPE_COUNT: 2114520Snw141292 rc = scf_value_get_count(value, val); 2124520Snw141292 break; 2134520Snw141292 case SCF_TYPE_INTEGER: 2144520Snw141292 rc = scf_value_get_integer(value, val); 2154520Snw141292 break; 21610504SKeyur.Desai@Sun.COM default: 21710504SKeyur.Desai@Sun.COM abort(); /* tested above */ 21810504SKeyur.Desai@Sun.COM /* NOTREACHED */ 2194520Snw141292 } 2204520Snw141292 22110504SKeyur.Desai@Sun.COM if (rc != 0) { 22210504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, "Can not retrieve config/%s: %s", 22310504SKeyur.Desai@Sun.COM name, scf_strerror(scf_error())); 22410504SKeyur.Desai@Sun.COM } 2254520Snw141292 2264520Snw141292 destruction: 2274520Snw141292 scf_value_destroy(value); 2284520Snw141292 scf_property_destroy(scf_prop); 2294520Snw141292 2304520Snw141292 return (rc); 2314520Snw141292 } 2324520Snw141292 2334520Snw141292 static char * 23410504SKeyur.Desai@Sun.COM scf_value2string(const char *name, scf_value_t *value) 2355908Sjp151216 { 23610504SKeyur.Desai@Sun.COM static size_t max_val = 0; 2374520Snw141292 23810504SKeyur.Desai@Sun.COM if (max_val == 0) 23910504SKeyur.Desai@Sun.COM max_val = scf_limit(SCF_LIMIT_MAX_VALUE_LENGTH); 2404520Snw141292 24110504SKeyur.Desai@Sun.COM char buf[max_val + 1]; 24210504SKeyur.Desai@Sun.COM if (scf_value_get_astring(value, buf, max_val + 1) < 0) { 24310504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, "Can not retrieve config/%s: %s", 24410504SKeyur.Desai@Sun.COM name, scf_strerror(scf_error())); 24510504SKeyur.Desai@Sun.COM return (NULL); 2464520Snw141292 } 2474520Snw141292 24810504SKeyur.Desai@Sun.COM char *s = strdup(buf); 24910504SKeyur.Desai@Sun.COM if (s == NULL) 25010504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, "Out of memory"); 2514520Snw141292 25210504SKeyur.Desai@Sun.COM return (s); 2534520Snw141292 } 2544520Snw141292 2555317Sjp151216 static int 2565317Sjp151216 get_val_ds(idmap_cfg_handles_t *handles, const char *name, int defport, 2576616Sdm199847 idmap_ad_disc_ds_t **val) 2585317Sjp151216 { 2596616Sdm199847 idmap_ad_disc_ds_t *servers = NULL; 2605317Sjp151216 scf_property_t *scf_prop; 2615317Sjp151216 scf_value_t *value; 2625317Sjp151216 scf_iter_t *iter; 2635317Sjp151216 char *host, *portstr; 2645447Snw141292 int len, i; 2655317Sjp151216 int count = 0; 2665447Snw141292 int rc = -1; 2675317Sjp151216 2685317Sjp151216 *val = NULL; 2695317Sjp151216 2705317Sjp151216 restart: 2715317Sjp151216 scf_prop = scf_property_create(handles->main); 2726616Sdm199847 if (scf_prop == NULL) { 2736616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 2746616Sdm199847 scf_strerror(scf_error())); 2756616Sdm199847 return (-1); 2766616Sdm199847 } 2776616Sdm199847 2785317Sjp151216 value = scf_value_create(handles->main); 2796616Sdm199847 if (value == NULL) { 2806616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 2816616Sdm199847 scf_strerror(scf_error())); 2826616Sdm199847 scf_property_destroy(scf_prop); 2836616Sdm199847 return (-1); 2846616Sdm199847 } 2856616Sdm199847 2865317Sjp151216 iter = scf_iter_create(handles->main); 2876616Sdm199847 if (iter == NULL) { 2886616Sdm199847 idmapdlog(LOG_ERR, "scf_iter_create() failed: %s", 2896616Sdm199847 scf_strerror(scf_error())); 2906616Sdm199847 scf_value_destroy(value); 2916616Sdm199847 scf_property_destroy(scf_prop); 2926616Sdm199847 return (-1); 2936616Sdm199847 } 2945317Sjp151216 2955447Snw141292 if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) { 2965317Sjp151216 /* this is OK: the property is just undefined */ 2975447Snw141292 rc = 0; 2985317Sjp151216 goto destruction; 2995447Snw141292 } 3005317Sjp151216 3015317Sjp151216 if (scf_iter_property_values(iter, scf_prop) < 0) { 3025317Sjp151216 idmapdlog(LOG_ERR, 3036017Snw141292 "scf_iter_property_values(%s) failed: %s", 3046017Snw141292 name, scf_strerror(scf_error())); 3055317Sjp151216 goto destruction; 3065317Sjp151216 } 3075317Sjp151216 3085317Sjp151216 /* Workaround scf bugs -- can't reset an iteration */ 3095317Sjp151216 if (count == 0) { 3105317Sjp151216 while (scf_iter_next_value(iter, value) > 0) 3115317Sjp151216 count++; 3125317Sjp151216 3135447Snw141292 if (count == 0) { 3145317Sjp151216 /* no values */ 3155447Snw141292 rc = 0; 3165317Sjp151216 goto destruction; 3175447Snw141292 } 3185317Sjp151216 3195317Sjp151216 scf_value_destroy(value); 3205317Sjp151216 scf_iter_destroy(iter); 3215317Sjp151216 scf_property_destroy(scf_prop); 3225317Sjp151216 goto restart; 3235317Sjp151216 } 3245317Sjp151216 3255317Sjp151216 if ((servers = calloc(count + 1, sizeof (*servers))) == NULL) { 3266017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 3275317Sjp151216 goto destruction; 3285317Sjp151216 } 3295317Sjp151216 3305447Snw141292 i = 0; 3315447Snw141292 while (i < count && scf_iter_next_value(iter, value) > 0) { 3325447Snw141292 servers[i].priority = 0; 3335447Snw141292 servers[i].weight = 100; 3345447Snw141292 servers[i].port = defport; 33510504SKeyur.Desai@Sun.COM if ((host = scf_value2string(name, value)) == NULL) { 3365317Sjp151216 goto destruction; 3375317Sjp151216 } 3385317Sjp151216 if ((portstr = strchr(host, ':')) != NULL) { 3395317Sjp151216 *portstr++ = '\0'; 3405447Snw141292 servers[i].port = strtol(portstr, 3415317Sjp151216 (char **)NULL, 10); 3425447Snw141292 if (servers[i].port == 0) 3435447Snw141292 servers[i].port = defport; 3445317Sjp151216 } 3455447Snw141292 len = strlcpy(servers[i].host, host, 3465317Sjp151216 sizeof (servers->host)); 3475317Sjp151216 3485317Sjp151216 free(host); 3495317Sjp151216 3505317Sjp151216 /* Ignore this server if the hostname is too long */ 3515317Sjp151216 if (len < sizeof (servers->host)) 3525447Snw141292 i++; 3535317Sjp151216 } 3545317Sjp151216 3555317Sjp151216 *val = servers; 3565317Sjp151216 3575447Snw141292 rc = 0; 3585447Snw141292 3595317Sjp151216 destruction: 3605317Sjp151216 scf_value_destroy(value); 3615317Sjp151216 scf_iter_destroy(iter); 3625317Sjp151216 scf_property_destroy(scf_prop); 3635317Sjp151216 3645317Sjp151216 if (rc < 0) { 3655317Sjp151216 if (servers) 3665317Sjp151216 free(servers); 3675317Sjp151216 *val = NULL; 3685317Sjp151216 } 3695317Sjp151216 3705317Sjp151216 return (rc); 3715317Sjp151216 } 3725317Sjp151216 3734520Snw141292 3744520Snw141292 static int 37510504SKeyur.Desai@Sun.COM get_val_astring(idmap_cfg_handles_t *handles, const char *name, char **val) 3764520Snw141292 { 3774520Snw141292 int rc = 0; 3784520Snw141292 3796616Sdm199847 scf_property_t *scf_prop; 3806616Sdm199847 scf_value_t *value; 3816616Sdm199847 3826616Sdm199847 scf_prop = scf_property_create(handles->main); 3836616Sdm199847 if (scf_prop == NULL) { 3846616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 3856616Sdm199847 scf_strerror(scf_error())); 3866616Sdm199847 return (-1); 3876616Sdm199847 } 3886616Sdm199847 value = scf_value_create(handles->main); 3896616Sdm199847 if (value == NULL) { 3906616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 3916616Sdm199847 scf_strerror(scf_error())); 3926616Sdm199847 scf_property_destroy(scf_prop); 3936616Sdm199847 return (-1); 3946616Sdm199847 } 3954520Snw141292 3965317Sjp151216 *val = NULL; 3974520Snw141292 3985317Sjp151216 if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) 3994520Snw141292 /* this is OK: the property is just undefined */ 4004520Snw141292 goto destruction; 4014520Snw141292 4025317Sjp151216 if (scf_property_get_value(scf_prop, value) < 0) { 4034644Sbaban idmapdlog(LOG_ERR, 4046017Snw141292 "scf_property_get_value(%s) failed: %s", 4056017Snw141292 name, scf_strerror(scf_error())); 4064520Snw141292 rc = -1; 4074520Snw141292 goto destruction; 4084520Snw141292 } 4094520Snw141292 41010504SKeyur.Desai@Sun.COM *val = scf_value2string(name, value); 41110504SKeyur.Desai@Sun.COM if (*val == NULL) 4124520Snw141292 rc = -1; 4134520Snw141292 4144520Snw141292 destruction: 4154520Snw141292 scf_value_destroy(value); 4164520Snw141292 scf_property_destroy(scf_prop); 4174520Snw141292 4184520Snw141292 if (rc < 0) { 4194520Snw141292 if (*val) 4204520Snw141292 free(*val); 4214520Snw141292 *val = NULL; 4224520Snw141292 } 4234520Snw141292 4244520Snw141292 return (rc); 4254520Snw141292 } 4264520Snw141292 4275317Sjp151216 4284695Sbaban static int 42910504SKeyur.Desai@Sun.COM del_val(idmap_cfg_handles_t *handles, const char *name) 43010504SKeyur.Desai@Sun.COM { 43110504SKeyur.Desai@Sun.COM int rc = -1; 43210504SKeyur.Desai@Sun.COM int ret; 43310504SKeyur.Desai@Sun.COM scf_transaction_t *tx = NULL; 43410504SKeyur.Desai@Sun.COM scf_transaction_entry_t *ent = NULL; 43510504SKeyur.Desai@Sun.COM 43610504SKeyur.Desai@Sun.COM if ((tx = scf_transaction_create(handles->main)) == NULL) { 43710504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 43810504SKeyur.Desai@Sun.COM "scf_transaction_create() failed: %s", 43910504SKeyur.Desai@Sun.COM scf_strerror(scf_error())); 44010504SKeyur.Desai@Sun.COM goto destruction; 44110504SKeyur.Desai@Sun.COM } 44210504SKeyur.Desai@Sun.COM if ((ent = scf_entry_create(handles->main)) == NULL) { 44310504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 44410504SKeyur.Desai@Sun.COM "scf_entry_create() failed: %s", 44510504SKeyur.Desai@Sun.COM scf_strerror(scf_error())); 44610504SKeyur.Desai@Sun.COM goto destruction; 44710504SKeyur.Desai@Sun.COM } 44810504SKeyur.Desai@Sun.COM 44910504SKeyur.Desai@Sun.COM do { 45010504SKeyur.Desai@Sun.COM if (scf_pg_update(handles->config_pg) == -1) { 45110504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 45210504SKeyur.Desai@Sun.COM "scf_pg_update(%s) failed: %s", 45310504SKeyur.Desai@Sun.COM name, scf_strerror(scf_error())); 45410504SKeyur.Desai@Sun.COM goto destruction; 45510504SKeyur.Desai@Sun.COM } 45610504SKeyur.Desai@Sun.COM if (scf_transaction_start(tx, handles->config_pg) != 0) { 45710504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 45810504SKeyur.Desai@Sun.COM "scf_transaction_start(%s) failed: %s", 45910504SKeyur.Desai@Sun.COM name, scf_strerror(scf_error())); 46010504SKeyur.Desai@Sun.COM goto destruction; 46110504SKeyur.Desai@Sun.COM } 46210504SKeyur.Desai@Sun.COM 46310504SKeyur.Desai@Sun.COM if (scf_transaction_property_delete(tx, ent, name) != 0) { 46410504SKeyur.Desai@Sun.COM /* Don't complain if it already doesn't exist. */ 46510504SKeyur.Desai@Sun.COM if (scf_error() != SCF_ERROR_NOT_FOUND) { 46610504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 46710504SKeyur.Desai@Sun.COM "scf_transaction_property_delete() failed:" 46810504SKeyur.Desai@Sun.COM " %s", 46910504SKeyur.Desai@Sun.COM scf_strerror(scf_error())); 47010504SKeyur.Desai@Sun.COM } 47110504SKeyur.Desai@Sun.COM goto destruction; 47210504SKeyur.Desai@Sun.COM } 47310504SKeyur.Desai@Sun.COM 47410504SKeyur.Desai@Sun.COM ret = scf_transaction_commit(tx); 47510504SKeyur.Desai@Sun.COM 47610504SKeyur.Desai@Sun.COM if (ret == 0) 47710504SKeyur.Desai@Sun.COM scf_transaction_reset(tx); 47810504SKeyur.Desai@Sun.COM } while (ret == 0); 47910504SKeyur.Desai@Sun.COM 48010504SKeyur.Desai@Sun.COM if (ret == -1) { 48110504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 48210504SKeyur.Desai@Sun.COM "scf_transaction_commit(%s) failed: %s", 48310504SKeyur.Desai@Sun.COM name, scf_strerror(scf_error())); 48410504SKeyur.Desai@Sun.COM goto destruction; 48510504SKeyur.Desai@Sun.COM } 48610504SKeyur.Desai@Sun.COM 48710504SKeyur.Desai@Sun.COM rc = 0; 48810504SKeyur.Desai@Sun.COM 48910504SKeyur.Desai@Sun.COM destruction: 49010504SKeyur.Desai@Sun.COM if (ent != NULL) 49110504SKeyur.Desai@Sun.COM scf_entry_destroy(ent); 49210504SKeyur.Desai@Sun.COM if (tx != NULL) 49310504SKeyur.Desai@Sun.COM scf_transaction_destroy(tx); 49410504SKeyur.Desai@Sun.COM return (rc); 49510504SKeyur.Desai@Sun.COM } 49610504SKeyur.Desai@Sun.COM 49710504SKeyur.Desai@Sun.COM 49810504SKeyur.Desai@Sun.COM static int 49910504SKeyur.Desai@Sun.COM set_val_astring(idmap_cfg_handles_t *handles, const char *name, const char *val) 5004695Sbaban { 5015447Snw141292 int rc = -1; 5025447Snw141292 int ret = -2; 5035447Snw141292 int i; 5044695Sbaban scf_property_t *scf_prop = NULL; 5054695Sbaban scf_value_t *value = NULL; 5064695Sbaban scf_transaction_t *tx = NULL; 5074695Sbaban scf_transaction_entry_t *ent = NULL; 5084695Sbaban 5095317Sjp151216 if ((scf_prop = scf_property_create(handles->main)) == NULL || 5105317Sjp151216 (value = scf_value_create(handles->main)) == NULL || 5115317Sjp151216 (tx = scf_transaction_create(handles->main)) == NULL || 5125317Sjp151216 (ent = scf_entry_create(handles->main)) == NULL) { 5136017Snw141292 idmapdlog(LOG_ERR, "Unable to set property %s", 5146017Snw141292 name, scf_strerror(scf_error())); 5154695Sbaban goto destruction; 5164695Sbaban } 5174695Sbaban 5185447Snw141292 for (i = 0; i < MAX_TRIES && (ret == -2 || ret == 0); i++) { 5195317Sjp151216 if (scf_transaction_start(tx, handles->config_pg) == -1) { 5204695Sbaban idmapdlog(LOG_ERR, 5216017Snw141292 "scf_transaction_start(%s) failed: %s", 5226017Snw141292 name, scf_strerror(scf_error())); 5234695Sbaban goto destruction; 5244695Sbaban } 5254695Sbaban 5265447Snw141292 if (scf_transaction_property_new(tx, ent, name, 5275447Snw141292 SCF_TYPE_ASTRING) < 0) { 5284695Sbaban idmapdlog(LOG_ERR, 5296017Snw141292 "scf_transaction_property_new() failed: %s", 5306017Snw141292 scf_strerror(scf_error())); 5314695Sbaban goto destruction; 5324695Sbaban } 5334695Sbaban 5344695Sbaban if (scf_value_set_astring(value, val) == -1) { 5354695Sbaban idmapdlog(LOG_ERR, 5366017Snw141292 "scf_value_set_astring() failed: %s", 5376017Snw141292 scf_strerror(scf_error())); 5384695Sbaban goto destruction; 5394695Sbaban } 5404695Sbaban 5414695Sbaban if (scf_entry_add_value(ent, value) == -1) { 5424695Sbaban idmapdlog(LOG_ERR, 5436017Snw141292 "scf_entry_add_value() failed: %s", 5446017Snw141292 scf_strerror(scf_error())); 5454695Sbaban goto destruction; 5464695Sbaban } 5474695Sbaban 5485447Snw141292 if ((ret = scf_transaction_commit(tx)) == 1) 5495447Snw141292 break; 5505447Snw141292 5515447Snw141292 if (ret == 0 && i < MAX_TRIES - 1) { 5524695Sbaban /* 5534695Sbaban * Property group set in scf_transaction_start() 5544695Sbaban * is not the most recent. Update pg, reset tx and 5554695Sbaban * retry tx. 5564695Sbaban */ 5574695Sbaban idmapdlog(LOG_WARNING, 5586017Snw141292 "scf_transaction_commit(%s) failed - Retry: %s", 5596017Snw141292 name, scf_strerror(scf_error())); 5605317Sjp151216 if (scf_pg_update(handles->config_pg) == -1) { 5614695Sbaban idmapdlog(LOG_ERR, 5626017Snw141292 "scf_pg_update() failed: %s", 5636017Snw141292 scf_strerror(scf_error())); 5644695Sbaban goto destruction; 5654695Sbaban } 5664695Sbaban scf_transaction_reset(tx); 5674695Sbaban } 5684695Sbaban } 5694695Sbaban 5705447Snw141292 5715447Snw141292 if (ret == 1) 5725447Snw141292 rc = 0; 5735447Snw141292 else if (ret != -2) 5744695Sbaban idmapdlog(LOG_ERR, 5756017Snw141292 "scf_transaction_commit(%s) failed: %s", 5766017Snw141292 name, scf_strerror(scf_error())); 5774695Sbaban 5784695Sbaban destruction: 5794695Sbaban scf_value_destroy(value); 5804695Sbaban scf_entry_destroy(ent); 5814695Sbaban scf_transaction_destroy(tx); 5824695Sbaban scf_property_destroy(scf_prop); 5834695Sbaban return (rc); 5844695Sbaban } 5854695Sbaban 5868361SJulian.Pullen@Sun.COM 5878361SJulian.Pullen@Sun.COM 5888361SJulian.Pullen@Sun.COM /* 5898361SJulian.Pullen@Sun.COM * This function updates a boolean value. 5908361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 5918361SJulian.Pullen@Sun.COM */ 5925317Sjp151216 static int 5938671SJulian.Pullen@Sun.COM update_bool(boolean_t *value, boolean_t *new, char *name) 5947031Snw141292 { 5957031Snw141292 if (*value == *new) 5967031Snw141292 return (0); 5977031Snw141292 5987031Snw141292 idmapdlog(LOG_INFO, "change %s=%s", name, *new ? "true" : "false"); 5997031Snw141292 *value = *new; 6007031Snw141292 return (1); 6017031Snw141292 } 6027031Snw141292 6038361SJulian.Pullen@Sun.COM 6048361SJulian.Pullen@Sun.COM /* 6058361SJulian.Pullen@Sun.COM * This function updates a string value. 6068361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 6078361SJulian.Pullen@Sun.COM */ 6087031Snw141292 static int 6097031Snw141292 update_string(char **value, char **new, char *name) 6104520Snw141292 { 6115317Sjp151216 if (*new == NULL) 6126097Snw141292 return (0); 6134520Snw141292 6145317Sjp151216 if (*value != NULL && strcmp(*new, *value) == 0) { 6155317Sjp151216 free(*new); 6165317Sjp151216 *new = NULL; 6176097Snw141292 return (0); 6184520Snw141292 } 6194520Snw141292 6206017Snw141292 idmapdlog(LOG_INFO, "change %s=%s", name, CHECK_NULL(*new)); 6215317Sjp151216 if (*value != NULL) 6225317Sjp151216 free(*value); 6235317Sjp151216 *value = *new; 6245317Sjp151216 *new = NULL; 6256097Snw141292 return (1); 6265317Sjp151216 } 6275317Sjp151216 62810504SKeyur.Desai@Sun.COM static int 62910504SKeyur.Desai@Sun.COM update_enum(int *value, int *new, char *name, struct enum_lookup_map *map) 63010504SKeyur.Desai@Sun.COM { 63110504SKeyur.Desai@Sun.COM if (*value == *new) 63210504SKeyur.Desai@Sun.COM return (0); 63310504SKeyur.Desai@Sun.COM 63410504SKeyur.Desai@Sun.COM idmapdlog(LOG_INFO, "change %s=%s", name, enum_lookup(*new, map)); 63510504SKeyur.Desai@Sun.COM 63610504SKeyur.Desai@Sun.COM *value = *new; 63710504SKeyur.Desai@Sun.COM 63810504SKeyur.Desai@Sun.COM return (1); 63910504SKeyur.Desai@Sun.COM } 6408361SJulian.Pullen@Sun.COM 6418361SJulian.Pullen@Sun.COM /* 6428361SJulian.Pullen@Sun.COM * This function updates a directory service structure. 6438361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 6448361SJulian.Pullen@Sun.COM */ 6455317Sjp151216 static int 6466616Sdm199847 update_dirs(idmap_ad_disc_ds_t **value, idmap_ad_disc_ds_t **new, char *name) 6475317Sjp151216 { 6485317Sjp151216 int i; 6495317Sjp151216 6505968Snw141292 if (*value == *new) 6515968Snw141292 /* Nothing to do */ 6526097Snw141292 return (0); 6535317Sjp151216 6545968Snw141292 if (*value != NULL && *new != NULL && 6555968Snw141292 ad_disc_compare_ds(*value, *new) == 0) { 6565317Sjp151216 free(*new); 6575317Sjp151216 *new = NULL; 6586097Snw141292 return (0); 6594520Snw141292 } 6604520Snw141292 6618361SJulian.Pullen@Sun.COM if (*value != NULL) 6625317Sjp151216 free(*value); 6635317Sjp151216 6645317Sjp151216 *value = *new; 6655317Sjp151216 *new = NULL; 6665968Snw141292 6675968Snw141292 if (*value == NULL) { 6685968Snw141292 /* We're unsetting this DS property */ 6696017Snw141292 idmapdlog(LOG_INFO, "change %s=<none>", name); 6706097Snw141292 return (1); 6715968Snw141292 } 6725968Snw141292 6735968Snw141292 /* List all the new DSs */ 6745968Snw141292 for (i = 0; (*value)[i].host[0] != '\0'; i++) 6756017Snw141292 idmapdlog(LOG_INFO, "change %s=%s port=%d", name, 6765968Snw141292 (*value)[i].host, (*value)[i].port); 6776097Snw141292 return (1); 6785317Sjp151216 } 6795317Sjp151216 6808361SJulian.Pullen@Sun.COM /* 6818361SJulian.Pullen@Sun.COM * This function updates a trusted domains structure. 6828361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 6838361SJulian.Pullen@Sun.COM */ 6848361SJulian.Pullen@Sun.COM static int 6858361SJulian.Pullen@Sun.COM update_trusted_domains(ad_disc_trusteddomains_t **value, 6868361SJulian.Pullen@Sun.COM ad_disc_trusteddomains_t **new, char *name) 6878361SJulian.Pullen@Sun.COM { 6888361SJulian.Pullen@Sun.COM int i; 6898361SJulian.Pullen@Sun.COM 6908361SJulian.Pullen@Sun.COM if (*value == *new) 6918361SJulian.Pullen@Sun.COM /* Nothing to do */ 6928361SJulian.Pullen@Sun.COM return (0); 6938361SJulian.Pullen@Sun.COM 6948361SJulian.Pullen@Sun.COM if (*value != NULL && *new != NULL && 6958361SJulian.Pullen@Sun.COM ad_disc_compare_trusteddomains(*value, *new) == 0) { 6968361SJulian.Pullen@Sun.COM free(*new); 6978361SJulian.Pullen@Sun.COM *new = NULL; 6988361SJulian.Pullen@Sun.COM return (0); 6998361SJulian.Pullen@Sun.COM } 7008361SJulian.Pullen@Sun.COM 7018361SJulian.Pullen@Sun.COM if (*value != NULL) 7028361SJulian.Pullen@Sun.COM free(*value); 7038361SJulian.Pullen@Sun.COM 7048361SJulian.Pullen@Sun.COM *value = *new; 7058361SJulian.Pullen@Sun.COM *new = NULL; 7068361SJulian.Pullen@Sun.COM 7078361SJulian.Pullen@Sun.COM if (*value == NULL) { 7088361SJulian.Pullen@Sun.COM /* We're unsetting this DS property */ 7098361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=<none>", name); 7108361SJulian.Pullen@Sun.COM return (1); 7118361SJulian.Pullen@Sun.COM } 7128361SJulian.Pullen@Sun.COM 7138361SJulian.Pullen@Sun.COM /* List all the new domains */ 7148361SJulian.Pullen@Sun.COM for (i = 0; (*value)[i].domain[0] != '\0'; i++) 7158361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s direction=%s", name, 7168361SJulian.Pullen@Sun.COM (*value)[i].domain, 7178361SJulian.Pullen@Sun.COM (*value)[i].direction == 3 ? "bi-directional" : "inbound"); 7188361SJulian.Pullen@Sun.COM return (1); 7198361SJulian.Pullen@Sun.COM } 7208361SJulian.Pullen@Sun.COM 7218361SJulian.Pullen@Sun.COM 7228361SJulian.Pullen@Sun.COM /* 7238361SJulian.Pullen@Sun.COM * This function updates a domains in a forest structure. 7248361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 7258361SJulian.Pullen@Sun.COM */ 7268361SJulian.Pullen@Sun.COM static int 7278361SJulian.Pullen@Sun.COM update_domains_in_forest(ad_disc_domainsinforest_t **value, 7288361SJulian.Pullen@Sun.COM ad_disc_domainsinforest_t **new, char *name) 7298361SJulian.Pullen@Sun.COM { 7308361SJulian.Pullen@Sun.COM int i; 7318361SJulian.Pullen@Sun.COM 7328361SJulian.Pullen@Sun.COM if (*value == *new) 7338361SJulian.Pullen@Sun.COM /* Nothing to do */ 7348361SJulian.Pullen@Sun.COM return (0); 7358361SJulian.Pullen@Sun.COM 7368361SJulian.Pullen@Sun.COM if (*value != NULL && *new != NULL && 7378361SJulian.Pullen@Sun.COM ad_disc_compare_domainsinforest(*value, *new) == 0) { 7388361SJulian.Pullen@Sun.COM free(*new); 7398361SJulian.Pullen@Sun.COM *new = NULL; 7408361SJulian.Pullen@Sun.COM return (0); 7418361SJulian.Pullen@Sun.COM } 7428361SJulian.Pullen@Sun.COM 7438361SJulian.Pullen@Sun.COM if (*value != NULL) 7448361SJulian.Pullen@Sun.COM free(*value); 7458361SJulian.Pullen@Sun.COM 7468361SJulian.Pullen@Sun.COM *value = *new; 7478361SJulian.Pullen@Sun.COM *new = NULL; 7488361SJulian.Pullen@Sun.COM 7498361SJulian.Pullen@Sun.COM if (*value == NULL) { 7508361SJulian.Pullen@Sun.COM /* We're unsetting this DS property */ 7518361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=<none>", name); 7528361SJulian.Pullen@Sun.COM return (1); 7538361SJulian.Pullen@Sun.COM } 7548361SJulian.Pullen@Sun.COM 7558361SJulian.Pullen@Sun.COM /* List all the new domains */ 7568361SJulian.Pullen@Sun.COM for (i = 0; (*value)[i].domain[0] != '\0'; i++) 7578361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s", name, 7588361SJulian.Pullen@Sun.COM (*value)[i].domain); 7598361SJulian.Pullen@Sun.COM return (1); 7608361SJulian.Pullen@Sun.COM } 7618361SJulian.Pullen@Sun.COM 7628361SJulian.Pullen@Sun.COM 7638361SJulian.Pullen@Sun.COM static void 7648361SJulian.Pullen@Sun.COM free_trusted_forests(idmap_trustedforest_t **value, int *num_values) 7658361SJulian.Pullen@Sun.COM { 7668361SJulian.Pullen@Sun.COM int i; 7678361SJulian.Pullen@Sun.COM 7688361SJulian.Pullen@Sun.COM for (i = 0; i < *num_values; i++) { 7698361SJulian.Pullen@Sun.COM free((*value)[i].forest_name); 7708361SJulian.Pullen@Sun.COM free((*value)[i].global_catalog); 7718361SJulian.Pullen@Sun.COM free((*value)[i].domains_in_forest); 7728361SJulian.Pullen@Sun.COM } 7738361SJulian.Pullen@Sun.COM free(*value); 7748361SJulian.Pullen@Sun.COM *value = NULL; 7758361SJulian.Pullen@Sun.COM *num_values = 0; 7768361SJulian.Pullen@Sun.COM } 7778361SJulian.Pullen@Sun.COM 7788361SJulian.Pullen@Sun.COM 7798361SJulian.Pullen@Sun.COM static int 7808361SJulian.Pullen@Sun.COM compare_trusteddomainsinforest(ad_disc_domainsinforest_t *df1, 7818361SJulian.Pullen@Sun.COM ad_disc_domainsinforest_t *df2) 7828361SJulian.Pullen@Sun.COM { 7838671SJulian.Pullen@Sun.COM int i, j; 7848671SJulian.Pullen@Sun.COM int num_df1 = 0; 7858671SJulian.Pullen@Sun.COM int num_df2 = 0; 7868671SJulian.Pullen@Sun.COM boolean_t match; 7878361SJulian.Pullen@Sun.COM 7888361SJulian.Pullen@Sun.COM for (i = 0; df1[i].domain[0] != '\0'; i++) 7898361SJulian.Pullen@Sun.COM if (df1[i].trusted) 7908361SJulian.Pullen@Sun.COM num_df1++; 7918361SJulian.Pullen@Sun.COM 7928361SJulian.Pullen@Sun.COM for (j = 0; df2[j].domain[0] != '\0'; j++) 7938361SJulian.Pullen@Sun.COM if (df2[j].trusted) 7948361SJulian.Pullen@Sun.COM num_df2++; 7958361SJulian.Pullen@Sun.COM 7968361SJulian.Pullen@Sun.COM if (num_df1 != num_df2) 7978361SJulian.Pullen@Sun.COM return (1); 7988361SJulian.Pullen@Sun.COM 7998361SJulian.Pullen@Sun.COM for (i = 0; df1[i].domain[0] != '\0'; i++) { 8008361SJulian.Pullen@Sun.COM if (df1[i].trusted) { 8018671SJulian.Pullen@Sun.COM match = B_FALSE; 8028361SJulian.Pullen@Sun.COM for (j = 0; df2[j].domain[0] != '\0'; j++) { 8038361SJulian.Pullen@Sun.COM if (df2[j].trusted && 80410122SJordan.Brown@Sun.COM domain_eq(df1[i].domain, df2[j].domain) && 80510122SJordan.Brown@Sun.COM strcmp(df1[i].sid, df2[j].sid) == 0) { 8068671SJulian.Pullen@Sun.COM match = B_TRUE; 8078361SJulian.Pullen@Sun.COM break; 8088361SJulian.Pullen@Sun.COM } 8098361SJulian.Pullen@Sun.COM } 8108361SJulian.Pullen@Sun.COM if (!match) 8118361SJulian.Pullen@Sun.COM return (1); 8128361SJulian.Pullen@Sun.COM } 8138361SJulian.Pullen@Sun.COM } 8148361SJulian.Pullen@Sun.COM return (0); 8158361SJulian.Pullen@Sun.COM } 8168361SJulian.Pullen@Sun.COM 8178361SJulian.Pullen@Sun.COM 8188361SJulian.Pullen@Sun.COM 8198361SJulian.Pullen@Sun.COM /* 8208361SJulian.Pullen@Sun.COM * This function updates trusted forest structure. 8218361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 8228361SJulian.Pullen@Sun.COM */ 8238361SJulian.Pullen@Sun.COM static int 8248361SJulian.Pullen@Sun.COM update_trusted_forest(idmap_trustedforest_t **value, int *num_value, 8258361SJulian.Pullen@Sun.COM idmap_trustedforest_t **new, int *num_new, char *name) 8268361SJulian.Pullen@Sun.COM { 8278361SJulian.Pullen@Sun.COM int i, j; 8288671SJulian.Pullen@Sun.COM boolean_t match; 8298361SJulian.Pullen@Sun.COM 8308361SJulian.Pullen@Sun.COM if (*value == *new) 8318361SJulian.Pullen@Sun.COM /* Nothing to do */ 8328361SJulian.Pullen@Sun.COM return (0); 8338361SJulian.Pullen@Sun.COM 8348361SJulian.Pullen@Sun.COM if (*value != NULL && *new != NULL) { 8358361SJulian.Pullen@Sun.COM if (*num_value != *num_new) 8368361SJulian.Pullen@Sun.COM goto not_equal; 8378361SJulian.Pullen@Sun.COM for (i = 0; i < *num_value; i++) { 8388671SJulian.Pullen@Sun.COM match = B_FALSE; 8398361SJulian.Pullen@Sun.COM for (j = 0; j < *num_new; j++) { 8408361SJulian.Pullen@Sun.COM if (strcmp((*value)[i].forest_name, 8418361SJulian.Pullen@Sun.COM (*new)[j].forest_name) == 0 && 8428361SJulian.Pullen@Sun.COM ad_disc_compare_ds( 8438361SJulian.Pullen@Sun.COM (*value)[i].global_catalog, 84410122SJordan.Brown@Sun.COM (*new)[j].global_catalog) == 0 && 8458361SJulian.Pullen@Sun.COM compare_trusteddomainsinforest( 8468361SJulian.Pullen@Sun.COM (*value)[i].domains_in_forest, 84710122SJordan.Brown@Sun.COM (*new)[j].domains_in_forest) == 0) { 8488671SJulian.Pullen@Sun.COM match = B_TRUE; 8498361SJulian.Pullen@Sun.COM break; 8508361SJulian.Pullen@Sun.COM } 8518361SJulian.Pullen@Sun.COM } 8528361SJulian.Pullen@Sun.COM if (!match) 8538361SJulian.Pullen@Sun.COM goto not_equal; 8548361SJulian.Pullen@Sun.COM } 8558361SJulian.Pullen@Sun.COM free_trusted_forests(new, num_new); 8568361SJulian.Pullen@Sun.COM return (0); 8578361SJulian.Pullen@Sun.COM } 8588361SJulian.Pullen@Sun.COM not_equal: 8598361SJulian.Pullen@Sun.COM if (*value != NULL) 8608361SJulian.Pullen@Sun.COM free_trusted_forests(value, num_value); 8618361SJulian.Pullen@Sun.COM *value = *new; 8628361SJulian.Pullen@Sun.COM *num_value = *num_new; 8638361SJulian.Pullen@Sun.COM *new = NULL; 8648361SJulian.Pullen@Sun.COM *num_new = 0; 8658361SJulian.Pullen@Sun.COM 8668361SJulian.Pullen@Sun.COM if (*value == NULL) { 8678361SJulian.Pullen@Sun.COM /* We're unsetting this DS property */ 8688361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=<none>", name); 8698361SJulian.Pullen@Sun.COM return (1); 8708361SJulian.Pullen@Sun.COM } 8718361SJulian.Pullen@Sun.COM 8728361SJulian.Pullen@Sun.COM /* List all the trusted forests */ 8738361SJulian.Pullen@Sun.COM for (i = 0; i < *num_value; i++) { 8748361SJulian.Pullen@Sun.COM for (j = 0; (*value)[i].domains_in_forest[j].domain[0] != '\0'; 8758361SJulian.Pullen@Sun.COM j++) { 8768361SJulian.Pullen@Sun.COM /* List trusted Domains in the forest. */ 8778361SJulian.Pullen@Sun.COM if ((*value)[i].domains_in_forest[j].trusted) 8788361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s domain=%s", 8798361SJulian.Pullen@Sun.COM name, (*value)[i].forest_name, 8808361SJulian.Pullen@Sun.COM (*value)[i].domains_in_forest[j].domain); 8818361SJulian.Pullen@Sun.COM } 8828361SJulian.Pullen@Sun.COM /* List the hosts */ 8838361SJulian.Pullen@Sun.COM for (j = 0; (*value)[i].global_catalog[j].host[0] != '\0'; j++) 8848361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s host=%s port=%d", 8858361SJulian.Pullen@Sun.COM name, (*value)[i].forest_name, 8868361SJulian.Pullen@Sun.COM (*value)[i].global_catalog[j].host, 8878361SJulian.Pullen@Sun.COM (*value)[i].global_catalog[j].port); 8888361SJulian.Pullen@Sun.COM } 8898361SJulian.Pullen@Sun.COM return (1); 8908361SJulian.Pullen@Sun.COM } 8918361SJulian.Pullen@Sun.COM 89210504SKeyur.Desai@Sun.COM const char * 89310504SKeyur.Desai@Sun.COM enum_lookup(int value, struct enum_lookup_map *map) 89410504SKeyur.Desai@Sun.COM { 89510504SKeyur.Desai@Sun.COM for (; map->string != NULL; map++) { 89610504SKeyur.Desai@Sun.COM if (value == map->value) { 89710504SKeyur.Desai@Sun.COM return (map->string); 89810504SKeyur.Desai@Sun.COM } 89910504SKeyur.Desai@Sun.COM } 90010504SKeyur.Desai@Sun.COM return ("(invalid)"); 90110504SKeyur.Desai@Sun.COM } 9025317Sjp151216 9035317Sjp151216 /* 9045968Snw141292 * Returns 1 if the PF_ROUTE socket event indicates that we should rescan the 9055968Snw141292 * interfaces. 9065317Sjp151216 * 9075968Snw141292 * Shamelessly based on smb_nics_changed() and other PF_ROUTE uses in ON. 9085968Snw141292 */ 9095968Snw141292 static 910*12065SKeyur.Desai@Sun.COM boolean_t 9115968Snw141292 pfroute_event_is_interesting(int rt_sock) 9125968Snw141292 { 9135968Snw141292 int nbytes; 9145968Snw141292 int64_t msg[2048 / 8]; 9155968Snw141292 struct rt_msghdr *rtm; 916*12065SKeyur.Desai@Sun.COM boolean_t is_interesting = B_FALSE; 9175968Snw141292 9185968Snw141292 for (;;) { 9195968Snw141292 if ((nbytes = read(rt_sock, msg, sizeof (msg))) <= 0) 9205968Snw141292 break; 9215968Snw141292 rtm = (struct rt_msghdr *)msg; 9225968Snw141292 if (rtm->rtm_version != RTM_VERSION) 9235968Snw141292 continue; 9245968Snw141292 if (nbytes < rtm->rtm_msglen) 9255968Snw141292 continue; 9265968Snw141292 switch (rtm->rtm_type) { 9275968Snw141292 case RTM_NEWADDR: 9285968Snw141292 case RTM_DELADDR: 9295968Snw141292 case RTM_IFINFO: 930*12065SKeyur.Desai@Sun.COM is_interesting = B_TRUE; 9315968Snw141292 break; 9325968Snw141292 default: 9335968Snw141292 break; 9345968Snw141292 } 9355968Snw141292 } 9365968Snw141292 return (is_interesting); 9375968Snw141292 } 9385968Snw141292 9395968Snw141292 /* 940*12065SKeyur.Desai@Sun.COM * Wait for an event, and report what kind of event occurred. 9415968Snw141292 * 942*12065SKeyur.Desai@Sun.COM * Note that there are cases where we are awoken but don't care about 943*12065SKeyur.Desai@Sun.COM * the lower-level event. We can't just loop here because we can't 944*12065SKeyur.Desai@Sun.COM * readily calculate how long to sleep the next time. We return 945*12065SKeyur.Desai@Sun.COM * EVENT_NOTHING and let the caller loop. 9465317Sjp151216 */ 9475317Sjp151216 static 948*12065SKeyur.Desai@Sun.COM enum event_type 949*12065SKeyur.Desai@Sun.COM wait_for_event(struct timespec *timeoutp) 9505317Sjp151216 { 9515317Sjp151216 port_event_t pe; 9525317Sjp151216 9535968Snw141292 memset(&pe, 0, sizeof (pe)); 9546097Snw141292 if (port_get(idmapd_ev_port, &pe, timeoutp) != 0) { 9555317Sjp151216 switch (errno) { 9565317Sjp151216 case EINTR: 957*12065SKeyur.Desai@Sun.COM return (EVENT_NOTHING); 9585317Sjp151216 case ETIME: 9595317Sjp151216 /* Timeout */ 960*12065SKeyur.Desai@Sun.COM return (EVENT_TIMEOUT); 9615317Sjp151216 default: 9625968Snw141292 /* EBADF, EBADFD, EFAULT, EINVAL (end of time?)? */ 9635968Snw141292 idmapdlog(LOG_ERR, "Event port failed: %s", 9645968Snw141292 strerror(errno)); 9655968Snw141292 exit(1); 9665968Snw141292 /* NOTREACHED */ 9674520Snw141292 } 9684520Snw141292 } 9694520Snw141292 970*12065SKeyur.Desai@Sun.COM 971*12065SKeyur.Desai@Sun.COM switch (pe.portev_source) { 972*12065SKeyur.Desai@Sun.COM case 0: 973*12065SKeyur.Desai@Sun.COM /* 974*12065SKeyur.Desai@Sun.COM * This isn't documented, but seems to be what you get if 975*12065SKeyur.Desai@Sun.COM * the timeout is zero seconds and there are no events 976*12065SKeyur.Desai@Sun.COM * pending. 977*12065SKeyur.Desai@Sun.COM */ 978*12065SKeyur.Desai@Sun.COM return (EVENT_TIMEOUT); 979*12065SKeyur.Desai@Sun.COM 980*12065SKeyur.Desai@Sun.COM case PORT_SOURCE_USER: 981*12065SKeyur.Desai@Sun.COM if (pe.portev_events == POKE_AUTO_DISCOVERY) 982*12065SKeyur.Desai@Sun.COM return (EVENT_DEGRADE); 983*12065SKeyur.Desai@Sun.COM if (pe.portev_events == RECONFIGURE) 984*12065SKeyur.Desai@Sun.COM return (EVENT_REFRESH); 985*12065SKeyur.Desai@Sun.COM break; 9865317Sjp151216 987*12065SKeyur.Desai@Sun.COM case PORT_SOURCE_FD: 988*12065SKeyur.Desai@Sun.COM if (pe.portev_object == rt_sock) { 989*12065SKeyur.Desai@Sun.COM /* 990*12065SKeyur.Desai@Sun.COM * PF_ROUTE socket read event: 991*12065SKeyur.Desai@Sun.COM * re-associate fd 992*12065SKeyur.Desai@Sun.COM * handle event 993*12065SKeyur.Desai@Sun.COM */ 994*12065SKeyur.Desai@Sun.COM if (port_associate(idmapd_ev_port, PORT_SOURCE_FD, 995*12065SKeyur.Desai@Sun.COM rt_sock, POLLIN, NULL) != 0) { 996*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, "Failed to re-associate the " 997*12065SKeyur.Desai@Sun.COM "routing socket with the event port: %s", 998*12065SKeyur.Desai@Sun.COM strerror(errno)); 999*12065SKeyur.Desai@Sun.COM abort(); 1000*12065SKeyur.Desai@Sun.COM } 1001*12065SKeyur.Desai@Sun.COM /* 1002*12065SKeyur.Desai@Sun.COM * The network configuration may still be in flux. 1003*12065SKeyur.Desai@Sun.COM * No matter, the resolver will re-transmit and 1004*12065SKeyur.Desai@Sun.COM * timeout if need be. 1005*12065SKeyur.Desai@Sun.COM */ 1006*12065SKeyur.Desai@Sun.COM if (pfroute_event_is_interesting(rt_sock)) { 1007*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, 1008*12065SKeyur.Desai@Sun.COM "Interesting routing event"); 1009*12065SKeyur.Desai@Sun.COM return (EVENT_ROUTING); 1010*12065SKeyur.Desai@Sun.COM } else { 1011*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, 1012*12065SKeyur.Desai@Sun.COM "Boring routing event"); 1013*12065SKeyur.Desai@Sun.COM return (EVENT_NOTHING); 1014*12065SKeyur.Desai@Sun.COM } 10155968Snw141292 } 1016*12065SKeyur.Desai@Sun.COM /* Event on an FD other than the routing FD? Ignore it. */ 1017*12065SKeyur.Desai@Sun.COM break; 10185968Snw141292 } 10195968Snw141292 1020*12065SKeyur.Desai@Sun.COM return (EVENT_NOTHING); 10215317Sjp151216 } 10225317Sjp151216 10235317Sjp151216 void * 10245317Sjp151216 idmap_cfg_update_thread(void *arg) 10255317Sjp151216 { 10265317Sjp151216 1027*12065SKeyur.Desai@Sun.COM const ad_disc_t ad_ctx = _idmapdstate.cfg->handles.ad_ctx; 10285317Sjp151216 1029*12065SKeyur.Desai@Sun.COM for (;;) { 1030*12065SKeyur.Desai@Sun.COM struct timespec timeout; 1031*12065SKeyur.Desai@Sun.COM struct timespec *timeoutp; 1032*12065SKeyur.Desai@Sun.COM int rc; 1033*12065SKeyur.Desai@Sun.COM int ttl; 10345968Snw141292 10355968Snw141292 (void) ad_disc_SubnetChanged(ad_ctx); 10365317Sjp151216 1037*12065SKeyur.Desai@Sun.COM rc = idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER); 1038*12065SKeyur.Desai@Sun.COM if (rc < -1) { 10398671SJulian.Pullen@Sun.COM idmapdlog(LOG_ERR, "Fatal errors while reading " 10406097Snw141292 "SMF properties"); 10416097Snw141292 exit(1); 1042*12065SKeyur.Desai@Sun.COM } else if (rc == -1) { 1043*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_WARNING, 1044*12065SKeyur.Desai@Sun.COM "Errors re-loading configuration may cause AD " 1045*12065SKeyur.Desai@Sun.COM "lookups to fail"); 10465317Sjp151216 } 10475317Sjp151216 1048*12065SKeyur.Desai@Sun.COM /* 1049*12065SKeyur.Desai@Sun.COM * Wait for an interesting event. Note that we might get 1050*12065SKeyur.Desai@Sun.COM * boring events between interesting events. If so, we loop. 1051*12065SKeyur.Desai@Sun.COM */ 1052*12065SKeyur.Desai@Sun.COM for (;;) { 1053*12065SKeyur.Desai@Sun.COM ttl = ad_disc_get_TTL(ad_ctx); 1054*12065SKeyur.Desai@Sun.COM 1055*12065SKeyur.Desai@Sun.COM if (ttl < 0) { 1056*12065SKeyur.Desai@Sun.COM timeoutp = NULL; 1057*12065SKeyur.Desai@Sun.COM } else { 1058*12065SKeyur.Desai@Sun.COM timeoutp = &timeout; 1059*12065SKeyur.Desai@Sun.COM timeout.tv_sec = ttl; 1060*12065SKeyur.Desai@Sun.COM timeout.tv_nsec = 0; 1061*12065SKeyur.Desai@Sun.COM } 1062*12065SKeyur.Desai@Sun.COM 1063*12065SKeyur.Desai@Sun.COM switch (wait_for_event(timeoutp)) { 1064*12065SKeyur.Desai@Sun.COM case EVENT_NOTHING: 1065*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, "Boring event."); 1066*12065SKeyur.Desai@Sun.COM continue; 1067*12065SKeyur.Desai@Sun.COM case EVENT_REFRESH: 1068*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_INFO, "SMF refresh"); 1069*12065SKeyur.Desai@Sun.COM /* 1070*12065SKeyur.Desai@Sun.COM * Blow away the ccache, we might have 1071*12065SKeyur.Desai@Sun.COM * re-joined the domain or joined a new one 1072*12065SKeyur.Desai@Sun.COM */ 1073*12065SKeyur.Desai@Sun.COM (void) unlink(IDMAP_CACHEDIR "/ccache"); 1074*12065SKeyur.Desai@Sun.COM break; 1075*12065SKeyur.Desai@Sun.COM case EVENT_DEGRADE: 1076*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, 1077*12065SKeyur.Desai@Sun.COM "Service degraded"); 1078*12065SKeyur.Desai@Sun.COM break; 1079*12065SKeyur.Desai@Sun.COM case EVENT_TIMEOUT: 1080*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, "TTL expired"); 1081*12065SKeyur.Desai@Sun.COM break; 1082*12065SKeyur.Desai@Sun.COM case EVENT_ROUTING: 1083*12065SKeyur.Desai@Sun.COM /* Already logged to DEBUG */ 1084*12065SKeyur.Desai@Sun.COM break; 1085*12065SKeyur.Desai@Sun.COM } 1086*12065SKeyur.Desai@Sun.COM /* An interesting event! */ 1087*12065SKeyur.Desai@Sun.COM break; 1088*12065SKeyur.Desai@Sun.COM } 10895317Sjp151216 } 1090*12065SKeyur.Desai@Sun.COM /* 1091*12065SKeyur.Desai@Sun.COM * Lint isn't happy with the concept of a function declared to 1092*12065SKeyur.Desai@Sun.COM * return something, that doesn't return. Of course, merely adding 1093*12065SKeyur.Desai@Sun.COM * the return isn't enough, because it's never reached... 1094*12065SKeyur.Desai@Sun.COM */ 10955317Sjp151216 /*NOTREACHED*/ 10965317Sjp151216 return (NULL); 10975317Sjp151216 } 10985317Sjp151216 10995968Snw141292 int 11005968Snw141292 idmap_cfg_start_updates(void) 11015968Snw141292 { 11025968Snw141292 if ((idmapd_ev_port = port_create()) < 0) { 11036017Snw141292 idmapdlog(LOG_ERR, "Failed to create event port: %s", 11046017Snw141292 strerror(errno)); 11055968Snw141292 return (-1); 11065968Snw141292 } 11075968Snw141292 11085968Snw141292 if ((rt_sock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) { 11096017Snw141292 idmapdlog(LOG_ERR, "Failed to open routing socket: %s", 11106017Snw141292 strerror(errno)); 11115968Snw141292 (void) close(idmapd_ev_port); 11125968Snw141292 return (-1); 11135968Snw141292 } 11145317Sjp151216 11155968Snw141292 if (fcntl(rt_sock, F_SETFL, O_NDELAY|O_NONBLOCK) < 0) { 11166017Snw141292 idmapdlog(LOG_ERR, "Failed to set routing socket flags: %s", 11176017Snw141292 strerror(errno)); 11185968Snw141292 (void) close(rt_sock); 11195968Snw141292 (void) close(idmapd_ev_port); 11204520Snw141292 return (-1); 11215968Snw141292 } 11225968Snw141292 11235968Snw141292 if (port_associate(idmapd_ev_port, PORT_SOURCE_FD, 11245968Snw141292 rt_sock, POLLIN, NULL) != 0) { 11256017Snw141292 idmapdlog(LOG_ERR, "Failed to associate the routing " 11266017Snw141292 "socket with the event port: %s", strerror(errno)); 11275968Snw141292 (void) close(rt_sock); 11285968Snw141292 (void) close(idmapd_ev_port); 11295968Snw141292 return (-1); 11305968Snw141292 } 11315968Snw141292 11325968Snw141292 if ((errno = pthread_create(&update_thread_handle, NULL, 11335968Snw141292 idmap_cfg_update_thread, NULL)) != 0) { 11346017Snw141292 idmapdlog(LOG_ERR, "Failed to start update thread: %s", 11356017Snw141292 strerror(errno)); 11365968Snw141292 (void) port_dissociate(idmapd_ev_port, PORT_SOURCE_FD, rt_sock); 11375968Snw141292 (void) close(rt_sock); 11385968Snw141292 (void) close(idmapd_ev_port); 11395968Snw141292 return (-1); 11405968Snw141292 } 11415968Snw141292 11425968Snw141292 return (0); 11435317Sjp151216 } 11445317Sjp151216 11456097Snw141292 /* 11466616Sdm199847 * Reject attribute names with invalid characters. 11476616Sdm199847 */ 11486616Sdm199847 static 11496616Sdm199847 int 11506616Sdm199847 valid_ldap_attr(const char *attr) { 11516616Sdm199847 for (; *attr; attr++) { 11526616Sdm199847 if (!isalnum(*attr) && *attr != '-' && 11536616Sdm199847 *attr != '_' && *attr != '.' && *attr != ';') 11546616Sdm199847 return (0); 11556616Sdm199847 } 11566616Sdm199847 return (1); 11576616Sdm199847 } 11586616Sdm199847 115910504SKeyur.Desai@Sun.COM static 116010504SKeyur.Desai@Sun.COM int 116110504SKeyur.Desai@Sun.COM check_smf_debug_mode(idmap_cfg_handles_t *handles) 116210504SKeyur.Desai@Sun.COM { 116310504SKeyur.Desai@Sun.COM boolean_t new_debug_mode; 116410504SKeyur.Desai@Sun.COM int rc; 116510504SKeyur.Desai@Sun.COM 116610504SKeyur.Desai@Sun.COM rc = prop_exists(handles, "debug", &new_debug_mode); 116710504SKeyur.Desai@Sun.COM if (rc != 0) 116810504SKeyur.Desai@Sun.COM return (rc); 116910504SKeyur.Desai@Sun.COM 117010504SKeyur.Desai@Sun.COM if (_idmapdstate.debug_mode != new_debug_mode) { 117110504SKeyur.Desai@Sun.COM if (!_idmapdstate.debug_mode) { 117210504SKeyur.Desai@Sun.COM _idmapdstate.debug_mode = new_debug_mode; 117310504SKeyur.Desai@Sun.COM idmap_log_stderr(LOG_DEBUG); 117410504SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, "debug mode enabled"); 117510504SKeyur.Desai@Sun.COM } else { 117610504SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, "debug mode disabled"); 117710504SKeyur.Desai@Sun.COM idmap_log_stderr(-1); 117810504SKeyur.Desai@Sun.COM _idmapdstate.debug_mode = new_debug_mode; 117910504SKeyur.Desai@Sun.COM } 118010504SKeyur.Desai@Sun.COM } 118110504SKeyur.Desai@Sun.COM 118210504SKeyur.Desai@Sun.COM return (0); 118310504SKeyur.Desai@Sun.COM } 118410504SKeyur.Desai@Sun.COM 11856616Sdm199847 /* 11866097Snw141292 * This is the half of idmap_cfg_load() that loads property values from 11876097Snw141292 * SMF (using the config/ property group of the idmap FMRI). 11886097Snw141292 * 11896097Snw141292 * Return values: 0 -> success, -1 -> failure, -2 -> hard failures 11906616Sdm199847 * -3 -> hard smf config failures 11916097Snw141292 * reading from SMF. 11926097Snw141292 */ 11936097Snw141292 static 11945317Sjp151216 int 11956097Snw141292 idmap_cfg_load_smf(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg, 119610504SKeyur.Desai@Sun.COM int * const errors) 11975317Sjp151216 { 11985447Snw141292 int rc; 119910504SKeyur.Desai@Sun.COM char *s; 120010504SKeyur.Desai@Sun.COM 120110504SKeyur.Desai@Sun.COM *errors = 0; 12025317Sjp151216 12035317Sjp151216 if (scf_pg_update(handles->config_pg) < 0) { 12046017Snw141292 idmapdlog(LOG_ERR, "scf_pg_update() failed: %s", 12056017Snw141292 scf_strerror(scf_error())); 12066097Snw141292 return (-2); 12075317Sjp151216 } 12085317Sjp151216 12095317Sjp151216 if (scf_pg_update(handles->general_pg) < 0) { 12106017Snw141292 idmapdlog(LOG_ERR, "scf_pg_update() failed: %s", 12116017Snw141292 scf_strerror(scf_error())); 12126097Snw141292 return (-2); 12135317Sjp151216 } 12145317Sjp151216 121510504SKeyur.Desai@Sun.COM rc = check_smf_debug_mode(handles); 12166616Sdm199847 if (rc != 0) 121710504SKeyur.Desai@Sun.COM (*errors)++; 12186017Snw141292 12197031Snw141292 rc = get_val_int(handles, "unresolvable_sid_mapping", 12207031Snw141292 &pgcfg->eph_map_unres_sids, SCF_TYPE_BOOLEAN); 12217031Snw141292 if (rc != 0) 122210504SKeyur.Desai@Sun.COM (*errors)++; 122310504SKeyur.Desai@Sun.COM 122410504SKeyur.Desai@Sun.COM rc = get_val_astring(handles, "directory_based_mapping", &s); 122510504SKeyur.Desai@Sun.COM if (rc != 0) 122610504SKeyur.Desai@Sun.COM (*errors)++; 122710504SKeyur.Desai@Sun.COM else if (s == NULL || strcasecmp(s, "none") == 0) 122810504SKeyur.Desai@Sun.COM pgcfg->directory_based_mapping = DIRECTORY_MAPPING_NONE; 122910504SKeyur.Desai@Sun.COM else if (strcasecmp(s, "name") == 0) 123010504SKeyur.Desai@Sun.COM pgcfg->directory_based_mapping = DIRECTORY_MAPPING_NAME; 123110504SKeyur.Desai@Sun.COM else if (strcasecmp(s, "idmu") == 0) 123210504SKeyur.Desai@Sun.COM pgcfg->directory_based_mapping = DIRECTORY_MAPPING_IDMU; 123310504SKeyur.Desai@Sun.COM else { 123410504SKeyur.Desai@Sun.COM pgcfg->directory_based_mapping = DIRECTORY_MAPPING_NONE; 123510504SKeyur.Desai@Sun.COM idmapdlog(LOG_ERR, 123610504SKeyur.Desai@Sun.COM "config/directory_based_mapping: invalid value \"%s\" ignored", 123710504SKeyur.Desai@Sun.COM s); 123810504SKeyur.Desai@Sun.COM (*errors)++; 123910504SKeyur.Desai@Sun.COM } 124010504SKeyur.Desai@Sun.COM free(s); 12417031Snw141292 12425317Sjp151216 rc = get_val_int(handles, "list_size_limit", 12435317Sjp151216 &pgcfg->list_size_limit, SCF_TYPE_COUNT); 12447031Snw141292 if (rc != 0) 124510504SKeyur.Desai@Sun.COM (*errors)++; 12465317Sjp151216 12475317Sjp151216 rc = get_val_astring(handles, "domain_name", 12485317Sjp151216 &pgcfg->domain_name); 12495447Snw141292 if (rc != 0) 125010504SKeyur.Desai@Sun.COM (*errors)++; 12518361SJulian.Pullen@Sun.COM else { 12526097Snw141292 (void) ad_disc_set_DomainName(handles->ad_ctx, 12536097Snw141292 pgcfg->domain_name); 12548671SJulian.Pullen@Sun.COM pgcfg->domain_name_auto_disc = B_FALSE; 12558361SJulian.Pullen@Sun.COM } 12565317Sjp151216 12575317Sjp151216 rc = get_val_astring(handles, "default_domain", 12585317Sjp151216 &pgcfg->default_domain); 12595317Sjp151216 if (rc != 0) { 12605447Snw141292 /* 12615447Snw141292 * SCF failures fetching config/default_domain we treat 12625447Snw141292 * as fatal as they may leave ID mapping rules that 12635447Snw141292 * match unqualified winnames flapping in the wind. 12645447Snw141292 */ 12656097Snw141292 return (-2); 12665317Sjp151216 } 12675317Sjp151216 126810504SKeyur.Desai@Sun.COM if (pgcfg->default_domain == NULL && pgcfg->domain_name != NULL) { 126910504SKeyur.Desai@Sun.COM pgcfg->default_domain = strdup(pgcfg->domain_name); 12704695Sbaban } 12714520Snw141292 12725317Sjp151216 rc = get_val_astring(handles, "machine_sid", &pgcfg->machine_sid); 12735447Snw141292 if (rc != 0) 127410504SKeyur.Desai@Sun.COM (*errors)++; 12755317Sjp151216 if (pgcfg->machine_sid == NULL) { 12765317Sjp151216 /* If machine_sid not configured, generate one */ 12776097Snw141292 if (generate_machine_sid(&pgcfg->machine_sid) < 0) 12786097Snw141292 return (-2); 12795317Sjp151216 rc = set_val_astring(handles, "machine_sid", 12805317Sjp151216 pgcfg->machine_sid); 12815447Snw141292 if (rc != 0) 128210504SKeyur.Desai@Sun.COM (*errors)++; 12835317Sjp151216 } 12845317Sjp151216 12855317Sjp151216 rc = get_val_ds(handles, "domain_controller", 389, 12865317Sjp151216 &pgcfg->domain_controller); 12875447Snw141292 if (rc != 0) 128810504SKeyur.Desai@Sun.COM (*errors)++; 12898361SJulian.Pullen@Sun.COM else { 12906097Snw141292 (void) ad_disc_set_DomainController(handles->ad_ctx, 12915447Snw141292 pgcfg->domain_controller); 12928671SJulian.Pullen@Sun.COM pgcfg->domain_controller_auto_disc = B_FALSE; 12938361SJulian.Pullen@Sun.COM } 12945317Sjp151216 12955317Sjp151216 rc = get_val_astring(handles, "forest_name", &pgcfg->forest_name); 12965447Snw141292 if (rc != 0) 129710504SKeyur.Desai@Sun.COM (*errors)++; 12988361SJulian.Pullen@Sun.COM else { 12996097Snw141292 (void) ad_disc_set_ForestName(handles->ad_ctx, 13006097Snw141292 pgcfg->forest_name); 13018671SJulian.Pullen@Sun.COM pgcfg->forest_name_auto_disc = B_FALSE; 13028361SJulian.Pullen@Sun.COM } 13035317Sjp151216 13045317Sjp151216 rc = get_val_astring(handles, "site_name", &pgcfg->site_name); 13055447Snw141292 if (rc != 0) 130610504SKeyur.Desai@Sun.COM (*errors)++; 13075447Snw141292 else 13086097Snw141292 (void) ad_disc_set_SiteName(handles->ad_ctx, pgcfg->site_name); 13095317Sjp151216 13105317Sjp151216 rc = get_val_ds(handles, "global_catalog", 3268, 13115317Sjp151216 &pgcfg->global_catalog); 13125447Snw141292 if (rc != 0) 131310504SKeyur.Desai@Sun.COM (*errors)++; 13148361SJulian.Pullen@Sun.COM else { 13156097Snw141292 (void) ad_disc_set_GlobalCatalog(handles->ad_ctx, 13166097Snw141292 pgcfg->global_catalog); 13178671SJulian.Pullen@Sun.COM pgcfg->global_catalog_auto_disc = B_FALSE; 13188361SJulian.Pullen@Sun.COM } 13195447Snw141292 132010504SKeyur.Desai@Sun.COM /* Unless we're doing directory-based name mapping, we're done. */ 132110504SKeyur.Desai@Sun.COM if (pgcfg->directory_based_mapping != DIRECTORY_MAPPING_NAME) 132210504SKeyur.Desai@Sun.COM return (0); 13236097Snw141292 13246097Snw141292 rc = get_val_astring(handles, "ad_unixuser_attr", 13256097Snw141292 &pgcfg->ad_unixuser_attr); 13266097Snw141292 if (rc != 0) 13276097Snw141292 return (-2); 13286616Sdm199847 if (pgcfg->ad_unixuser_attr != NULL && 13296616Sdm199847 !valid_ldap_attr(pgcfg->ad_unixuser_attr)) { 13306616Sdm199847 idmapdlog(LOG_ERR, "config/ad_unixuser_attr=%s is not a " 13316616Sdm199847 "valid LDAP attribute name", pgcfg->ad_unixuser_attr); 13326616Sdm199847 return (-3); 13336616Sdm199847 } 13346097Snw141292 13356097Snw141292 rc = get_val_astring(handles, "ad_unixgroup_attr", 13366097Snw141292 &pgcfg->ad_unixgroup_attr); 13376097Snw141292 if (rc != 0) 13386097Snw141292 return (-2); 13396616Sdm199847 if (pgcfg->ad_unixgroup_attr != NULL && 13406616Sdm199847 !valid_ldap_attr(pgcfg->ad_unixgroup_attr)) { 13416616Sdm199847 idmapdlog(LOG_ERR, "config/ad_unixgroup_attr=%s is not a " 13426616Sdm199847 "valid LDAP attribute name", pgcfg->ad_unixgroup_attr); 13436616Sdm199847 return (-3); 13446616Sdm199847 } 13455731Sbaban 13466097Snw141292 rc = get_val_astring(handles, "nldap_winname_attr", 13476097Snw141292 &pgcfg->nldap_winname_attr); 13486097Snw141292 if (rc != 0) 13496097Snw141292 return (-2); 13506616Sdm199847 if (pgcfg->nldap_winname_attr != NULL && 13516616Sdm199847 !valid_ldap_attr(pgcfg->nldap_winname_attr)) { 13526616Sdm199847 idmapdlog(LOG_ERR, "config/nldap_winname_attr=%s is not a " 13536616Sdm199847 "valid LDAP attribute name", pgcfg->nldap_winname_attr); 13546097Snw141292 return (-3); 13556097Snw141292 } 13566097Snw141292 if (pgcfg->ad_unixuser_attr == NULL && 13576616Sdm199847 pgcfg->ad_unixgroup_attr == NULL && 13586616Sdm199847 pgcfg->nldap_winname_attr == NULL) { 13596097Snw141292 idmapdlog(LOG_ERR, 136010504SKeyur.Desai@Sun.COM "If config/directory_based_mapping property is set to " 136110504SKeyur.Desai@Sun.COM "\"name\" then at least one of the following name mapping " 13626097Snw141292 "attributes must be specified. (config/ad_unixuser_attr OR " 13636616Sdm199847 "config/ad_unixgroup_attr OR config/nldap_winname_attr)"); 13646097Snw141292 return (-3); 13655731Sbaban } 13665731Sbaban 13676097Snw141292 return (rc); 13685447Snw141292 13696097Snw141292 } 13705317Sjp151216 13718361SJulian.Pullen@Sun.COM 13726097Snw141292 /* 13736097Snw141292 * This is the half of idmap_cfg_load() that auto-discovers values of 13746097Snw141292 * discoverable properties that weren't already set via SMF properties. 13756097Snw141292 * 13766097Snw141292 * idmap_cfg_discover() is called *after* idmap_cfg_load_smf(), so it 13776097Snw141292 * needs to be careful not to overwrite any properties set in SMF. 13786097Snw141292 */ 13796097Snw141292 static 13806097Snw141292 void 13816097Snw141292 idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg) 13826097Snw141292 { 13836097Snw141292 ad_disc_t ad_ctx = handles->ad_ctx; 13848361SJulian.Pullen@Sun.COM ad_disc_t trusted_ctx; 13858361SJulian.Pullen@Sun.COM int i, j, k, l; 13868361SJulian.Pullen@Sun.COM char *forestname; 13878361SJulian.Pullen@Sun.COM int num_trusteddomains; 13888671SJulian.Pullen@Sun.COM boolean_t new_forest; 13898361SJulian.Pullen@Sun.COM char *trusteddomain; 13908361SJulian.Pullen@Sun.COM idmap_ad_disc_ds_t *globalcatalog; 13918361SJulian.Pullen@Sun.COM idmap_trustedforest_t *trustedforests; 13928361SJulian.Pullen@Sun.COM ad_disc_domainsinforest_t *domainsinforest; 13936097Snw141292 1394*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, "Running discovery."); 1395*12065SKeyur.Desai@Sun.COM 13966097Snw141292 ad_disc_refresh(ad_ctx); 13976097Snw141292 13986097Snw141292 if (pgcfg->default_domain == NULL) 13998361SJulian.Pullen@Sun.COM pgcfg->default_domain = ad_disc_get_DomainName(ad_ctx, 14008361SJulian.Pullen@Sun.COM NULL); 14015317Sjp151216 14026097Snw141292 if (pgcfg->domain_name == NULL) 14038361SJulian.Pullen@Sun.COM pgcfg->domain_name = ad_disc_get_DomainName(ad_ctx, 14048361SJulian.Pullen@Sun.COM &pgcfg->domain_name_auto_disc); 14055317Sjp151216 14066097Snw141292 if (pgcfg->domain_controller == NULL) 14075317Sjp151216 pgcfg->domain_controller = 14088361SJulian.Pullen@Sun.COM ad_disc_get_DomainController(ad_ctx, AD_DISC_PREFER_SITE, 14098361SJulian.Pullen@Sun.COM &pgcfg->domain_controller_auto_disc); 14106097Snw141292 14116097Snw141292 if (pgcfg->forest_name == NULL) 14128361SJulian.Pullen@Sun.COM pgcfg->forest_name = ad_disc_get_ForestName(ad_ctx, 14138361SJulian.Pullen@Sun.COM &pgcfg->forest_name_auto_disc); 14146097Snw141292 14156097Snw141292 if (pgcfg->site_name == NULL) 14168361SJulian.Pullen@Sun.COM pgcfg->site_name = ad_disc_get_SiteName(ad_ctx, 14178361SJulian.Pullen@Sun.COM &pgcfg->site_name_auto_disc); 14186097Snw141292 14196097Snw141292 if (pgcfg->global_catalog == NULL) 14206097Snw141292 pgcfg->global_catalog = 14218361SJulian.Pullen@Sun.COM ad_disc_get_GlobalCatalog(ad_ctx, AD_DISC_PREFER_SITE, 14228361SJulian.Pullen@Sun.COM &pgcfg->global_catalog_auto_disc); 14238361SJulian.Pullen@Sun.COM 14248361SJulian.Pullen@Sun.COM pgcfg->domains_in_forest = 14258361SJulian.Pullen@Sun.COM ad_disc_get_DomainsInForest(ad_ctx, NULL); 14268361SJulian.Pullen@Sun.COM 14278361SJulian.Pullen@Sun.COM pgcfg->trusted_domains = 14288361SJulian.Pullen@Sun.COM ad_disc_get_TrustedDomains(ad_ctx, NULL); 14298361SJulian.Pullen@Sun.COM 14308361SJulian.Pullen@Sun.COM if (pgcfg->forest_name != NULL && pgcfg->trusted_domains != NULL && 14318361SJulian.Pullen@Sun.COM pgcfg->trusted_domains[0].domain[0] != '\0') { 14328361SJulian.Pullen@Sun.COM /* 14338361SJulian.Pullen@Sun.COM * We have trusted domains. We need to go through every 14348361SJulian.Pullen@Sun.COM * one and find its forest. If it is a new forest we then need 14358361SJulian.Pullen@Sun.COM * to find its Global Catalog and the domains in the forest 14368361SJulian.Pullen@Sun.COM */ 14378361SJulian.Pullen@Sun.COM for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++) 14388361SJulian.Pullen@Sun.COM continue; 14398361SJulian.Pullen@Sun.COM num_trusteddomains = i; 14408361SJulian.Pullen@Sun.COM 14418361SJulian.Pullen@Sun.COM trustedforests = calloc(num_trusteddomains, 14428361SJulian.Pullen@Sun.COM sizeof (idmap_trustedforest_t)); 14438361SJulian.Pullen@Sun.COM j = 0; 14448361SJulian.Pullen@Sun.COM for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++) { 14458361SJulian.Pullen@Sun.COM trusteddomain = pgcfg->trusted_domains[i].domain; 14468361SJulian.Pullen@Sun.COM trusted_ctx = ad_disc_init(); 14478361SJulian.Pullen@Sun.COM ad_disc_set_DomainName(trusted_ctx, 14488361SJulian.Pullen@Sun.COM trusteddomain); 14498361SJulian.Pullen@Sun.COM forestname = 14508361SJulian.Pullen@Sun.COM ad_disc_get_ForestName(trusted_ctx, NULL); 14518361SJulian.Pullen@Sun.COM if (forestname == NULL) { 14528361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, "unable to discover " 14538361SJulian.Pullen@Sun.COM "Forest Name for the trusted domain %s", 14548361SJulian.Pullen@Sun.COM trusteddomain); 14558361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 14568361SJulian.Pullen@Sun.COM continue; 14578361SJulian.Pullen@Sun.COM } 14588361SJulian.Pullen@Sun.COM 14598361SJulian.Pullen@Sun.COM if (strcasecmp(forestname, pgcfg->forest_name) == 0) { 14608361SJulian.Pullen@Sun.COM /* 14618361SJulian.Pullen@Sun.COM * Ignore the domain as it is part of 14628361SJulian.Pullen@Sun.COM * the primary forest 14638361SJulian.Pullen@Sun.COM */ 14648361SJulian.Pullen@Sun.COM free(forestname); 14658361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 14668361SJulian.Pullen@Sun.COM continue; 14678361SJulian.Pullen@Sun.COM } 14688361SJulian.Pullen@Sun.COM 14698361SJulian.Pullen@Sun.COM /* Is this a new forest? */ 14708671SJulian.Pullen@Sun.COM new_forest = B_TRUE; 14718361SJulian.Pullen@Sun.COM for (k = 0; k < j; k++) { 14728361SJulian.Pullen@Sun.COM if (strcasecmp(forestname, 14738361SJulian.Pullen@Sun.COM trustedforests[k].forest_name) == 0) { 14748671SJulian.Pullen@Sun.COM new_forest = B_FALSE; 14758361SJulian.Pullen@Sun.COM domainsinforest = 14768361SJulian.Pullen@Sun.COM trustedforests[k].domains_in_forest; 14778361SJulian.Pullen@Sun.COM break; 14788361SJulian.Pullen@Sun.COM } 14798361SJulian.Pullen@Sun.COM } 14808361SJulian.Pullen@Sun.COM if (!new_forest) { 14818361SJulian.Pullen@Sun.COM /* Mark the domain as trusted */ 14828361SJulian.Pullen@Sun.COM for (l = 0; 14838361SJulian.Pullen@Sun.COM domainsinforest[l].domain[0] != '\0'; l++) { 148410122SJordan.Brown@Sun.COM if (domain_eq(trusteddomain, 148510122SJordan.Brown@Sun.COM domainsinforest[l].domain)) { 14868361SJulian.Pullen@Sun.COM domainsinforest[l].trusted = 14878361SJulian.Pullen@Sun.COM TRUE; 14888361SJulian.Pullen@Sun.COM break; 14898361SJulian.Pullen@Sun.COM } 14908361SJulian.Pullen@Sun.COM } 14918361SJulian.Pullen@Sun.COM free(forestname); 14928361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 14938361SJulian.Pullen@Sun.COM continue; 14948361SJulian.Pullen@Sun.COM } 14958361SJulian.Pullen@Sun.COM 14968361SJulian.Pullen@Sun.COM /* 14978361SJulian.Pullen@Sun.COM * Get the Global Catalog and the domains in 14988361SJulian.Pullen@Sun.COM * this new forest. 14998361SJulian.Pullen@Sun.COM */ 15008361SJulian.Pullen@Sun.COM globalcatalog = 15018361SJulian.Pullen@Sun.COM ad_disc_get_GlobalCatalog(trusted_ctx, 15028361SJulian.Pullen@Sun.COM AD_DISC_PREFER_SITE, NULL); 15038361SJulian.Pullen@Sun.COM if (globalcatalog == NULL) { 15048361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, 15058361SJulian.Pullen@Sun.COM "unable to discover Global " 15068361SJulian.Pullen@Sun.COM "Catalog for the trusted domain %s", 15078361SJulian.Pullen@Sun.COM trusteddomain); 15088361SJulian.Pullen@Sun.COM free(forestname); 15098361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 15108361SJulian.Pullen@Sun.COM continue; 15118361SJulian.Pullen@Sun.COM } 15128361SJulian.Pullen@Sun.COM domainsinforest = 15138361SJulian.Pullen@Sun.COM ad_disc_get_DomainsInForest(trusted_ctx, 15148361SJulian.Pullen@Sun.COM NULL); 15158361SJulian.Pullen@Sun.COM if (domainsinforest == NULL) { 15168361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, 15178361SJulian.Pullen@Sun.COM "unable to discover Domains in the Forest " 15188361SJulian.Pullen@Sun.COM "for the trusted domain %s", 15198361SJulian.Pullen@Sun.COM trusteddomain); 15208361SJulian.Pullen@Sun.COM free(globalcatalog); 15218361SJulian.Pullen@Sun.COM free(forestname); 15228361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 15238361SJulian.Pullen@Sun.COM continue; 15248361SJulian.Pullen@Sun.COM } 15258361SJulian.Pullen@Sun.COM 15268361SJulian.Pullen@Sun.COM trustedforests[j].forest_name = forestname; 15278361SJulian.Pullen@Sun.COM trustedforests[j].global_catalog = globalcatalog; 15288361SJulian.Pullen@Sun.COM trustedforests[j].domains_in_forest = domainsinforest; 15298361SJulian.Pullen@Sun.COM j++; 15308361SJulian.Pullen@Sun.COM /* Mark the domain as trusted */ 15318361SJulian.Pullen@Sun.COM for (l = 0; domainsinforest[l].domain[0] != '\0'; 15328361SJulian.Pullen@Sun.COM l++) { 153310122SJordan.Brown@Sun.COM if (domain_eq(trusteddomain, 153410122SJordan.Brown@Sun.COM domainsinforest[l].domain)) { 15358361SJulian.Pullen@Sun.COM domainsinforest[l].trusted = TRUE; 15368361SJulian.Pullen@Sun.COM break; 15378361SJulian.Pullen@Sun.COM } 15388361SJulian.Pullen@Sun.COM } 15398361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 15408361SJulian.Pullen@Sun.COM } 15418361SJulian.Pullen@Sun.COM if (j > 0) { 15428361SJulian.Pullen@Sun.COM pgcfg->num_trusted_forests = j; 15438361SJulian.Pullen@Sun.COM pgcfg->trusted_forests = trustedforests; 154410122SJordan.Brown@Sun.COM } else { 154510122SJordan.Brown@Sun.COM free(trustedforests); 15468361SJulian.Pullen@Sun.COM } 15478361SJulian.Pullen@Sun.COM } 15486097Snw141292 15496097Snw141292 if (pgcfg->domain_name == NULL) 15506097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Domain Name"); 15516097Snw141292 if (pgcfg->domain_controller == NULL) 15526097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Domain Controller"); 15536097Snw141292 if (pgcfg->forest_name == NULL) 15546097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Forest Name"); 15556097Snw141292 if (pgcfg->site_name == NULL) 15566097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Site Name"); 15576097Snw141292 if (pgcfg->global_catalog == NULL) 15586097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Global Catalog"); 15598361SJulian.Pullen@Sun.COM if (pgcfg->domains_in_forest == NULL) 15608361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, 15618361SJulian.Pullen@Sun.COM "unable to discover Domains in the Forest"); 15628361SJulian.Pullen@Sun.COM if (pgcfg->trusted_domains == NULL) 15638361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, "unable to discover Trusted Domains"); 1564*12065SKeyur.Desai@Sun.COM 1565*12065SKeyur.Desai@Sun.COM ad_disc_done(ad_ctx); 1566*12065SKeyur.Desai@Sun.COM idmapdlog(LOG_DEBUG, "Discovery done."); 15676097Snw141292 } 15685317Sjp151216 15698361SJulian.Pullen@Sun.COM 15706097Snw141292 /* 15716097Snw141292 * idmap_cfg_load() is called at startup, and periodically via the 15726097Snw141292 * update thread when the auto-discovery TTLs expire, as well as part of 15736097Snw141292 * the refresh method, to update the current configuration. It always 15746097Snw141292 * reads from SMF, but you still have to refresh the service after 15756097Snw141292 * changing the config pg in order for the changes to take effect. 15766097Snw141292 * 15776097Snw141292 * There are two flags: 15786097Snw141292 * 15796097Snw141292 * - CFG_DISCOVER 15806097Snw141292 * - CFG_LOG 15816097Snw141292 * 15826097Snw141292 * If CFG_DISCOVER is set then idmap_cfg_load() calls 15836097Snw141292 * idmap_cfg_discover() to discover, via DNS and LDAP lookups, property 15846097Snw141292 * values that weren't set in SMF. 15856097Snw141292 * 15866097Snw141292 * If CFG_LOG is set then idmap_cfg_load() will log (to LOG_NOTICE) 15876097Snw141292 * whether the configuration changed. This should be used only from the 15886097Snw141292 * refresh method. 15896097Snw141292 * 15906097Snw141292 * Return values: 0 -> success, -1 -> failure, -2 -> hard failures 15916097Snw141292 * reading from SMF. 15926097Snw141292 */ 15936097Snw141292 int 15946097Snw141292 idmap_cfg_load(idmap_cfg_t *cfg, int flags) 15956097Snw141292 { 15966097Snw141292 int rc = 0; 159710504SKeyur.Desai@Sun.COM int errors; 15986097Snw141292 int changed = 0; 15998361SJulian.Pullen@Sun.COM int ad_reload_required = 0; 16006097Snw141292 idmap_pg_config_t new_pgcfg, *live_pgcfg; 16016097Snw141292 16026097Snw141292 live_pgcfg = &cfg->pgcfg; 16036097Snw141292 (void) memset(&new_pgcfg, 0, sizeof (new_pgcfg)); 16046097Snw141292 16056097Snw141292 pthread_mutex_lock(&cfg->handles.mutex); 16066097Snw141292 16076097Snw141292 if ((rc = idmap_cfg_load_smf(&cfg->handles, &new_pgcfg, &errors)) < -1) 16086097Snw141292 goto err; 16096097Snw141292 16106097Snw141292 if (flags & CFG_DISCOVER) 16116097Snw141292 idmap_cfg_discover(&cfg->handles, &new_pgcfg); 16126097Snw141292 16136097Snw141292 WRLOCK_CONFIG(); 16146097Snw141292 if (live_pgcfg->list_size_limit != new_pgcfg.list_size_limit) { 16156097Snw141292 idmapdlog(LOG_INFO, "change list_size=%d", 16166097Snw141292 new_pgcfg.list_size_limit); 16176097Snw141292 live_pgcfg->list_size_limit = new_pgcfg.list_size_limit; 16185317Sjp151216 } 16195317Sjp151216 16206097Snw141292 /* Non-discoverable props updated here */ 16217031Snw141292 changed += update_string(&live_pgcfg->machine_sid, 16226097Snw141292 &new_pgcfg.machine_sid, "machine_sid"); 16236097Snw141292 16247031Snw141292 changed += update_bool(&live_pgcfg->eph_map_unres_sids, 16257031Snw141292 &new_pgcfg.eph_map_unres_sids, "unresolvable_sid_mapping"); 16267031Snw141292 162710504SKeyur.Desai@Sun.COM changed += update_enum(&live_pgcfg->directory_based_mapping, 162810504SKeyur.Desai@Sun.COM &new_pgcfg.directory_based_mapping, "directory_based_mapping", 162910504SKeyur.Desai@Sun.COM directory_mapping_map); 16306097Snw141292 16317031Snw141292 changed += update_string(&live_pgcfg->ad_unixuser_attr, 16326097Snw141292 &new_pgcfg.ad_unixuser_attr, "ad_unixuser_attr"); 16336097Snw141292 16347031Snw141292 changed += update_string(&live_pgcfg->ad_unixgroup_attr, 16356097Snw141292 &new_pgcfg.ad_unixgroup_attr, "ad_unixgroup_attr"); 16366097Snw141292 16377031Snw141292 changed += update_string(&live_pgcfg->nldap_winname_attr, 16386097Snw141292 &new_pgcfg.nldap_winname_attr, "nldap_winname_attr"); 16396097Snw141292 16406097Snw141292 /* Props that can be discovered and set in SMF updated here */ 164110504SKeyur.Desai@Sun.COM changed += update_string(&live_pgcfg->default_domain, 164210504SKeyur.Desai@Sun.COM &new_pgcfg.default_domain, "default_domain"); 16436097Snw141292 16447031Snw141292 changed += update_string(&live_pgcfg->domain_name, 16456097Snw141292 &new_pgcfg.domain_name, "domain_name"); 16468361SJulian.Pullen@Sun.COM live_pgcfg->domain_name_auto_disc = new_pgcfg.domain_name_auto_disc; 16476097Snw141292 16486097Snw141292 changed += update_dirs(&live_pgcfg->domain_controller, 16496097Snw141292 &new_pgcfg.domain_controller, "domain_controller"); 16508361SJulian.Pullen@Sun.COM live_pgcfg->domain_controller_auto_disc = 16518361SJulian.Pullen@Sun.COM new_pgcfg.domain_controller_auto_disc; 16526097Snw141292 16537031Snw141292 changed += update_string(&live_pgcfg->forest_name, 16546097Snw141292 &new_pgcfg.forest_name, "forest_name"); 16558361SJulian.Pullen@Sun.COM live_pgcfg->forest_name_auto_disc = new_pgcfg.forest_name_auto_disc; 16566097Snw141292 16577031Snw141292 changed += update_string(&live_pgcfg->site_name, 16586097Snw141292 &new_pgcfg.site_name, "site_name"); 16598361SJulian.Pullen@Sun.COM live_pgcfg->site_name_auto_disc = new_pgcfg.site_name_auto_disc; 16606097Snw141292 16616097Snw141292 if (update_dirs(&live_pgcfg->global_catalog, 16626097Snw141292 &new_pgcfg.global_catalog, "global_catalog")) { 16636097Snw141292 changed++; 16646097Snw141292 if (live_pgcfg->global_catalog != NULL && 16656097Snw141292 live_pgcfg->global_catalog[0].host[0] != '\0') 16668361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 16678361SJulian.Pullen@Sun.COM } 16688361SJulian.Pullen@Sun.COM live_pgcfg->global_catalog_auto_disc = 16698361SJulian.Pullen@Sun.COM new_pgcfg.global_catalog_auto_disc; 16708361SJulian.Pullen@Sun.COM 16718361SJulian.Pullen@Sun.COM if (update_domains_in_forest(&live_pgcfg->domains_in_forest, 16728361SJulian.Pullen@Sun.COM &new_pgcfg.domains_in_forest, "domains_in_forest")) { 16738361SJulian.Pullen@Sun.COM changed++; 16748361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 16755317Sjp151216 } 16765317Sjp151216 16778361SJulian.Pullen@Sun.COM if (update_trusted_domains(&live_pgcfg->trusted_domains, 16788361SJulian.Pullen@Sun.COM &new_pgcfg.trusted_domains, "trusted_domains")) { 16798361SJulian.Pullen@Sun.COM changed++; 16808361SJulian.Pullen@Sun.COM if (live_pgcfg->trusted_domains != NULL && 16818361SJulian.Pullen@Sun.COM live_pgcfg->trusted_domains[0].domain[0] != '\0') 16828361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 16838361SJulian.Pullen@Sun.COM } 16848361SJulian.Pullen@Sun.COM 16858361SJulian.Pullen@Sun.COM if (update_trusted_forest(&live_pgcfg->trusted_forests, 16868361SJulian.Pullen@Sun.COM &live_pgcfg->num_trusted_forests, &new_pgcfg.trusted_forests, 16878361SJulian.Pullen@Sun.COM &new_pgcfg.num_trusted_forests, "trusted_forest")) { 16888361SJulian.Pullen@Sun.COM changed++; 16898361SJulian.Pullen@Sun.COM if (live_pgcfg->trusted_forests != NULL) 16908361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 16918361SJulian.Pullen@Sun.COM } 16928361SJulian.Pullen@Sun.COM 16938361SJulian.Pullen@Sun.COM if (ad_reload_required) 16948361SJulian.Pullen@Sun.COM reload_ad(); 16958361SJulian.Pullen@Sun.COM 16966097Snw141292 idmap_cfg_unload(&new_pgcfg); 16976097Snw141292 16986097Snw141292 if (flags & CFG_LOG) { 16996097Snw141292 /* 17006097Snw141292 * If the config changes as a result of a refresh of the 17016097Snw141292 * service, then logging about it can provide useful 17026097Snw141292 * feedback to the sysadmin. 17036097Snw141292 */ 17046097Snw141292 idmapdlog(LOG_NOTICE, "Configuration %schanged", 17056097Snw141292 changed ? "" : "un"); 17065317Sjp151216 } 17075447Snw141292 17086097Snw141292 UNLOCK_CONFIG(); 17096097Snw141292 17106097Snw141292 err: 17116097Snw141292 pthread_mutex_unlock(&cfg->handles.mutex); 17124520Snw141292 17135731Sbaban if (rc < -1) 17145447Snw141292 return (rc); 17155447Snw141292 17165447Snw141292 return ((errors == 0) ? 0 : -1); 17174520Snw141292 } 17184520Snw141292 17194644Sbaban /* 17204644Sbaban * Initialize 'cfg'. 17214644Sbaban */ 17224520Snw141292 idmap_cfg_t * 17235908Sjp151216 idmap_cfg_init() 17245908Sjp151216 { 17255317Sjp151216 idmap_cfg_handles_t *handles; 17264520Snw141292 17274520Snw141292 /* First the smf repository handles: */ 17284520Snw141292 idmap_cfg_t *cfg = calloc(1, sizeof (idmap_cfg_t)); 17294520Snw141292 if (!cfg) { 17306017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 17314520Snw141292 return (NULL); 17324520Snw141292 } 17335317Sjp151216 handles = &cfg->handles; 17344520Snw141292 17355317Sjp151216 (void) pthread_mutex_init(&handles->mutex, NULL); 17365317Sjp151216 17375317Sjp151216 if (!(handles->main = scf_handle_create(SCF_VERSION))) { 17386017Snw141292 idmapdlog(LOG_ERR, "scf_handle_create() failed: %s", 17396017Snw141292 scf_strerror(scf_error())); 17404520Snw141292 goto error; 17414520Snw141292 } 17424520Snw141292 17435317Sjp151216 if (scf_handle_bind(handles->main) < 0) { 17446017Snw141292 idmapdlog(LOG_ERR, "scf_handle_bind() failed: %s", 17456017Snw141292 scf_strerror(scf_error())); 17464520Snw141292 goto error; 17474520Snw141292 } 17484520Snw141292 17495317Sjp151216 if (!(handles->service = scf_service_create(handles->main)) || 17505317Sjp151216 !(handles->instance = scf_instance_create(handles->main)) || 17515317Sjp151216 !(handles->config_pg = scf_pg_create(handles->main)) || 17525317Sjp151216 !(handles->general_pg = scf_pg_create(handles->main))) { 17536017Snw141292 idmapdlog(LOG_ERR, "scf handle creation failed: %s", 17546017Snw141292 scf_strerror(scf_error())); 17554520Snw141292 goto error; 17564520Snw141292 } 17574520Snw141292 17585317Sjp151216 if (scf_handle_decode_fmri(handles->main, 17595908Sjp151216 FMRI_BASE "/:properties/" CONFIG_PG, 17605908Sjp151216 NULL, /* scope */ 17615908Sjp151216 handles->service, /* service */ 17625908Sjp151216 handles->instance, /* instance */ 17635908Sjp151216 handles->config_pg, /* pg */ 17645908Sjp151216 NULL, /* prop */ 17655908Sjp151216 SCF_DECODE_FMRI_EXACT) < 0) { 17666017Snw141292 idmapdlog(LOG_ERR, "scf_handle_decode_fmri() failed: %s", 17676017Snw141292 scf_strerror(scf_error())); 17684520Snw141292 goto error; 17694520Snw141292 } 17704520Snw141292 17715317Sjp151216 if (scf_service_get_pg(handles->service, 17725908Sjp151216 GENERAL_PG, handles->general_pg) < 0) { 17736017Snw141292 idmapdlog(LOG_ERR, "scf_service_get_pg() failed: %s", 17746017Snw141292 scf_strerror(scf_error())); 17754520Snw141292 goto error; 17764520Snw141292 } 17774520Snw141292 177810504SKeyur.Desai@Sun.COM if (check_smf_debug_mode(handles) != 0) 177910504SKeyur.Desai@Sun.COM goto error; 178010504SKeyur.Desai@Sun.COM 17815317Sjp151216 /* Initialize AD Auto Discovery context */ 17825317Sjp151216 handles->ad_ctx = ad_disc_init(); 17835317Sjp151216 if (handles->ad_ctx == NULL) 17845317Sjp151216 goto error; 17855317Sjp151216 17864520Snw141292 return (cfg); 17874520Snw141292 17884520Snw141292 error: 17894520Snw141292 (void) idmap_cfg_fini(cfg); 17904520Snw141292 return (NULL); 17914520Snw141292 } 17924520Snw141292 17935317Sjp151216 void 17945908Sjp151216 idmap_cfg_unload(idmap_pg_config_t *pgcfg) 17955908Sjp151216 { 17965317Sjp151216 17975317Sjp151216 if (pgcfg->default_domain) { 17985317Sjp151216 free(pgcfg->default_domain); 17995317Sjp151216 pgcfg->default_domain = NULL; 18005317Sjp151216 } 18015317Sjp151216 if (pgcfg->domain_name) { 18025317Sjp151216 free(pgcfg->domain_name); 18035317Sjp151216 pgcfg->domain_name = NULL; 18045317Sjp151216 } 18055317Sjp151216 if (pgcfg->machine_sid) { 18065317Sjp151216 free(pgcfg->machine_sid); 18075317Sjp151216 pgcfg->machine_sid = NULL; 18085317Sjp151216 } 18095317Sjp151216 if (pgcfg->domain_controller) { 18105317Sjp151216 free(pgcfg->domain_controller); 18115317Sjp151216 pgcfg->domain_controller = NULL; 18125317Sjp151216 } 18135317Sjp151216 if (pgcfg->forest_name) { 18145317Sjp151216 free(pgcfg->forest_name); 18155317Sjp151216 pgcfg->forest_name = NULL; 18165317Sjp151216 } 18175317Sjp151216 if (pgcfg->site_name) { 18185317Sjp151216 free(pgcfg->site_name); 18195317Sjp151216 pgcfg->site_name = NULL; 18205317Sjp151216 } 18215317Sjp151216 if (pgcfg->global_catalog) { 18224520Snw141292 free(pgcfg->global_catalog); 18235317Sjp151216 pgcfg->global_catalog = NULL; 18245317Sjp151216 } 18258361SJulian.Pullen@Sun.COM if (pgcfg->trusted_domains) { 18268361SJulian.Pullen@Sun.COM free(pgcfg->trusted_domains); 18278361SJulian.Pullen@Sun.COM pgcfg->trusted_domains = NULL; 18288361SJulian.Pullen@Sun.COM } 18298361SJulian.Pullen@Sun.COM if (pgcfg->trusted_forests) 18308361SJulian.Pullen@Sun.COM free_trusted_forests(&pgcfg->trusted_forests, 18318361SJulian.Pullen@Sun.COM &pgcfg->num_trusted_forests); 18328361SJulian.Pullen@Sun.COM 18335731Sbaban if (pgcfg->ad_unixuser_attr) { 18345731Sbaban free(pgcfg->ad_unixuser_attr); 18355731Sbaban pgcfg->ad_unixuser_attr = NULL; 18365731Sbaban } 18375731Sbaban if (pgcfg->ad_unixgroup_attr) { 18385731Sbaban free(pgcfg->ad_unixgroup_attr); 18395731Sbaban pgcfg->ad_unixgroup_attr = NULL; 18405731Sbaban } 18415731Sbaban if (pgcfg->nldap_winname_attr) { 18425731Sbaban free(pgcfg->nldap_winname_attr); 18435731Sbaban pgcfg->nldap_winname_attr = NULL; 18445731Sbaban } 18454520Snw141292 } 18464520Snw141292 18474520Snw141292 int 18484520Snw141292 idmap_cfg_fini(idmap_cfg_t *cfg) 18494520Snw141292 { 18505317Sjp151216 idmap_cfg_handles_t *handles = &cfg->handles; 18515317Sjp151216 idmap_cfg_unload(&cfg->pgcfg); 18524520Snw141292 18535317Sjp151216 (void) pthread_mutex_destroy(&handles->mutex); 18545317Sjp151216 scf_pg_destroy(handles->config_pg); 18555317Sjp151216 scf_pg_destroy(handles->general_pg); 18565317Sjp151216 scf_instance_destroy(handles->instance); 18575317Sjp151216 scf_service_destroy(handles->service); 18585317Sjp151216 scf_handle_destroy(handles->main); 18595731Sbaban if (handles->ad_ctx != NULL) 18605731Sbaban ad_disc_fini(handles->ad_ctx); 18614520Snw141292 free(cfg); 18624520Snw141292 18634520Snw141292 return (0); 18644520Snw141292 } 18655968Snw141292 18665968Snw141292 void 18675968Snw141292 idmap_cfg_poke_updates(void) 18685968Snw141292 { 18696097Snw141292 if (idmapd_ev_port != -1) 18706097Snw141292 (void) port_send(idmapd_ev_port, POKE_AUTO_DISCOVERY, NULL); 18715968Snw141292 } 18725968Snw141292 18735968Snw141292 /*ARGSUSED*/ 18745968Snw141292 void 18756097Snw141292 idmap_cfg_hup_handler(int sig) 18766097Snw141292 { 18775968Snw141292 if (idmapd_ev_port >= 0) 18785968Snw141292 (void) port_send(idmapd_ev_port, RECONFIGURE, NULL); 18795968Snw141292 } 188010504SKeyur.Desai@Sun.COM 188110504SKeyur.Desai@Sun.COM /* 188210504SKeyur.Desai@Sun.COM * Upgrade the DS mapping flags. 188310504SKeyur.Desai@Sun.COM * 188410504SKeyur.Desai@Sun.COM * If the old ds_name_mapping_enabled flag is present, then 188510504SKeyur.Desai@Sun.COM * if the new directory_based_mapping value is present, then 188610504SKeyur.Desai@Sun.COM * if the two are compatible, delete the old and note it 188710504SKeyur.Desai@Sun.COM * else delete the old and warn 188810504SKeyur.Desai@Sun.COM * else 188910504SKeyur.Desai@Sun.COM * set the new based on the old, and note it 189010504SKeyur.Desai@Sun.COM * delete the old 189110504SKeyur.Desai@Sun.COM */ 189210504SKeyur.Desai@Sun.COM static 189310504SKeyur.Desai@Sun.COM int 189410504SKeyur.Desai@Sun.COM upgrade_directory_mapping(idmap_cfg_handles_t *handles) 189510504SKeyur.Desai@Sun.COM { 189610504SKeyur.Desai@Sun.COM boolean_t legacy_ds_name_mapping_present; 189710504SKeyur.Desai@Sun.COM const char DS_NAME_MAPPING_ENABLED[] = "ds_name_mapping_enabled"; 189810504SKeyur.Desai@Sun.COM const char DIRECTORY_BASED_MAPPING[] = "directory_based_mapping"; 189910504SKeyur.Desai@Sun.COM int rc; 190010504SKeyur.Desai@Sun.COM 190110504SKeyur.Desai@Sun.COM rc = prop_exists(handles, DS_NAME_MAPPING_ENABLED, 190210504SKeyur.Desai@Sun.COM &legacy_ds_name_mapping_present); 190310504SKeyur.Desai@Sun.COM 190410504SKeyur.Desai@Sun.COM if (rc != 0) 190510504SKeyur.Desai@Sun.COM return (rc); 190610504SKeyur.Desai@Sun.COM 190710504SKeyur.Desai@Sun.COM if (!legacy_ds_name_mapping_present) 190810504SKeyur.Desai@Sun.COM return (0); 190910504SKeyur.Desai@Sun.COM 191010504SKeyur.Desai@Sun.COM boolean_t legacy_ds_name_mapping_enabled; 191110504SKeyur.Desai@Sun.COM rc = get_val_int(handles, DS_NAME_MAPPING_ENABLED, 191210504SKeyur.Desai@Sun.COM &legacy_ds_name_mapping_enabled, SCF_TYPE_BOOLEAN); 191310504SKeyur.Desai@Sun.COM if (rc != 0) 191410504SKeyur.Desai@Sun.COM return (rc); 191510504SKeyur.Desai@Sun.COM 191610504SKeyur.Desai@Sun.COM char *legacy_mode; 191710504SKeyur.Desai@Sun.COM char *legacy_bool_string; 191810504SKeyur.Desai@Sun.COM if (legacy_ds_name_mapping_enabled) { 191910504SKeyur.Desai@Sun.COM legacy_mode = "name"; 192010504SKeyur.Desai@Sun.COM legacy_bool_string = "true"; 192110504SKeyur.Desai@Sun.COM } else { 192210504SKeyur.Desai@Sun.COM legacy_mode = "none"; 192310504SKeyur.Desai@Sun.COM legacy_bool_string = "false"; 192410504SKeyur.Desai@Sun.COM } 192510504SKeyur.Desai@Sun.COM 192610504SKeyur.Desai@Sun.COM char *directory_based_mapping; 192710504SKeyur.Desai@Sun.COM rc = get_val_astring(handles, DIRECTORY_BASED_MAPPING, 192810504SKeyur.Desai@Sun.COM &directory_based_mapping); 192910504SKeyur.Desai@Sun.COM if (rc != 0) 193010504SKeyur.Desai@Sun.COM return (rc); 193110504SKeyur.Desai@Sun.COM 193210504SKeyur.Desai@Sun.COM if (directory_based_mapping == NULL) { 193310504SKeyur.Desai@Sun.COM idmapdlog(LOG_INFO, 193410504SKeyur.Desai@Sun.COM "Upgrading old %s=%s setting\n" 193510504SKeyur.Desai@Sun.COM "to %s=%s.", 193610504SKeyur.Desai@Sun.COM DS_NAME_MAPPING_ENABLED, legacy_bool_string, 193710504SKeyur.Desai@Sun.COM DIRECTORY_BASED_MAPPING, legacy_mode); 193810504SKeyur.Desai@Sun.COM rc = set_val_astring(handles, DIRECTORY_BASED_MAPPING, 193910504SKeyur.Desai@Sun.COM legacy_mode); 194010504SKeyur.Desai@Sun.COM if (rc != 0) 194110504SKeyur.Desai@Sun.COM return (rc); 194210504SKeyur.Desai@Sun.COM } else { 194310504SKeyur.Desai@Sun.COM boolean_t new_name_mapping; 194410504SKeyur.Desai@Sun.COM if (strcasecmp(directory_based_mapping, "name") == 0) 194510504SKeyur.Desai@Sun.COM new_name_mapping = B_TRUE; 194610504SKeyur.Desai@Sun.COM else 194710504SKeyur.Desai@Sun.COM new_name_mapping = B_FALSE; 194810504SKeyur.Desai@Sun.COM 194910504SKeyur.Desai@Sun.COM if (legacy_ds_name_mapping_enabled == new_name_mapping) { 195010504SKeyur.Desai@Sun.COM idmapdlog(LOG_INFO, 195110504SKeyur.Desai@Sun.COM "Automatically removing old %s=%s setting\n" 195210504SKeyur.Desai@Sun.COM "in favor of %s=%s.", 195310504SKeyur.Desai@Sun.COM DS_NAME_MAPPING_ENABLED, legacy_bool_string, 195410504SKeyur.Desai@Sun.COM DIRECTORY_BASED_MAPPING, directory_based_mapping); 195510504SKeyur.Desai@Sun.COM } else { 195610504SKeyur.Desai@Sun.COM idmapdlog(LOG_WARNING, 195710504SKeyur.Desai@Sun.COM "Removing conflicting %s=%s setting\n" 195810504SKeyur.Desai@Sun.COM "in favor of %s=%s.", 195910504SKeyur.Desai@Sun.COM DS_NAME_MAPPING_ENABLED, legacy_bool_string, 196010504SKeyur.Desai@Sun.COM DIRECTORY_BASED_MAPPING, directory_based_mapping); 196110504SKeyur.Desai@Sun.COM } 196210504SKeyur.Desai@Sun.COM free(directory_based_mapping); 196310504SKeyur.Desai@Sun.COM } 196410504SKeyur.Desai@Sun.COM 196510504SKeyur.Desai@Sun.COM rc = del_val(handles, DS_NAME_MAPPING_ENABLED); 196610504SKeyur.Desai@Sun.COM if (rc != 0) 196710504SKeyur.Desai@Sun.COM return (rc); 196810504SKeyur.Desai@Sun.COM 196910504SKeyur.Desai@Sun.COM return (0); 197010504SKeyur.Desai@Sun.COM } 197110504SKeyur.Desai@Sun.COM 197210504SKeyur.Desai@Sun.COM /* 197310504SKeyur.Desai@Sun.COM * Do whatever is necessary to upgrade idmap's configuration before 197410504SKeyur.Desai@Sun.COM * we load it. 197510504SKeyur.Desai@Sun.COM */ 197610504SKeyur.Desai@Sun.COM int 197710504SKeyur.Desai@Sun.COM idmap_cfg_upgrade(idmap_cfg_t *cfg) 197810504SKeyur.Desai@Sun.COM { 197910504SKeyur.Desai@Sun.COM int rc; 198010504SKeyur.Desai@Sun.COM 198110504SKeyur.Desai@Sun.COM rc = upgrade_directory_mapping(&cfg->handles); 198210504SKeyur.Desai@Sun.COM if (rc != 0) 198310504SKeyur.Desai@Sun.COM return (rc); 198410504SKeyur.Desai@Sun.COM 198510504SKeyur.Desai@Sun.COM return (0); 198610504SKeyur.Desai@Sun.COM } 1987