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 /* 225772Sas200622 * 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 73*6030Sjb150015 if (handle == NULL) 745331Samw return (SMBD_SMF_SYSTEM_ERR); 755331Samw 765331Samw /* 775331Samw * only create a handle if it doesn't exist. It is ok to exist 785331Samw * since the pg handle will be set as a side effect. 795331Samw */ 805331Samw if (handle->scf_pg == NULL) 81*6030Sjb150015 if ((handle->scf_pg = 82*6030Sjb150015 scf_pg_create(handle->scf_handle)) == NULL) 83*6030Sjb150015 return (SMBD_SMF_SYSTEM_ERR); 845331Samw 855331Samw /* 865331Samw * if the pgroup exists, we are done. If it doesn't, then we 875331Samw * need to actually add one to the service instance. 885331Samw */ 895331Samw if (scf_service_get_pg(handle->scf_service, 905331Samw pgroup, handle->scf_pg) != 0) { 915331Samw /* doesn't exist so create one */ 925331Samw if (scf_service_add_pg(handle->scf_service, pgroup, 935331Samw SCF_GROUP_APPLICATION, 0, handle->scf_pg) != 0) { 945331Samw err = scf_error(); 955331Samw if (err != SCF_ERROR_NONE) 965331Samw smb_smf_scf_log_error(NULL); 975331Samw switch (err) { 985331Samw case SCF_ERROR_PERMISSION_DENIED: 995331Samw ret = SMBD_SMF_NO_PERMISSION; 1005331Samw break; 1015331Samw default: 1025331Samw ret = SMBD_SMF_SYSTEM_ERR; 1035331Samw break; 1045331Samw } 1055331Samw } 1065331Samw } 1075331Samw return (ret); 1085331Samw } 1095331Samw 1105331Samw /* 1115331Samw * Start transaction on current pg in handle. 1125331Samw * The pg could be service or instance level. 1135331Samw * Must be called after pg handle is obtained 1145331Samw * from create or get. 1155331Samw */ 1165331Samw int 1175331Samw smb_smf_start_transaction(smb_scfhandle_t *handle) 1185331Samw { 1195331Samw int ret = SMBD_SMF_OK; 1205331Samw 1215331Samw if (!handle || (!handle->scf_pg)) 1225331Samw return (SMBD_SMF_SYSTEM_ERR); 1235331Samw 1245331Samw /* 1255331Samw * lookup the property group and create it if it doesn't already 1265331Samw * exist. 1275331Samw */ 1285331Samw if (handle->scf_state == SCH_STATE_INIT) { 1295331Samw if (ret == SMBD_SMF_OK) { 1305331Samw handle->scf_trans = 1315331Samw scf_transaction_create(handle->scf_handle); 1325331Samw if (handle->scf_trans != NULL) { 1335331Samw if (scf_transaction_start(handle->scf_trans, 1345331Samw handle->scf_pg) != 0) { 1355331Samw ret = SMBD_SMF_SYSTEM_ERR; 1365331Samw scf_transaction_destroy( 1375331Samw handle->scf_trans); 1385331Samw handle->scf_trans = NULL; 1395331Samw } 1405331Samw } else { 1415331Samw ret = SMBD_SMF_SYSTEM_ERR; 1425331Samw } 1435331Samw } 1445331Samw } 1455331Samw if (ret == SMBD_SMF_SYSTEM_ERR && 1465331Samw scf_error() == SCF_ERROR_PERMISSION_DENIED) 1475331Samw ret = SMBD_SMF_NO_PERMISSION; 1485331Samw 1495331Samw return (ret); 1505331Samw } 1515331Samw 1525331Samw /* 1535331Samw * smb_smf_end_transaction(handle) 1545331Samw * 1555331Samw * Commit the changes that were added to the transaction in the 1565331Samw * handle. Do all necessary cleanup. 1575331Samw */ 1585331Samw int 1595331Samw smb_smf_end_transaction(smb_scfhandle_t *handle) 1605331Samw { 1615331Samw int ret = SMBD_SMF_OK; 1625331Samw 1635331Samw if (handle == NULL) 1645331Samw return (SMBD_SMF_SYSTEM_ERR); 1655331Samw 1665331Samw if (handle->scf_trans == NULL) { 1675331Samw ret = SMBD_SMF_SYSTEM_ERR; 1685331Samw } else { 1695331Samw if (scf_transaction_commit(handle->scf_trans) < 0) { 1705331Samw ret = SMBD_SMF_SYSTEM_ERR; 1715331Samw smb_smf_scf_log_error("Failed to commit " 1725331Samw "transaction: %s"); 1735331Samw } 1745331Samw scf_transaction_destroy_children(handle->scf_trans); 1755331Samw scf_transaction_destroy(handle->scf_trans); 1765331Samw handle->scf_trans = NULL; 1775331Samw } 1785331Samw return (ret); 1795331Samw } 1805331Samw 1815331Samw /* 1825331Samw * Sets string property in current pg 1835331Samw */ 1845331Samw int 1855331Samw smb_smf_set_string_property(smb_scfhandle_t *handle, 1865331Samw char *propname, char *valstr) 1875331Samw { 1885331Samw int ret = SMBD_SMF_OK; 1895331Samw scf_value_t *value = NULL; 1905331Samw scf_transaction_entry_t *entry = NULL; 1915331Samw 1925331Samw if (handle == NULL) 1935331Samw return (SMBD_SMF_SYSTEM_ERR); 1945331Samw 1955331Samw /* 1965331Samw * properties must be set in transactions and don't take 1975331Samw * effect until the transaction has been ended/committed. 1985331Samw */ 1995331Samw value = scf_value_create(handle->scf_handle); 2005331Samw entry = scf_entry_create(handle->scf_handle); 2015331Samw if (value != NULL && entry != NULL) { 2025331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 2035331Samw propname, SCF_TYPE_ASTRING) == 0 || 2045331Samw scf_transaction_property_new(handle->scf_trans, entry, 2055331Samw propname, SCF_TYPE_ASTRING) == 0) { 2065331Samw if (scf_value_set_astring(value, valstr) == 0) { 2075331Samw if (scf_entry_add_value(entry, value) != 0) { 2085331Samw ret = SMBD_SMF_SYSTEM_ERR; 2095331Samw scf_value_destroy(value); 2105331Samw } 2115331Samw /* the value is in the transaction */ 2125331Samw value = NULL; 2135331Samw } else { 2145331Samw /* value couldn't be constructed */ 2155331Samw ret = SMBD_SMF_SYSTEM_ERR; 2165331Samw } 2175331Samw /* the entry is in the transaction */ 2185331Samw entry = NULL; 2195331Samw } else { 2205331Samw ret = SMBD_SMF_SYSTEM_ERR; 2215331Samw } 2225331Samw } else { 2235331Samw ret = SMBD_SMF_SYSTEM_ERR; 2245331Samw } 2255331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 2265331Samw switch (scf_error()) { 2275331Samw case SCF_ERROR_PERMISSION_DENIED: 2285331Samw ret = SMBD_SMF_NO_PERMISSION; 2295331Samw break; 2305331Samw } 2315331Samw } 2325331Samw 2335331Samw /* 2345331Samw * cleanup if there were any errors that didn't leave these 2355331Samw * values where they would be cleaned up later. 2365331Samw */ 2375331Samw if (value != NULL) 2385331Samw scf_value_destroy(value); 2395331Samw if (entry != NULL) 2405331Samw scf_entry_destroy(entry); 2415331Samw return (ret); 2425331Samw } 2435331Samw 2445331Samw /* 2455331Samw * Gets string property value.upto sz size. 2465331Samw * Caller is responsible to have enough memory allocated. 2475331Samw */ 2485331Samw int 2495331Samw smb_smf_get_string_property(smb_scfhandle_t *handle, char *propname, 2505331Samw char *valstr, size_t sz) 2515331Samw { 2525331Samw int ret = SMBD_SMF_OK; 2535331Samw scf_value_t *value; 2545331Samw scf_property_t *prop; 2555331Samw 2565331Samw if (handle == NULL) 2575331Samw return (SMBD_SMF_SYSTEM_ERR); 2585331Samw 2595331Samw value = scf_value_create(handle->scf_handle); 2605331Samw prop = scf_property_create(handle->scf_handle); 2615331Samw if (value && prop && 2625331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 2635331Samw if (scf_property_get_value(prop, value) == 0) { 2645331Samw if (scf_value_get_astring(value, valstr, sz) < 0) { 2655331Samw ret = SMBD_SMF_SYSTEM_ERR; 2665331Samw } 2675331Samw } else { 2685331Samw ret = SMBD_SMF_SYSTEM_ERR; 2695331Samw } 2705331Samw } else { 2715331Samw ret = SMBD_SMF_SYSTEM_ERR; 2725331Samw } 2735331Samw if (value != NULL) 2745331Samw scf_value_destroy(value); 2755331Samw if (prop != NULL) 2765331Samw scf_property_destroy(prop); 2775331Samw return (ret); 2785331Samw } 2795331Samw 2805331Samw /* 2815331Samw * Set integer value of property. 2825331Samw * The value is returned as int64_t value 2835331Samw * Caller ensures appropriate translation. 2845331Samw */ 2855331Samw int 2865331Samw smb_smf_set_integer_property(smb_scfhandle_t *handle, char *propname, 2875331Samw int64_t valint) 2885331Samw { 2895331Samw int ret = SMBD_SMF_OK; 2905331Samw scf_value_t *value = NULL; 2915331Samw scf_transaction_entry_t *entry = NULL; 2925331Samw 2935331Samw if (handle == NULL) 2945331Samw return (SMBD_SMF_SYSTEM_ERR); 2955331Samw 2965331Samw /* 2975331Samw * properties must be set in transactions and don't take 2985331Samw * effect until the transaction has been ended/committed. 2995331Samw */ 3005331Samw value = scf_value_create(handle->scf_handle); 3015331Samw entry = scf_entry_create(handle->scf_handle); 3025331Samw if (value != NULL && entry != NULL) { 3035331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 3045331Samw propname, SCF_TYPE_INTEGER) == 0 || 3055331Samw scf_transaction_property_new(handle->scf_trans, entry, 3065331Samw propname, SCF_TYPE_INTEGER) == 0) { 3075331Samw scf_value_set_integer(value, valint); 3085331Samw if (scf_entry_add_value(entry, value) != 0) { 3095331Samw ret = SMBD_SMF_SYSTEM_ERR; 3105331Samw scf_value_destroy(value); 3115331Samw } 3125331Samw /* the value is in the transaction */ 3135331Samw value = NULL; 3145331Samw } 3155331Samw /* the entry is in the transaction */ 3165331Samw entry = NULL; 3175331Samw } else { 3185331Samw ret = SMBD_SMF_SYSTEM_ERR; 3195331Samw } 3205331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 3215331Samw switch (scf_error()) { 3225331Samw case SCF_ERROR_PERMISSION_DENIED: 3235331Samw ret = SMBD_SMF_NO_PERMISSION; 3245331Samw break; 3255331Samw } 3265331Samw } 3275331Samw /* 3285331Samw * cleanup if there were any errors that didn't leave these 3295331Samw * values where they would be cleaned up later. 3305331Samw */ 3315331Samw if (value != NULL) 3325331Samw scf_value_destroy(value); 3335331Samw if (entry != NULL) 3345331Samw scf_entry_destroy(entry); 3355331Samw return (ret); 3365331Samw } 3375331Samw 3385331Samw /* 3395331Samw * Gets integer property value. 3405331Samw * Caller is responsible to have enough memory allocated. 3415331Samw */ 3425331Samw int 3435331Samw smb_smf_get_integer_property(smb_scfhandle_t *handle, char *propname, 3445331Samw int64_t *valint) 3455331Samw { 3465331Samw int ret = SMBD_SMF_OK; 3475331Samw scf_value_t *value = NULL; 3485331Samw scf_property_t *prop = NULL; 3495331Samw 3505331Samw if (handle == NULL) 3515331Samw return (SMBD_SMF_SYSTEM_ERR); 3525331Samw 3535331Samw value = scf_value_create(handle->scf_handle); 3545331Samw prop = scf_property_create(handle->scf_handle); 3555331Samw if ((prop) && (value) && 3565331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 3575331Samw if (scf_property_get_value(prop, value) == 0) { 3585331Samw if (scf_value_get_integer(value, 3595331Samw valint) != 0) { 3605331Samw ret = SMBD_SMF_SYSTEM_ERR; 3615331Samw } 3625331Samw } else { 3635331Samw ret = SMBD_SMF_SYSTEM_ERR; 3645331Samw } 3655331Samw } else { 3665331Samw ret = SMBD_SMF_SYSTEM_ERR; 3675331Samw } 3685331Samw if (value != NULL) 3695331Samw scf_value_destroy(value); 3705331Samw if (prop != NULL) 3715331Samw scf_property_destroy(prop); 3725331Samw return (ret); 3735331Samw } 3745331Samw 3755331Samw /* 3765331Samw * Set boolean value of property. 3775331Samw * The value is returned as int64_t value 3785331Samw * Caller ensures appropriate translation. 3795331Samw */ 3805331Samw int 3815331Samw smb_smf_set_boolean_property(smb_scfhandle_t *handle, char *propname, 3825331Samw uint8_t valbool) 3835331Samw { 3845331Samw int ret = SMBD_SMF_OK; 3855331Samw scf_value_t *value = NULL; 3865331Samw scf_transaction_entry_t *entry = NULL; 3875331Samw 3885331Samw if (handle == NULL) 3895331Samw return (SMBD_SMF_SYSTEM_ERR); 3905331Samw 3915331Samw /* 3925331Samw * properties must be set in transactions and don't take 3935331Samw * effect until the transaction has been ended/committed. 3945331Samw */ 3955331Samw value = scf_value_create(handle->scf_handle); 3965331Samw entry = scf_entry_create(handle->scf_handle); 3975331Samw if (value != NULL && entry != NULL) { 3985331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 3995331Samw propname, SCF_TYPE_BOOLEAN) == 0 || 4005331Samw scf_transaction_property_new(handle->scf_trans, entry, 4015331Samw propname, SCF_TYPE_BOOLEAN) == 0) { 4025331Samw scf_value_set_boolean(value, valbool); 4035331Samw if (scf_entry_add_value(entry, value) != 0) { 4045331Samw ret = SMBD_SMF_SYSTEM_ERR; 4055331Samw scf_value_destroy(value); 4065331Samw } 4075331Samw /* the value is in the transaction */ 4085331Samw value = NULL; 4095331Samw } 4105331Samw /* the entry is in the transaction */ 4115331Samw entry = NULL; 4125331Samw } else { 4135331Samw ret = SMBD_SMF_SYSTEM_ERR; 4145331Samw } 4155331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 4165331Samw switch (scf_error()) { 4175331Samw case SCF_ERROR_PERMISSION_DENIED: 4185331Samw ret = SMBD_SMF_NO_PERMISSION; 4195331Samw break; 4205331Samw } 4215331Samw } 4225331Samw /* 4235331Samw * cleanup if there were any errors that didn't leave these 4245331Samw * values where they would be cleaned up later. 4255331Samw */ 4265331Samw if (value != NULL) 4275331Samw scf_value_destroy(value); 4285331Samw if (entry != NULL) 4295331Samw scf_entry_destroy(entry); 4305331Samw return (ret); 4315331Samw } 4325331Samw 4335331Samw /* 4345331Samw * Gets boolean property value. 4355331Samw * Caller is responsible to have enough memory allocated. 4365331Samw */ 4375331Samw int 4385331Samw smb_smf_get_boolean_property(smb_scfhandle_t *handle, char *propname, 4395331Samw uint8_t *valbool) 4405331Samw { 4415331Samw int ret = SMBD_SMF_OK; 4425331Samw scf_value_t *value = NULL; 4435331Samw scf_property_t *prop = NULL; 4445331Samw 4455331Samw if (handle == NULL) 4465331Samw return (SMBD_SMF_SYSTEM_ERR); 4475331Samw 4485331Samw value = scf_value_create(handle->scf_handle); 4495331Samw prop = scf_property_create(handle->scf_handle); 4505331Samw if ((prop) && (value) && 4515331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 4525331Samw if (scf_property_get_value(prop, value) == 0) { 4535331Samw if (scf_value_get_boolean(value, 4545331Samw valbool) != 0) { 4555331Samw ret = SMBD_SMF_SYSTEM_ERR; 4565331Samw } 4575331Samw } else { 4585331Samw ret = SMBD_SMF_SYSTEM_ERR; 4595331Samw } 4605331Samw } else { 4615331Samw ret = SMBD_SMF_SYSTEM_ERR; 4625331Samw } 4635331Samw if (value != NULL) 4645331Samw scf_value_destroy(value); 4655331Samw if (prop != NULL) 4665331Samw scf_property_destroy(prop); 4675331Samw return (ret); 4685331Samw } 4695331Samw 4705331Samw /* 4715331Samw * Sets a blob property value. 4725331Samw */ 4735331Samw int 4745331Samw smb_smf_set_opaque_property(smb_scfhandle_t *handle, char *propname, 4755331Samw void *voidval, size_t sz) 4765331Samw { 4775331Samw int ret = SMBD_SMF_OK; 4785331Samw scf_value_t *value; 4795331Samw scf_transaction_entry_t *entry; 4805331Samw 4815331Samw if (handle == NULL) 4825331Samw return (SMBD_SMF_SYSTEM_ERR); 4835331Samw 4845331Samw /* 4855331Samw * properties must be set in transactions and don't take 4865331Samw * effect until the transaction has been ended/committed. 4875331Samw */ 4885331Samw value = scf_value_create(handle->scf_handle); 4895331Samw entry = scf_entry_create(handle->scf_handle); 4905331Samw if (value != NULL && entry != NULL) { 4915331Samw if (scf_transaction_property_change(handle->scf_trans, entry, 4925331Samw propname, SCF_TYPE_OPAQUE) == 0 || 4935331Samw scf_transaction_property_new(handle->scf_trans, entry, 4945331Samw propname, SCF_TYPE_OPAQUE) == 0) { 4955331Samw if (scf_value_set_opaque(value, voidval, sz) == 0) { 4965331Samw if (scf_entry_add_value(entry, value) != 0) { 4975331Samw ret = SMBD_SMF_SYSTEM_ERR; 4985331Samw scf_value_destroy(value); 4995331Samw } 5005331Samw /* the value is in the transaction */ 5015331Samw value = NULL; 5025331Samw } else { 5035331Samw /* value couldn't be constructed */ 5045331Samw ret = SMBD_SMF_SYSTEM_ERR; 5055331Samw } 5065331Samw /* the entry is in the transaction */ 5075331Samw entry = NULL; 5085331Samw } else { 5095331Samw ret = SMBD_SMF_SYSTEM_ERR; 5105331Samw } 5115331Samw } else { 5125331Samw ret = SMBD_SMF_SYSTEM_ERR; 5135331Samw } 5145331Samw if (ret == SMBD_SMF_SYSTEM_ERR) { 5155331Samw switch (scf_error()) { 5165331Samw case SCF_ERROR_PERMISSION_DENIED: 5175331Samw ret = SMBD_SMF_NO_PERMISSION; 5185331Samw break; 5195331Samw } 5205331Samw } 5215331Samw /* 5225331Samw * cleanup if there were any errors that didn't leave these 5235331Samw * values where they would be cleaned up later. 5245331Samw */ 5255331Samw if (value != NULL) 5265331Samw scf_value_destroy(value); 5275331Samw if (entry != NULL) 5285331Samw scf_entry_destroy(entry); 5295331Samw return (ret); 5305331Samw } 5315331Samw 5325331Samw /* 5335331Samw * Gets a blob property value. 5345331Samw * Caller is responsible to have enough memory allocated. 5355331Samw */ 5365331Samw int 5375331Samw smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname, 5385331Samw void *v, size_t sz) 5395331Samw { 5405331Samw int ret = SMBD_SMF_OK; 5415331Samw scf_value_t *value = NULL; 5425331Samw scf_property_t *prop = NULL; 5435331Samw 5445331Samw if (handle == NULL) 5455331Samw return (SMBD_SMF_SYSTEM_ERR); 5465331Samw 5475331Samw value = scf_value_create(handle->scf_handle); 5485331Samw prop = scf_property_create(handle->scf_handle); 5495331Samw if ((prop) && (value) && 5505331Samw (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 5515331Samw if (scf_property_get_value(prop, value) == 0) { 5525331Samw if (scf_value_get_opaque(value, (char *)v, sz) != sz) { 5535331Samw ret = SMBD_SMF_SYSTEM_ERR; 5545331Samw } 5555331Samw } else { 5565331Samw ret = SMBD_SMF_SYSTEM_ERR; 5575331Samw } 5585331Samw } else { 5595331Samw ret = SMBD_SMF_SYSTEM_ERR; 5605331Samw } 5615331Samw if (value != NULL) 5625331Samw scf_value_destroy(value); 5635331Samw if (prop != NULL) 5645331Samw scf_property_destroy(prop); 5655331Samw return (ret); 5665331Samw } 5675331Samw 5685331Samw /* 5695331Samw * smb_smf_scf_init() 5705331Samw * 5715331Samw * must be called before using any of the SCF functions. 5725331Samw * Returns smb_scfhandle_t pointer if success. 5735331Samw */ 5745331Samw smb_scfhandle_t * 5755331Samw smb_smf_scf_init(char *svc_name) 5765331Samw { 5775331Samw smb_scfhandle_t *handle; 5785331Samw 5795331Samw handle = malloc(sizeof (smb_scfhandle_t)); 5805331Samw if (handle != NULL) { 5815331Samw bzero((char *)handle, sizeof (smb_scfhandle_t)); 5825331Samw handle->scf_state = SCH_STATE_INITIALIZING; 5835331Samw handle->scf_handle = scf_handle_create(SCF_VERSION); 5845331Samw if (handle->scf_handle != NULL) { 5855331Samw if (scf_handle_bind(handle->scf_handle) == 0) { 5865331Samw handle->scf_scope = 5875331Samw scf_scope_create(handle->scf_handle); 588*6030Sjb150015 589*6030Sjb150015 if (handle->scf_scope == NULL) 590*6030Sjb150015 goto err; 591*6030Sjb150015 5925331Samw if (scf_handle_get_local_scope( 5935331Samw handle->scf_handle, handle->scf_scope) != 0) 5945331Samw goto err; 5955331Samw 5965331Samw handle->scf_service = 5975331Samw scf_service_create(handle->scf_handle); 5985331Samw 599*6030Sjb150015 if (handle->scf_service == NULL) 600*6030Sjb150015 goto err; 601*6030Sjb150015 6025331Samw if (scf_scope_get_service(handle->scf_scope, 6035331Samw svc_name, handle->scf_service) 6045331Samw != SCF_SUCCESS) { 6055331Samw goto err; 6065331Samw } 6075331Samw handle->scf_pg = 6085331Samw scf_pg_create(handle->scf_handle); 609*6030Sjb150015 610*6030Sjb150015 if (handle->scf_pg == NULL) 611*6030Sjb150015 goto err; 612*6030Sjb150015 6135331Samw handle->scf_state = SCH_STATE_INIT; 6145331Samw } else { 6155331Samw goto err; 6165331Samw } 6175331Samw } else { 6185331Samw free(handle); 6195331Samw handle = NULL; 6205331Samw smb_smf_scf_log_error("Could not access SMF " 6215331Samw "repository: %s\n"); 6225331Samw } 6235331Samw } 6245331Samw return (handle); 6255331Samw 6265331Samw /* error handling/unwinding */ 6275331Samw err: 6285331Samw (void) smb_smf_scf_fini(handle); 6295331Samw (void) smb_smf_scf_log_error("SMF initialization problem: %s\n"); 6305331Samw return (NULL); 6315331Samw } 6325331Samw 6335331Samw /* 6345331Samw * smb_smf_scf_fini(handle) 6355331Samw * 6365331Samw * must be called when done. Called with the handle allocated in 6375331Samw * smb_smf_scf_init(), it cleans up the state and frees any SCF resources 6385331Samw * still in use. 6395331Samw */ 6405331Samw void 6415331Samw smb_smf_scf_fini(smb_scfhandle_t *handle) 6425331Samw { 6435331Samw if (handle != NULL) { 6445331Samw int unbind = 0; 6455331Samw scf_iter_destroy(handle->scf_pg_iter); 6465331Samw handle->scf_pg_iter = NULL; 6475331Samw 6485331Samw scf_iter_destroy(handle->scf_inst_iter); 6495331Samw handle->scf_inst_iter = NULL; 6505331Samw 6515331Samw unbind = 1; 6525331Samw scf_scope_destroy(handle->scf_scope); 6535331Samw handle->scf_scope = NULL; 6545331Samw 6555331Samw scf_instance_destroy(handle->scf_instance); 6565331Samw handle->scf_instance = NULL; 6575331Samw 6585331Samw scf_service_destroy(handle->scf_service); 6595331Samw handle->scf_service = NULL; 6605331Samw 6615331Samw scf_pg_destroy(handle->scf_pg); 6625331Samw handle->scf_pg = NULL; 6635331Samw 6645331Samw handle->scf_state = SCH_STATE_UNINIT; 6655331Samw if (unbind) 6665331Samw (void) scf_handle_unbind(handle->scf_handle); 6675331Samw scf_handle_destroy(handle->scf_handle); 6685331Samw handle->scf_handle = NULL; 6695331Samw 6705331Samw free(handle); 6715331Samw } 6725331Samw } 673