1*4bff34e3Sthurlow /* 2*4bff34e3Sthurlow * CDDL HEADER START 3*4bff34e3Sthurlow * 4*4bff34e3Sthurlow * The contents of this file are subject to the terms of the 5*4bff34e3Sthurlow * Common Development and Distribution License (the "License"). 6*4bff34e3Sthurlow * You may not use this file except in compliance with the License. 7*4bff34e3Sthurlow * 8*4bff34e3Sthurlow * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*4bff34e3Sthurlow * or http://www.opensolaris.org/os/licensing. 10*4bff34e3Sthurlow * See the License for the specific language governing permissions 11*4bff34e3Sthurlow * and limitations under the License. 12*4bff34e3Sthurlow * 13*4bff34e3Sthurlow * When distributing Covered Code, include this CDDL HEADER in each 14*4bff34e3Sthurlow * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*4bff34e3Sthurlow * If applicable, add the following below this CDDL HEADER, with the 16*4bff34e3Sthurlow * fields enclosed by brackets "[]" replaced with your own identifying 17*4bff34e3Sthurlow * information: Portions Copyright [yyyy] [name of copyright owner] 18*4bff34e3Sthurlow * 19*4bff34e3Sthurlow * CDDL HEADER END 20*4bff34e3Sthurlow */ 21*4bff34e3Sthurlow 22*4bff34e3Sthurlow /* 23*4bff34e3Sthurlow * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*4bff34e3Sthurlow * Use is subject to license terms. 25*4bff34e3Sthurlow */ 26*4bff34e3Sthurlow 27*4bff34e3Sthurlow #pragma ident "%Z%%M% %I% %E% SMI" 28*4bff34e3Sthurlow 29*4bff34e3Sthurlow /* helper functions for using libscf with CIFS */ 30*4bff34e3Sthurlow 31*4bff34e3Sthurlow #include <libscf.h> 32*4bff34e3Sthurlow #include <string.h> 33*4bff34e3Sthurlow #include <stdio.h> 34*4bff34e3Sthurlow #include <stdlib.h> 35*4bff34e3Sthurlow #include <syslog.h> 36*4bff34e3Sthurlow #include <errno.h> 37*4bff34e3Sthurlow #include <uuid/uuid.h> 38*4bff34e3Sthurlow #include <sys/param.h> 39*4bff34e3Sthurlow #include <libintl.h> 40*4bff34e3Sthurlow #include <assert.h> 41*4bff34e3Sthurlow #include <strings.h> 42*4bff34e3Sthurlow 43*4bff34e3Sthurlow #include "libshare.h" 44*4bff34e3Sthurlow #include "libshare_smbfs.h" 45*4bff34e3Sthurlow 46*4bff34e3Sthurlow /* 47*4bff34e3Sthurlow * smb_smf_scf_log_error(msg) 48*4bff34e3Sthurlow * Logs error messages from scf API's 49*4bff34e3Sthurlow */ 50*4bff34e3Sthurlow static void 51*4bff34e3Sthurlow smb_smf_scf_log_error(char *msg) 52*4bff34e3Sthurlow { 53*4bff34e3Sthurlow if (!msg) { 54*4bff34e3Sthurlow syslog(LOG_ERR, " SMBC SMF problem: %s\n", 55*4bff34e3Sthurlow scf_strerror(scf_error())); 56*4bff34e3Sthurlow } else { /*LINTED E_SEC_PRINTF_E_VAR_FMT*/ 57*4bff34e3Sthurlow syslog(LOG_ERR, msg, scf_strerror(scf_error())); 58*4bff34e3Sthurlow } 59*4bff34e3Sthurlow } 60*4bff34e3Sthurlow 61*4bff34e3Sthurlow /* 62*4bff34e3Sthurlow * smb_smf_scf_fini(handle) 63*4bff34e3Sthurlow * 64*4bff34e3Sthurlow * must be called when done. Called with the handle allocated in 65*4bff34e3Sthurlow * smb_smf_scf_init(), it cleans up the state and frees any SCF resources 66*4bff34e3Sthurlow * still in use. 67*4bff34e3Sthurlow */ 68*4bff34e3Sthurlow void 69*4bff34e3Sthurlow smb_smf_scf_fini(smb_scfhandle_t *handle) 70*4bff34e3Sthurlow { 71*4bff34e3Sthurlow if (handle != NULL) { 72*4bff34e3Sthurlow int unbind = 0; 73*4bff34e3Sthurlow if (handle->scf_pg_iter != NULL) { 74*4bff34e3Sthurlow scf_iter_destroy(handle->scf_pg_iter); 75*4bff34e3Sthurlow handle->scf_pg_iter = NULL; 76*4bff34e3Sthurlow } 77*4bff34e3Sthurlow if (handle->scf_inst_iter != NULL) { 78*4bff34e3Sthurlow scf_iter_destroy(handle->scf_inst_iter); 79*4bff34e3Sthurlow handle->scf_inst_iter = NULL; 80*4bff34e3Sthurlow } 81*4bff34e3Sthurlow if (handle->scf_scope != NULL) { 82*4bff34e3Sthurlow unbind = 1; 83*4bff34e3Sthurlow scf_scope_destroy(handle->scf_scope); 84*4bff34e3Sthurlow handle->scf_scope = NULL; 85*4bff34e3Sthurlow } 86*4bff34e3Sthurlow if (handle->scf_instance != NULL) { 87*4bff34e3Sthurlow scf_instance_destroy(handle->scf_instance); 88*4bff34e3Sthurlow handle->scf_instance = NULL; 89*4bff34e3Sthurlow } 90*4bff34e3Sthurlow if (handle->scf_service != NULL) { 91*4bff34e3Sthurlow scf_service_destroy(handle->scf_service); 92*4bff34e3Sthurlow handle->scf_service = NULL; 93*4bff34e3Sthurlow } 94*4bff34e3Sthurlow if (handle->scf_pg != NULL) { 95*4bff34e3Sthurlow scf_pg_destroy(handle->scf_pg); 96*4bff34e3Sthurlow handle->scf_pg = NULL; 97*4bff34e3Sthurlow } 98*4bff34e3Sthurlow if (handle->scf_handle != NULL) { 99*4bff34e3Sthurlow handle->scf_state = SCH_STATE_UNINIT; 100*4bff34e3Sthurlow if (unbind) 101*4bff34e3Sthurlow (void) scf_handle_unbind(handle->scf_handle); 102*4bff34e3Sthurlow scf_handle_destroy(handle->scf_handle); 103*4bff34e3Sthurlow handle->scf_handle = NULL; 104*4bff34e3Sthurlow } 105*4bff34e3Sthurlow free(handle); 106*4bff34e3Sthurlow } 107*4bff34e3Sthurlow } 108*4bff34e3Sthurlow 109*4bff34e3Sthurlow 110*4bff34e3Sthurlow /* 111*4bff34e3Sthurlow * Check if instance with given name exists for a service. 112*4bff34e3Sthurlow * Returns 0 is instance exist 113*4bff34e3Sthurlow */ 114*4bff34e3Sthurlow int 115*4bff34e3Sthurlow smb_smf_instance_exists(smb_scfhandle_t *handle, char *inst_name) 116*4bff34e3Sthurlow { 117*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 118*4bff34e3Sthurlow if (handle == NULL) { 119*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 120*4bff34e3Sthurlow } 121*4bff34e3Sthurlow 122*4bff34e3Sthurlow handle->scf_instance = scf_instance_create(handle->scf_handle); 123*4bff34e3Sthurlow if (scf_service_get_instance(handle->scf_service, inst_name, 124*4bff34e3Sthurlow handle->scf_instance) != SCF_SUCCESS) { 125*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 126*4bff34e3Sthurlow } 127*4bff34e3Sthurlow scf_instance_destroy(handle->scf_instance); 128*4bff34e3Sthurlow handle->scf_instance = NULL; 129*4bff34e3Sthurlow return (ret); 130*4bff34e3Sthurlow } 131*4bff34e3Sthurlow 132*4bff34e3Sthurlow /* 133*4bff34e3Sthurlow * Create a service instance. returns 0 if successful. 134*4bff34e3Sthurlow * If instance already exists enable it. 135*4bff34e3Sthurlow */ 136*4bff34e3Sthurlow int 137*4bff34e3Sthurlow smb_smf_instance_create(smb_scfhandle_t *handle, char *serv_prefix, 138*4bff34e3Sthurlow char *inst_name) 139*4bff34e3Sthurlow { 140*4bff34e3Sthurlow char *instance; 141*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 142*4bff34e3Sthurlow int sz; 143*4bff34e3Sthurlow 144*4bff34e3Sthurlow if (handle == NULL) { 145*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 146*4bff34e3Sthurlow } 147*4bff34e3Sthurlow 148*4bff34e3Sthurlow if (!serv_prefix || !inst_name) { 149*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 150*4bff34e3Sthurlow } 151*4bff34e3Sthurlow sz = strlen(serv_prefix) + strlen(inst_name) + 2; 152*4bff34e3Sthurlow instance = malloc(sz); 153*4bff34e3Sthurlow if (!instance) { 154*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 155*4bff34e3Sthurlow } 156*4bff34e3Sthurlow (void) snprintf(instance, sz, "%s:%s", serv_prefix, inst_name); 157*4bff34e3Sthurlow handle->scf_instance = scf_instance_create(handle->scf_handle); 158*4bff34e3Sthurlow if (scf_service_get_instance(handle->scf_service, inst_name, 159*4bff34e3Sthurlow handle->scf_instance) != SCF_SUCCESS) { 160*4bff34e3Sthurlow if (scf_service_add_instance(handle->scf_service, 161*4bff34e3Sthurlow inst_name, handle->scf_instance) == SCF_SUCCESS) { 162*4bff34e3Sthurlow if (smf_enable_instance(instance, 0)) 163*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 164*4bff34e3Sthurlow } else { 165*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 166*4bff34e3Sthurlow } 167*4bff34e3Sthurlow } else { 168*4bff34e3Sthurlow if (smf_enable_instance(instance, 0)) 169*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 170*4bff34e3Sthurlow } 171*4bff34e3Sthurlow free(instance); 172*4bff34e3Sthurlow return (ret); 173*4bff34e3Sthurlow } 174*4bff34e3Sthurlow 175*4bff34e3Sthurlow /* 176*4bff34e3Sthurlow * Delete a specified instance. Return SMBC_SMF_OK for success. 177*4bff34e3Sthurlow */ 178*4bff34e3Sthurlow int 179*4bff34e3Sthurlow smb_smf_instance_delete(smb_scfhandle_t *handle, char *inst_name) 180*4bff34e3Sthurlow { 181*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 182*4bff34e3Sthurlow 183*4bff34e3Sthurlow if (handle == NULL) { 184*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 185*4bff34e3Sthurlow } 186*4bff34e3Sthurlow 187*4bff34e3Sthurlow handle->scf_instance = scf_instance_create(handle->scf_handle); 188*4bff34e3Sthurlow if (scf_service_get_instance(handle->scf_service, inst_name, 189*4bff34e3Sthurlow handle->scf_instance) == SCF_SUCCESS) { 190*4bff34e3Sthurlow if (scf_instance_delete(handle->scf_instance) == SCF_SUCCESS) { 191*4bff34e3Sthurlow return (ret); 192*4bff34e3Sthurlow } else { 193*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 194*4bff34e3Sthurlow } 195*4bff34e3Sthurlow } else { 196*4bff34e3Sthurlow smb_smf_scf_log_error(NULL); 197*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 198*4bff34e3Sthurlow } 199*4bff34e3Sthurlow return (ret); 200*4bff34e3Sthurlow } 201*4bff34e3Sthurlow 202*4bff34e3Sthurlow /* 203*4bff34e3Sthurlow * smb_smf_scf_init() 204*4bff34e3Sthurlow * 205*4bff34e3Sthurlow * must be called before using any of the SCF functions. 206*4bff34e3Sthurlow * Returns smb_scfhandle_t pointer if success. 207*4bff34e3Sthurlow */ 208*4bff34e3Sthurlow smb_scfhandle_t * 209*4bff34e3Sthurlow smb_smf_scf_init(char *svc_name) 210*4bff34e3Sthurlow { 211*4bff34e3Sthurlow smb_scfhandle_t *handle; 212*4bff34e3Sthurlow 213*4bff34e3Sthurlow handle = malloc(sizeof (smb_scfhandle_t)); 214*4bff34e3Sthurlow if (handle != NULL) { 215*4bff34e3Sthurlow bzero((char *)handle, sizeof (smb_scfhandle_t)); 216*4bff34e3Sthurlow handle->scf_state = SCH_STATE_INITIALIZING; 217*4bff34e3Sthurlow handle->scf_handle = scf_handle_create(SCF_VERSION); 218*4bff34e3Sthurlow if (handle->scf_handle != NULL) { 219*4bff34e3Sthurlow if (scf_handle_bind(handle->scf_handle) == 0) { 220*4bff34e3Sthurlow handle->scf_scope = 221*4bff34e3Sthurlow scf_scope_create(handle->scf_handle); 222*4bff34e3Sthurlow if (scf_handle_get_local_scope( 223*4bff34e3Sthurlow handle->scf_handle, handle->scf_scope) != 0) 224*4bff34e3Sthurlow goto err; 225*4bff34e3Sthurlow 226*4bff34e3Sthurlow handle->scf_service = 227*4bff34e3Sthurlow scf_service_create(handle->scf_handle); 228*4bff34e3Sthurlow 229*4bff34e3Sthurlow if (scf_scope_get_service(handle->scf_scope, 230*4bff34e3Sthurlow svc_name, handle->scf_service) 231*4bff34e3Sthurlow != SCF_SUCCESS) { 232*4bff34e3Sthurlow goto err; 233*4bff34e3Sthurlow } 234*4bff34e3Sthurlow handle->scf_pg = 235*4bff34e3Sthurlow scf_pg_create(handle->scf_handle); 236*4bff34e3Sthurlow handle->scf_state = SCH_STATE_INIT; 237*4bff34e3Sthurlow } else { 238*4bff34e3Sthurlow goto err; 239*4bff34e3Sthurlow } 240*4bff34e3Sthurlow } else { 241*4bff34e3Sthurlow free(handle); 242*4bff34e3Sthurlow handle = NULL; 243*4bff34e3Sthurlow smb_smf_scf_log_error("Could not access SMF " 244*4bff34e3Sthurlow "repository: %s\n"); 245*4bff34e3Sthurlow } 246*4bff34e3Sthurlow } 247*4bff34e3Sthurlow return (handle); 248*4bff34e3Sthurlow 249*4bff34e3Sthurlow /* error handling/unwinding */ 250*4bff34e3Sthurlow err: 251*4bff34e3Sthurlow (void) smb_smf_scf_fini(handle); 252*4bff34e3Sthurlow (void) smb_smf_scf_log_error("SMF initialization problem: %s\n"); 253*4bff34e3Sthurlow return (NULL); 254*4bff34e3Sthurlow } 255*4bff34e3Sthurlow 256*4bff34e3Sthurlow /* 257*4bff34e3Sthurlow * smb_smf_create_service_pgroup(handle, pgroup) 258*4bff34e3Sthurlow * 259*4bff34e3Sthurlow * create a new property group at service level. 260*4bff34e3Sthurlow */ 261*4bff34e3Sthurlow int 262*4bff34e3Sthurlow smb_smf_create_service_pgroup(smb_scfhandle_t *handle, char *pgroup) 263*4bff34e3Sthurlow { 264*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 265*4bff34e3Sthurlow int err; 266*4bff34e3Sthurlow 267*4bff34e3Sthurlow if (handle == NULL) { 268*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 269*4bff34e3Sthurlow } 270*4bff34e3Sthurlow 271*4bff34e3Sthurlow /* 272*4bff34e3Sthurlow * only create a handle if it doesn't exist. It is ok to exist 273*4bff34e3Sthurlow * since the pg handle will be set as a side effect. 274*4bff34e3Sthurlow */ 275*4bff34e3Sthurlow if (handle->scf_pg == NULL) { 276*4bff34e3Sthurlow handle->scf_pg = scf_pg_create(handle->scf_handle); 277*4bff34e3Sthurlow } 278*4bff34e3Sthurlow /* 279*4bff34e3Sthurlow * if the pgroup exists, we are done. If it doesn't, then we 280*4bff34e3Sthurlow * need to actually add one to the service instance. 281*4bff34e3Sthurlow */ 282*4bff34e3Sthurlow if (scf_service_get_pg(handle->scf_service, 283*4bff34e3Sthurlow pgroup, handle->scf_pg) != 0) { 284*4bff34e3Sthurlow /* doesn't exist so create one */ 285*4bff34e3Sthurlow if (scf_service_add_pg(handle->scf_service, pgroup, 286*4bff34e3Sthurlow SCF_GROUP_FRAMEWORK, 0, handle->scf_pg) != 0) { 287*4bff34e3Sthurlow err = scf_error(); 288*4bff34e3Sthurlow if (err != SCF_ERROR_NONE) 289*4bff34e3Sthurlow smb_smf_scf_log_error(NULL); 290*4bff34e3Sthurlow switch (err) { 291*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 292*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 293*4bff34e3Sthurlow break; 294*4bff34e3Sthurlow default: 295*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 296*4bff34e3Sthurlow break; 297*4bff34e3Sthurlow } 298*4bff34e3Sthurlow } 299*4bff34e3Sthurlow } 300*4bff34e3Sthurlow return (ret); 301*4bff34e3Sthurlow } 302*4bff34e3Sthurlow 303*4bff34e3Sthurlow /* 304*4bff34e3Sthurlow * smb_smf_create_instance_pgroup(handle, pgroup) 305*4bff34e3Sthurlow * 306*4bff34e3Sthurlow * create a new property group at instance level. 307*4bff34e3Sthurlow */ 308*4bff34e3Sthurlow int 309*4bff34e3Sthurlow smb_smf_create_instance_pgroup(smb_scfhandle_t *handle, char *pgroup) 310*4bff34e3Sthurlow { 311*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 312*4bff34e3Sthurlow int err; 313*4bff34e3Sthurlow 314*4bff34e3Sthurlow if (handle == NULL) { 315*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 316*4bff34e3Sthurlow } 317*4bff34e3Sthurlow 318*4bff34e3Sthurlow /* 319*4bff34e3Sthurlow * only create a handle if it doesn't exist. It is ok to exist 320*4bff34e3Sthurlow * since the pg handle will be set as a side effect. 321*4bff34e3Sthurlow */ 322*4bff34e3Sthurlow if (handle->scf_pg == NULL) { 323*4bff34e3Sthurlow handle->scf_pg = scf_pg_create(handle->scf_handle); 324*4bff34e3Sthurlow } 325*4bff34e3Sthurlow 326*4bff34e3Sthurlow /* 327*4bff34e3Sthurlow * if the pgroup exists, we are done. If it doesn't, then we 328*4bff34e3Sthurlow * need to actually add one to the service instance. 329*4bff34e3Sthurlow */ 330*4bff34e3Sthurlow if (scf_instance_get_pg(handle->scf_instance, 331*4bff34e3Sthurlow pgroup, handle->scf_pg) != 0) { 332*4bff34e3Sthurlow /* doesn't exist so create one */ 333*4bff34e3Sthurlow if (scf_instance_add_pg(handle->scf_instance, pgroup, 334*4bff34e3Sthurlow SCF_GROUP_APPLICATION, 0, handle->scf_pg) != 0) { 335*4bff34e3Sthurlow err = scf_error(); 336*4bff34e3Sthurlow if (err != SCF_ERROR_NONE) 337*4bff34e3Sthurlow smb_smf_scf_log_error(NULL); 338*4bff34e3Sthurlow switch (err) { 339*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 340*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 341*4bff34e3Sthurlow break; 342*4bff34e3Sthurlow default: 343*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 344*4bff34e3Sthurlow break; 345*4bff34e3Sthurlow } 346*4bff34e3Sthurlow } 347*4bff34e3Sthurlow } 348*4bff34e3Sthurlow return (ret); 349*4bff34e3Sthurlow } 350*4bff34e3Sthurlow 351*4bff34e3Sthurlow /* 352*4bff34e3Sthurlow * smb_smf_delete_service_pgroup(handle, pgroup) 353*4bff34e3Sthurlow * 354*4bff34e3Sthurlow * remove the property group from the current service. 355*4bff34e3Sthurlow * but only if it actually exists. 356*4bff34e3Sthurlow */ 357*4bff34e3Sthurlow int 358*4bff34e3Sthurlow smb_smf_delete_service_pgroup(smb_scfhandle_t *handle, char *pgroup) 359*4bff34e3Sthurlow { 360*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 361*4bff34e3Sthurlow int err; 362*4bff34e3Sthurlow 363*4bff34e3Sthurlow if (handle == NULL) { 364*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 365*4bff34e3Sthurlow } 366*4bff34e3Sthurlow 367*4bff34e3Sthurlow /* 368*4bff34e3Sthurlow * only create a handle if it doesn't exist. It is ok to exist 369*4bff34e3Sthurlow * since the pg handle will be set as a side effect. 370*4bff34e3Sthurlow */ 371*4bff34e3Sthurlow if (handle->scf_pg == NULL) { 372*4bff34e3Sthurlow handle->scf_pg = scf_pg_create(handle->scf_handle); 373*4bff34e3Sthurlow } 374*4bff34e3Sthurlow 375*4bff34e3Sthurlow /* 376*4bff34e3Sthurlow * only delete if it does exist. 377*4bff34e3Sthurlow */ 378*4bff34e3Sthurlow if (scf_service_get_pg(handle->scf_service, 379*4bff34e3Sthurlow pgroup, handle->scf_pg) == 0) { 380*4bff34e3Sthurlow /* does exist so delete it */ 381*4bff34e3Sthurlow if (scf_pg_delete(handle->scf_pg) != 0) { 382*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 383*4bff34e3Sthurlow err = scf_error(); 384*4bff34e3Sthurlow if (err != SCF_ERROR_NONE) { 385*4bff34e3Sthurlow smb_smf_scf_log_error("SMF delpg " 386*4bff34e3Sthurlow "problem: %s\n"); 387*4bff34e3Sthurlow } 388*4bff34e3Sthurlow } 389*4bff34e3Sthurlow } else { 390*4bff34e3Sthurlow err = scf_error(); 391*4bff34e3Sthurlow if (err != SCF_ERROR_NONE) 392*4bff34e3Sthurlow smb_smf_scf_log_error("SMF getpg problem: %s\n"); 393*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 394*4bff34e3Sthurlow } 395*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR && 396*4bff34e3Sthurlow scf_error() == SCF_ERROR_PERMISSION_DENIED) { 397*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 398*4bff34e3Sthurlow } 399*4bff34e3Sthurlow return (ret); 400*4bff34e3Sthurlow } 401*4bff34e3Sthurlow 402*4bff34e3Sthurlow /* 403*4bff34e3Sthurlow * smb_smf_delete_instance_pgroup(handle, pgroup) 404*4bff34e3Sthurlow * 405*4bff34e3Sthurlow * remove the property group from the current instance. 406*4bff34e3Sthurlow * but only if it actually exists. 407*4bff34e3Sthurlow */ 408*4bff34e3Sthurlow int 409*4bff34e3Sthurlow smb_smf_delete_instance_pgroup(smb_scfhandle_t *handle, char *pgroup) 410*4bff34e3Sthurlow { 411*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 412*4bff34e3Sthurlow int err; 413*4bff34e3Sthurlow 414*4bff34e3Sthurlow if (handle == NULL) { 415*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 416*4bff34e3Sthurlow } 417*4bff34e3Sthurlow 418*4bff34e3Sthurlow /* 419*4bff34e3Sthurlow * only create a handle if it doesn't exist. It is ok to exist 420*4bff34e3Sthurlow * since the pg handle will be set as a side effect. 421*4bff34e3Sthurlow */ 422*4bff34e3Sthurlow if (handle->scf_pg == NULL) { 423*4bff34e3Sthurlow handle->scf_pg = scf_pg_create(handle->scf_handle); 424*4bff34e3Sthurlow } 425*4bff34e3Sthurlow 426*4bff34e3Sthurlow /* 427*4bff34e3Sthurlow * only delete if it does exist. 428*4bff34e3Sthurlow */ 429*4bff34e3Sthurlow if (scf_instance_get_pg(handle->scf_instance, 430*4bff34e3Sthurlow pgroup, handle->scf_pg) == 0) { 431*4bff34e3Sthurlow /* does exist so delete it */ 432*4bff34e3Sthurlow if (scf_pg_delete(handle->scf_pg) != 0) { 433*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 434*4bff34e3Sthurlow err = scf_error(); 435*4bff34e3Sthurlow if (err != SCF_ERROR_NONE) { 436*4bff34e3Sthurlow smb_smf_scf_log_error("SMF delpg " 437*4bff34e3Sthurlow "problem: %s\n"); 438*4bff34e3Sthurlow } 439*4bff34e3Sthurlow } 440*4bff34e3Sthurlow } else { 441*4bff34e3Sthurlow err = scf_error(); 442*4bff34e3Sthurlow if (err != SCF_ERROR_NONE) 443*4bff34e3Sthurlow smb_smf_scf_log_error("SMF getpg problem: %s\n"); 444*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 445*4bff34e3Sthurlow } 446*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR && 447*4bff34e3Sthurlow scf_error() == SCF_ERROR_PERMISSION_DENIED) { 448*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 449*4bff34e3Sthurlow } 450*4bff34e3Sthurlow return (ret); 451*4bff34e3Sthurlow } 452*4bff34e3Sthurlow 453*4bff34e3Sthurlow /* 454*4bff34e3Sthurlow * Start transaction on current pg in handle. 455*4bff34e3Sthurlow * The pg could be service or instance level. 456*4bff34e3Sthurlow * Must be called after pg handle is obtained 457*4bff34e3Sthurlow * from create or get. 458*4bff34e3Sthurlow */ 459*4bff34e3Sthurlow int 460*4bff34e3Sthurlow smb_smf_start_transaction(smb_scfhandle_t *handle) 461*4bff34e3Sthurlow { 462*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 463*4bff34e3Sthurlow 464*4bff34e3Sthurlow if (!handle || (!handle->scf_pg)) { 465*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 466*4bff34e3Sthurlow } 467*4bff34e3Sthurlow /* 468*4bff34e3Sthurlow * lookup the property group and create it if it doesn't already 469*4bff34e3Sthurlow * exist. 470*4bff34e3Sthurlow */ 471*4bff34e3Sthurlow if (handle->scf_state == SCH_STATE_INIT) { 472*4bff34e3Sthurlow if (ret == SMBC_SMF_OK) { 473*4bff34e3Sthurlow handle->scf_trans = 474*4bff34e3Sthurlow scf_transaction_create(handle->scf_handle); 475*4bff34e3Sthurlow if (handle->scf_trans != NULL) { 476*4bff34e3Sthurlow if (scf_transaction_start(handle->scf_trans, 477*4bff34e3Sthurlow handle->scf_pg) != 0) { 478*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 479*4bff34e3Sthurlow scf_transaction_destroy( 480*4bff34e3Sthurlow handle->scf_trans); 481*4bff34e3Sthurlow handle->scf_trans = NULL; 482*4bff34e3Sthurlow } 483*4bff34e3Sthurlow } else { 484*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 485*4bff34e3Sthurlow } 486*4bff34e3Sthurlow } 487*4bff34e3Sthurlow } 488*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR && 489*4bff34e3Sthurlow scf_error() == SCF_ERROR_PERMISSION_DENIED) { 490*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 491*4bff34e3Sthurlow } 492*4bff34e3Sthurlow return (ret); 493*4bff34e3Sthurlow } 494*4bff34e3Sthurlow 495*4bff34e3Sthurlow /* 496*4bff34e3Sthurlow * smb_smf_end_transaction(handle) 497*4bff34e3Sthurlow * 498*4bff34e3Sthurlow * Commit the changes that were added to the transaction in the 499*4bff34e3Sthurlow * handle. Do all necessary cleanup. 500*4bff34e3Sthurlow */ 501*4bff34e3Sthurlow int 502*4bff34e3Sthurlow smb_smf_end_transaction(smb_scfhandle_t *handle) 503*4bff34e3Sthurlow { 504*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 505*4bff34e3Sthurlow 506*4bff34e3Sthurlow if (handle == NULL) { 507*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 508*4bff34e3Sthurlow } 509*4bff34e3Sthurlow 510*4bff34e3Sthurlow if (handle->scf_trans == NULL) { 511*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 512*4bff34e3Sthurlow } else { 513*4bff34e3Sthurlow if (scf_transaction_commit(handle->scf_trans) < 0) { 514*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 515*4bff34e3Sthurlow smb_smf_scf_log_error("Failed to commit " 516*4bff34e3Sthurlow "transaction: %s"); 517*4bff34e3Sthurlow } 518*4bff34e3Sthurlow scf_transaction_destroy_children(handle->scf_trans); 519*4bff34e3Sthurlow scf_transaction_destroy(handle->scf_trans); 520*4bff34e3Sthurlow handle->scf_trans = NULL; 521*4bff34e3Sthurlow } 522*4bff34e3Sthurlow return (ret); 523*4bff34e3Sthurlow } 524*4bff34e3Sthurlow 525*4bff34e3Sthurlow /* 526*4bff34e3Sthurlow * Deletes property in current pg 527*4bff34e3Sthurlow */ 528*4bff34e3Sthurlow int 529*4bff34e3Sthurlow smb_smf_delete_property(smb_scfhandle_t *handle, char *propname) 530*4bff34e3Sthurlow { 531*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 532*4bff34e3Sthurlow scf_transaction_entry_t *entry = NULL; 533*4bff34e3Sthurlow 534*4bff34e3Sthurlow if (handle == NULL) { 535*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 536*4bff34e3Sthurlow } 537*4bff34e3Sthurlow 538*4bff34e3Sthurlow /* 539*4bff34e3Sthurlow * properties must be set in transactions and don't take 540*4bff34e3Sthurlow * effect until the transaction has been ended/committed. 541*4bff34e3Sthurlow */ 542*4bff34e3Sthurlow entry = scf_entry_create(handle->scf_handle); 543*4bff34e3Sthurlow if (entry != NULL) { 544*4bff34e3Sthurlow if (scf_transaction_property_delete(handle->scf_trans, entry, 545*4bff34e3Sthurlow propname) != 0) { 546*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 547*4bff34e3Sthurlow } 548*4bff34e3Sthurlow } else { 549*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 550*4bff34e3Sthurlow } 551*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR) { 552*4bff34e3Sthurlow switch (scf_error()) { 553*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 554*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 555*4bff34e3Sthurlow break; 556*4bff34e3Sthurlow } 557*4bff34e3Sthurlow } 558*4bff34e3Sthurlow 559*4bff34e3Sthurlow /* 560*4bff34e3Sthurlow * cleanup if there were any errors that didn't leave these 561*4bff34e3Sthurlow * values where they would be cleaned up later. 562*4bff34e3Sthurlow */ 563*4bff34e3Sthurlow if ((ret != SMBC_SMF_OK) && (entry != NULL)) { 564*4bff34e3Sthurlow scf_entry_destroy(entry); 565*4bff34e3Sthurlow } 566*4bff34e3Sthurlow return (ret); 567*4bff34e3Sthurlow } 568*4bff34e3Sthurlow 569*4bff34e3Sthurlow /* 570*4bff34e3Sthurlow * Sets string property in current pg 571*4bff34e3Sthurlow */ 572*4bff34e3Sthurlow int 573*4bff34e3Sthurlow smb_smf_set_string_property(smb_scfhandle_t *handle, 574*4bff34e3Sthurlow char *propname, char *valstr) 575*4bff34e3Sthurlow { 576*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 577*4bff34e3Sthurlow scf_value_t *value = NULL; 578*4bff34e3Sthurlow scf_transaction_entry_t *entry = NULL; 579*4bff34e3Sthurlow 580*4bff34e3Sthurlow if (handle == NULL) { 581*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 582*4bff34e3Sthurlow } 583*4bff34e3Sthurlow 584*4bff34e3Sthurlow /* 585*4bff34e3Sthurlow * properties must be set in transactions and don't take 586*4bff34e3Sthurlow * effect until the transaction has been ended/committed. 587*4bff34e3Sthurlow */ 588*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 589*4bff34e3Sthurlow entry = scf_entry_create(handle->scf_handle); 590*4bff34e3Sthurlow if (value != NULL && entry != NULL) { 591*4bff34e3Sthurlow if (scf_transaction_property_change(handle->scf_trans, entry, 592*4bff34e3Sthurlow propname, SCF_TYPE_ASTRING) == 0 || 593*4bff34e3Sthurlow scf_transaction_property_new(handle->scf_trans, entry, 594*4bff34e3Sthurlow propname, SCF_TYPE_ASTRING) == 0) { 595*4bff34e3Sthurlow if (scf_value_set_astring(value, valstr) == 0) { 596*4bff34e3Sthurlow if (scf_entry_add_value(entry, value) != 0) { 597*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 598*4bff34e3Sthurlow scf_value_destroy(value); 599*4bff34e3Sthurlow } 600*4bff34e3Sthurlow /* the value is in the transaction */ 601*4bff34e3Sthurlow value = NULL; 602*4bff34e3Sthurlow } else { 603*4bff34e3Sthurlow /* value couldn't be constructed */ 604*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 605*4bff34e3Sthurlow } 606*4bff34e3Sthurlow /* the entry is in the transaction */ 607*4bff34e3Sthurlow entry = NULL; 608*4bff34e3Sthurlow } else { 609*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 610*4bff34e3Sthurlow } 611*4bff34e3Sthurlow } else { 612*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 613*4bff34e3Sthurlow } 614*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR) { 615*4bff34e3Sthurlow switch (scf_error()) { 616*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 617*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 618*4bff34e3Sthurlow break; 619*4bff34e3Sthurlow } 620*4bff34e3Sthurlow } 621*4bff34e3Sthurlow 622*4bff34e3Sthurlow /* 623*4bff34e3Sthurlow * cleanup if there were any errors that didn't leave these 624*4bff34e3Sthurlow * values where they would be cleaned up later. 625*4bff34e3Sthurlow */ 626*4bff34e3Sthurlow if (value != NULL) 627*4bff34e3Sthurlow scf_value_destroy(value); 628*4bff34e3Sthurlow if (entry != NULL) 629*4bff34e3Sthurlow scf_entry_destroy(entry); 630*4bff34e3Sthurlow return (ret); 631*4bff34e3Sthurlow } 632*4bff34e3Sthurlow 633*4bff34e3Sthurlow /* 634*4bff34e3Sthurlow * Gets string property value.upto sz size. 635*4bff34e3Sthurlow * Caller is responsible to have enough memory allocated. 636*4bff34e3Sthurlow */ 637*4bff34e3Sthurlow int 638*4bff34e3Sthurlow smb_smf_get_string_property(smb_scfhandle_t *handle, char *propname, 639*4bff34e3Sthurlow char *valstr, size_t sz) 640*4bff34e3Sthurlow { 641*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 642*4bff34e3Sthurlow scf_value_t *value; 643*4bff34e3Sthurlow scf_property_t *prop; 644*4bff34e3Sthurlow 645*4bff34e3Sthurlow if (handle == NULL) { 646*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 647*4bff34e3Sthurlow } 648*4bff34e3Sthurlow 649*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 650*4bff34e3Sthurlow prop = scf_property_create(handle->scf_handle); 651*4bff34e3Sthurlow if (value && prop && 652*4bff34e3Sthurlow (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 653*4bff34e3Sthurlow if (scf_property_get_value(prop, value) == 0) { 654*4bff34e3Sthurlow if (scf_value_get_astring(value, valstr, sz) < 0) { 655*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 656*4bff34e3Sthurlow } 657*4bff34e3Sthurlow } else { 658*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 659*4bff34e3Sthurlow } 660*4bff34e3Sthurlow } else { 661*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 662*4bff34e3Sthurlow } 663*4bff34e3Sthurlow if (value != NULL) 664*4bff34e3Sthurlow scf_value_destroy(value); 665*4bff34e3Sthurlow if (prop != NULL) 666*4bff34e3Sthurlow scf_property_destroy(prop); 667*4bff34e3Sthurlow return (ret); 668*4bff34e3Sthurlow } 669*4bff34e3Sthurlow 670*4bff34e3Sthurlow /* 671*4bff34e3Sthurlow * Get integer value of property. 672*4bff34e3Sthurlow * The value is returned as int64_t value 673*4bff34e3Sthurlow * Caller ensures appropriate translation. 674*4bff34e3Sthurlow */ 675*4bff34e3Sthurlow int 676*4bff34e3Sthurlow smb_smf_set_integer_property(smb_scfhandle_t *handle, char *propname, 677*4bff34e3Sthurlow int64_t valint) 678*4bff34e3Sthurlow { 679*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 680*4bff34e3Sthurlow scf_value_t *value = NULL; 681*4bff34e3Sthurlow scf_transaction_entry_t *entry = NULL; 682*4bff34e3Sthurlow 683*4bff34e3Sthurlow if (handle == NULL) { 684*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 685*4bff34e3Sthurlow } 686*4bff34e3Sthurlow 687*4bff34e3Sthurlow /* 688*4bff34e3Sthurlow * properties must be set in transactions and don't take 689*4bff34e3Sthurlow * effect until the transaction has been ended/committed. 690*4bff34e3Sthurlow */ 691*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 692*4bff34e3Sthurlow entry = scf_entry_create(handle->scf_handle); 693*4bff34e3Sthurlow if (value != NULL && entry != NULL) { 694*4bff34e3Sthurlow if (scf_transaction_property_change(handle->scf_trans, entry, 695*4bff34e3Sthurlow propname, SCF_TYPE_INTEGER) == 0 || 696*4bff34e3Sthurlow scf_transaction_property_new(handle->scf_trans, entry, 697*4bff34e3Sthurlow propname, SCF_TYPE_INTEGER) == 0) { 698*4bff34e3Sthurlow scf_value_set_integer(value, valint); 699*4bff34e3Sthurlow if (scf_entry_add_value(entry, value) != 0) { 700*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 701*4bff34e3Sthurlow scf_value_destroy(value); 702*4bff34e3Sthurlow } 703*4bff34e3Sthurlow /* the value is in the transaction */ 704*4bff34e3Sthurlow value = NULL; 705*4bff34e3Sthurlow } 706*4bff34e3Sthurlow /* the entry is in the transaction */ 707*4bff34e3Sthurlow entry = NULL; 708*4bff34e3Sthurlow } else { 709*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 710*4bff34e3Sthurlow } 711*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR) { 712*4bff34e3Sthurlow switch (scf_error()) { 713*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 714*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 715*4bff34e3Sthurlow break; 716*4bff34e3Sthurlow } 717*4bff34e3Sthurlow } 718*4bff34e3Sthurlow /* 719*4bff34e3Sthurlow * cleanup if there were any errors that didn't leave these 720*4bff34e3Sthurlow * values where they would be cleaned up later. 721*4bff34e3Sthurlow */ 722*4bff34e3Sthurlow if (value != NULL) 723*4bff34e3Sthurlow scf_value_destroy(value); 724*4bff34e3Sthurlow if (entry != NULL) 725*4bff34e3Sthurlow scf_entry_destroy(entry); 726*4bff34e3Sthurlow return (ret); 727*4bff34e3Sthurlow } 728*4bff34e3Sthurlow 729*4bff34e3Sthurlow /* 730*4bff34e3Sthurlow * Sets integer property value. 731*4bff34e3Sthurlow * Caller is responsible to have enough memory allocated. 732*4bff34e3Sthurlow */ 733*4bff34e3Sthurlow int 734*4bff34e3Sthurlow smb_smf_get_integer_property(smb_scfhandle_t *handle, char *propname, 735*4bff34e3Sthurlow int64_t *valint) 736*4bff34e3Sthurlow { 737*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 738*4bff34e3Sthurlow scf_value_t *value = NULL; 739*4bff34e3Sthurlow scf_property_t *prop = NULL; 740*4bff34e3Sthurlow 741*4bff34e3Sthurlow if (handle == NULL) { 742*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 743*4bff34e3Sthurlow } 744*4bff34e3Sthurlow 745*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 746*4bff34e3Sthurlow prop = scf_property_create(handle->scf_handle); 747*4bff34e3Sthurlow if ((prop) && (value) && 748*4bff34e3Sthurlow (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 749*4bff34e3Sthurlow if (scf_property_get_value(prop, value) == 0) { 750*4bff34e3Sthurlow if (scf_value_get_integer(value, 751*4bff34e3Sthurlow valint) != 0) { 752*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 753*4bff34e3Sthurlow } 754*4bff34e3Sthurlow } else { 755*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 756*4bff34e3Sthurlow } 757*4bff34e3Sthurlow } else { 758*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 759*4bff34e3Sthurlow } 760*4bff34e3Sthurlow if (value != NULL) 761*4bff34e3Sthurlow scf_value_destroy(value); 762*4bff34e3Sthurlow if (prop != NULL) 763*4bff34e3Sthurlow scf_property_destroy(prop); 764*4bff34e3Sthurlow return (ret); 765*4bff34e3Sthurlow } 766*4bff34e3Sthurlow 767*4bff34e3Sthurlow /* 768*4bff34e3Sthurlow * Get boolean value of property. 769*4bff34e3Sthurlow * The value is returned as int64_t value 770*4bff34e3Sthurlow * Caller ensures appropriate translation. 771*4bff34e3Sthurlow */ 772*4bff34e3Sthurlow int 773*4bff34e3Sthurlow smb_smf_set_boolean_property(smb_scfhandle_t *handle, char *propname, 774*4bff34e3Sthurlow uint8_t valbool) 775*4bff34e3Sthurlow { 776*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 777*4bff34e3Sthurlow scf_value_t *value = NULL; 778*4bff34e3Sthurlow scf_transaction_entry_t *entry = NULL; 779*4bff34e3Sthurlow 780*4bff34e3Sthurlow if (handle == NULL) { 781*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 782*4bff34e3Sthurlow } 783*4bff34e3Sthurlow 784*4bff34e3Sthurlow /* 785*4bff34e3Sthurlow * properties must be set in transactions and don't take 786*4bff34e3Sthurlow * effect until the transaction has been ended/committed. 787*4bff34e3Sthurlow */ 788*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 789*4bff34e3Sthurlow entry = scf_entry_create(handle->scf_handle); 790*4bff34e3Sthurlow if (value != NULL && entry != NULL) { 791*4bff34e3Sthurlow if (scf_transaction_property_change(handle->scf_trans, entry, 792*4bff34e3Sthurlow propname, SCF_TYPE_BOOLEAN) == 0 || 793*4bff34e3Sthurlow scf_transaction_property_new(handle->scf_trans, entry, 794*4bff34e3Sthurlow propname, SCF_TYPE_BOOLEAN) == 0) { 795*4bff34e3Sthurlow scf_value_set_boolean(value, valbool); 796*4bff34e3Sthurlow if (scf_entry_add_value(entry, value) != 0) { 797*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 798*4bff34e3Sthurlow scf_value_destroy(value); 799*4bff34e3Sthurlow } 800*4bff34e3Sthurlow /* the value is in the transaction */ 801*4bff34e3Sthurlow value = NULL; 802*4bff34e3Sthurlow } 803*4bff34e3Sthurlow /* the entry is in the transaction */ 804*4bff34e3Sthurlow entry = NULL; 805*4bff34e3Sthurlow } else { 806*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 807*4bff34e3Sthurlow } 808*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR) { 809*4bff34e3Sthurlow switch (scf_error()) { 810*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 811*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 812*4bff34e3Sthurlow break; 813*4bff34e3Sthurlow } 814*4bff34e3Sthurlow } 815*4bff34e3Sthurlow /* 816*4bff34e3Sthurlow * cleanup if there were any errors that didn't leave these 817*4bff34e3Sthurlow * values where they would be cleaned up later. 818*4bff34e3Sthurlow */ 819*4bff34e3Sthurlow if (value != NULL) 820*4bff34e3Sthurlow scf_value_destroy(value); 821*4bff34e3Sthurlow if (entry != NULL) 822*4bff34e3Sthurlow scf_entry_destroy(entry); 823*4bff34e3Sthurlow return (ret); 824*4bff34e3Sthurlow } 825*4bff34e3Sthurlow 826*4bff34e3Sthurlow /* 827*4bff34e3Sthurlow * Sets boolean property value. 828*4bff34e3Sthurlow * Caller is responsible to have enough memory allocated. 829*4bff34e3Sthurlow */ 830*4bff34e3Sthurlow int 831*4bff34e3Sthurlow smb_smf_get_boolean_property(smb_scfhandle_t *handle, char *propname, 832*4bff34e3Sthurlow uint8_t *valbool) 833*4bff34e3Sthurlow { 834*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 835*4bff34e3Sthurlow scf_value_t *value = NULL; 836*4bff34e3Sthurlow scf_property_t *prop = NULL; 837*4bff34e3Sthurlow 838*4bff34e3Sthurlow if (handle == NULL) { 839*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 840*4bff34e3Sthurlow } 841*4bff34e3Sthurlow 842*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 843*4bff34e3Sthurlow prop = scf_property_create(handle->scf_handle); 844*4bff34e3Sthurlow if ((prop) && (value) && 845*4bff34e3Sthurlow (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 846*4bff34e3Sthurlow if (scf_property_get_value(prop, value) == 0) { 847*4bff34e3Sthurlow if (scf_value_get_boolean(value, 848*4bff34e3Sthurlow valbool) != 0) { 849*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 850*4bff34e3Sthurlow } 851*4bff34e3Sthurlow } else { 852*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 853*4bff34e3Sthurlow } 854*4bff34e3Sthurlow } else { 855*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 856*4bff34e3Sthurlow } 857*4bff34e3Sthurlow if (value != NULL) 858*4bff34e3Sthurlow scf_value_destroy(value); 859*4bff34e3Sthurlow if (prop != NULL) 860*4bff34e3Sthurlow scf_property_destroy(prop); 861*4bff34e3Sthurlow return (ret); 862*4bff34e3Sthurlow } 863*4bff34e3Sthurlow 864*4bff34e3Sthurlow /* 865*4bff34e3Sthurlow * Sets a blob property value. 866*4bff34e3Sthurlow */ 867*4bff34e3Sthurlow int 868*4bff34e3Sthurlow smb_smf_set_opaque_property(smb_scfhandle_t *handle, char *propname, 869*4bff34e3Sthurlow void *voidval, size_t sz) 870*4bff34e3Sthurlow { 871*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 872*4bff34e3Sthurlow scf_value_t *value; 873*4bff34e3Sthurlow scf_transaction_entry_t *entry; 874*4bff34e3Sthurlow 875*4bff34e3Sthurlow if (handle == NULL) { 876*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 877*4bff34e3Sthurlow } 878*4bff34e3Sthurlow 879*4bff34e3Sthurlow /* 880*4bff34e3Sthurlow * properties must be set in transactions and don't take 881*4bff34e3Sthurlow * effect until the transaction has been ended/committed. 882*4bff34e3Sthurlow */ 883*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 884*4bff34e3Sthurlow entry = scf_entry_create(handle->scf_handle); 885*4bff34e3Sthurlow if (value != NULL && entry != NULL) { 886*4bff34e3Sthurlow if (scf_transaction_property_change(handle->scf_trans, entry, 887*4bff34e3Sthurlow propname, SCF_TYPE_OPAQUE) == 0 || 888*4bff34e3Sthurlow scf_transaction_property_new(handle->scf_trans, entry, 889*4bff34e3Sthurlow propname, SCF_TYPE_OPAQUE) == 0) { 890*4bff34e3Sthurlow if (scf_value_set_opaque(value, voidval, sz) == 0) { 891*4bff34e3Sthurlow if (scf_entry_add_value(entry, value) != 0) { 892*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 893*4bff34e3Sthurlow scf_value_destroy(value); 894*4bff34e3Sthurlow } 895*4bff34e3Sthurlow /* the value is in the transaction */ 896*4bff34e3Sthurlow value = NULL; 897*4bff34e3Sthurlow } else { 898*4bff34e3Sthurlow /* value couldn't be constructed */ 899*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 900*4bff34e3Sthurlow } 901*4bff34e3Sthurlow /* the entry is in the transaction */ 902*4bff34e3Sthurlow entry = NULL; 903*4bff34e3Sthurlow } else { 904*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 905*4bff34e3Sthurlow } 906*4bff34e3Sthurlow } else { 907*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 908*4bff34e3Sthurlow } 909*4bff34e3Sthurlow if (ret == SMBC_SMF_SYSTEM_ERR) { 910*4bff34e3Sthurlow switch (scf_error()) { 911*4bff34e3Sthurlow case SCF_ERROR_PERMISSION_DENIED: 912*4bff34e3Sthurlow ret = SMBC_SMF_NO_PERMISSION; 913*4bff34e3Sthurlow break; 914*4bff34e3Sthurlow } 915*4bff34e3Sthurlow } 916*4bff34e3Sthurlow /* 917*4bff34e3Sthurlow * cleanup if there were any errors that didn't leave these 918*4bff34e3Sthurlow * values where they would be cleaned up later. 919*4bff34e3Sthurlow */ 920*4bff34e3Sthurlow if (value != NULL) 921*4bff34e3Sthurlow scf_value_destroy(value); 922*4bff34e3Sthurlow if (entry != NULL) 923*4bff34e3Sthurlow scf_entry_destroy(entry); 924*4bff34e3Sthurlow return (ret); 925*4bff34e3Sthurlow } 926*4bff34e3Sthurlow 927*4bff34e3Sthurlow /* 928*4bff34e3Sthurlow * Gets a blob property value. 929*4bff34e3Sthurlow * Caller is responsible to have enough memory allocated. 930*4bff34e3Sthurlow */ 931*4bff34e3Sthurlow int 932*4bff34e3Sthurlow smb_smf_get_opaque_property(smb_scfhandle_t *handle, char *propname, 933*4bff34e3Sthurlow void *v, size_t sz) 934*4bff34e3Sthurlow { 935*4bff34e3Sthurlow int ret = SMBC_SMF_OK; 936*4bff34e3Sthurlow scf_value_t *value = NULL; 937*4bff34e3Sthurlow scf_property_t *prop = NULL; 938*4bff34e3Sthurlow 939*4bff34e3Sthurlow if (handle == NULL) { 940*4bff34e3Sthurlow return (SMBC_SMF_SYSTEM_ERR); 941*4bff34e3Sthurlow } 942*4bff34e3Sthurlow 943*4bff34e3Sthurlow value = scf_value_create(handle->scf_handle); 944*4bff34e3Sthurlow prop = scf_property_create(handle->scf_handle); 945*4bff34e3Sthurlow if ((prop) && (value) && 946*4bff34e3Sthurlow (scf_pg_get_property(handle->scf_pg, propname, prop) == 0)) { 947*4bff34e3Sthurlow if (scf_property_get_value(prop, value) == 0) { 948*4bff34e3Sthurlow if (scf_value_get_opaque(value, (char *)v, sz) != sz) { 949*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 950*4bff34e3Sthurlow } 951*4bff34e3Sthurlow } else { 952*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 953*4bff34e3Sthurlow } 954*4bff34e3Sthurlow } else { 955*4bff34e3Sthurlow ret = SMBC_SMF_SYSTEM_ERR; 956*4bff34e3Sthurlow } 957*4bff34e3Sthurlow if (value != NULL) 958*4bff34e3Sthurlow scf_value_destroy(value); 959*4bff34e3Sthurlow if (prop != NULL) 960*4bff34e3Sthurlow scf_property_destroy(prop); 961*4bff34e3Sthurlow return (ret); 962*4bff34e3Sthurlow } 963*4bff34e3Sthurlow 964*4bff34e3Sthurlow /* 965*4bff34e3Sthurlow * Gets an instance iterator for the service specified. 966*4bff34e3Sthurlow */ 967*4bff34e3Sthurlow smb_scfhandle_t * 968*4bff34e3Sthurlow smb_smf_get_iterator(char *svc_name) 969*4bff34e3Sthurlow { 970*4bff34e3Sthurlow smb_scfhandle_t *handle = NULL; 971*4bff34e3Sthurlow 972*4bff34e3Sthurlow handle = smb_smf_scf_init(svc_name); 973*4bff34e3Sthurlow if (!handle) { 974*4bff34e3Sthurlow return (NULL); 975*4bff34e3Sthurlow } 976*4bff34e3Sthurlow 977*4bff34e3Sthurlow handle->scf_inst_iter = scf_iter_create(handle->scf_handle); 978*4bff34e3Sthurlow if (handle->scf_inst_iter) { 979*4bff34e3Sthurlow if (scf_iter_service_instances(handle->scf_inst_iter, 980*4bff34e3Sthurlow handle->scf_service) != 0) { 981*4bff34e3Sthurlow smb_smf_scf_fini(handle); 982*4bff34e3Sthurlow handle = NULL; 983*4bff34e3Sthurlow } else { 984*4bff34e3Sthurlow handle->scf_instance = NULL; 985*4bff34e3Sthurlow } 986*4bff34e3Sthurlow } else { 987*4bff34e3Sthurlow smb_smf_scf_fini(handle); 988*4bff34e3Sthurlow handle = NULL; 989*4bff34e3Sthurlow } 990*4bff34e3Sthurlow return (handle); 991*4bff34e3Sthurlow } 992