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