1c5c4113dSnw /* 2c5c4113dSnw * CDDL HEADER START 3c5c4113dSnw * 4c5c4113dSnw * The contents of this file are subject to the terms of the 5c5c4113dSnw * Common Development and Distribution License (the "License"). 6c5c4113dSnw * You may not use this file except in compliance with the License. 7c5c4113dSnw * 8c5c4113dSnw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9c5c4113dSnw * or http://www.opensolaris.org/os/licensing. 10c5c4113dSnw * See the License for the specific language governing permissions 11c5c4113dSnw * and limitations under the License. 12c5c4113dSnw * 13c5c4113dSnw * When distributing Covered Code, include this CDDL HEADER in each 14c5c4113dSnw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15c5c4113dSnw * If applicable, add the following below this CDDL HEADER, with the 16c5c4113dSnw * fields enclosed by brackets "[]" replaced with your own identifying 17c5c4113dSnw * information: Portions Copyright [yyyy] [name of copyright owner] 18c5c4113dSnw * 19c5c4113dSnw * CDDL HEADER END 20c5c4113dSnw */ 21c5c4113dSnw /* 22c5c4113dSnw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23c5c4113dSnw * Use is subject to license terms. 24c5c4113dSnw */ 25c5c4113dSnw 26c5c4113dSnw #pragma ident "%Z%%M% %I% %E% SMI" 27c5c4113dSnw 28c5c4113dSnw /* 29c5c4113dSnw * Config routines common to idmap(1M) and idmapd(1M) 30c5c4113dSnw */ 31c5c4113dSnw 32c5c4113dSnw #include <stdlib.h> 33c5c4113dSnw #include <synch.h> 34c5c4113dSnw #include <assert.h> 35c5c4113dSnw #include <sys/varargs.h> 36c5c4113dSnw #include <sys/systeminfo.h> 37c5c4113dSnw #include <strings.h> 38c5c4113dSnw #include <libintl.h> 39c5c4113dSnw #include <ctype.h> 40c5c4113dSnw #include <errno.h> 41651c0131Sbaban #include "idmapd.h" 42c5c4113dSnw #include <stdio.h> 43c5c4113dSnw #include <stdarg.h> 44*8edda628Sbaban #include <uuid/uuid.h> 45c5c4113dSnw 46*8edda628Sbaban #define MACHINE_SID_LEN (9 + UUID_LEN/4 * 11) 47c5c4113dSnw #define FMRI_BASE "svc:/system/idmap" 48c5c4113dSnw #define CONFIG_PG "config" 49c5c4113dSnw #define GENERAL_PG "general" 50c5c4113dSnw /* initial length of the array for policy options/attributes: */ 51c5c4113dSnw #define DEF_ARRAY_LENGTH 16 52c5c4113dSnw 53651c0131Sbaban static const char *me = "idmapd"; 54c5c4113dSnw 55*8edda628Sbaban static int 56*8edda628Sbaban generate_machine_sid(char **machine_sid) { 57*8edda628Sbaban char *p; 58*8edda628Sbaban uuid_t uu; 59*8edda628Sbaban int i, j, len, rlen; 60*8edda628Sbaban uint32_t rid; 61*8edda628Sbaban 62*8edda628Sbaban /* 63*8edda628Sbaban * Generate and split 128-bit UUID into four 32-bit RIDs 64*8edda628Sbaban * The machine_sid will be of the form S-1-5-N1-N2-N3-N4 65*8edda628Sbaban * We depart from Windows here, which instead of 128 66*8edda628Sbaban * bits worth of random numbers uses 96 bits. 67*8edda628Sbaban */ 68*8edda628Sbaban 69*8edda628Sbaban *machine_sid = calloc(1, MACHINE_SID_LEN); 70*8edda628Sbaban if (*machine_sid == NULL) { 71*8edda628Sbaban idmapdlog(LOG_ERR, "%s: Out of memory", me); 72*8edda628Sbaban return (-1); 73*8edda628Sbaban } 74*8edda628Sbaban (void) strcpy(*machine_sid, "S-1-5-21"); 75*8edda628Sbaban p = *machine_sid + strlen("S-1-5-21"); 76*8edda628Sbaban len = MACHINE_SID_LEN - strlen("S-1-5-21"); 77*8edda628Sbaban 78*8edda628Sbaban uuid_clear(uu); 79*8edda628Sbaban uuid_generate_random(uu); 80*8edda628Sbaban 81*8edda628Sbaban for (i = 0; i < UUID_LEN/4; i++) { 82*8edda628Sbaban j = i * 4; 83*8edda628Sbaban rid = (uu[j] << 24) | (uu[j + 1] << 16) | 84*8edda628Sbaban (uu[j + 2] << 8) | (uu[j + 3]); 85*8edda628Sbaban rlen = snprintf(p, len, "-%u", rid); 86*8edda628Sbaban p += rlen; 87*8edda628Sbaban len -= rlen; 88*8edda628Sbaban } 89*8edda628Sbaban 90*8edda628Sbaban return (0); 91*8edda628Sbaban } 92*8edda628Sbaban 93c5c4113dSnw /* Check if in the case of failure the original value of *val is preserved */ 94c5c4113dSnw static int 95c5c4113dSnw get_val_int(idmap_cfg_t *cfg, char *name, void *val, scf_type_t type) 96c5c4113dSnw { 97c5c4113dSnw int rc = 0; 98c5c4113dSnw 99c5c4113dSnw scf_property_t *scf_prop = scf_property_create(cfg->handles.main); 100c5c4113dSnw scf_value_t *value = scf_value_create(cfg->handles.main); 101c5c4113dSnw 102c5c4113dSnw 103c5c4113dSnw if (0 > scf_pg_get_property(cfg->handles.config_pg, name, scf_prop)) 104c5c4113dSnw /* this is OK: the property is just undefined */ 105c5c4113dSnw goto destruction; 106c5c4113dSnw 107c5c4113dSnw 108c5c4113dSnw if (0 > scf_property_get_value(scf_prop, value)) 109c5c4113dSnw /* It is still OK when a property doesn't have any value */ 110c5c4113dSnw goto destruction; 111c5c4113dSnw 112c5c4113dSnw switch (type) { 113c5c4113dSnw case SCF_TYPE_BOOLEAN: 114c5c4113dSnw rc = scf_value_get_boolean(value, val); 115c5c4113dSnw break; 116c5c4113dSnw case SCF_TYPE_COUNT: 117c5c4113dSnw rc = scf_value_get_count(value, val); 118c5c4113dSnw break; 119c5c4113dSnw case SCF_TYPE_INTEGER: 120c5c4113dSnw rc = scf_value_get_integer(value, val); 121c5c4113dSnw break; 122c5c4113dSnw default: 123651c0131Sbaban idmapdlog(LOG_ERR, "%s: Invalid scf integer type (%d)", 124651c0131Sbaban me, type); 125c5c4113dSnw rc = -1; 126c5c4113dSnw break; 127c5c4113dSnw } 128c5c4113dSnw 129c5c4113dSnw 130c5c4113dSnw destruction: 131c5c4113dSnw scf_value_destroy(value); 132c5c4113dSnw scf_property_destroy(scf_prop); 133c5c4113dSnw 134c5c4113dSnw return (rc); 135c5c4113dSnw } 136c5c4113dSnw 137c5c4113dSnw static char * 138c5c4113dSnw scf_value2string(scf_value_t *value) { 139c5c4113dSnw int rc = -1; 140c5c4113dSnw char buf_size = 127; 141c5c4113dSnw int length; 142c5c4113dSnw char *buf = NULL; 143c5c4113dSnw buf = (char *) malloc(sizeof (char) * buf_size); 144c5c4113dSnw 145c5c4113dSnw for (;;) { 146c5c4113dSnw length = scf_value_get_astring(value, buf, buf_size); 147c5c4113dSnw if (length < 0) { 148c5c4113dSnw rc = -1; 149c5c4113dSnw goto destruction; 150c5c4113dSnw } 151c5c4113dSnw 152c5c4113dSnw if (length == buf_size - 1) { 153c5c4113dSnw buf_size *= 2; 154c5c4113dSnw buf = (char *)realloc(buf, buf_size * sizeof (char)); 155c5c4113dSnw if (!buf) { 156651c0131Sbaban idmapdlog(LOG_ERR, "%s: Out of memory", me); 157c5c4113dSnw rc = -1; 158c5c4113dSnw goto destruction; 159c5c4113dSnw } 160c5c4113dSnw } else { 161c5c4113dSnw rc = 0; 162c5c4113dSnw break; 163c5c4113dSnw } 164c5c4113dSnw } 165c5c4113dSnw 166c5c4113dSnw destruction: 167c5c4113dSnw if (rc < 0) { 168c5c4113dSnw if (buf) 169c5c4113dSnw free(buf); 170c5c4113dSnw buf = NULL; 171c5c4113dSnw } 172c5c4113dSnw 173c5c4113dSnw return (buf); 174c5c4113dSnw } 175c5c4113dSnw 176c5c4113dSnw 177c5c4113dSnw static int 178c5c4113dSnw get_val_astring(idmap_cfg_t *cfg, char *name, char **val) 179c5c4113dSnw { 180c5c4113dSnw int rc = 0; 181c5c4113dSnw 182c5c4113dSnw scf_property_t *scf_prop = scf_property_create(cfg->handles.main); 183c5c4113dSnw scf_value_t *value = scf_value_create(cfg->handles.main); 184c5c4113dSnw 185c5c4113dSnw 186c5c4113dSnw if (0 > scf_pg_get_property(cfg->handles.config_pg, name, scf_prop)) 187c5c4113dSnw /* this is OK: the property is just undefined */ 188c5c4113dSnw goto destruction; 189c5c4113dSnw 190c5c4113dSnw if (0 > scf_property_get_value(scf_prop, value)) { 191651c0131Sbaban idmapdlog(LOG_ERR, 192651c0131Sbaban "%s: scf_property_get_value(%s) failed: %s", 193651c0131Sbaban me, name, scf_strerror(scf_error())); 194c5c4113dSnw rc = -1; 195c5c4113dSnw goto destruction; 196c5c4113dSnw } 197c5c4113dSnw 198c5c4113dSnw if (!(*val = scf_value2string(value))) { 199c5c4113dSnw rc = -1; 200651c0131Sbaban idmapdlog(LOG_ERR, 201651c0131Sbaban "%s: scf_value2string(%s) failed: %s", 202651c0131Sbaban me, name, scf_strerror(scf_error())); 203c5c4113dSnw } 204c5c4113dSnw 205c5c4113dSnw destruction: 206c5c4113dSnw scf_value_destroy(value); 207c5c4113dSnw scf_property_destroy(scf_prop); 208c5c4113dSnw 209c5c4113dSnw if (rc < 0) { 210c5c4113dSnw if (*val) 211c5c4113dSnw free(*val); 212c5c4113dSnw *val = NULL; 213c5c4113dSnw } 214c5c4113dSnw 215c5c4113dSnw return (rc); 216c5c4113dSnw } 217c5c4113dSnw 218*8edda628Sbaban static int 219*8edda628Sbaban set_val_astring(idmap_cfg_t *cfg, char *name, const char *val) 220*8edda628Sbaban { 221*8edda628Sbaban int rc = 0, i; 222*8edda628Sbaban scf_property_t *scf_prop = NULL; 223*8edda628Sbaban scf_value_t *value = NULL; 224*8edda628Sbaban scf_transaction_t *tx = NULL; 225*8edda628Sbaban scf_transaction_entry_t *ent = NULL; 226*8edda628Sbaban 227*8edda628Sbaban if ((scf_prop = scf_property_create(cfg->handles.main)) == NULL || 228*8edda628Sbaban (value = scf_value_create(cfg->handles.main)) == NULL || 229*8edda628Sbaban (tx = scf_transaction_create(cfg->handles.main)) == NULL || 230*8edda628Sbaban (ent = scf_entry_create(cfg->handles.main)) == NULL) { 231*8edda628Sbaban idmapdlog(LOG_ERR, "%s: Unable to set property %s: %s", 232*8edda628Sbaban me, name, scf_strerror(scf_error())); 233*8edda628Sbaban rc = -1; 234*8edda628Sbaban goto destruction; 235*8edda628Sbaban } 236*8edda628Sbaban 237*8edda628Sbaban for (i = 0; i < MAX_TRIES && rc == 0; i++) { 238*8edda628Sbaban if (scf_transaction_start(tx, cfg->handles.config_pg) == -1) { 239*8edda628Sbaban idmapdlog(LOG_ERR, 240*8edda628Sbaban "%s: scf_transaction_start(%s) failed: %s", 241*8edda628Sbaban me, name, scf_strerror(scf_error())); 242*8edda628Sbaban rc = -1; 243*8edda628Sbaban goto destruction; 244*8edda628Sbaban } 245*8edda628Sbaban 246*8edda628Sbaban rc = scf_transaction_property_new(tx, ent, name, 247*8edda628Sbaban SCF_TYPE_ASTRING); 248*8edda628Sbaban if (rc == -1) { 249*8edda628Sbaban idmapdlog(LOG_ERR, 250*8edda628Sbaban "%s: scf_transaction_property_new() failed: %s", 251*8edda628Sbaban me, scf_strerror(scf_error())); 252*8edda628Sbaban goto destruction; 253*8edda628Sbaban } 254*8edda628Sbaban 255*8edda628Sbaban if (scf_value_set_astring(value, val) == -1) { 256*8edda628Sbaban idmapdlog(LOG_ERR, 257*8edda628Sbaban "%s: scf_value_set_astring() failed: %s", 258*8edda628Sbaban me, scf_strerror(scf_error())); 259*8edda628Sbaban rc = -1; 260*8edda628Sbaban goto destruction; 261*8edda628Sbaban } 262*8edda628Sbaban 263*8edda628Sbaban if (scf_entry_add_value(ent, value) == -1) { 264*8edda628Sbaban idmapdlog(LOG_ERR, 265*8edda628Sbaban "%s: scf_entry_add_value() failed: %s", 266*8edda628Sbaban me, scf_strerror(scf_error())); 267*8edda628Sbaban rc = -1; 268*8edda628Sbaban goto destruction; 269*8edda628Sbaban } 270*8edda628Sbaban 271*8edda628Sbaban rc = scf_transaction_commit(tx); 272*8edda628Sbaban if (rc == 0 && i < MAX_TRIES - 1) { 273*8edda628Sbaban /* 274*8edda628Sbaban * Property group set in scf_transaction_start() 275*8edda628Sbaban * is not the most recent. Update pg, reset tx and 276*8edda628Sbaban * retry tx. 277*8edda628Sbaban */ 278*8edda628Sbaban idmapdlog(LOG_WARNING, 279*8edda628Sbaban "%s: scf_transaction_commit(%s) failed - Retry: %s", 280*8edda628Sbaban me, name, scf_strerror(scf_error())); 281*8edda628Sbaban if (scf_pg_update(cfg->handles.config_pg) == -1) { 282*8edda628Sbaban idmapdlog(LOG_ERR, 283*8edda628Sbaban "%s: scf_pg_update() failed: %s", 284*8edda628Sbaban me, scf_strerror(scf_error())); 285*8edda628Sbaban rc = -1; 286*8edda628Sbaban goto destruction; 287*8edda628Sbaban } 288*8edda628Sbaban scf_transaction_reset(tx); 289*8edda628Sbaban } 290*8edda628Sbaban } 291*8edda628Sbaban 292*8edda628Sbaban /* Log failure message if all retries failed */ 293*8edda628Sbaban if (rc == 0) { 294*8edda628Sbaban idmapdlog(LOG_ERR, 295*8edda628Sbaban "%s: scf_transaction_commit(%s) failed: %s", 296*8edda628Sbaban me, name, scf_strerror(scf_error())); 297*8edda628Sbaban rc = -1; 298*8edda628Sbaban } 299*8edda628Sbaban 300*8edda628Sbaban destruction: 301*8edda628Sbaban scf_value_destroy(value); 302*8edda628Sbaban scf_entry_destroy(ent); 303*8edda628Sbaban scf_transaction_destroy(tx); 304*8edda628Sbaban scf_property_destroy(scf_prop); 305*8edda628Sbaban return (rc); 306*8edda628Sbaban } 307*8edda628Sbaban 308c5c4113dSnw int 309c5c4113dSnw idmap_cfg_load(idmap_cfg_t *cfg) 310c5c4113dSnw { 311c5c4113dSnw int rc = 0; 312c5c4113dSnw 313c5c4113dSnw cfg->pgcfg.list_size_limit = 0; 314c5c4113dSnw cfg->pgcfg.mapping_domain = NULL; 315c5c4113dSnw cfg->pgcfg.machine_sid = NULL; 316c5c4113dSnw cfg->pgcfg.domain_controller = NULL; 317c5c4113dSnw cfg->pgcfg.global_catalog = NULL; 318c5c4113dSnw 319c5c4113dSnw if (0 > scf_pg_update(cfg->handles.config_pg)) { 320651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf_pg_update() failed: %s", 321651c0131Sbaban me, scf_strerror(scf_error())); 322c5c4113dSnw return (-1); 323c5c4113dSnw } 324c5c4113dSnw 325c5c4113dSnw if (0 > scf_pg_update(cfg->handles.general_pg)) { 326651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf_pg_update() failed: %s", 327651c0131Sbaban me, scf_strerror(scf_error())); 328c5c4113dSnw return (-1); 329c5c4113dSnw } 330c5c4113dSnw 331c5c4113dSnw rc = get_val_int(cfg, "list_size_limit", 332c5c4113dSnw &cfg->pgcfg.list_size_limit, SCF_TYPE_COUNT); 333c5c4113dSnw if (rc != 0) 334c5c4113dSnw return (-1); 335c5c4113dSnw 336c5c4113dSnw rc = get_val_astring(cfg, "mapping_domain", 337c5c4113dSnw &cfg->pgcfg.mapping_domain); 338c5c4113dSnw if (rc != 0) 339c5c4113dSnw return (-1); 340c5c4113dSnw 341c5c4113dSnw /* 342c5c4113dSnw * If there is no mapping_domain in idmap's smf config then 343c5c4113dSnw * set it to the joined domain. 344c5c4113dSnw * Till domain join is implemented, temporarily set it to 345c5c4113dSnw * the system domain for testing purposes. 346c5c4113dSnw */ 347c5c4113dSnw if (!cfg->pgcfg.mapping_domain) { 348c5c4113dSnw char test[1]; 349c5c4113dSnw long dname_size = sysinfo(SI_SRPC_DOMAIN, test, 1); 350c5c4113dSnw if (dname_size > 0) { 351c5c4113dSnw cfg->pgcfg.mapping_domain = 352c5c4113dSnw (char *)malloc(dname_size * sizeof (char)); 353c5c4113dSnw dname_size = sysinfo(SI_SRPC_DOMAIN, 354c5c4113dSnw cfg->pgcfg.mapping_domain, dname_size); 355c5c4113dSnw } 356c5c4113dSnw if (dname_size <= 0) { 357651c0131Sbaban idmapdlog(LOG_ERR, 358651c0131Sbaban "%s: unable to get name service domain", me); 359c5c4113dSnw if (cfg->pgcfg.mapping_domain) 360c5c4113dSnw free(cfg->pgcfg.mapping_domain); 361c5c4113dSnw cfg->pgcfg.mapping_domain = NULL; 362c5c4113dSnw } 363c5c4113dSnw } 364c5c4113dSnw 365c5c4113dSnw rc = get_val_astring(cfg, "machine_sid", &cfg->pgcfg.machine_sid); 366c5c4113dSnw if (rc != 0) 367c5c4113dSnw return (-1); 368*8edda628Sbaban if (cfg->pgcfg.machine_sid == NULL) { 369*8edda628Sbaban /* If machine_sid not configured, generate one */ 370*8edda628Sbaban if (generate_machine_sid(&cfg->pgcfg.machine_sid) < 0) 371*8edda628Sbaban return (-1); 372*8edda628Sbaban rc = set_val_astring(cfg, "machine_sid", 373*8edda628Sbaban cfg->pgcfg.machine_sid); 374*8edda628Sbaban if (rc < 0) { 375*8edda628Sbaban free(cfg->pgcfg.machine_sid); 376*8edda628Sbaban cfg->pgcfg.machine_sid = NULL; 377*8edda628Sbaban return (-1); 378*8edda628Sbaban } 379*8edda628Sbaban } 380c5c4113dSnw 381c5c4113dSnw rc = get_val_astring(cfg, "global_catalog", &cfg->pgcfg.global_catalog); 382c5c4113dSnw if (rc != 0) 383c5c4113dSnw return (-1); 384c5c4113dSnw 385c5c4113dSnw rc = get_val_astring(cfg, "domain_controller", 386c5c4113dSnw &cfg->pgcfg.domain_controller); 387c5c4113dSnw if (rc != 0) 388c5c4113dSnw return (-1); 389c5c4113dSnw 390c5c4113dSnw return (rc); 391c5c4113dSnw } 392c5c4113dSnw 393651c0131Sbaban /* 394651c0131Sbaban * Initialize 'cfg'. 395651c0131Sbaban */ 396c5c4113dSnw idmap_cfg_t * 397c5c4113dSnw idmap_cfg_init() { 398c5c4113dSnw 399c5c4113dSnw /* First the smf repository handles: */ 400c5c4113dSnw idmap_cfg_t *cfg = calloc(1, sizeof (idmap_cfg_t)); 401c5c4113dSnw if (!cfg) { 402651c0131Sbaban idmapdlog(LOG_ERR, "%s: Out of memory", me); 403c5c4113dSnw return (NULL); 404c5c4113dSnw } 405c5c4113dSnw 406c5c4113dSnw if (!(cfg->handles.main = scf_handle_create(SCF_VERSION))) { 407651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf_handle_create() failed: %s", 408651c0131Sbaban me, scf_strerror(scf_error())); 409c5c4113dSnw goto error; 410c5c4113dSnw } 411c5c4113dSnw 412c5c4113dSnw if (0 > scf_handle_bind(cfg->handles.main)) { 413651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf_handle_bind() failed: %s", 414651c0131Sbaban me, scf_strerror(scf_error())); 415c5c4113dSnw goto error; 416c5c4113dSnw } 417c5c4113dSnw 418c5c4113dSnw if (!(cfg->handles.service = scf_service_create(cfg->handles.main)) || 419c5c4113dSnw !(cfg->handles.instance = scf_instance_create(cfg->handles.main)) || 420c5c4113dSnw !(cfg->handles.config_pg = scf_pg_create(cfg->handles.main)) || 421c5c4113dSnw !(cfg->handles.general_pg = scf_pg_create(cfg->handles.main))) { 422651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf handle creation failed: %s", 423651c0131Sbaban me, scf_strerror(scf_error())); 424c5c4113dSnw goto error; 425c5c4113dSnw } 426c5c4113dSnw 427c5c4113dSnw if (0 > scf_handle_decode_fmri(cfg->handles.main, 428c5c4113dSnw FMRI_BASE "/:properties/" CONFIG_PG, 429c5c4113dSnw NULL, /* scope */ 430c5c4113dSnw cfg->handles.service, /* service */ 431c5c4113dSnw cfg->handles.instance, /* instance */ 432c5c4113dSnw cfg->handles.config_pg, /* pg */ 433c5c4113dSnw NULL, /* prop */ 434c5c4113dSnw SCF_DECODE_FMRI_EXACT)) { 435651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf_handle_decode_fmri() failed: %s", 436651c0131Sbaban me, scf_strerror(scf_error())); 437c5c4113dSnw goto error; 438c5c4113dSnw 439c5c4113dSnw } 440c5c4113dSnw 441c5c4113dSnw if (0 > scf_service_get_pg(cfg->handles.service, 442c5c4113dSnw GENERAL_PG, cfg->handles.general_pg)) { 443651c0131Sbaban idmapdlog(LOG_ERR, "%s: scf_service_get_pg() failed: %s", 444651c0131Sbaban me, scf_strerror(scf_error())); 445c5c4113dSnw goto error; 446c5c4113dSnw } 447c5c4113dSnw 448c5c4113dSnw return (cfg); 449c5c4113dSnw 450c5c4113dSnw error: 451c5c4113dSnw (void) idmap_cfg_fini(cfg); 452c5c4113dSnw return (NULL); 453c5c4113dSnw } 454c5c4113dSnw 455c5c4113dSnw /* ARGSUSED */ 456c5c4113dSnw static void 457c5c4113dSnw idmap_pgcfg_fini(idmap_pg_config_t *pgcfg) { 458c5c4113dSnw if (pgcfg->mapping_domain) 459c5c4113dSnw free(pgcfg->mapping_domain); 460c5c4113dSnw if (pgcfg->machine_sid) 461c5c4113dSnw free(pgcfg->mapping_domain); 462c5c4113dSnw if (pgcfg->global_catalog) 463c5c4113dSnw free(pgcfg->global_catalog); 464c5c4113dSnw if (pgcfg->domain_controller) 465c5c4113dSnw free(pgcfg->domain_controller); 466c5c4113dSnw } 467c5c4113dSnw 468c5c4113dSnw int 469c5c4113dSnw idmap_cfg_fini(idmap_cfg_t *cfg) 470c5c4113dSnw { 471c5c4113dSnw idmap_pgcfg_fini(&cfg->pgcfg); 472c5c4113dSnw 473c5c4113dSnw scf_pg_destroy(cfg->handles.config_pg); 474c5c4113dSnw scf_pg_destroy(cfg->handles.general_pg); 475c5c4113dSnw scf_instance_destroy(cfg->handles.instance); 476c5c4113dSnw scf_service_destroy(cfg->handles.service); 477c5c4113dSnw scf_handle_destroy(cfg->handles.main); 478c5c4113dSnw free(cfg); 479c5c4113dSnw 480c5c4113dSnw return (0); 481c5c4113dSnw } 482