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