15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 22*5772Sas200622 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw #pragma ident "%Z%%M% %I% %E% SMI" 275331Samw 285331Samw /* helper functions for using libscf with CIFS */ 295331Samw 305331Samw #include <libscf.h> 315331Samw #include <string.h> 325331Samw #include <stdio.h> 335331Samw #include <stdlib.h> 345331Samw #include <syslog.h> 355331Samw #include <errno.h> 365331Samw #include <libintl.h> 375331Samw #include <assert.h> 385331Samw #include <strings.h> 395331Samw 405331Samw #include <uuid/uuid.h> 415331Samw #include <sys/param.h> 425331Samw 435331Samw #include <smbsrv/alloc.h> 445331Samw 455331Samw #include <smbsrv/libsmb.h> 465331Samw 475331Samw /* 485331Samw * smb_smf_scf_log_error(msg) 495331Samw * Logs error messages from scf API's 505331Samw */ 515331Samw static void 525331Samw smb_smf_scf_log_error(char *msg) 535331Samw { 545331Samw if (!msg) { 555331Samw syslog(LOG_ERR, " SMBD SMF problem: %s\n", 565331Samw scf_strerror(scf_error())); 575331Samw } else { /*LINTED E_SEC_PRINTF_E_VAR_FMT*/ 585331Samw syslog(LOG_ERR, msg, scf_strerror(scf_error())); 595331Samw } 605331Samw } 615331Samw 625331Samw /* 635331Samw * smb_smf_create_service_pgroup(handle, pgroup) 645331Samw * 655331Samw * create a new property group at service level. 665331Samw */ 675331Samw int 685331Samw smb_smf_create_service_pgroup(smb_scfhandle_t *handle, char *pgroup) 695331Samw { 705331Samw int ret = SMBD_SMF_OK; 715331Samw int err; 725331Samw 735331Samw if (handle == NULL) { 745331Samw return (SMBD_SMF_SYSTEM_ERR); 755331Samw } 765331Samw 775331Samw /* 785331Samw * only create a handle if it doesn't exist. It is ok to exist 795331Samw * since the pg handle will be set as a side effect. 805331Samw */ 815331Samw if (handle->scf_pg == NULL) 825331Samw handle->scf_pg = scf_pg_create(handle->scf_handle); 835331Samw 845331Samw /* 855331Samw * if the pgroup exists, we are done. If it doesn't, then we 865331Samw * need to actually add one to the service instance. 875331Samw */ 885331Samw if (scf_service_get_pg(handle->scf_service, 895331Samw pgroup, handle->scf_pg) != 0) { 905331Samw /* doesn't exist so create one */ 915331Samw if (scf_service_add_pg(handle->scf_service, pgroup, 925331Samw SCF_GROUP_APPLICATION, 0, handle->scf_pg) != 0) { 935331Samw err = scf_error(); 945331Samw if (err != SCF_ERROR_NONE) 955331Samw smb_smf_scf_log_error(NULL); 965331Samw switch (err) { 975331Samw case SCF_ERROR_PERMISSION_DENIED: 985331Samw ret = SMBD_SMF_NO_PERMISSION; 995331Samw break; 1005331Samw default: 1015331Samw ret = SMBD_SMF_SYSTEM_ERR; 1025331Samw break; 1035331Samw } 1045331Samw } 1055331Samw } 1065331Samw return (ret); 1075331Samw } 1085331Samw 1095331Samw /* 1105331Samw * Start transaction on current pg in handle. 1115331Samw * The pg could be service or instance level. 1125331Samw * Must be called after pg handle is obtained 1135331Samw * from create or get. 1145331Samw */ 1155331Samw int 1165331Samw smb_smf_start_transaction(smb_scfhandle_t *handle) 1175331Samw { 1185331Samw int ret = SMBD_SMF_OK; 1195331Samw 1205331Samw if (!handle || (!handle->scf_pg)) 1215331Samw return (SMBD_SMF_SYSTEM_ERR); 1225331Samw 1235331Samw /* 1245331Samw * lookup the property group and create it if it doesn't already 1255331Samw * exist. 1265331Samw */ 1275331Samw if (handle->scf_state == SCH_STATE_INIT) { 1285331Samw if (ret == SMBD_SMF_OK) { 1295331Samw handle->scf_trans = 1305331Samw scf_transaction_create(handle->scf_handle); 1315331Samw if (handle->scf_trans != NULL) { 1325331Samw if (scf_transaction_start(handle->scf_trans, 1335331Samw handle->scf_pg) != 0) { 1345331Samw ret = SMBD_SMF_SYSTEM_ERR; 1355331Samw scf_transaction_destroy( 1365331Samw handle->scf_trans); 1375331Samw handle->scf_trans = NULL; 1385331Samw } 1395331Samw } else { 1405331Samw ret = SMBD_SMF_SYSTEM_ERR; 1415331Samw } 1425331Samw } 1435331Samw } 1445331Samw if (ret == SMBD_SMF_SYSTEM_ERR && 1455331Samw scf_error() == SCF_ERROR_PERMISSION_DENIED) 1465331Samw ret = SMBD_SMF_NO_PERMISSION; 1475331Samw 1485331Samw return (ret); 1495331Samw } 1505331Samw 1515331Samw /* 1525331Samw * smb_smf_end_transaction(handle) 1535331Samw * 1545331Samw * Commit the changes that were added to the transaction in the 1555331Samw * handle. Do all necessary cleanup. 1565331Samw */ 1575331Samw int 1585331Samw smb_smf_end_transaction(smb_scfhandle_t *handle) 1595331Samw { 1605331Samw int ret = SMBD_SMF_OK; 1615331Samw 1625331Samw if (handle == NULL) 1635331Samw return (SMBD_SMF_SYSTEM_ERR); 1645331Samw 1655331Samw if (handle->scf_trans == NULL) { 1665331Samw ret = SMBD_SMF_SYSTEM_ERR; 1675331Samw } else { 1685331Samw if (scf_transaction_commit(handle->scf_trans) < 0) { 1695331Samw ret = SMBD_SMF_SYSTEM_ERR; 1705331Samw smb_smf_scf_log_error("Failed to commit " 1715331Samw "transaction: %s"); 1725331Samw } 1735331Samw scf_transaction_destroy_children(handle->scf_trans); 1745331Samw scf_transaction_destroy(handle->scf_trans); 1755331Samw handle->scf_trans = NULL; 1765331Samw } 1775331Samw return (ret); 1785331Samw } 1795331Samw 1805331Samw /* 1815331Samw * Sets string property in current pg 1825331Samw */ 1835331Samw int 1845331Samw smb_smf_set_string_property(smb_scfhandle_t *handle, 1855331Samw char *propname, char *valstr) 1865331Samw { 1875331Samw int ret = SMBD_SMF_OK; 1885331Samw scf_value_t *value = NULL; 1895331Samw scf_transaction_entry_t *entry = NULL; 1905331Samw 1915331Samw if (handle == NULL) 1925331Samw return (SMBD_SMF_SYSTEM_ERR); 1935331Samw 1945331Samw /* 1955331Samw * properties must be set in transactions and don't take 1965331Samw * effect until the transaction has been ended/committed. 1975331Samw */ 1985331Samw value = scf_value_create(handle->scf_handle); 1995331Samw entry = scf_entry_create(handle->scf_handle); 2005331Samw if (value != NULL && entry != NULL) { 2015331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 2025331Samw propname, SCF_TYPE_ASTRING) == 0 || 2035331Samw scf_transaction_property_new(handle->scf_trans, entry, 2045331Samw propname, SCF_TYPE_ASTRING) == 0) { 2055331Samw if (scf_value_set_astring(value, valstr) == 0) { 2065331Samw if (scf_entry_add_value(entry, value) != 0) { 2075331Samw ret = SMBD_SMF_SYSTEM_ERR; 2085331Samw scf_value_destroy(value); 2095331Samw } 2105331Samw /* the value is in the transaction */ 2115331Samw value = NULL; 2125331Samw } else { 2135331Samw /* value couldn't be constructed */ 2145331Samw ret = SMBD_SMF_SYSTEM_ERR; 2155331Samw } 2165331Samw /* the entry is in the transaction */ 2175331Samw entry = NULL; 2185331Samw } else { 2195331Samw ret = SMBD_SMF_SYSTEM_ERR; 2205331Samw } 2215331Samw } else { 2225331Samw ret = SMBD_SMF_SYSTEM_ERR; 2235331Samw } 2245331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 2255331Samw switch (scf_error()) { 2265331Samw case SCF_ERROR_PERMISSION_DENIED: 2275331Samw ret = SMBD_SMF_NO_PERMISSION; 2285331Samw break; 2295331Samw } 2305331Samw } 2315331Samw 2325331Samw /* 2335331Samw * cleanup if there were any errors that didn't leave these 2345331Samw * values where they would be cleaned up later. 2355331Samw */ 2365331Samw if (value != NULL) 2375331Samw scf_value_destroy(value); 2385331Samw if (entry != NULL) 2395331Samw scf_entry_destroy(entry); 2405331Samw return (ret); 2415331Samw } 2425331Samw 2435331Samw /* 2445331Samw * Gets string property value.upto sz size. 2455331Samw * Caller is responsible to have enough memory allocated. 2465331Samw */ 2475331Samw int 2485331Samw smb_smf_get_string_property(smb_scfhandle_t *handle, char *propname, 2495331Samw char *valstr, size_t sz) 2505331Samw { 2515331Samw int ret = SMBD_SMF_OK; 2525331Samw scf_value_t *value; 2535331Samw scf_property_t *prop; 2545331Samw 2555331Samw if (handle == NULL) 2565331Samw return (SMBD_SMF_SYSTEM_ERR); 2575331Samw 2585331Samw value = scf_value_create(handle->scf_handle); 2595331Samw prop = scf_property_create(handle->scf_handle); 2605331Samw if (value && prop && 2615331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 2625331Samw if (scf_property_get_value(prop, value) == 0) { 2635331Samw if (scf_value_get_astring(value, valstr, sz) < 0) { 2645331Samw ret = SMBD_SMF_SYSTEM_ERR; 2655331Samw } 2665331Samw } else { 2675331Samw ret = SMBD_SMF_SYSTEM_ERR; 2685331Samw } 2695331Samw } else { 2705331Samw ret = SMBD_SMF_SYSTEM_ERR; 2715331Samw } 2725331Samw if (value != NULL) 2735331Samw scf_value_destroy(value); 2745331Samw if (prop != NULL) 2755331Samw scf_property_destroy(prop); 2765331Samw return (ret); 2775331Samw } 2785331Samw 2795331Samw /* 2805331Samw * Set integer value of property. 2815331Samw * The value is returned as int64_t value 2825331Samw * Caller ensures appropriate translation. 2835331Samw */ 2845331Samw int 2855331Samw smb_smf_set_integer_property(smb_scfhandle_t *handle, char *propname, 2865331Samw int64_t valint) 2875331Samw { 2885331Samw int ret = SMBD_SMF_OK; 2895331Samw scf_value_t *value = NULL; 2905331Samw scf_transaction_entry_t *entry = NULL; 2915331Samw 2925331Samw if (handle == NULL) 2935331Samw return (SMBD_SMF_SYSTEM_ERR); 2945331Samw 2955331Samw /* 2965331Samw * properties must be set in transactions and don't take 2975331Samw * effect until the transaction has been ended/committed. 2985331Samw */ 2995331Samw value = scf_value_create(handle->scf_handle); 3005331Samw entry = scf_entry_create(handle->scf_handle); 3015331Samw if (value != NULL && entry != NULL) { 3025331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 3035331Samw propname, SCF_TYPE_INTEGER) == 0 || 3045331Samw scf_transaction_property_new(handle->scf_trans, entry, 3055331Samw propname, SCF_TYPE_INTEGER) == 0) { 3065331Samw scf_value_set_integer(value, valint); 3075331Samw if (scf_entry_add_value(entry, value) != 0) { 3085331Samw ret = SMBD_SMF_SYSTEM_ERR; 3095331Samw scf_value_destroy(value); 3105331Samw } 3115331Samw /* the value is in the transaction */ 3125331Samw value = NULL; 3135331Samw } 3145331Samw /* the entry is in the transaction */ 3155331Samw entry = NULL; 3165331Samw } else { 3175331Samw ret = SMBD_SMF_SYSTEM_ERR; 3185331Samw } 3195331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 3205331Samw switch (scf_error()) { 3215331Samw case SCF_ERROR_PERMISSION_DENIED: 3225331Samw ret = SMBD_SMF_NO_PERMISSION; 3235331Samw break; 3245331Samw } 3255331Samw } 3265331Samw /* 3275331Samw * cleanup if there were any errors that didn't leave these 3285331Samw * values where they would be cleaned up later. 3295331Samw */ 3305331Samw if (value != NULL) 3315331Samw scf_value_destroy(value); 3325331Samw if (entry != NULL) 3335331Samw scf_entry_destroy(entry); 3345331Samw return (ret); 3355331Samw } 3365331Samw 3375331Samw /* 3385331Samw * Gets integer property value. 3395331Samw * Caller is responsible to have enough memory allocated. 3405331Samw */ 3415331Samw int 3425331Samw smb_smf_get_integer_property(smb_scfhandle_t *handle, char *propname, 3435331Samw int64_t *valint) 3445331Samw { 3455331Samw int ret = SMBD_SMF_OK; 3465331Samw scf_value_t *value = NULL; 3475331Samw scf_property_t *prop = NULL; 3485331Samw 3495331Samw if (handle == NULL) 3505331Samw return (SMBD_SMF_SYSTEM_ERR); 3515331Samw 3525331Samw value = scf_value_create(handle->scf_handle); 3535331Samw prop = scf_property_create(handle->scf_handle); 3545331Samw if ((prop) && (value) && 3555331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 3565331Samw if (scf_property_get_value(prop, value) == 0) { 3575331Samw if (scf_value_get_integer(value, 3585331Samw valint) != 0) { 3595331Samw ret = SMBD_SMF_SYSTEM_ERR; 3605331Samw } 3615331Samw } else { 3625331Samw ret = SMBD_SMF_SYSTEM_ERR; 3635331Samw } 3645331Samw } else { 3655331Samw ret = SMBD_SMF_SYSTEM_ERR; 3665331Samw } 3675331Samw if (value != NULL) 3685331Samw scf_value_destroy(value); 3695331Samw if (prop != NULL) 3705331Samw scf_property_destroy(prop); 3715331Samw return (ret); 3725331Samw } 3735331Samw 3745331Samw /* 3755331Samw * Set boolean value of property. 3765331Samw * The value is returned as int64_t value 3775331Samw * Caller ensures appropriate translation. 3785331Samw */ 3795331Samw int 3805331Samw smb_smf_set_boolean_property(smb_scfhandle_t *handle, char *propname, 3815331Samw uint8_t valbool) 3825331Samw { 3835331Samw int ret = SMBD_SMF_OK; 3845331Samw scf_value_t *value = NULL; 3855331Samw scf_transaction_entry_t *entry = NULL; 3865331Samw 3875331Samw if (handle == NULL) 3885331Samw return (SMBD_SMF_SYSTEM_ERR); 3895331Samw 3905331Samw /* 3915331Samw * properties must be set in transactions and don't take 3925331Samw * effect until the transaction has been ended/committed. 3935331Samw */ 3945331Samw value = scf_value_create(handle->scf_handle); 3955331Samw entry = scf_entry_create(handle->scf_handle); 3965331Samw if (value != NULL && entry != NULL) { 3975331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 3985331Samw propname, SCF_TYPE_BOOLEAN) == 0 || 3995331Samw scf_transaction_property_new(handle->scf_trans, entry, 4005331Samw propname, SCF_TYPE_BOOLEAN) == 0) { 4015331Samw scf_value_set_boolean(value, valbool); 4025331Samw if (scf_entry_add_value(entry, value) != 0) { 4035331Samw ret = SMBD_SMF_SYSTEM_ERR; 4045331Samw scf_value_destroy(value); 4055331Samw } 4065331Samw /* the value is in the transaction */ 4075331Samw value = NULL; 4085331Samw } 4095331Samw /* the entry is in the transaction */ 4105331Samw entry = NULL; 4115331Samw } else { 4125331Samw ret = SMBD_SMF_SYSTEM_ERR; 4135331Samw } 4145331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 4155331Samw switch (scf_error()) { 4165331Samw case SCF_ERROR_PERMISSION_DENIED: 4175331Samw ret = SMBD_SMF_NO_PERMISSION; 4185331Samw break; 4195331Samw } 4205331Samw } 4215331Samw /* 4225331Samw * cleanup if there were any errors that didn't leave these 4235331Samw * values where they would be cleaned up later. 4245331Samw */ 4255331Samw if (value != NULL) 4265331Samw scf_value_destroy(value); 4275331Samw if (entry != NULL) 4285331Samw scf_entry_destroy(entry); 4295331Samw return (ret); 4305331Samw } 4315331Samw 4325331Samw /* 4335331Samw * Gets boolean property value. 4345331Samw * Caller is responsible to have enough memory allocated. 4355331Samw */ 4365331Samw int 4375331Samw smb_smf_get_boolean_property(smb_scfhandle_t *handle, char *propname, 4385331Samw uint8_t *valbool) 4395331Samw { 4405331Samw int ret = SMBD_SMF_OK; 4415331Samw scf_value_t *value = NULL; 4425331Samw scf_property_t *prop = NULL; 4435331Samw 4445331Samw if (handle == NULL) 4455331Samw return (SMBD_SMF_SYSTEM_ERR); 4465331Samw 4475331Samw value = scf_value_create(handle->scf_handle); 4485331Samw prop = scf_property_create(handle->scf_handle); 4495331Samw if ((prop) && (value) && 4505331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 4515331Samw if (scf_property_get_value(prop, value) == 0) { 4525331Samw if (scf_value_get_boolean(value, 4535331Samw valbool) != 0) { 4545331Samw ret = SMBD_SMF_SYSTEM_ERR; 4555331Samw } 4565331Samw } else { 4575331Samw ret = SMBD_SMF_SYSTEM_ERR; 4585331Samw } 4595331Samw } else { 4605331Samw ret = SMBD_SMF_SYSTEM_ERR; 4615331Samw } 4625331Samw if (value != NULL) 4635331Samw scf_value_destroy(value); 4645331Samw if (prop != NULL) 4655331Samw scf_property_destroy(prop); 4665331Samw return (ret); 4675331Samw } 4685331Samw 4695331Samw /* 4705331Samw * Sets a blob property value. 4715331Samw */ 4725331Samw int 4735331Samw smb_smf_set_opaque_property(smb_scfhandle_t *handle, char *propname, 4745331Samw void *voidval, size_t sz) 4755331Samw { 4765331Samw int ret = SMBD_SMF_OK; 4775331Samw scf_value_t *value; 4785331Samw scf_transaction_entry_t *entry; 4795331Samw 4805331Samw if (handle == NULL) 4815331Samw return (SMBD_SMF_SYSTEM_ERR); 4825331Samw 4835331Samw /* 4845331Samw * properties must be set in transactions and don't take 4855331Samw * effect until the transaction has been ended/committed. 4865331Samw */ 4875331Samw value = scf_value_create(handle->scf_handle); 4885331Samw entry = scf_entry_create(handle->scf_handle); 4895331Samw if (value != NULL && entry != NULL) { 4905331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 4915331Samw propname, SCF_TYPE_OPAQUE) == 0 || 4925331Samw scf_transaction_property_new(handle->scf_trans, entry, 4935331Samw propname, SCF_TYPE_OPAQUE) == 0) { 4945331Samw if (scf_value_set_opaque(value, voidval, sz) == 0) { 4955331Samw if (scf_entry_add_value(entry, value) != 0) { 4965331Samw ret = SMBD_SMF_SYSTEM_ERR; 4975331Samw scf_value_destroy(value); 4985331Samw } 4995331Samw /* the value is in the transaction */ 5005331Samw value = NULL; 5015331Samw } else { 5025331Samw /* value couldn't be constructed */ 5035331Samw ret = SMBD_SMF_SYSTEM_ERR; 5045331Samw } 5055331Samw /* the entry is in the transaction */ 5065331Samw entry = NULL; 5075331Samw } else { 5085331Samw ret = SMBD_SMF_SYSTEM_ERR; 5095331Samw } 5105331Samw } else { 5115331Samw ret = SMBD_SMF_SYSTEM_ERR; 5125331Samw } 5135331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 5145331Samw switch (scf_error()) { 5155331Samw case SCF_ERROR_PERMISSION_DENIED: 5165331Samw ret = SMBD_SMF_NO_PERMISSION; 5175331Samw break; 5185331Samw } 5195331Samw } 5205331Samw /* 5215331Samw * cleanup if there were any errors that didn't leave these 5225331Samw * values where they would be cleaned up later. 5235331Samw */ 5245331Samw if (value != NULL) 5255331Samw scf_value_destroy(value); 5265331Samw if (entry != NULL) 5275331Samw scf_entry_destroy(entry); 5285331Samw return (ret); 5295331Samw } 5305331Samw 5315331Samw /* 5325331Samw * Gets a blob property value. 5335331Samw * Caller is responsible to have enough memory allocated. 5345331Samw */ 5355331Samw int 5365331Samw smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname, 5375331Samw void *v, size_t sz) 5385331Samw { 5395331Samw int ret = SMBD_SMF_OK; 5405331Samw scf_value_t *value = NULL; 5415331Samw scf_property_t *prop = NULL; 5425331Samw 5435331Samw if (handle == NULL) 5445331Samw return (SMBD_SMF_SYSTEM_ERR); 5455331Samw 5465331Samw value = scf_value_create(handle->scf_handle); 5475331Samw prop = scf_property_create(handle->scf_handle); 5485331Samw if ((prop) && (value) && 5495331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 5505331Samw if (scf_property_get_value(prop, value) == 0) { 5515331Samw if (scf_value_get_opaque(value, (char *)v, sz) != sz) { 5525331Samw ret = SMBD_SMF_SYSTEM_ERR; 5535331Samw } 5545331Samw } else { 5555331Samw ret = SMBD_SMF_SYSTEM_ERR; 5565331Samw } 5575331Samw } else { 5585331Samw ret = SMBD_SMF_SYSTEM_ERR; 5595331Samw } 5605331Samw if (value != NULL) 5615331Samw scf_value_destroy(value); 5625331Samw if (prop != NULL) 5635331Samw scf_property_destroy(prop); 5645331Samw return (ret); 5655331Samw } 5665331Samw 5675331Samw /* 5685331Samw * smb_smf_scf_init() 5695331Samw * 5705331Samw * must be called before using any of the SCF functions. 5715331Samw * Returns smb_scfhandle_t pointer if success. 5725331Samw */ 5735331Samw smb_scfhandle_t * 5745331Samw smb_smf_scf_init(char *svc_name) 5755331Samw { 5765331Samw smb_scfhandle_t *handle; 5775331Samw 5785331Samw handle = malloc(sizeof (smb_scfhandle_t)); 5795331Samw if (handle != NULL) { 5805331Samw bzero((char *)handle, sizeof (smb_scfhandle_t)); 5815331Samw handle->scf_state = SCH_STATE_INITIALIZING; 5825331Samw handle->scf_handle = scf_handle_create(SCF_VERSION); 5835331Samw if (handle->scf_handle != NULL) { 5845331Samw if (scf_handle_bind(handle->scf_handle) == 0) { 5855331Samw handle->scf_scope = 5865331Samw scf_scope_create(handle->scf_handle); 5875331Samw if (scf_handle_get_local_scope( 5885331Samw handle->scf_handle, handle->scf_scope) != 0) 5895331Samw goto err; 5905331Samw 5915331Samw handle->scf_service = 5925331Samw scf_service_create(handle->scf_handle); 5935331Samw 5945331Samw if (scf_scope_get_service(handle->scf_scope, 5955331Samw svc_name, handle->scf_service) 5965331Samw != SCF_SUCCESS) { 5975331Samw goto err; 5985331Samw } 5995331Samw handle->scf_pg = 6005331Samw scf_pg_create(handle->scf_handle); 6015331Samw handle->scf_state = SCH_STATE_INIT; 6025331Samw } else { 6035331Samw goto err; 6045331Samw } 6055331Samw } else { 6065331Samw free(handle); 6075331Samw handle = NULL; 6085331Samw smb_smf_scf_log_error("Could not access SMF " 6095331Samw "repository: %s\n"); 6105331Samw } 6115331Samw } 6125331Samw return (handle); 6135331Samw 6145331Samw /* error handling/unwinding */ 6155331Samw err: 6165331Samw (void) smb_smf_scf_fini(handle); 6175331Samw (void) smb_smf_scf_log_error("SMF initialization problem: %s\n"); 6185331Samw return (NULL); 6195331Samw } 6205331Samw 6215331Samw /* 6225331Samw * smb_smf_scf_fini(handle) 6235331Samw * 6245331Samw * must be called when done. Called with the handle allocated in 6255331Samw * smb_smf_scf_init(), it cleans up the state and frees any SCF resources 6265331Samw * still in use. 6275331Samw */ 6285331Samw void 6295331Samw smb_smf_scf_fini(smb_scfhandle_t *handle) 6305331Samw { 6315331Samw if (handle != NULL) { 6325331Samw int unbind = 0; 6335331Samw scf_iter_destroy(handle->scf_pg_iter); 6345331Samw handle->scf_pg_iter = NULL; 6355331Samw 6365331Samw scf_iter_destroy(handle->scf_inst_iter); 6375331Samw handle->scf_inst_iter = NULL; 6385331Samw 6395331Samw unbind = 1; 6405331Samw scf_scope_destroy(handle->scf_scope); 6415331Samw handle->scf_scope = NULL; 6425331Samw 6435331Samw scf_instance_destroy(handle->scf_instance); 6445331Samw handle->scf_instance = NULL; 6455331Samw 6465331Samw scf_service_destroy(handle->scf_service); 6475331Samw handle->scf_service = NULL; 6485331Samw 6495331Samw scf_pg_destroy(handle->scf_pg); 6505331Samw handle->scf_pg = NULL; 6515331Samw 6525331Samw handle->scf_state = SCH_STATE_UNINIT; 6535331Samw if (unbind) 6545331Samw (void) scf_handle_unbind(handle->scf_handle); 6555331Samw scf_handle_destroy(handle->scf_handle); 6565331Samw handle->scf_handle = NULL; 6575331Samw 6585331Samw free(handle); 6595331Samw } 6605331Samw } 661