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*8671SJulian.Pullen@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 234520Snw141292 * Use is subject to license terms. 244520Snw141292 */ 254520Snw141292 264520Snw141292 274520Snw141292 /* 284520Snw141292 * Config routines common to idmap(1M) and idmapd(1M) 294520Snw141292 */ 304520Snw141292 314520Snw141292 #include <stdlib.h> 324520Snw141292 #include <strings.h> 334520Snw141292 #include <libintl.h> 344520Snw141292 #include <ctype.h> 354520Snw141292 #include <errno.h> 364644Sbaban #include "idmapd.h" 374520Snw141292 #include <stdio.h> 384520Snw141292 #include <stdarg.h> 394695Sbaban #include <uuid/uuid.h> 405317Sjp151216 #include <pthread.h> 415317Sjp151216 #include <port.h> 425968Snw141292 #include <net/route.h> 438361SJulian.Pullen@Sun.COM #include <sys/u8_textprep.h> 445317Sjp151216 #include "addisc.h" 454520Snw141292 467031Snw141292 #define MACHINE_SID_LEN (9 + 3 * 11) 475968Snw141292 #define FMRI_BASE "svc:/system/idmap" 485968Snw141292 #define CONFIG_PG "config" 495968Snw141292 #define GENERAL_PG "general" 505968Snw141292 #define RECONFIGURE 1 515968Snw141292 #define POKE_AUTO_DISCOVERY 2 524520Snw141292 535317Sjp151216 /*LINTLIBRARY*/ 545317Sjp151216 555317Sjp151216 565317Sjp151216 static pthread_t update_thread_handle = 0; 575317Sjp151216 585968Snw141292 static int idmapd_ev_port = -1; 595968Snw141292 static int rt_sock = -1; 605317Sjp151216 614695Sbaban static int 625908Sjp151216 generate_machine_sid(char **machine_sid) 635908Sjp151216 { 644695Sbaban char *p; 654695Sbaban uuid_t uu; 664695Sbaban int i, j, len, rlen; 674695Sbaban uint32_t rid; 684695Sbaban 694695Sbaban /* 707031Snw141292 * Generate and split 128-bit UUID into three 32-bit RIDs The 717031Snw141292 * machine_sid will be of the form S-1-5-21-N1-N2-N3 (that's 727031Snw141292 * four RIDs altogether). 737031Snw141292 * 747031Snw141292 * Technically we could use upto 14 random RIDs here, but it 757031Snw141292 * turns out that with some versions of Windows using SIDs with 767031Snw141292 * more than five RIDs in security descriptors causes problems. 774695Sbaban */ 784695Sbaban 794695Sbaban *machine_sid = calloc(1, MACHINE_SID_LEN); 804695Sbaban if (*machine_sid == NULL) { 816017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 824695Sbaban return (-1); 834695Sbaban } 844695Sbaban (void) strcpy(*machine_sid, "S-1-5-21"); 854695Sbaban p = *machine_sid + strlen("S-1-5-21"); 864695Sbaban len = MACHINE_SID_LEN - strlen("S-1-5-21"); 874695Sbaban 884695Sbaban uuid_clear(uu); 894695Sbaban uuid_generate_random(uu); 904695Sbaban 917031Snw141292 #if UUID_LEN != 16 927031Snw141292 #error UUID size is not 16! 937031Snw141292 #endif 947031Snw141292 957031Snw141292 for (i = 0; i < 3; i++) { 964695Sbaban j = i * 4; 974695Sbaban rid = (uu[j] << 24) | (uu[j + 1] << 16) | 985908Sjp151216 (uu[j + 2] << 8) | (uu[j + 3]); 994695Sbaban rlen = snprintf(p, len, "-%u", rid); 1004695Sbaban p += rlen; 1014695Sbaban len -= rlen; 1024695Sbaban } 1034695Sbaban 1044695Sbaban return (0); 1054695Sbaban } 1064695Sbaban 1076616Sdm199847 1086616Sdm199847 /* In the case of error, exists is set to FALSE anyway */ 1096616Sdm199847 static int 110*8671SJulian.Pullen@Sun.COM prop_exists(idmap_cfg_handles_t *handles, char *name, boolean_t *exists) 1116017Snw141292 { 1126616Sdm199847 1136616Sdm199847 scf_property_t *scf_prop; 1146616Sdm199847 scf_value_t *value; 1156616Sdm199847 116*8671SJulian.Pullen@Sun.COM *exists = B_FALSE; 1176017Snw141292 1186616Sdm199847 scf_prop = scf_property_create(handles->main); 1196616Sdm199847 if (scf_prop == NULL) { 1206616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 1216616Sdm199847 scf_strerror(scf_error())); 1226616Sdm199847 return (-1); 1236616Sdm199847 } 1246616Sdm199847 value = scf_value_create(handles->main); 1256616Sdm199847 if (value == NULL) { 1266616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 1276616Sdm199847 scf_strerror(scf_error())); 1286616Sdm199847 scf_property_destroy(scf_prop); 1296616Sdm199847 return (-1); 1306616Sdm199847 } 1316017Snw141292 1326017Snw141292 if (scf_pg_get_property(handles->config_pg, name, scf_prop) == 0) 133*8671SJulian.Pullen@Sun.COM *exists = B_TRUE; 1346017Snw141292 1356017Snw141292 scf_value_destroy(value); 1366017Snw141292 scf_property_destroy(scf_prop); 1376017Snw141292 1386616Sdm199847 return (0); 1396017Snw141292 } 1406017Snw141292 1414520Snw141292 /* Check if in the case of failure the original value of *val is preserved */ 1424520Snw141292 static int 1435317Sjp151216 get_val_int(idmap_cfg_handles_t *handles, char *name, 1445317Sjp151216 void *val, scf_type_t type) 1454520Snw141292 { 1464520Snw141292 int rc = 0; 1474520Snw141292 1486616Sdm199847 scf_property_t *scf_prop; 1496616Sdm199847 scf_value_t *value; 1506616Sdm199847 1517031Snw141292 switch (type) { 1527031Snw141292 case SCF_TYPE_BOOLEAN: 1537031Snw141292 *(uint8_t *)val = 0; 1547031Snw141292 break; 1557031Snw141292 case SCF_TYPE_COUNT: 1567031Snw141292 *(uint64_t *)val = 0; 1577031Snw141292 break; 1587031Snw141292 case SCF_TYPE_INTEGER: 1597031Snw141292 *(int64_t *)val = 0; 1607031Snw141292 break; 1617031Snw141292 default: 1627031Snw141292 idmapdlog(LOG_ERR, "Invalid scf integer type (%d)", 1637031Snw141292 type); 1647031Snw141292 abort(); 1657031Snw141292 } 1667031Snw141292 1676616Sdm199847 scf_prop = scf_property_create(handles->main); 1686616Sdm199847 if (scf_prop == NULL) { 1696616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 1706616Sdm199847 scf_strerror(scf_error())); 1716616Sdm199847 return (-1); 1726616Sdm199847 } 1736616Sdm199847 value = scf_value_create(handles->main); 1746616Sdm199847 if (value == NULL) { 1756616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 1766616Sdm199847 scf_strerror(scf_error())); 1776616Sdm199847 scf_property_destroy(scf_prop); 1786616Sdm199847 return (-1); 1796616Sdm199847 } 1804520Snw141292 1815317Sjp151216 if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) 1824520Snw141292 /* this is OK: the property is just undefined */ 1834520Snw141292 goto destruction; 1844520Snw141292 1854520Snw141292 1865317Sjp151216 if (scf_property_get_value(scf_prop, value) < 0) 1874520Snw141292 /* It is still OK when a property doesn't have any value */ 1884520Snw141292 goto destruction; 1894520Snw141292 1904520Snw141292 switch (type) { 1914520Snw141292 case SCF_TYPE_BOOLEAN: 1924520Snw141292 rc = scf_value_get_boolean(value, val); 1934520Snw141292 break; 1944520Snw141292 case SCF_TYPE_COUNT: 1954520Snw141292 rc = scf_value_get_count(value, val); 1964520Snw141292 break; 1974520Snw141292 case SCF_TYPE_INTEGER: 1984520Snw141292 rc = scf_value_get_integer(value, val); 1994520Snw141292 break; 2004520Snw141292 } 2014520Snw141292 2024520Snw141292 2034520Snw141292 destruction: 2044520Snw141292 scf_value_destroy(value); 2054520Snw141292 scf_property_destroy(scf_prop); 2064520Snw141292 2074520Snw141292 return (rc); 2084520Snw141292 } 2094520Snw141292 2104520Snw141292 static char * 2115908Sjp151216 scf_value2string(scf_value_t *value) 2125908Sjp151216 { 2134520Snw141292 int rc = -1; 2144520Snw141292 char buf_size = 127; 2154520Snw141292 int length; 2164520Snw141292 char *buf = NULL; 2174520Snw141292 buf = (char *) malloc(sizeof (char) * buf_size); 2184520Snw141292 2194520Snw141292 for (;;) { 2204520Snw141292 length = scf_value_get_astring(value, buf, buf_size); 2214520Snw141292 if (length < 0) { 2224520Snw141292 rc = -1; 2234520Snw141292 goto destruction; 2244520Snw141292 } 2254520Snw141292 2264520Snw141292 if (length == buf_size - 1) { 2274520Snw141292 buf_size *= 2; 2284520Snw141292 buf = (char *)realloc(buf, buf_size * sizeof (char)); 2294520Snw141292 if (!buf) { 2306017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 2314520Snw141292 rc = -1; 2324520Snw141292 goto destruction; 2334520Snw141292 } 2344520Snw141292 } else { 2354520Snw141292 rc = 0; 2365908Sjp151216 break; 2375908Sjp151216 } 2384520Snw141292 } 2394520Snw141292 2404520Snw141292 destruction: 2414520Snw141292 if (rc < 0) { 2424520Snw141292 if (buf) 2434520Snw141292 free(buf); 2444520Snw141292 buf = NULL; 2454520Snw141292 } 2464520Snw141292 2474520Snw141292 return (buf); 2484520Snw141292 } 2494520Snw141292 2505317Sjp151216 static int 2515317Sjp151216 get_val_ds(idmap_cfg_handles_t *handles, const char *name, int defport, 2526616Sdm199847 idmap_ad_disc_ds_t **val) 2535317Sjp151216 { 2546616Sdm199847 idmap_ad_disc_ds_t *servers = NULL; 2555317Sjp151216 scf_property_t *scf_prop; 2565317Sjp151216 scf_value_t *value; 2575317Sjp151216 scf_iter_t *iter; 2585317Sjp151216 char *host, *portstr; 2595447Snw141292 int len, i; 2605317Sjp151216 int count = 0; 2615447Snw141292 int rc = -1; 2625317Sjp151216 2635317Sjp151216 *val = NULL; 2645317Sjp151216 2655317Sjp151216 restart: 2665317Sjp151216 scf_prop = scf_property_create(handles->main); 2676616Sdm199847 if (scf_prop == NULL) { 2686616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 2696616Sdm199847 scf_strerror(scf_error())); 2706616Sdm199847 return (-1); 2716616Sdm199847 } 2726616Sdm199847 2735317Sjp151216 value = scf_value_create(handles->main); 2746616Sdm199847 if (value == NULL) { 2756616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 2766616Sdm199847 scf_strerror(scf_error())); 2776616Sdm199847 scf_property_destroy(scf_prop); 2786616Sdm199847 return (-1); 2796616Sdm199847 } 2806616Sdm199847 2815317Sjp151216 iter = scf_iter_create(handles->main); 2826616Sdm199847 if (iter == NULL) { 2836616Sdm199847 idmapdlog(LOG_ERR, "scf_iter_create() failed: %s", 2846616Sdm199847 scf_strerror(scf_error())); 2856616Sdm199847 scf_value_destroy(value); 2866616Sdm199847 scf_property_destroy(scf_prop); 2876616Sdm199847 return (-1); 2886616Sdm199847 } 2895317Sjp151216 2905447Snw141292 if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) { 2915317Sjp151216 /* this is OK: the property is just undefined */ 2925447Snw141292 rc = 0; 2935317Sjp151216 goto destruction; 2945447Snw141292 } 2955317Sjp151216 2965317Sjp151216 if (scf_iter_property_values(iter, scf_prop) < 0) { 2975317Sjp151216 idmapdlog(LOG_ERR, 2986017Snw141292 "scf_iter_property_values(%s) failed: %s", 2996017Snw141292 name, scf_strerror(scf_error())); 3005317Sjp151216 goto destruction; 3015317Sjp151216 } 3025317Sjp151216 3035317Sjp151216 /* Workaround scf bugs -- can't reset an iteration */ 3045317Sjp151216 if (count == 0) { 3055317Sjp151216 while (scf_iter_next_value(iter, value) > 0) 3065317Sjp151216 count++; 3075317Sjp151216 3085447Snw141292 if (count == 0) { 3095317Sjp151216 /* no values */ 3105447Snw141292 rc = 0; 3115317Sjp151216 goto destruction; 3125447Snw141292 } 3135317Sjp151216 3145317Sjp151216 scf_value_destroy(value); 3155317Sjp151216 scf_iter_destroy(iter); 3165317Sjp151216 scf_property_destroy(scf_prop); 3175317Sjp151216 goto restart; 3185317Sjp151216 } 3195317Sjp151216 3205317Sjp151216 if ((servers = calloc(count + 1, sizeof (*servers))) == NULL) { 3216017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 3225317Sjp151216 goto destruction; 3235317Sjp151216 } 3245317Sjp151216 3255447Snw141292 i = 0; 3265447Snw141292 while (i < count && scf_iter_next_value(iter, value) > 0) { 3275447Snw141292 servers[i].priority = 0; 3285447Snw141292 servers[i].weight = 100; 3295447Snw141292 servers[i].port = defport; 3305317Sjp151216 if ((host = scf_value2string(value)) == NULL) { 3315317Sjp151216 goto destruction; 3325317Sjp151216 } 3335317Sjp151216 if ((portstr = strchr(host, ':')) != NULL) { 3345317Sjp151216 *portstr++ = '\0'; 3355447Snw141292 servers[i].port = strtol(portstr, 3365317Sjp151216 (char **)NULL, 10); 3375447Snw141292 if (servers[i].port == 0) 3385447Snw141292 servers[i].port = defport; 3395317Sjp151216 } 3405447Snw141292 len = strlcpy(servers[i].host, host, 3415317Sjp151216 sizeof (servers->host)); 3425317Sjp151216 3435317Sjp151216 free(host); 3445317Sjp151216 3455317Sjp151216 /* Ignore this server if the hostname is too long */ 3465317Sjp151216 if (len < sizeof (servers->host)) 3475447Snw141292 i++; 3485317Sjp151216 } 3495317Sjp151216 3505317Sjp151216 *val = servers; 3515317Sjp151216 3525447Snw141292 rc = 0; 3535447Snw141292 3545317Sjp151216 destruction: 3555317Sjp151216 scf_value_destroy(value); 3565317Sjp151216 scf_iter_destroy(iter); 3575317Sjp151216 scf_property_destroy(scf_prop); 3585317Sjp151216 3595317Sjp151216 if (rc < 0) { 3605317Sjp151216 if (servers) 3615317Sjp151216 free(servers); 3625317Sjp151216 *val = NULL; 3635317Sjp151216 } 3645317Sjp151216 3655317Sjp151216 return (rc); 3665317Sjp151216 } 3675317Sjp151216 3684520Snw141292 3694520Snw141292 static int 3705317Sjp151216 get_val_astring(idmap_cfg_handles_t *handles, char *name, char **val) 3714520Snw141292 { 3724520Snw141292 int rc = 0; 3734520Snw141292 3746616Sdm199847 scf_property_t *scf_prop; 3756616Sdm199847 scf_value_t *value; 3766616Sdm199847 3776616Sdm199847 scf_prop = scf_property_create(handles->main); 3786616Sdm199847 if (scf_prop == NULL) { 3796616Sdm199847 idmapdlog(LOG_ERR, "scf_property_create() failed: %s", 3806616Sdm199847 scf_strerror(scf_error())); 3816616Sdm199847 return (-1); 3826616Sdm199847 } 3836616Sdm199847 value = scf_value_create(handles->main); 3846616Sdm199847 if (value == NULL) { 3856616Sdm199847 idmapdlog(LOG_ERR, "scf_value_create() failed: %s", 3866616Sdm199847 scf_strerror(scf_error())); 3876616Sdm199847 scf_property_destroy(scf_prop); 3886616Sdm199847 return (-1); 3896616Sdm199847 } 3904520Snw141292 3915317Sjp151216 *val = NULL; 3924520Snw141292 3935317Sjp151216 if (scf_pg_get_property(handles->config_pg, name, scf_prop) < 0) 3944520Snw141292 /* this is OK: the property is just undefined */ 3954520Snw141292 goto destruction; 3964520Snw141292 3975317Sjp151216 if (scf_property_get_value(scf_prop, value) < 0) { 3984644Sbaban idmapdlog(LOG_ERR, 3996017Snw141292 "scf_property_get_value(%s) failed: %s", 4006017Snw141292 name, scf_strerror(scf_error())); 4014520Snw141292 rc = -1; 4024520Snw141292 goto destruction; 4034520Snw141292 } 4044520Snw141292 4055317Sjp151216 if (!(*val = scf_value2string(value))) 4064520Snw141292 rc = -1; 4074520Snw141292 4084520Snw141292 destruction: 4094520Snw141292 scf_value_destroy(value); 4104520Snw141292 scf_property_destroy(scf_prop); 4114520Snw141292 4124520Snw141292 if (rc < 0) { 4134520Snw141292 if (*val) 4144520Snw141292 free(*val); 4154520Snw141292 *val = NULL; 4164520Snw141292 } 4174520Snw141292 4184520Snw141292 return (rc); 4194520Snw141292 } 4204520Snw141292 4215317Sjp151216 4224695Sbaban static int 4235317Sjp151216 set_val_astring(idmap_cfg_handles_t *handles, char *name, const char *val) 4244695Sbaban { 4255447Snw141292 int rc = -1; 4265447Snw141292 int ret = -2; 4275447Snw141292 int i; 4284695Sbaban scf_property_t *scf_prop = NULL; 4294695Sbaban scf_value_t *value = NULL; 4304695Sbaban scf_transaction_t *tx = NULL; 4314695Sbaban scf_transaction_entry_t *ent = NULL; 4324695Sbaban 4335317Sjp151216 if ((scf_prop = scf_property_create(handles->main)) == NULL || 4345317Sjp151216 (value = scf_value_create(handles->main)) == NULL || 4355317Sjp151216 (tx = scf_transaction_create(handles->main)) == NULL || 4365317Sjp151216 (ent = scf_entry_create(handles->main)) == NULL) { 4376017Snw141292 idmapdlog(LOG_ERR, "Unable to set property %s", 4386017Snw141292 name, scf_strerror(scf_error())); 4394695Sbaban goto destruction; 4404695Sbaban } 4414695Sbaban 4425447Snw141292 for (i = 0; i < MAX_TRIES && (ret == -2 || ret == 0); i++) { 4435317Sjp151216 if (scf_transaction_start(tx, handles->config_pg) == -1) { 4444695Sbaban idmapdlog(LOG_ERR, 4456017Snw141292 "scf_transaction_start(%s) failed: %s", 4466017Snw141292 name, scf_strerror(scf_error())); 4474695Sbaban goto destruction; 4484695Sbaban } 4494695Sbaban 4505447Snw141292 if (scf_transaction_property_new(tx, ent, name, 4515447Snw141292 SCF_TYPE_ASTRING) < 0) { 4524695Sbaban idmapdlog(LOG_ERR, 4536017Snw141292 "scf_transaction_property_new() failed: %s", 4546017Snw141292 scf_strerror(scf_error())); 4554695Sbaban goto destruction; 4564695Sbaban } 4574695Sbaban 4584695Sbaban if (scf_value_set_astring(value, val) == -1) { 4594695Sbaban idmapdlog(LOG_ERR, 4606017Snw141292 "scf_value_set_astring() failed: %s", 4616017Snw141292 scf_strerror(scf_error())); 4624695Sbaban goto destruction; 4634695Sbaban } 4644695Sbaban 4654695Sbaban if (scf_entry_add_value(ent, value) == -1) { 4664695Sbaban idmapdlog(LOG_ERR, 4676017Snw141292 "scf_entry_add_value() failed: %s", 4686017Snw141292 scf_strerror(scf_error())); 4694695Sbaban goto destruction; 4704695Sbaban } 4714695Sbaban 4725447Snw141292 if ((ret = scf_transaction_commit(tx)) == 1) 4735447Snw141292 break; 4745447Snw141292 4755447Snw141292 if (ret == 0 && i < MAX_TRIES - 1) { 4764695Sbaban /* 4774695Sbaban * Property group set in scf_transaction_start() 4784695Sbaban * is not the most recent. Update pg, reset tx and 4794695Sbaban * retry tx. 4804695Sbaban */ 4814695Sbaban idmapdlog(LOG_WARNING, 4826017Snw141292 "scf_transaction_commit(%s) failed - Retry: %s", 4836017Snw141292 name, scf_strerror(scf_error())); 4845317Sjp151216 if (scf_pg_update(handles->config_pg) == -1) { 4854695Sbaban idmapdlog(LOG_ERR, 4866017Snw141292 "scf_pg_update() failed: %s", 4876017Snw141292 scf_strerror(scf_error())); 4884695Sbaban goto destruction; 4894695Sbaban } 4904695Sbaban scf_transaction_reset(tx); 4914695Sbaban } 4924695Sbaban } 4934695Sbaban 4945447Snw141292 4955447Snw141292 if (ret == 1) 4965447Snw141292 rc = 0; 4975447Snw141292 else if (ret != -2) 4984695Sbaban idmapdlog(LOG_ERR, 4996017Snw141292 "scf_transaction_commit(%s) failed: %s", 5006017Snw141292 name, scf_strerror(scf_error())); 5014695Sbaban 5024695Sbaban destruction: 5034695Sbaban scf_value_destroy(value); 5044695Sbaban scf_entry_destroy(ent); 5054695Sbaban scf_transaction_destroy(tx); 5064695Sbaban scf_property_destroy(scf_prop); 5074695Sbaban return (rc); 5084695Sbaban } 5094695Sbaban 5108361SJulian.Pullen@Sun.COM 5118361SJulian.Pullen@Sun.COM 5128361SJulian.Pullen@Sun.COM /* 5138361SJulian.Pullen@Sun.COM * This function updates a boolean value. 5148361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 5158361SJulian.Pullen@Sun.COM */ 5165317Sjp151216 static int 517*8671SJulian.Pullen@Sun.COM update_bool(boolean_t *value, boolean_t *new, char *name) 5187031Snw141292 { 5197031Snw141292 if (*value == *new) 5207031Snw141292 return (0); 5217031Snw141292 5227031Snw141292 idmapdlog(LOG_INFO, "change %s=%s", name, *new ? "true" : "false"); 5237031Snw141292 *value = *new; 5247031Snw141292 return (1); 5257031Snw141292 } 5267031Snw141292 5278361SJulian.Pullen@Sun.COM 5288361SJulian.Pullen@Sun.COM /* 5298361SJulian.Pullen@Sun.COM * This function updates a string value. 5308361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 5318361SJulian.Pullen@Sun.COM */ 5327031Snw141292 static int 5337031Snw141292 update_string(char **value, char **new, char *name) 5344520Snw141292 { 5355317Sjp151216 if (*new == NULL) 5366097Snw141292 return (0); 5374520Snw141292 5385317Sjp151216 if (*value != NULL && strcmp(*new, *value) == 0) { 5395317Sjp151216 free(*new); 5405317Sjp151216 *new = NULL; 5416097Snw141292 return (0); 5424520Snw141292 } 5434520Snw141292 5446017Snw141292 idmapdlog(LOG_INFO, "change %s=%s", name, CHECK_NULL(*new)); 5455317Sjp151216 if (*value != NULL) 5465317Sjp151216 free(*value); 5475317Sjp151216 *value = *new; 5485317Sjp151216 *new = NULL; 5496097Snw141292 return (1); 5505317Sjp151216 } 5515317Sjp151216 5528361SJulian.Pullen@Sun.COM 5538361SJulian.Pullen@Sun.COM /* 5548361SJulian.Pullen@Sun.COM * This function updates a directory service structure. 5558361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 5568361SJulian.Pullen@Sun.COM */ 5575317Sjp151216 static int 5586616Sdm199847 update_dirs(idmap_ad_disc_ds_t **value, idmap_ad_disc_ds_t **new, char *name) 5595317Sjp151216 { 5605317Sjp151216 int i; 5615317Sjp151216 5625968Snw141292 if (*value == *new) 5635968Snw141292 /* Nothing to do */ 5646097Snw141292 return (0); 5655317Sjp151216 5665968Snw141292 if (*value != NULL && *new != NULL && 5675968Snw141292 ad_disc_compare_ds(*value, *new) == 0) { 5685317Sjp151216 free(*new); 5695317Sjp151216 *new = NULL; 5706097Snw141292 return (0); 5714520Snw141292 } 5724520Snw141292 5738361SJulian.Pullen@Sun.COM if (*value != NULL) 5745317Sjp151216 free(*value); 5755317Sjp151216 5765317Sjp151216 *value = *new; 5775317Sjp151216 *new = NULL; 5785968Snw141292 5795968Snw141292 if (*value == NULL) { 5805968Snw141292 /* We're unsetting this DS property */ 5816017Snw141292 idmapdlog(LOG_INFO, "change %s=<none>", name); 5826097Snw141292 return (1); 5835968Snw141292 } 5845968Snw141292 5855968Snw141292 /* List all the new DSs */ 5865968Snw141292 for (i = 0; (*value)[i].host[0] != '\0'; i++) 5876017Snw141292 idmapdlog(LOG_INFO, "change %s=%s port=%d", name, 5885968Snw141292 (*value)[i].host, (*value)[i].port); 5896097Snw141292 return (1); 5905317Sjp151216 } 5915317Sjp151216 5928361SJulian.Pullen@Sun.COM /* 5938361SJulian.Pullen@Sun.COM * This function updates a trusted domains structure. 5948361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 5958361SJulian.Pullen@Sun.COM */ 5968361SJulian.Pullen@Sun.COM static int 5978361SJulian.Pullen@Sun.COM update_trusted_domains(ad_disc_trusteddomains_t **value, 5988361SJulian.Pullen@Sun.COM ad_disc_trusteddomains_t **new, char *name) 5998361SJulian.Pullen@Sun.COM { 6008361SJulian.Pullen@Sun.COM int i; 6018361SJulian.Pullen@Sun.COM 6028361SJulian.Pullen@Sun.COM if (*value == *new) 6038361SJulian.Pullen@Sun.COM /* Nothing to do */ 6048361SJulian.Pullen@Sun.COM return (0); 6058361SJulian.Pullen@Sun.COM 6068361SJulian.Pullen@Sun.COM if (*value != NULL && *new != NULL && 6078361SJulian.Pullen@Sun.COM ad_disc_compare_trusteddomains(*value, *new) == 0) { 6088361SJulian.Pullen@Sun.COM free(*new); 6098361SJulian.Pullen@Sun.COM *new = NULL; 6108361SJulian.Pullen@Sun.COM return (0); 6118361SJulian.Pullen@Sun.COM } 6128361SJulian.Pullen@Sun.COM 6138361SJulian.Pullen@Sun.COM if (*value != NULL) 6148361SJulian.Pullen@Sun.COM free(*value); 6158361SJulian.Pullen@Sun.COM 6168361SJulian.Pullen@Sun.COM *value = *new; 6178361SJulian.Pullen@Sun.COM *new = NULL; 6188361SJulian.Pullen@Sun.COM 6198361SJulian.Pullen@Sun.COM if (*value == NULL) { 6208361SJulian.Pullen@Sun.COM /* We're unsetting this DS property */ 6218361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=<none>", name); 6228361SJulian.Pullen@Sun.COM return (1); 6238361SJulian.Pullen@Sun.COM } 6248361SJulian.Pullen@Sun.COM 6258361SJulian.Pullen@Sun.COM /* List all the new domains */ 6268361SJulian.Pullen@Sun.COM for (i = 0; (*value)[i].domain[0] != '\0'; i++) 6278361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s direction=%s", name, 6288361SJulian.Pullen@Sun.COM (*value)[i].domain, 6298361SJulian.Pullen@Sun.COM (*value)[i].direction == 3 ? "bi-directional" : "inbound"); 6308361SJulian.Pullen@Sun.COM return (1); 6318361SJulian.Pullen@Sun.COM } 6328361SJulian.Pullen@Sun.COM 6338361SJulian.Pullen@Sun.COM 6348361SJulian.Pullen@Sun.COM /* 6358361SJulian.Pullen@Sun.COM * This function updates a domains in a forest structure. 6368361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 6378361SJulian.Pullen@Sun.COM */ 6388361SJulian.Pullen@Sun.COM static int 6398361SJulian.Pullen@Sun.COM update_domains_in_forest(ad_disc_domainsinforest_t **value, 6408361SJulian.Pullen@Sun.COM ad_disc_domainsinforest_t **new, char *name) 6418361SJulian.Pullen@Sun.COM { 6428361SJulian.Pullen@Sun.COM int i; 6438361SJulian.Pullen@Sun.COM 6448361SJulian.Pullen@Sun.COM if (*value == *new) 6458361SJulian.Pullen@Sun.COM /* Nothing to do */ 6468361SJulian.Pullen@Sun.COM return (0); 6478361SJulian.Pullen@Sun.COM 6488361SJulian.Pullen@Sun.COM if (*value != NULL && *new != NULL && 6498361SJulian.Pullen@Sun.COM ad_disc_compare_domainsinforest(*value, *new) == 0) { 6508361SJulian.Pullen@Sun.COM free(*new); 6518361SJulian.Pullen@Sun.COM *new = NULL; 6528361SJulian.Pullen@Sun.COM return (0); 6538361SJulian.Pullen@Sun.COM } 6548361SJulian.Pullen@Sun.COM 6558361SJulian.Pullen@Sun.COM if (*value != NULL) 6568361SJulian.Pullen@Sun.COM free(*value); 6578361SJulian.Pullen@Sun.COM 6588361SJulian.Pullen@Sun.COM *value = *new; 6598361SJulian.Pullen@Sun.COM *new = NULL; 6608361SJulian.Pullen@Sun.COM 6618361SJulian.Pullen@Sun.COM if (*value == NULL) { 6628361SJulian.Pullen@Sun.COM /* We're unsetting this DS property */ 6638361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=<none>", name); 6648361SJulian.Pullen@Sun.COM return (1); 6658361SJulian.Pullen@Sun.COM } 6668361SJulian.Pullen@Sun.COM 6678361SJulian.Pullen@Sun.COM /* List all the new domains */ 6688361SJulian.Pullen@Sun.COM for (i = 0; (*value)[i].domain[0] != '\0'; i++) 6698361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s", name, 6708361SJulian.Pullen@Sun.COM (*value)[i].domain); 6718361SJulian.Pullen@Sun.COM return (1); 6728361SJulian.Pullen@Sun.COM } 6738361SJulian.Pullen@Sun.COM 6748361SJulian.Pullen@Sun.COM 6758361SJulian.Pullen@Sun.COM static void 6768361SJulian.Pullen@Sun.COM free_trusted_forests(idmap_trustedforest_t **value, int *num_values) 6778361SJulian.Pullen@Sun.COM { 6788361SJulian.Pullen@Sun.COM int i; 6798361SJulian.Pullen@Sun.COM 6808361SJulian.Pullen@Sun.COM for (i = 0; i < *num_values; i++) { 6818361SJulian.Pullen@Sun.COM free((*value)[i].forest_name); 6828361SJulian.Pullen@Sun.COM free((*value)[i].global_catalog); 6838361SJulian.Pullen@Sun.COM free((*value)[i].domains_in_forest); 6848361SJulian.Pullen@Sun.COM } 6858361SJulian.Pullen@Sun.COM free(*value); 6868361SJulian.Pullen@Sun.COM *value = NULL; 6878361SJulian.Pullen@Sun.COM *num_values = 0; 6888361SJulian.Pullen@Sun.COM } 6898361SJulian.Pullen@Sun.COM 6908361SJulian.Pullen@Sun.COM 6918361SJulian.Pullen@Sun.COM static int 6928361SJulian.Pullen@Sun.COM compare_trusteddomainsinforest(ad_disc_domainsinforest_t *df1, 6938361SJulian.Pullen@Sun.COM ad_disc_domainsinforest_t *df2) 6948361SJulian.Pullen@Sun.COM { 695*8671SJulian.Pullen@Sun.COM int i, j; 696*8671SJulian.Pullen@Sun.COM int num_df1 = 0; 697*8671SJulian.Pullen@Sun.COM int num_df2 = 0; 698*8671SJulian.Pullen@Sun.COM boolean_t match; 699*8671SJulian.Pullen@Sun.COM int err; 7008361SJulian.Pullen@Sun.COM 7018361SJulian.Pullen@Sun.COM for (i = 0; df1[i].domain[0] != '\0'; i++) 7028361SJulian.Pullen@Sun.COM if (df1[i].trusted) 7038361SJulian.Pullen@Sun.COM num_df1++; 7048361SJulian.Pullen@Sun.COM 7058361SJulian.Pullen@Sun.COM for (j = 0; df2[j].domain[0] != '\0'; j++) 7068361SJulian.Pullen@Sun.COM if (df2[j].trusted) 7078361SJulian.Pullen@Sun.COM num_df2++; 7088361SJulian.Pullen@Sun.COM 7098361SJulian.Pullen@Sun.COM if (num_df1 != num_df2) 7108361SJulian.Pullen@Sun.COM return (1); 7118361SJulian.Pullen@Sun.COM 7128361SJulian.Pullen@Sun.COM for (i = 0; df1[i].domain[0] != '\0'; i++) { 7138361SJulian.Pullen@Sun.COM if (df1[i].trusted) { 714*8671SJulian.Pullen@Sun.COM match = B_FALSE; 7158361SJulian.Pullen@Sun.COM for (j = 0; df2[j].domain[0] != '\0'; j++) { 7168361SJulian.Pullen@Sun.COM if (df2[j].trusted && 7178361SJulian.Pullen@Sun.COM u8_strcmp(df1[i].domain, df2[i].domain, 0, 7188361SJulian.Pullen@Sun.COM U8_STRCMP_CI_LOWER, U8_UNICODE_LATEST, &err) 7198361SJulian.Pullen@Sun.COM == 0 && err == 0 && 7208361SJulian.Pullen@Sun.COM strcmp(df1[i].sid, df2[i].sid) == 0) { 721*8671SJulian.Pullen@Sun.COM match = B_TRUE; 7228361SJulian.Pullen@Sun.COM break; 7238361SJulian.Pullen@Sun.COM } 7248361SJulian.Pullen@Sun.COM } 7258361SJulian.Pullen@Sun.COM if (!match) 7268361SJulian.Pullen@Sun.COM return (1); 7278361SJulian.Pullen@Sun.COM } 7288361SJulian.Pullen@Sun.COM } 7298361SJulian.Pullen@Sun.COM return (0); 7308361SJulian.Pullen@Sun.COM } 7318361SJulian.Pullen@Sun.COM 7328361SJulian.Pullen@Sun.COM 7338361SJulian.Pullen@Sun.COM 7348361SJulian.Pullen@Sun.COM /* 7358361SJulian.Pullen@Sun.COM * This function updates trusted forest structure. 7368361SJulian.Pullen@Sun.COM * If nothing has changed it returns 0 else 1 7378361SJulian.Pullen@Sun.COM */ 7388361SJulian.Pullen@Sun.COM static int 7398361SJulian.Pullen@Sun.COM update_trusted_forest(idmap_trustedforest_t **value, int *num_value, 7408361SJulian.Pullen@Sun.COM idmap_trustedforest_t **new, int *num_new, char *name) 7418361SJulian.Pullen@Sun.COM { 7428361SJulian.Pullen@Sun.COM int i, j; 743*8671SJulian.Pullen@Sun.COM boolean_t match; 7448361SJulian.Pullen@Sun.COM 7458361SJulian.Pullen@Sun.COM if (*value == *new) 7468361SJulian.Pullen@Sun.COM /* Nothing to do */ 7478361SJulian.Pullen@Sun.COM return (0); 7488361SJulian.Pullen@Sun.COM 7498361SJulian.Pullen@Sun.COM if (*value != NULL && *new != NULL) { 7508361SJulian.Pullen@Sun.COM if (*num_value != *num_new) 7518361SJulian.Pullen@Sun.COM goto not_equal; 7528361SJulian.Pullen@Sun.COM for (i = 0; i < *num_value; i++) { 753*8671SJulian.Pullen@Sun.COM match = B_FALSE; 7548361SJulian.Pullen@Sun.COM for (j = 0; j < *num_new; j++) { 7558361SJulian.Pullen@Sun.COM if (strcmp((*value)[i].forest_name, 7568361SJulian.Pullen@Sun.COM (*new)[j].forest_name) == 0 && 7578361SJulian.Pullen@Sun.COM ad_disc_compare_ds( 7588361SJulian.Pullen@Sun.COM (*value)[i].global_catalog, 7598361SJulian.Pullen@Sun.COM (*new)[i].global_catalog) == 0 && 7608361SJulian.Pullen@Sun.COM compare_trusteddomainsinforest( 7618361SJulian.Pullen@Sun.COM (*value)[i].domains_in_forest, 7628361SJulian.Pullen@Sun.COM (*new)[i].domains_in_forest) == 0) { 763*8671SJulian.Pullen@Sun.COM match = B_TRUE; 7648361SJulian.Pullen@Sun.COM break; 7658361SJulian.Pullen@Sun.COM } 7668361SJulian.Pullen@Sun.COM } 7678361SJulian.Pullen@Sun.COM if (!match) 7688361SJulian.Pullen@Sun.COM goto not_equal; 7698361SJulian.Pullen@Sun.COM } 7708361SJulian.Pullen@Sun.COM free_trusted_forests(new, num_new); 7718361SJulian.Pullen@Sun.COM return (0); 7728361SJulian.Pullen@Sun.COM } 7738361SJulian.Pullen@Sun.COM not_equal: 7748361SJulian.Pullen@Sun.COM if (*value != NULL) 7758361SJulian.Pullen@Sun.COM free_trusted_forests(value, num_value); 7768361SJulian.Pullen@Sun.COM *value = *new; 7778361SJulian.Pullen@Sun.COM *num_value = *num_new; 7788361SJulian.Pullen@Sun.COM *new = NULL; 7798361SJulian.Pullen@Sun.COM *num_new = 0; 7808361SJulian.Pullen@Sun.COM 7818361SJulian.Pullen@Sun.COM if (*value == NULL) { 7828361SJulian.Pullen@Sun.COM /* We're unsetting this DS property */ 7838361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=<none>", name); 7848361SJulian.Pullen@Sun.COM return (1); 7858361SJulian.Pullen@Sun.COM } 7868361SJulian.Pullen@Sun.COM 7878361SJulian.Pullen@Sun.COM /* List all the trusted forests */ 7888361SJulian.Pullen@Sun.COM for (i = 0; i < *num_value; i++) { 7898361SJulian.Pullen@Sun.COM for (j = 0; (*value)[i].domains_in_forest[j].domain[0] != '\0'; 7908361SJulian.Pullen@Sun.COM j++) { 7918361SJulian.Pullen@Sun.COM /* List trusted Domains in the forest. */ 7928361SJulian.Pullen@Sun.COM if ((*value)[i].domains_in_forest[j].trusted) 7938361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s domain=%s", 7948361SJulian.Pullen@Sun.COM name, (*value)[i].forest_name, 7958361SJulian.Pullen@Sun.COM (*value)[i].domains_in_forest[j].domain); 7968361SJulian.Pullen@Sun.COM } 7978361SJulian.Pullen@Sun.COM /* List the hosts */ 7988361SJulian.Pullen@Sun.COM for (j = 0; (*value)[i].global_catalog[j].host[0] != '\0'; j++) 7998361SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "change %s=%s host=%s port=%d", 8008361SJulian.Pullen@Sun.COM name, (*value)[i].forest_name, 8018361SJulian.Pullen@Sun.COM (*value)[i].global_catalog[j].host, 8028361SJulian.Pullen@Sun.COM (*value)[i].global_catalog[j].port); 8038361SJulian.Pullen@Sun.COM } 8048361SJulian.Pullen@Sun.COM return (1); 8058361SJulian.Pullen@Sun.COM } 8068361SJulian.Pullen@Sun.COM 8075317Sjp151216 8085968Snw141292 #define MAX_CHECK_TIME (20 * 60) 8094520Snw141292 8105317Sjp151216 /* 8115968Snw141292 * Returns 1 if the PF_ROUTE socket event indicates that we should rescan the 8125968Snw141292 * interfaces. 8135317Sjp151216 * 8145968Snw141292 * Shamelessly based on smb_nics_changed() and other PF_ROUTE uses in ON. 8155968Snw141292 */ 8165968Snw141292 static 8175968Snw141292 int 8185968Snw141292 pfroute_event_is_interesting(int rt_sock) 8195968Snw141292 { 8205968Snw141292 int nbytes; 8215968Snw141292 int64_t msg[2048 / 8]; 8225968Snw141292 struct rt_msghdr *rtm; 8235968Snw141292 int is_interesting = FALSE; 8245968Snw141292 8255968Snw141292 for (;;) { 8265968Snw141292 if ((nbytes = read(rt_sock, msg, sizeof (msg))) <= 0) 8275968Snw141292 break; 8285968Snw141292 rtm = (struct rt_msghdr *)msg; 8295968Snw141292 if (rtm->rtm_version != RTM_VERSION) 8305968Snw141292 continue; 8315968Snw141292 if (nbytes < rtm->rtm_msglen) 8325968Snw141292 continue; 8335968Snw141292 switch (rtm->rtm_type) { 8345968Snw141292 case RTM_NEWADDR: 8355968Snw141292 case RTM_DELADDR: 8365968Snw141292 case RTM_IFINFO: 8375968Snw141292 is_interesting = TRUE; 8385968Snw141292 break; 8395968Snw141292 default: 8405968Snw141292 break; 8415968Snw141292 } 8425968Snw141292 } 8435968Snw141292 return (is_interesting); 8445968Snw141292 } 8455968Snw141292 8465968Snw141292 /* 8475968Snw141292 * Returns 1 if SIGHUP has been received (see hup_handler() elsewhere) or if an 8485968Snw141292 * interface address was added or removed; otherwise it returns 0. 8495968Snw141292 * 8505968Snw141292 * Note that port_get() does not update its timeout argument when EINTR, unlike 8515968Snw141292 * nanosleep(). We probably don't care very much here, but if we did care then 8525968Snw141292 * we could always use a timer event and associate it with the same event port, 8535317Sjp151216 * then we could get accurate waiting regardless of EINTRs. 8545317Sjp151216 */ 8555317Sjp151216 static 8565317Sjp151216 int 8576097Snw141292 wait_for_event(int poke_is_interesting, struct timespec *timeoutp) 8585317Sjp151216 { 8595317Sjp151216 port_event_t pe; 8605317Sjp151216 8615317Sjp151216 retry: 8625968Snw141292 memset(&pe, 0, sizeof (pe)); 8636097Snw141292 if (port_get(idmapd_ev_port, &pe, timeoutp) != 0) { 8645317Sjp151216 switch (errno) { 8655317Sjp151216 case EINTR: 8665968Snw141292 goto retry; 8675317Sjp151216 case ETIME: 8685317Sjp151216 /* Timeout */ 8695968Snw141292 return (FALSE); 8705317Sjp151216 default: 8715968Snw141292 /* EBADF, EBADFD, EFAULT, EINVAL (end of time?)? */ 8725968Snw141292 idmapdlog(LOG_ERR, "Event port failed: %s", 8735968Snw141292 strerror(errno)); 8745968Snw141292 exit(1); 8755968Snw141292 /* NOTREACHED */ 8765317Sjp151216 break; 8774520Snw141292 } 8784520Snw141292 } 8794520Snw141292 8805968Snw141292 if (pe.portev_source == PORT_SOURCE_USER && 8815968Snw141292 pe.portev_events == POKE_AUTO_DISCOVERY) 8825968Snw141292 return (poke_is_interesting ? TRUE : FALSE); 8835317Sjp151216 8845968Snw141292 if (pe.portev_source == PORT_SOURCE_FD && pe.portev_object == rt_sock) { 8855968Snw141292 /* PF_ROUTE socket read event, re-associate fd, handle event */ 8865968Snw141292 if (port_associate(idmapd_ev_port, PORT_SOURCE_FD, rt_sock, 8875968Snw141292 POLLIN, NULL) != 0) { 8885968Snw141292 idmapdlog(LOG_ERR, "Failed to re-associate the " 8895968Snw141292 "routing socket with the event port: %s", 8905968Snw141292 strerror(errno)); 8915968Snw141292 exit(1); 8925968Snw141292 } 8935968Snw141292 /* 8945968Snw141292 * The network configuration may still be in flux. No matter, 8955968Snw141292 * the resolver will re-transmit and timout if need be. 8965968Snw141292 */ 8975968Snw141292 return (pfroute_event_is_interesting(rt_sock)); 8985968Snw141292 } 8995968Snw141292 9005968Snw141292 if (pe.portev_source == PORT_SOURCE_USER && 9015968Snw141292 pe.portev_events == RECONFIGURE) { 9025447Snw141292 int rc; 9035447Snw141292 9045447Snw141292 /* 9055447Snw141292 * Blow away the ccache, we might have re-joined the 9065447Snw141292 * domain or joined a new one 9075447Snw141292 */ 9085447Snw141292 (void) unlink(IDMAP_CACHEDIR "/ccache"); 9095447Snw141292 /* HUP is the refresh method, so re-read SMF config */ 910*8671SJulian.Pullen@Sun.COM idmapdlog(LOG_INFO, "SMF refresh"); 9116097Snw141292 rc = idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER|CFG_LOG); 9126097Snw141292 if (rc < -1) { 913*8671SJulian.Pullen@Sun.COM idmapdlog(LOG_ERR, "Fatal errors while reading " 9146097Snw141292 "SMF properties"); 9156097Snw141292 exit(1); 9166097Snw141292 } else if (rc == -1) { 917*8671SJulian.Pullen@Sun.COM idmapdlog(LOG_WARNING, "Various errors " 9186097Snw141292 "re-loading configuration may cause AD lookups " 9196097Snw141292 "to fail"); 9206097Snw141292 } 9216097Snw141292 return (FALSE); 9225317Sjp151216 } 9235317Sjp151216 9245968Snw141292 return (FALSE); 9255317Sjp151216 } 9265317Sjp151216 9275317Sjp151216 void * 9285317Sjp151216 idmap_cfg_update_thread(void *arg) 9295317Sjp151216 { 9305317Sjp151216 9315968Snw141292 int ttl, changed, poke_is_interesting; 9325317Sjp151216 idmap_cfg_handles_t *handles = &_idmapdstate.cfg->handles; 9335317Sjp151216 ad_disc_t ad_ctx = handles->ad_ctx; 9346097Snw141292 struct timespec timeout, *timeoutp; 9355317Sjp151216 9365968Snw141292 poke_is_interesting = 1; 9375968Snw141292 for (ttl = 0, changed = TRUE; ; ttl = ad_disc_get_TTL(ad_ctx)) { 9386097Snw141292 /* 9396097Snw141292 * If ttl < 0 then we can wait for an event without timing out. 9406097Snw141292 * If idmapd needs to notice that the system has been joined to 9416097Snw141292 * a Windows domain then idmapd needs to be refreshed. 9426097Snw141292 */ 9436097Snw141292 timeoutp = (ttl < 0) ? NULL : &timeout; 9446097Snw141292 if (ttl > MAX_CHECK_TIME) 9455317Sjp151216 ttl = MAX_CHECK_TIME; 9465968Snw141292 timeout.tv_sec = ttl; 9475968Snw141292 timeout.tv_nsec = 0; 9486097Snw141292 changed = wait_for_event(poke_is_interesting, timeoutp); 9495968Snw141292 9505968Snw141292 /* 9515968Snw141292 * If there are no interesting events, and this is not the first 9525968Snw141292 * time through the loop, and we haven't waited the most that 9535968Snw141292 * we're willing to wait, so do nothing but wait some more. 9545968Snw141292 */ 9555968Snw141292 if (changed == FALSE && ttl > 0 && ttl < MAX_CHECK_TIME) 9565968Snw141292 continue; 9575968Snw141292 9585968Snw141292 (void) ad_disc_SubnetChanged(ad_ctx); 9595317Sjp151216 9606097Snw141292 if (idmap_cfg_load(_idmapdstate.cfg, CFG_DISCOVER) < -1) { 961*8671SJulian.Pullen@Sun.COM idmapdlog(LOG_ERR, "Fatal errors while reading " 9626097Snw141292 "SMF properties"); 9636097Snw141292 exit(1); 9645317Sjp151216 } 9655317Sjp151216 9666097Snw141292 if (_idmapdstate.cfg->pgcfg.global_catalog == NULL || 9676097Snw141292 _idmapdstate.cfg->pgcfg.global_catalog[0].host[0] == '\0') 9686097Snw141292 poke_is_interesting = 1; 9696097Snw141292 else 9706097Snw141292 poke_is_interesting = 0; 9715317Sjp151216 } 9725317Sjp151216 /*NOTREACHED*/ 9735317Sjp151216 return (NULL); 9745317Sjp151216 } 9755317Sjp151216 9765968Snw141292 int 9775968Snw141292 idmap_cfg_start_updates(void) 9785968Snw141292 { 9795968Snw141292 if ((idmapd_ev_port = port_create()) < 0) { 9806017Snw141292 idmapdlog(LOG_ERR, "Failed to create event port: %s", 9816017Snw141292 strerror(errno)); 9825968Snw141292 return (-1); 9835968Snw141292 } 9845968Snw141292 9855968Snw141292 if ((rt_sock = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) { 9866017Snw141292 idmapdlog(LOG_ERR, "Failed to open routing socket: %s", 9876017Snw141292 strerror(errno)); 9885968Snw141292 (void) close(idmapd_ev_port); 9895968Snw141292 return (-1); 9905968Snw141292 } 9915317Sjp151216 9925968Snw141292 if (fcntl(rt_sock, F_SETFL, O_NDELAY|O_NONBLOCK) < 0) { 9936017Snw141292 idmapdlog(LOG_ERR, "Failed to set routing socket flags: %s", 9946017Snw141292 strerror(errno)); 9955968Snw141292 (void) close(rt_sock); 9965968Snw141292 (void) close(idmapd_ev_port); 9974520Snw141292 return (-1); 9985968Snw141292 } 9995968Snw141292 10005968Snw141292 if (port_associate(idmapd_ev_port, PORT_SOURCE_FD, 10015968Snw141292 rt_sock, POLLIN, NULL) != 0) { 10026017Snw141292 idmapdlog(LOG_ERR, "Failed to associate the routing " 10036017Snw141292 "socket with the event port: %s", strerror(errno)); 10045968Snw141292 (void) close(rt_sock); 10055968Snw141292 (void) close(idmapd_ev_port); 10065968Snw141292 return (-1); 10075968Snw141292 } 10085968Snw141292 10095968Snw141292 if ((errno = pthread_create(&update_thread_handle, NULL, 10105968Snw141292 idmap_cfg_update_thread, NULL)) != 0) { 10116017Snw141292 idmapdlog(LOG_ERR, "Failed to start update thread: %s", 10126017Snw141292 strerror(errno)); 10135968Snw141292 (void) port_dissociate(idmapd_ev_port, PORT_SOURCE_FD, rt_sock); 10145968Snw141292 (void) close(rt_sock); 10155968Snw141292 (void) close(idmapd_ev_port); 10165968Snw141292 return (-1); 10175968Snw141292 } 10185968Snw141292 10195968Snw141292 return (0); 10205317Sjp151216 } 10215317Sjp151216 10226097Snw141292 /* 10236616Sdm199847 * Reject attribute names with invalid characters. 10246616Sdm199847 */ 10256616Sdm199847 static 10266616Sdm199847 int 10276616Sdm199847 valid_ldap_attr(const char *attr) { 10286616Sdm199847 for (; *attr; attr++) { 10296616Sdm199847 if (!isalnum(*attr) && *attr != '-' && 10306616Sdm199847 *attr != '_' && *attr != '.' && *attr != ';') 10316616Sdm199847 return (0); 10326616Sdm199847 } 10336616Sdm199847 return (1); 10346616Sdm199847 } 10356616Sdm199847 10366616Sdm199847 /* 10376097Snw141292 * This is the half of idmap_cfg_load() that loads property values from 10386097Snw141292 * SMF (using the config/ property group of the idmap FMRI). 10396097Snw141292 * 10406097Snw141292 * Return values: 0 -> success, -1 -> failure, -2 -> hard failures 10416616Sdm199847 * -3 -> hard smf config failures 10426097Snw141292 * reading from SMF. 10436097Snw141292 */ 10446097Snw141292 static 10455317Sjp151216 int 10466097Snw141292 idmap_cfg_load_smf(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg, 10476097Snw141292 int *errors) 10485317Sjp151216 { 10495447Snw141292 int rc; 10505731Sbaban uint8_t bool_val; 10515317Sjp151216 char *str = NULL; 1052*8671SJulian.Pullen@Sun.COM boolean_t new_debug_mode; 10535317Sjp151216 10545317Sjp151216 if (scf_pg_update(handles->config_pg) < 0) { 10556017Snw141292 idmapdlog(LOG_ERR, "scf_pg_update() failed: %s", 10566017Snw141292 scf_strerror(scf_error())); 10576097Snw141292 return (-2); 10585317Sjp151216 } 10595317Sjp151216 10605317Sjp151216 if (scf_pg_update(handles->general_pg) < 0) { 10616017Snw141292 idmapdlog(LOG_ERR, "scf_pg_update() failed: %s", 10626017Snw141292 scf_strerror(scf_error())); 10636097Snw141292 return (-2); 10645317Sjp151216 } 10655317Sjp151216 10666616Sdm199847 10676616Sdm199847 rc = prop_exists(handles, "debug", &new_debug_mode); 10686616Sdm199847 if (rc != 0) 10696616Sdm199847 errors++; 10706616Sdm199847 10716017Snw141292 if (_idmapdstate.debug_mode != new_debug_mode) { 1072*8671SJulian.Pullen@Sun.COM if (!_idmapdstate.debug_mode) { 10736017Snw141292 _idmapdstate.debug_mode = new_debug_mode; 10747031Snw141292 idmap_log_stderr(LOG_DEBUG); 10756017Snw141292 idmapdlog(LOG_DEBUG, "debug mode enabled"); 10766017Snw141292 } else { 10776017Snw141292 idmapdlog(LOG_DEBUG, "debug mode disabled"); 10787031Snw141292 idmap_log_stderr(-1); 10796017Snw141292 _idmapdstate.debug_mode = new_debug_mode; 10806017Snw141292 } 10816017Snw141292 } 10826017Snw141292 10837031Snw141292 rc = get_val_int(handles, "unresolvable_sid_mapping", 10847031Snw141292 &pgcfg->eph_map_unres_sids, SCF_TYPE_BOOLEAN); 10857031Snw141292 if (rc != 0) 10867031Snw141292 errors++; 10877031Snw141292 10885317Sjp151216 rc = get_val_int(handles, "list_size_limit", 10895317Sjp151216 &pgcfg->list_size_limit, SCF_TYPE_COUNT); 10907031Snw141292 if (rc != 0) 10915447Snw141292 errors++; 10925317Sjp151216 10935317Sjp151216 rc = get_val_astring(handles, "domain_name", 10945317Sjp151216 &pgcfg->domain_name); 10955447Snw141292 if (rc != 0) 10965447Snw141292 errors++; 10978361SJulian.Pullen@Sun.COM else { 10986097Snw141292 (void) ad_disc_set_DomainName(handles->ad_ctx, 10996097Snw141292 pgcfg->domain_name); 1100*8671SJulian.Pullen@Sun.COM pgcfg->domain_name_auto_disc = B_FALSE; 11018361SJulian.Pullen@Sun.COM } 11025317Sjp151216 11035317Sjp151216 rc = get_val_astring(handles, "default_domain", 11045317Sjp151216 &pgcfg->default_domain); 11055317Sjp151216 if (rc != 0) { 11065447Snw141292 /* 11075447Snw141292 * SCF failures fetching config/default_domain we treat 11085447Snw141292 * as fatal as they may leave ID mapping rules that 11095447Snw141292 * match unqualified winnames flapping in the wind. 11105447Snw141292 */ 11116097Snw141292 return (-2); 11125317Sjp151216 } 11135317Sjp151216 11145317Sjp151216 rc = get_val_astring(handles, "mapping_domain", &str); 11155447Snw141292 if (rc != 0) 11165447Snw141292 errors++; 11175317Sjp151216 11185317Sjp151216 /* 11195317Sjp151216 * We treat default_domain as having been specified in SMF IFF 11205317Sjp151216 * either (the config/default_domain property was set) or (the 11215317Sjp151216 * old, obsolete, never documented config/mapping_domain 11225317Sjp151216 * property was set and the new config/domain_name property was 11235317Sjp151216 * not set). 11245317Sjp151216 */ 1125*8671SJulian.Pullen@Sun.COM pgcfg->dflt_dom_set_in_smf = B_TRUE; 11265317Sjp151216 if (pgcfg->default_domain == NULL) { 11275317Sjp151216 1128*8671SJulian.Pullen@Sun.COM pgcfg->dflt_dom_set_in_smf = B_FALSE; 11295317Sjp151216 11305317Sjp151216 if (pgcfg->domain_name != NULL) { 11315317Sjp151216 pgcfg->default_domain = strdup(pgcfg->domain_name); 11325317Sjp151216 if (str != NULL) { 11335317Sjp151216 idmapdlog(LOG_WARNING, 11346017Snw141292 "Ignoring obsolete, undocumented " 11356017Snw141292 "config/mapping_domain property"); 11365317Sjp151216 } 11375317Sjp151216 } else if (str != NULL) { 11385317Sjp151216 pgcfg->default_domain = strdup(str); 1139*8671SJulian.Pullen@Sun.COM pgcfg->dflt_dom_set_in_smf = B_TRUE; 11405317Sjp151216 idmapdlog(LOG_WARNING, 11416017Snw141292 "The config/mapping_domain property is " 11425317Sjp151216 "obsolete; support for it will be removed, " 11436017Snw141292 "please use config/default_domain instead"); 11444695Sbaban } 11454695Sbaban } 11464520Snw141292 11475317Sjp151216 if (str != NULL) 11485317Sjp151216 free(str); 11495317Sjp151216 11505317Sjp151216 rc = get_val_astring(handles, "machine_sid", &pgcfg->machine_sid); 11515447Snw141292 if (rc != 0) 11525447Snw141292 errors++; 11535317Sjp151216 if (pgcfg->machine_sid == NULL) { 11545317Sjp151216 /* If machine_sid not configured, generate one */ 11556097Snw141292 if (generate_machine_sid(&pgcfg->machine_sid) < 0) 11566097Snw141292 return (-2); 11575317Sjp151216 rc = set_val_astring(handles, "machine_sid", 11585317Sjp151216 pgcfg->machine_sid); 11595447Snw141292 if (rc != 0) 11605447Snw141292 errors++; 11615317Sjp151216 } 11625317Sjp151216 11635317Sjp151216 str = NULL; 11645317Sjp151216 rc = get_val_ds(handles, "domain_controller", 389, 11655317Sjp151216 &pgcfg->domain_controller); 11665447Snw141292 if (rc != 0) 11675447Snw141292 errors++; 11688361SJulian.Pullen@Sun.COM else { 11696097Snw141292 (void) ad_disc_set_DomainController(handles->ad_ctx, 11705447Snw141292 pgcfg->domain_controller); 1171*8671SJulian.Pullen@Sun.COM pgcfg->domain_controller_auto_disc = B_FALSE; 11728361SJulian.Pullen@Sun.COM } 11735317Sjp151216 11745317Sjp151216 rc = get_val_astring(handles, "forest_name", &pgcfg->forest_name); 11755447Snw141292 if (rc != 0) 11765447Snw141292 errors++; 11778361SJulian.Pullen@Sun.COM else { 11786097Snw141292 (void) ad_disc_set_ForestName(handles->ad_ctx, 11796097Snw141292 pgcfg->forest_name); 1180*8671SJulian.Pullen@Sun.COM pgcfg->forest_name_auto_disc = B_FALSE; 11818361SJulian.Pullen@Sun.COM } 11825317Sjp151216 11835317Sjp151216 rc = get_val_astring(handles, "site_name", &pgcfg->site_name); 11845447Snw141292 if (rc != 0) 11855447Snw141292 errors++; 11865447Snw141292 else 11876097Snw141292 (void) ad_disc_set_SiteName(handles->ad_ctx, pgcfg->site_name); 11885317Sjp151216 11895317Sjp151216 str = NULL; 11905317Sjp151216 rc = get_val_ds(handles, "global_catalog", 3268, 11915317Sjp151216 &pgcfg->global_catalog); 11925447Snw141292 if (rc != 0) 11935447Snw141292 errors++; 11948361SJulian.Pullen@Sun.COM else { 11956097Snw141292 (void) ad_disc_set_GlobalCatalog(handles->ad_ctx, 11966097Snw141292 pgcfg->global_catalog); 1197*8671SJulian.Pullen@Sun.COM pgcfg->global_catalog_auto_disc = B_FALSE; 11988361SJulian.Pullen@Sun.COM } 11995447Snw141292 12005731Sbaban /* 12015731Sbaban * Read directory-based name mappings related SMF properties 12025731Sbaban */ 12035731Sbaban rc = get_val_int(handles, "ds_name_mapping_enabled", 12045731Sbaban &bool_val, SCF_TYPE_BOOLEAN); 12056097Snw141292 if (rc != 0) 12066097Snw141292 return (-2); 12076097Snw141292 12086097Snw141292 if (!bool_val) 12096097Snw141292 return (rc); 12105731Sbaban 1211*8671SJulian.Pullen@Sun.COM pgcfg->ds_name_mapping_enabled = B_TRUE; 12126097Snw141292 rc = get_val_astring(handles, "ad_unixuser_attr", 12136097Snw141292 &pgcfg->ad_unixuser_attr); 12146097Snw141292 if (rc != 0) 12156097Snw141292 return (-2); 12166616Sdm199847 if (pgcfg->ad_unixuser_attr != NULL && 12176616Sdm199847 !valid_ldap_attr(pgcfg->ad_unixuser_attr)) { 12186616Sdm199847 idmapdlog(LOG_ERR, "config/ad_unixuser_attr=%s is not a " 12196616Sdm199847 "valid LDAP attribute name", pgcfg->ad_unixuser_attr); 12206616Sdm199847 return (-3); 12216616Sdm199847 } 12226097Snw141292 12236097Snw141292 rc = get_val_astring(handles, "ad_unixgroup_attr", 12246097Snw141292 &pgcfg->ad_unixgroup_attr); 12256097Snw141292 if (rc != 0) 12266097Snw141292 return (-2); 12276616Sdm199847 if (pgcfg->ad_unixgroup_attr != NULL && 12286616Sdm199847 !valid_ldap_attr(pgcfg->ad_unixgroup_attr)) { 12296616Sdm199847 idmapdlog(LOG_ERR, "config/ad_unixgroup_attr=%s is not a " 12306616Sdm199847 "valid LDAP attribute name", pgcfg->ad_unixgroup_attr); 12316616Sdm199847 return (-3); 12326616Sdm199847 } 12335731Sbaban 12346097Snw141292 rc = get_val_astring(handles, "nldap_winname_attr", 12356097Snw141292 &pgcfg->nldap_winname_attr); 12366097Snw141292 if (rc != 0) 12376097Snw141292 return (-2); 12386616Sdm199847 if (pgcfg->nldap_winname_attr != NULL && 12396616Sdm199847 !valid_ldap_attr(pgcfg->nldap_winname_attr)) { 12406616Sdm199847 idmapdlog(LOG_ERR, "config/nldap_winname_attr=%s is not a " 12416616Sdm199847 "valid LDAP attribute name", pgcfg->nldap_winname_attr); 12426097Snw141292 return (-3); 12436097Snw141292 } 12446097Snw141292 if (pgcfg->ad_unixuser_attr == NULL && 12456616Sdm199847 pgcfg->ad_unixgroup_attr == NULL && 12466616Sdm199847 pgcfg->nldap_winname_attr == NULL) { 12476097Snw141292 idmapdlog(LOG_ERR, 12486097Snw141292 "If config/ds_name_mapping_enabled property is set to " 12496097Snw141292 "true then atleast one of the following name mapping " 12506097Snw141292 "attributes must be specified. (config/ad_unixuser_attr OR " 12516616Sdm199847 "config/ad_unixgroup_attr OR config/nldap_winname_attr)"); 12526097Snw141292 return (-3); 12535731Sbaban } 12545731Sbaban 12556097Snw141292 return (rc); 12565447Snw141292 12576097Snw141292 } 12585317Sjp151216 12598361SJulian.Pullen@Sun.COM 12606097Snw141292 /* 12616097Snw141292 * This is the half of idmap_cfg_load() that auto-discovers values of 12626097Snw141292 * discoverable properties that weren't already set via SMF properties. 12636097Snw141292 * 12646097Snw141292 * idmap_cfg_discover() is called *after* idmap_cfg_load_smf(), so it 12656097Snw141292 * needs to be careful not to overwrite any properties set in SMF. 12666097Snw141292 */ 12676097Snw141292 static 12686097Snw141292 void 12696097Snw141292 idmap_cfg_discover(idmap_cfg_handles_t *handles, idmap_pg_config_t *pgcfg) 12706097Snw141292 { 12716097Snw141292 ad_disc_t ad_ctx = handles->ad_ctx; 12728361SJulian.Pullen@Sun.COM ad_disc_t trusted_ctx; 12738361SJulian.Pullen@Sun.COM int i, j, k, l; 12748361SJulian.Pullen@Sun.COM char *forestname; 12758361SJulian.Pullen@Sun.COM int num_trusteddomains; 1276*8671SJulian.Pullen@Sun.COM boolean_t new_forest; 12778361SJulian.Pullen@Sun.COM int err; 12788361SJulian.Pullen@Sun.COM char *trusteddomain; 12798361SJulian.Pullen@Sun.COM idmap_ad_disc_ds_t *globalcatalog; 12808361SJulian.Pullen@Sun.COM idmap_trustedforest_t *trustedforests; 12818361SJulian.Pullen@Sun.COM ad_disc_domainsinforest_t *domainsinforest; 12826097Snw141292 12836097Snw141292 ad_disc_refresh(ad_ctx); 12846097Snw141292 12856097Snw141292 if (pgcfg->default_domain == NULL) 12868361SJulian.Pullen@Sun.COM pgcfg->default_domain = ad_disc_get_DomainName(ad_ctx, 12878361SJulian.Pullen@Sun.COM NULL); 12885317Sjp151216 12896097Snw141292 if (pgcfg->domain_name == NULL) 12908361SJulian.Pullen@Sun.COM pgcfg->domain_name = ad_disc_get_DomainName(ad_ctx, 12918361SJulian.Pullen@Sun.COM &pgcfg->domain_name_auto_disc); 12925317Sjp151216 12936097Snw141292 if (pgcfg->domain_controller == NULL) 12945317Sjp151216 pgcfg->domain_controller = 12958361SJulian.Pullen@Sun.COM ad_disc_get_DomainController(ad_ctx, AD_DISC_PREFER_SITE, 12968361SJulian.Pullen@Sun.COM &pgcfg->domain_controller_auto_disc); 12976097Snw141292 12986097Snw141292 if (pgcfg->forest_name == NULL) 12998361SJulian.Pullen@Sun.COM pgcfg->forest_name = ad_disc_get_ForestName(ad_ctx, 13008361SJulian.Pullen@Sun.COM &pgcfg->forest_name_auto_disc); 13016097Snw141292 13026097Snw141292 if (pgcfg->site_name == NULL) 13038361SJulian.Pullen@Sun.COM pgcfg->site_name = ad_disc_get_SiteName(ad_ctx, 13048361SJulian.Pullen@Sun.COM &pgcfg->site_name_auto_disc); 13056097Snw141292 13066097Snw141292 if (pgcfg->global_catalog == NULL) 13076097Snw141292 pgcfg->global_catalog = 13088361SJulian.Pullen@Sun.COM ad_disc_get_GlobalCatalog(ad_ctx, AD_DISC_PREFER_SITE, 13098361SJulian.Pullen@Sun.COM &pgcfg->global_catalog_auto_disc); 13108361SJulian.Pullen@Sun.COM 13118361SJulian.Pullen@Sun.COM pgcfg->domains_in_forest = 13128361SJulian.Pullen@Sun.COM ad_disc_get_DomainsInForest(ad_ctx, NULL); 13138361SJulian.Pullen@Sun.COM 13148361SJulian.Pullen@Sun.COM pgcfg->trusted_domains = 13158361SJulian.Pullen@Sun.COM ad_disc_get_TrustedDomains(ad_ctx, NULL); 13168361SJulian.Pullen@Sun.COM 13178361SJulian.Pullen@Sun.COM if (pgcfg->forest_name != NULL && pgcfg->trusted_domains != NULL && 13188361SJulian.Pullen@Sun.COM pgcfg->trusted_domains[0].domain[0] != '\0') { 13198361SJulian.Pullen@Sun.COM /* 13208361SJulian.Pullen@Sun.COM * We have trusted domains. We need to go through every 13218361SJulian.Pullen@Sun.COM * one and find its forest. If it is a new forest we then need 13228361SJulian.Pullen@Sun.COM * to find its Global Catalog and the domains in the forest 13238361SJulian.Pullen@Sun.COM */ 13248361SJulian.Pullen@Sun.COM for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++) 13258361SJulian.Pullen@Sun.COM continue; 13268361SJulian.Pullen@Sun.COM num_trusteddomains = i; 13278361SJulian.Pullen@Sun.COM 13288361SJulian.Pullen@Sun.COM trustedforests = calloc(num_trusteddomains, 13298361SJulian.Pullen@Sun.COM sizeof (idmap_trustedforest_t)); 13308361SJulian.Pullen@Sun.COM j = 0; 13318361SJulian.Pullen@Sun.COM for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++) { 13328361SJulian.Pullen@Sun.COM trusteddomain = pgcfg->trusted_domains[i].domain; 13338361SJulian.Pullen@Sun.COM trusted_ctx = ad_disc_init(); 13348361SJulian.Pullen@Sun.COM ad_disc_set_DomainName(trusted_ctx, 13358361SJulian.Pullen@Sun.COM trusteddomain); 13368361SJulian.Pullen@Sun.COM forestname = 13378361SJulian.Pullen@Sun.COM ad_disc_get_ForestName(trusted_ctx, NULL); 13388361SJulian.Pullen@Sun.COM if (forestname == NULL) { 13398361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, "unable to discover " 13408361SJulian.Pullen@Sun.COM "Forest Name for the trusted domain %s", 13418361SJulian.Pullen@Sun.COM trusteddomain); 13428361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 13438361SJulian.Pullen@Sun.COM continue; 13448361SJulian.Pullen@Sun.COM } 13458361SJulian.Pullen@Sun.COM 13468361SJulian.Pullen@Sun.COM if (strcasecmp(forestname, pgcfg->forest_name) == 0) { 13478361SJulian.Pullen@Sun.COM /* 13488361SJulian.Pullen@Sun.COM * Ignore the domain as it is part of 13498361SJulian.Pullen@Sun.COM * the primary forest 13508361SJulian.Pullen@Sun.COM */ 13518361SJulian.Pullen@Sun.COM free(forestname); 13528361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 13538361SJulian.Pullen@Sun.COM continue; 13548361SJulian.Pullen@Sun.COM } 13558361SJulian.Pullen@Sun.COM 13568361SJulian.Pullen@Sun.COM /* Is this a new forest? */ 1357*8671SJulian.Pullen@Sun.COM new_forest = B_TRUE; 13588361SJulian.Pullen@Sun.COM for (k = 0; k < j; k++) { 13598361SJulian.Pullen@Sun.COM if (strcasecmp(forestname, 13608361SJulian.Pullen@Sun.COM trustedforests[k].forest_name) == 0) { 1361*8671SJulian.Pullen@Sun.COM new_forest = B_FALSE; 13628361SJulian.Pullen@Sun.COM domainsinforest = 13638361SJulian.Pullen@Sun.COM trustedforests[k].domains_in_forest; 13648361SJulian.Pullen@Sun.COM break; 13658361SJulian.Pullen@Sun.COM } 13668361SJulian.Pullen@Sun.COM } 13678361SJulian.Pullen@Sun.COM if (!new_forest) { 13688361SJulian.Pullen@Sun.COM /* Mark the domain as trusted */ 13698361SJulian.Pullen@Sun.COM for (l = 0; 13708361SJulian.Pullen@Sun.COM domainsinforest[l].domain[0] != '\0'; l++) { 13718361SJulian.Pullen@Sun.COM if (u8_strcmp(trusteddomain, 13728361SJulian.Pullen@Sun.COM domainsinforest[l].domain, 0, 13738361SJulian.Pullen@Sun.COM U8_STRCMP_CI_LOWER, 13748361SJulian.Pullen@Sun.COM U8_UNICODE_LATEST, &err) == 0 && 13758361SJulian.Pullen@Sun.COM err == 0) { 13768361SJulian.Pullen@Sun.COM domainsinforest[l].trusted = 13778361SJulian.Pullen@Sun.COM TRUE; 13788361SJulian.Pullen@Sun.COM break; 13798361SJulian.Pullen@Sun.COM } 13808361SJulian.Pullen@Sun.COM } 13818361SJulian.Pullen@Sun.COM free(forestname); 13828361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 13838361SJulian.Pullen@Sun.COM continue; 13848361SJulian.Pullen@Sun.COM } 13858361SJulian.Pullen@Sun.COM 13868361SJulian.Pullen@Sun.COM /* 13878361SJulian.Pullen@Sun.COM * Get the Global Catalog and the domains in 13888361SJulian.Pullen@Sun.COM * this new forest. 13898361SJulian.Pullen@Sun.COM */ 13908361SJulian.Pullen@Sun.COM globalcatalog = 13918361SJulian.Pullen@Sun.COM ad_disc_get_GlobalCatalog(trusted_ctx, 13928361SJulian.Pullen@Sun.COM AD_DISC_PREFER_SITE, NULL); 13938361SJulian.Pullen@Sun.COM if (globalcatalog == NULL) { 13948361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, 13958361SJulian.Pullen@Sun.COM "unable to discover Global " 13968361SJulian.Pullen@Sun.COM "Catalog for the trusted domain %s", 13978361SJulian.Pullen@Sun.COM trusteddomain); 13988361SJulian.Pullen@Sun.COM free(forestname); 13998361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 14008361SJulian.Pullen@Sun.COM continue; 14018361SJulian.Pullen@Sun.COM } 14028361SJulian.Pullen@Sun.COM domainsinforest = 14038361SJulian.Pullen@Sun.COM ad_disc_get_DomainsInForest(trusted_ctx, 14048361SJulian.Pullen@Sun.COM NULL); 14058361SJulian.Pullen@Sun.COM if (domainsinforest == NULL) { 14068361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, 14078361SJulian.Pullen@Sun.COM "unable to discover Domains in the Forest " 14088361SJulian.Pullen@Sun.COM "for the trusted domain %s", 14098361SJulian.Pullen@Sun.COM trusteddomain); 14108361SJulian.Pullen@Sun.COM free(globalcatalog); 14118361SJulian.Pullen@Sun.COM free(forestname); 14128361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 14138361SJulian.Pullen@Sun.COM continue; 14148361SJulian.Pullen@Sun.COM } 14158361SJulian.Pullen@Sun.COM 14168361SJulian.Pullen@Sun.COM trustedforests[j].forest_name = forestname; 14178361SJulian.Pullen@Sun.COM trustedforests[j].global_catalog = globalcatalog; 14188361SJulian.Pullen@Sun.COM trustedforests[j].domains_in_forest = domainsinforest; 14198361SJulian.Pullen@Sun.COM j++; 14208361SJulian.Pullen@Sun.COM /* Mark the domain as trusted */ 14218361SJulian.Pullen@Sun.COM for (l = 0; domainsinforest[l].domain[0] != '\0'; 14228361SJulian.Pullen@Sun.COM l++) { 14238361SJulian.Pullen@Sun.COM if (u8_strcmp(trusteddomain, 14248361SJulian.Pullen@Sun.COM domainsinforest[l].domain, 0, 14258361SJulian.Pullen@Sun.COM U8_STRCMP_CI_LOWER, 14268361SJulian.Pullen@Sun.COM U8_UNICODE_LATEST, &err) == 0 && 14278361SJulian.Pullen@Sun.COM err == 0) { 14288361SJulian.Pullen@Sun.COM domainsinforest[l].trusted = TRUE; 14298361SJulian.Pullen@Sun.COM break; 14308361SJulian.Pullen@Sun.COM } 14318361SJulian.Pullen@Sun.COM } 14328361SJulian.Pullen@Sun.COM ad_disc_fini(trusted_ctx); 14338361SJulian.Pullen@Sun.COM } 14348361SJulian.Pullen@Sun.COM if (j > 0) { 14358361SJulian.Pullen@Sun.COM pgcfg->num_trusted_forests = j; 14368361SJulian.Pullen@Sun.COM pgcfg->trusted_forests = trustedforests; 14378361SJulian.Pullen@Sun.COM } 14388361SJulian.Pullen@Sun.COM } 14396097Snw141292 14406097Snw141292 if (pgcfg->domain_name == NULL) 14416097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Domain Name"); 14426097Snw141292 if (pgcfg->domain_controller == NULL) 14436097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Domain Controller"); 14446097Snw141292 if (pgcfg->forest_name == NULL) 14456097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Forest Name"); 14466097Snw141292 if (pgcfg->site_name == NULL) 14476097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Site Name"); 14486097Snw141292 if (pgcfg->global_catalog == NULL) 14496097Snw141292 idmapdlog(LOG_DEBUG, "unable to discover Global Catalog"); 14508361SJulian.Pullen@Sun.COM if (pgcfg->domains_in_forest == NULL) 14518361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, 14528361SJulian.Pullen@Sun.COM "unable to discover Domains in the Forest"); 14538361SJulian.Pullen@Sun.COM if (pgcfg->trusted_domains == NULL) 14548361SJulian.Pullen@Sun.COM idmapdlog(LOG_DEBUG, "unable to discover Trusted Domains"); 14556097Snw141292 } 14565317Sjp151216 14578361SJulian.Pullen@Sun.COM 14586097Snw141292 /* 14596097Snw141292 * idmap_cfg_load() is called at startup, and periodically via the 14606097Snw141292 * update thread when the auto-discovery TTLs expire, as well as part of 14616097Snw141292 * the refresh method, to update the current configuration. It always 14626097Snw141292 * reads from SMF, but you still have to refresh the service after 14636097Snw141292 * changing the config pg in order for the changes to take effect. 14646097Snw141292 * 14656097Snw141292 * There are two flags: 14666097Snw141292 * 14676097Snw141292 * - CFG_DISCOVER 14686097Snw141292 * - CFG_LOG 14696097Snw141292 * 14706097Snw141292 * If CFG_DISCOVER is set then idmap_cfg_load() calls 14716097Snw141292 * idmap_cfg_discover() to discover, via DNS and LDAP lookups, property 14726097Snw141292 * values that weren't set in SMF. 14736097Snw141292 * 14746097Snw141292 * If CFG_LOG is set then idmap_cfg_load() will log (to LOG_NOTICE) 14756097Snw141292 * whether the configuration changed. This should be used only from the 14766097Snw141292 * refresh method. 14776097Snw141292 * 14786097Snw141292 * Return values: 0 -> success, -1 -> failure, -2 -> hard failures 14796097Snw141292 * reading from SMF. 14806097Snw141292 */ 14816097Snw141292 int 14826097Snw141292 idmap_cfg_load(idmap_cfg_t *cfg, int flags) 14836097Snw141292 { 14846097Snw141292 int rc = 0; 14856097Snw141292 int errors = 0; 14866097Snw141292 int changed = 0; 14878361SJulian.Pullen@Sun.COM int ad_reload_required = 0; 14886097Snw141292 idmap_pg_config_t new_pgcfg, *live_pgcfg; 14896097Snw141292 14906097Snw141292 live_pgcfg = &cfg->pgcfg; 14916097Snw141292 (void) memset(&new_pgcfg, 0, sizeof (new_pgcfg)); 14926097Snw141292 14936097Snw141292 pthread_mutex_lock(&cfg->handles.mutex); 14946097Snw141292 14956097Snw141292 if ((rc = idmap_cfg_load_smf(&cfg->handles, &new_pgcfg, &errors)) < -1) 14966097Snw141292 goto err; 14976097Snw141292 14986097Snw141292 if (flags & CFG_DISCOVER) 14996097Snw141292 idmap_cfg_discover(&cfg->handles, &new_pgcfg); 15006097Snw141292 15016097Snw141292 WRLOCK_CONFIG(); 15026097Snw141292 if (live_pgcfg->list_size_limit != new_pgcfg.list_size_limit) { 15036097Snw141292 idmapdlog(LOG_INFO, "change list_size=%d", 15046097Snw141292 new_pgcfg.list_size_limit); 15056097Snw141292 live_pgcfg->list_size_limit = new_pgcfg.list_size_limit; 15065317Sjp151216 } 15075317Sjp151216 15086097Snw141292 /* Non-discoverable props updated here */ 15097031Snw141292 changed += update_string(&live_pgcfg->machine_sid, 15106097Snw141292 &new_pgcfg.machine_sid, "machine_sid"); 15116097Snw141292 15127031Snw141292 changed += update_bool(&live_pgcfg->eph_map_unres_sids, 15137031Snw141292 &new_pgcfg.eph_map_unres_sids, "unresolvable_sid_mapping"); 15147031Snw141292 15156097Snw141292 changed += live_pgcfg->ds_name_mapping_enabled != 15166097Snw141292 new_pgcfg.ds_name_mapping_enabled; 15176097Snw141292 live_pgcfg->ds_name_mapping_enabled = 15186097Snw141292 new_pgcfg.ds_name_mapping_enabled; 15196097Snw141292 15207031Snw141292 changed += update_string(&live_pgcfg->ad_unixuser_attr, 15216097Snw141292 &new_pgcfg.ad_unixuser_attr, "ad_unixuser_attr"); 15226097Snw141292 15237031Snw141292 changed += update_string(&live_pgcfg->ad_unixgroup_attr, 15246097Snw141292 &new_pgcfg.ad_unixgroup_attr, "ad_unixgroup_attr"); 15256097Snw141292 15267031Snw141292 changed += update_string(&live_pgcfg->nldap_winname_attr, 15276097Snw141292 &new_pgcfg.nldap_winname_attr, "nldap_winname_attr"); 15286097Snw141292 15296097Snw141292 /* Props that can be discovered and set in SMF updated here */ 1530*8671SJulian.Pullen@Sun.COM if (!live_pgcfg->dflt_dom_set_in_smf) 15317031Snw141292 changed += update_string(&live_pgcfg->default_domain, 15326097Snw141292 &new_pgcfg.default_domain, "default_domain"); 15336097Snw141292 15347031Snw141292 changed += update_string(&live_pgcfg->domain_name, 15356097Snw141292 &new_pgcfg.domain_name, "domain_name"); 15368361SJulian.Pullen@Sun.COM live_pgcfg->domain_name_auto_disc = new_pgcfg.domain_name_auto_disc; 15376097Snw141292 15386097Snw141292 changed += update_dirs(&live_pgcfg->domain_controller, 15396097Snw141292 &new_pgcfg.domain_controller, "domain_controller"); 15408361SJulian.Pullen@Sun.COM live_pgcfg->domain_controller_auto_disc = 15418361SJulian.Pullen@Sun.COM new_pgcfg.domain_controller_auto_disc; 15426097Snw141292 15437031Snw141292 changed += update_string(&live_pgcfg->forest_name, 15446097Snw141292 &new_pgcfg.forest_name, "forest_name"); 15458361SJulian.Pullen@Sun.COM live_pgcfg->forest_name_auto_disc = new_pgcfg.forest_name_auto_disc; 15466097Snw141292 15477031Snw141292 changed += update_string(&live_pgcfg->site_name, 15486097Snw141292 &new_pgcfg.site_name, "site_name"); 15498361SJulian.Pullen@Sun.COM live_pgcfg->site_name_auto_disc = new_pgcfg.site_name_auto_disc; 15506097Snw141292 15516097Snw141292 if (update_dirs(&live_pgcfg->global_catalog, 15526097Snw141292 &new_pgcfg.global_catalog, "global_catalog")) { 15536097Snw141292 changed++; 15546097Snw141292 if (live_pgcfg->global_catalog != NULL && 15556097Snw141292 live_pgcfg->global_catalog[0].host[0] != '\0') 15568361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 15578361SJulian.Pullen@Sun.COM } 15588361SJulian.Pullen@Sun.COM live_pgcfg->global_catalog_auto_disc = 15598361SJulian.Pullen@Sun.COM new_pgcfg.global_catalog_auto_disc; 15608361SJulian.Pullen@Sun.COM 15618361SJulian.Pullen@Sun.COM if (update_domains_in_forest(&live_pgcfg->domains_in_forest, 15628361SJulian.Pullen@Sun.COM &new_pgcfg.domains_in_forest, "domains_in_forest")) { 15638361SJulian.Pullen@Sun.COM changed++; 15648361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 15655317Sjp151216 } 15665317Sjp151216 15678361SJulian.Pullen@Sun.COM if (update_trusted_domains(&live_pgcfg->trusted_domains, 15688361SJulian.Pullen@Sun.COM &new_pgcfg.trusted_domains, "trusted_domains")) { 15698361SJulian.Pullen@Sun.COM changed++; 15708361SJulian.Pullen@Sun.COM if (live_pgcfg->trusted_domains != NULL && 15718361SJulian.Pullen@Sun.COM live_pgcfg->trusted_domains[0].domain[0] != '\0') 15728361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 15738361SJulian.Pullen@Sun.COM } 15748361SJulian.Pullen@Sun.COM 15758361SJulian.Pullen@Sun.COM if (update_trusted_forest(&live_pgcfg->trusted_forests, 15768361SJulian.Pullen@Sun.COM &live_pgcfg->num_trusted_forests, &new_pgcfg.trusted_forests, 15778361SJulian.Pullen@Sun.COM &new_pgcfg.num_trusted_forests, "trusted_forest")) { 15788361SJulian.Pullen@Sun.COM changed++; 15798361SJulian.Pullen@Sun.COM if (live_pgcfg->trusted_forests != NULL) 15808361SJulian.Pullen@Sun.COM ad_reload_required = TRUE; 15818361SJulian.Pullen@Sun.COM } 15828361SJulian.Pullen@Sun.COM 15838361SJulian.Pullen@Sun.COM if (ad_reload_required) 15848361SJulian.Pullen@Sun.COM reload_ad(); 15858361SJulian.Pullen@Sun.COM 15866097Snw141292 idmap_cfg_unload(&new_pgcfg); 15876097Snw141292 15886097Snw141292 if (flags & CFG_LOG) { 15896097Snw141292 /* 15906097Snw141292 * If the config changes as a result of a refresh of the 15916097Snw141292 * service, then logging about it can provide useful 15926097Snw141292 * feedback to the sysadmin. 15936097Snw141292 */ 15946097Snw141292 idmapdlog(LOG_NOTICE, "Configuration %schanged", 15956097Snw141292 changed ? "" : "un"); 15965317Sjp151216 } 15975447Snw141292 15986097Snw141292 UNLOCK_CONFIG(); 15996097Snw141292 16006097Snw141292 err: 16016097Snw141292 pthread_mutex_unlock(&cfg->handles.mutex); 16024520Snw141292 16035731Sbaban if (rc < -1) 16045447Snw141292 return (rc); 16055447Snw141292 16065447Snw141292 return ((errors == 0) ? 0 : -1); 16074520Snw141292 } 16084520Snw141292 16094644Sbaban /* 16104644Sbaban * Initialize 'cfg'. 16114644Sbaban */ 16124520Snw141292 idmap_cfg_t * 16135908Sjp151216 idmap_cfg_init() 16145908Sjp151216 { 16155317Sjp151216 idmap_cfg_handles_t *handles; 16164520Snw141292 16174520Snw141292 /* First the smf repository handles: */ 16184520Snw141292 idmap_cfg_t *cfg = calloc(1, sizeof (idmap_cfg_t)); 16194520Snw141292 if (!cfg) { 16206017Snw141292 idmapdlog(LOG_ERR, "Out of memory"); 16214520Snw141292 return (NULL); 16224520Snw141292 } 16235317Sjp151216 handles = &cfg->handles; 16244520Snw141292 16255317Sjp151216 (void) pthread_mutex_init(&handles->mutex, NULL); 16265317Sjp151216 16275317Sjp151216 if (!(handles->main = scf_handle_create(SCF_VERSION))) { 16286017Snw141292 idmapdlog(LOG_ERR, "scf_handle_create() failed: %s", 16296017Snw141292 scf_strerror(scf_error())); 16304520Snw141292 goto error; 16314520Snw141292 } 16324520Snw141292 16335317Sjp151216 if (scf_handle_bind(handles->main) < 0) { 16346017Snw141292 idmapdlog(LOG_ERR, "scf_handle_bind() failed: %s", 16356017Snw141292 scf_strerror(scf_error())); 16364520Snw141292 goto error; 16374520Snw141292 } 16384520Snw141292 16395317Sjp151216 if (!(handles->service = scf_service_create(handles->main)) || 16405317Sjp151216 !(handles->instance = scf_instance_create(handles->main)) || 16415317Sjp151216 !(handles->config_pg = scf_pg_create(handles->main)) || 16425317Sjp151216 !(handles->general_pg = scf_pg_create(handles->main))) { 16436017Snw141292 idmapdlog(LOG_ERR, "scf handle creation failed: %s", 16446017Snw141292 scf_strerror(scf_error())); 16454520Snw141292 goto error; 16464520Snw141292 } 16474520Snw141292 16485317Sjp151216 if (scf_handle_decode_fmri(handles->main, 16495908Sjp151216 FMRI_BASE "/:properties/" CONFIG_PG, 16505908Sjp151216 NULL, /* scope */ 16515908Sjp151216 handles->service, /* service */ 16525908Sjp151216 handles->instance, /* instance */ 16535908Sjp151216 handles->config_pg, /* pg */ 16545908Sjp151216 NULL, /* prop */ 16555908Sjp151216 SCF_DECODE_FMRI_EXACT) < 0) { 16566017Snw141292 idmapdlog(LOG_ERR, "scf_handle_decode_fmri() failed: %s", 16576017Snw141292 scf_strerror(scf_error())); 16584520Snw141292 goto error; 16594520Snw141292 } 16604520Snw141292 16615317Sjp151216 if (scf_service_get_pg(handles->service, 16625908Sjp151216 GENERAL_PG, handles->general_pg) < 0) { 16636017Snw141292 idmapdlog(LOG_ERR, "scf_service_get_pg() failed: %s", 16646017Snw141292 scf_strerror(scf_error())); 16654520Snw141292 goto error; 16664520Snw141292 } 16674520Snw141292 16685317Sjp151216 /* Initialize AD Auto Discovery context */ 16695317Sjp151216 handles->ad_ctx = ad_disc_init(); 16705317Sjp151216 if (handles->ad_ctx == NULL) 16715317Sjp151216 goto error; 16725317Sjp151216 16734520Snw141292 return (cfg); 16744520Snw141292 16754520Snw141292 error: 16764520Snw141292 (void) idmap_cfg_fini(cfg); 16774520Snw141292 return (NULL); 16784520Snw141292 } 16794520Snw141292 16805317Sjp151216 void 16815908Sjp151216 idmap_cfg_unload(idmap_pg_config_t *pgcfg) 16825908Sjp151216 { 16835317Sjp151216 16845317Sjp151216 if (pgcfg->default_domain) { 16855317Sjp151216 free(pgcfg->default_domain); 16865317Sjp151216 pgcfg->default_domain = NULL; 16875317Sjp151216 } 16885317Sjp151216 if (pgcfg->domain_name) { 16895317Sjp151216 free(pgcfg->domain_name); 16905317Sjp151216 pgcfg->domain_name = NULL; 16915317Sjp151216 } 16925317Sjp151216 if (pgcfg->machine_sid) { 16935317Sjp151216 free(pgcfg->machine_sid); 16945317Sjp151216 pgcfg->machine_sid = NULL; 16955317Sjp151216 } 16965317Sjp151216 if (pgcfg->domain_controller) { 16975317Sjp151216 free(pgcfg->domain_controller); 16985317Sjp151216 pgcfg->domain_controller = NULL; 16995317Sjp151216 } 17005317Sjp151216 if (pgcfg->forest_name) { 17015317Sjp151216 free(pgcfg->forest_name); 17025317Sjp151216 pgcfg->forest_name = NULL; 17035317Sjp151216 } 17045317Sjp151216 if (pgcfg->site_name) { 17055317Sjp151216 free(pgcfg->site_name); 17065317Sjp151216 pgcfg->site_name = NULL; 17075317Sjp151216 } 17085317Sjp151216 if (pgcfg->global_catalog) { 17094520Snw141292 free(pgcfg->global_catalog); 17105317Sjp151216 pgcfg->global_catalog = NULL; 17115317Sjp151216 } 17128361SJulian.Pullen@Sun.COM if (pgcfg->trusted_domains) { 17138361SJulian.Pullen@Sun.COM free(pgcfg->trusted_domains); 17148361SJulian.Pullen@Sun.COM pgcfg->trusted_domains = NULL; 17158361SJulian.Pullen@Sun.COM } 17168361SJulian.Pullen@Sun.COM if (pgcfg->trusted_forests) 17178361SJulian.Pullen@Sun.COM free_trusted_forests(&pgcfg->trusted_forests, 17188361SJulian.Pullen@Sun.COM &pgcfg->num_trusted_forests); 17198361SJulian.Pullen@Sun.COM 17205731Sbaban if (pgcfg->ad_unixuser_attr) { 17215731Sbaban free(pgcfg->ad_unixuser_attr); 17225731Sbaban pgcfg->ad_unixuser_attr = NULL; 17235731Sbaban } 17245731Sbaban if (pgcfg->ad_unixgroup_attr) { 17255731Sbaban free(pgcfg->ad_unixgroup_attr); 17265731Sbaban pgcfg->ad_unixgroup_attr = NULL; 17275731Sbaban } 17285731Sbaban if (pgcfg->nldap_winname_attr) { 17295731Sbaban free(pgcfg->nldap_winname_attr); 17305731Sbaban pgcfg->nldap_winname_attr = NULL; 17315731Sbaban } 17324520Snw141292 } 17334520Snw141292 17344520Snw141292 int 17354520Snw141292 idmap_cfg_fini(idmap_cfg_t *cfg) 17364520Snw141292 { 17375317Sjp151216 idmap_cfg_handles_t *handles = &cfg->handles; 17385317Sjp151216 idmap_cfg_unload(&cfg->pgcfg); 17394520Snw141292 17405317Sjp151216 (void) pthread_mutex_destroy(&handles->mutex); 17415317Sjp151216 scf_pg_destroy(handles->config_pg); 17425317Sjp151216 scf_pg_destroy(handles->general_pg); 17435317Sjp151216 scf_instance_destroy(handles->instance); 17445317Sjp151216 scf_service_destroy(handles->service); 17455317Sjp151216 scf_handle_destroy(handles->main); 17465731Sbaban if (handles->ad_ctx != NULL) 17475731Sbaban ad_disc_fini(handles->ad_ctx); 17484520Snw141292 free(cfg); 17494520Snw141292 17504520Snw141292 return (0); 17514520Snw141292 } 17525968Snw141292 17535968Snw141292 void 17545968Snw141292 idmap_cfg_poke_updates(void) 17555968Snw141292 { 17566097Snw141292 if (idmapd_ev_port != -1) 17576097Snw141292 (void) port_send(idmapd_ev_port, POKE_AUTO_DISCOVERY, NULL); 17585968Snw141292 } 17595968Snw141292 17605968Snw141292 /*ARGSUSED*/ 17615968Snw141292 void 17626097Snw141292 idmap_cfg_hup_handler(int sig) 17636097Snw141292 { 17645968Snw141292 if (idmapd_ev_port >= 0) 17655968Snw141292 (void) port_send(idmapd_ev_port, RECONFIGURE, NULL); 17665968Snw141292 } 1767