4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 /* helper functions for using libscf with CIFS */
37 #include <uuid/uuid.h>
38 #include <sys/param.h>
44 #include "libshare_smbfs.h"
47 * smb_smf_scf_log_error(msg)
48 * Logs error messages from scf API's
51 smb_smf_scf_log_error(char *msg
)
54 syslog(LOG_ERR
, " SMBC SMF problem: %s\n",
55 scf_strerror(scf_error()));
56 } else { /*LINTED E_SEC_PRINTF_E_VAR_FMT*/
57 syslog(LOG_ERR
, msg
, scf_strerror(scf_error()));
62 * smb_smf_scf_fini(handle)
64 * must be called when done. Called with the handle allocated in
65 * smb_smf_scf_init(), it cleans up the state and frees any SCF resources
69 smb_smf_scf_fini(smb_scfhandle_t
*handle
)
73 if (handle
->scf_pg_iter
!= NULL
) {
74 scf_iter_destroy(handle
->scf_pg_iter
);
75 handle
->scf_pg_iter
= NULL
;
77 if (handle
->scf_inst_iter
!= NULL
) {
78 scf_iter_destroy(handle
->scf_inst_iter
);
79 handle
->scf_inst_iter
= NULL
;
81 if (handle
->scf_scope
!= NULL
) {
83 scf_scope_destroy(handle
->scf_scope
);
84 handle
->scf_scope
= NULL
;
86 if (handle
->scf_instance
!= NULL
) {
87 scf_instance_destroy(handle
->scf_instance
);
88 handle
->scf_instance
= NULL
;
90 if (handle
->scf_service
!= NULL
) {
91 scf_service_destroy(handle
->scf_service
);
92 handle
->scf_service
= NULL
;
94 if (handle
->scf_pg
!= NULL
) {
95 scf_pg_destroy(handle
->scf_pg
);
96 handle
->scf_pg
= NULL
;
98 if (handle
->scf_handle
!= NULL
) {
99 handle
->scf_state
= SCH_STATE_UNINIT
;
101 (void) scf_handle_unbind(handle
->scf_handle
);
102 scf_handle_destroy(handle
->scf_handle
);
103 handle
->scf_handle
= NULL
;
111 * Check if instance with given name exists for a service.
112 * Returns 0 is instance exist
115 smb_smf_instance_exists(smb_scfhandle_t
*handle
, char *inst_name
)
117 int ret
= SMBC_SMF_OK
;
118 if (handle
== NULL
) {
119 return (SMBC_SMF_SYSTEM_ERR
);
122 handle
->scf_instance
= scf_instance_create(handle
->scf_handle
);
123 if (scf_service_get_instance(handle
->scf_service
, inst_name
,
124 handle
->scf_instance
) != SCF_SUCCESS
) {
125 ret
= SMBC_SMF_SYSTEM_ERR
;
127 scf_instance_destroy(handle
->scf_instance
);
128 handle
->scf_instance
= NULL
;
133 * Create a service instance. returns 0 if successful.
134 * If instance already exists enable it.
137 smb_smf_instance_create(smb_scfhandle_t
*handle
, char *serv_prefix
,
141 int ret
= SMBC_SMF_OK
;
144 if (handle
== NULL
) {
145 return (SMBC_SMF_SYSTEM_ERR
);
148 if (!serv_prefix
|| !inst_name
) {
149 return (SMBC_SMF_SYSTEM_ERR
);
151 sz
= strlen(serv_prefix
) + strlen(inst_name
) + 2;
152 instance
= malloc(sz
);
154 return (SMBC_SMF_SYSTEM_ERR
);
156 (void) snprintf(instance
, sz
, "%s:%s", serv_prefix
, inst_name
);
157 handle
->scf_instance
= scf_instance_create(handle
->scf_handle
);
158 if (scf_service_get_instance(handle
->scf_service
, inst_name
,
159 handle
->scf_instance
) != SCF_SUCCESS
) {
160 if (scf_service_add_instance(handle
->scf_service
,
161 inst_name
, handle
->scf_instance
) == SCF_SUCCESS
) {
162 if (smf_enable_instance(instance
, 0))
163 ret
= SMBC_SMF_SYSTEM_ERR
;
165 ret
= SMBC_SMF_SYSTEM_ERR
;
168 if (smf_enable_instance(instance
, 0))
169 ret
= SMBC_SMF_SYSTEM_ERR
;
176 * Delete a specified instance. Return SMBC_SMF_OK for success.
179 smb_smf_instance_delete(smb_scfhandle_t
*handle
, char *inst_name
)
181 int ret
= SMBC_SMF_OK
;
183 if (handle
== NULL
) {
184 return (SMBC_SMF_SYSTEM_ERR
);
187 handle
->scf_instance
= scf_instance_create(handle
->scf_handle
);
188 if (scf_service_get_instance(handle
->scf_service
, inst_name
,
189 handle
->scf_instance
) == SCF_SUCCESS
) {
190 if (scf_instance_delete(handle
->scf_instance
) == SCF_SUCCESS
) {
193 ret
= SMBC_SMF_SYSTEM_ERR
;
196 smb_smf_scf_log_error(NULL
);
197 ret
= SMBC_SMF_SYSTEM_ERR
;
205 * must be called before using any of the SCF functions.
206 * Returns smb_scfhandle_t pointer if success.
209 smb_smf_scf_init(char *svc_name
)
211 smb_scfhandle_t
*handle
;
213 handle
= malloc(sizeof (smb_scfhandle_t
));
214 if (handle
!= NULL
) {
215 bzero((char *)handle
, sizeof (smb_scfhandle_t
));
216 handle
->scf_state
= SCH_STATE_INITIALIZING
;
217 handle
->scf_handle
= scf_handle_create(SCF_VERSION
);
218 if (handle
->scf_handle
!= NULL
) {
219 if (scf_handle_bind(handle
->scf_handle
) == 0) {
221 scf_scope_create(handle
->scf_handle
);
222 if (scf_handle_get_local_scope(
223 handle
->scf_handle
, handle
->scf_scope
) != 0)
226 handle
->scf_service
=
227 scf_service_create(handle
->scf_handle
);
229 if (scf_scope_get_service(handle
->scf_scope
,
230 svc_name
, handle
->scf_service
)
235 scf_pg_create(handle
->scf_handle
);
236 handle
->scf_state
= SCH_STATE_INIT
;
243 smb_smf_scf_log_error("Could not access SMF "
249 /* error handling/unwinding */
251 (void) smb_smf_scf_fini(handle
);
252 (void) smb_smf_scf_log_error("SMF initialization problem: %s\n");
257 * smb_smf_create_service_pgroup(handle, pgroup)
259 * create a new property group at service level.
262 smb_smf_create_service_pgroup(smb_scfhandle_t
*handle
, char *pgroup
)
264 int ret
= SMBC_SMF_OK
;
267 if (handle
== NULL
) {
268 return (SMBC_SMF_SYSTEM_ERR
);
272 * only create a handle if it doesn't exist. It is ok to exist
273 * since the pg handle will be set as a side effect.
275 if (handle
->scf_pg
== NULL
) {
276 handle
->scf_pg
= scf_pg_create(handle
->scf_handle
);
279 * if the pgroup exists, we are done. If it doesn't, then we
280 * need to actually add one to the service instance.
282 if (scf_service_get_pg(handle
->scf_service
,
283 pgroup
, handle
->scf_pg
) != 0) {
284 /* doesn't exist so create one */
285 if (scf_service_add_pg(handle
->scf_service
, pgroup
,
286 SCF_GROUP_FRAMEWORK
, 0, handle
->scf_pg
) != 0) {
288 if (err
!= SCF_ERROR_NONE
)
289 smb_smf_scf_log_error(NULL
);
291 case SCF_ERROR_PERMISSION_DENIED
:
292 ret
= SMBC_SMF_NO_PERMISSION
;
295 ret
= SMBC_SMF_SYSTEM_ERR
;
304 * smb_smf_create_instance_pgroup(handle, pgroup)
306 * create a new property group at instance level.
309 smb_smf_create_instance_pgroup(smb_scfhandle_t
*handle
, char *pgroup
)
311 int ret
= SMBC_SMF_OK
;
314 if (handle
== NULL
) {
315 return (SMBC_SMF_SYSTEM_ERR
);
319 * only create a handle if it doesn't exist. It is ok to exist
320 * since the pg handle will be set as a side effect.
322 if (handle
->scf_pg
== NULL
) {
323 handle
->scf_pg
= scf_pg_create(handle
->scf_handle
);
327 * if the pgroup exists, we are done. If it doesn't, then we
328 * need to actually add one to the service instance.
330 if (scf_instance_get_pg(handle
->scf_instance
,
331 pgroup
, handle
->scf_pg
) != 0) {
332 /* doesn't exist so create one */
333 if (scf_instance_add_pg(handle
->scf_instance
, pgroup
,
334 SCF_GROUP_APPLICATION
, 0, handle
->scf_pg
) != 0) {
336 if (err
!= SCF_ERROR_NONE
)
337 smb_smf_scf_log_error(NULL
);
339 case SCF_ERROR_PERMISSION_DENIED
:
340 ret
= SMBC_SMF_NO_PERMISSION
;
343 ret
= SMBC_SMF_SYSTEM_ERR
;
352 * smb_smf_delete_service_pgroup(handle, pgroup)
354 * remove the property group from the current service.
355 * but only if it actually exists.
358 smb_smf_delete_service_pgroup(smb_scfhandle_t
*handle
, char *pgroup
)
360 int ret
= SMBC_SMF_OK
;
363 if (handle
== NULL
) {
364 return (SMBC_SMF_SYSTEM_ERR
);
368 * only create a handle if it doesn't exist. It is ok to exist
369 * since the pg handle will be set as a side effect.
371 if (handle
->scf_pg
== NULL
) {
372 handle
->scf_pg
= scf_pg_create(handle
->scf_handle
);
376 * only delete if it does exist.
378 if (scf_service_get_pg(handle
->scf_service
,
379 pgroup
, handle
->scf_pg
) == 0) {
380 /* does exist so delete it */
381 if (scf_pg_delete(handle
->scf_pg
) != 0) {
382 ret
= SMBC_SMF_SYSTEM_ERR
;
384 if (err
!= SCF_ERROR_NONE
) {
385 smb_smf_scf_log_error("SMF delpg "
391 if (err
!= SCF_ERROR_NONE
)
392 smb_smf_scf_log_error("SMF getpg problem: %s\n");
393 ret
= SMBC_SMF_SYSTEM_ERR
;
395 if (ret
== SMBC_SMF_SYSTEM_ERR
&&
396 scf_error() == SCF_ERROR_PERMISSION_DENIED
) {
397 ret
= SMBC_SMF_NO_PERMISSION
;
403 * smb_smf_delete_instance_pgroup(handle, pgroup)
405 * remove the property group from the current instance.
406 * but only if it actually exists.
409 smb_smf_delete_instance_pgroup(smb_scfhandle_t
*handle
, char *pgroup
)
411 int ret
= SMBC_SMF_OK
;
414 if (handle
== NULL
) {
415 return (SMBC_SMF_SYSTEM_ERR
);
419 * only create a handle if it doesn't exist. It is ok to exist
420 * since the pg handle will be set as a side effect.
422 if (handle
->scf_pg
== NULL
) {
423 handle
->scf_pg
= scf_pg_create(handle
->scf_handle
);
427 * only delete if it does exist.
429 if (scf_instance_get_pg(handle
->scf_instance
,
430 pgroup
, handle
->scf_pg
) == 0) {
431 /* does exist so delete it */
432 if (scf_pg_delete(handle
->scf_pg
) != 0) {
433 ret
= SMBC_SMF_SYSTEM_ERR
;
435 if (err
!= SCF_ERROR_NONE
) {
436 smb_smf_scf_log_error("SMF delpg "
442 if (err
!= SCF_ERROR_NONE
)
443 smb_smf_scf_log_error("SMF getpg problem: %s\n");
444 ret
= SMBC_SMF_SYSTEM_ERR
;
446 if (ret
== SMBC_SMF_SYSTEM_ERR
&&
447 scf_error() == SCF_ERROR_PERMISSION_DENIED
) {
448 ret
= SMBC_SMF_NO_PERMISSION
;
454 * Start transaction on current pg in handle.
455 * The pg could be service or instance level.
456 * Must be called after pg handle is obtained
457 * from create or get.
460 smb_smf_start_transaction(smb_scfhandle_t
*handle
)
462 int ret
= SMBC_SMF_OK
;
464 if (!handle
|| (!handle
->scf_pg
)) {
465 return (SMBC_SMF_SYSTEM_ERR
);
468 * lookup the property group and create it if it doesn't already
471 if (handle
->scf_state
== SCH_STATE_INIT
) {
472 if (ret
== SMBC_SMF_OK
) {
474 scf_transaction_create(handle
->scf_handle
);
475 if (handle
->scf_trans
!= NULL
) {
476 if (scf_transaction_start(handle
->scf_trans
,
477 handle
->scf_pg
) != 0) {
478 ret
= SMBC_SMF_SYSTEM_ERR
;
479 scf_transaction_destroy(
481 handle
->scf_trans
= NULL
;
484 ret
= SMBC_SMF_SYSTEM_ERR
;
488 if (ret
== SMBC_SMF_SYSTEM_ERR
&&
489 scf_error() == SCF_ERROR_PERMISSION_DENIED
) {
490 ret
= SMBC_SMF_NO_PERMISSION
;
496 * smb_smf_end_transaction(handle)
498 * Commit the changes that were added to the transaction in the
499 * handle. Do all necessary cleanup.
502 smb_smf_end_transaction(smb_scfhandle_t
*handle
)
504 int ret
= SMBC_SMF_OK
;
506 if (handle
== NULL
) {
507 return (SMBC_SMF_SYSTEM_ERR
);
510 if (handle
->scf_trans
== NULL
) {
511 ret
= SMBC_SMF_SYSTEM_ERR
;
513 if (scf_transaction_commit(handle
->scf_trans
) < 0) {
514 ret
= SMBC_SMF_SYSTEM_ERR
;
515 smb_smf_scf_log_error("Failed to commit "
518 scf_transaction_destroy_children(handle
->scf_trans
);
519 scf_transaction_destroy(handle
->scf_trans
);
520 handle
->scf_trans
= NULL
;
526 * Deletes property in current pg
529 smb_smf_delete_property(smb_scfhandle_t
*handle
, char *propname
)
531 int ret
= SMBC_SMF_OK
;
532 scf_transaction_entry_t
*entry
= NULL
;
534 if (handle
== NULL
) {
535 return (SMBC_SMF_SYSTEM_ERR
);
539 * properties must be set in transactions and don't take
540 * effect until the transaction has been ended/committed.
542 entry
= scf_entry_create(handle
->scf_handle
);
544 if (scf_transaction_property_delete(handle
->scf_trans
, entry
,
546 ret
= SMBC_SMF_SYSTEM_ERR
;
549 ret
= SMBC_SMF_SYSTEM_ERR
;
551 if (ret
== SMBC_SMF_SYSTEM_ERR
) {
552 switch (scf_error()) {
553 case SCF_ERROR_PERMISSION_DENIED
:
554 ret
= SMBC_SMF_NO_PERMISSION
;
560 * cleanup if there were any errors that didn't leave these
561 * values where they would be cleaned up later.
563 if ((ret
!= SMBC_SMF_OK
) && (entry
!= NULL
)) {
564 scf_entry_destroy(entry
);
570 * Sets string property in current pg
573 smb_smf_set_string_property(smb_scfhandle_t
*handle
,
574 char *propname
, char *valstr
)
576 int ret
= SMBC_SMF_OK
;
577 scf_value_t
*value
= NULL
;
578 scf_transaction_entry_t
*entry
= NULL
;
580 if (handle
== NULL
) {
581 return (SMBC_SMF_SYSTEM_ERR
);
585 * properties must be set in transactions and don't take
586 * effect until the transaction has been ended/committed.
588 value
= scf_value_create(handle
->scf_handle
);
589 entry
= scf_entry_create(handle
->scf_handle
);
590 if (value
!= NULL
&& entry
!= NULL
) {
591 if (scf_transaction_property_change(handle
->scf_trans
, entry
,
592 propname
, SCF_TYPE_ASTRING
) == 0 ||
593 scf_transaction_property_new(handle
->scf_trans
, entry
,
594 propname
, SCF_TYPE_ASTRING
) == 0) {
595 if (scf_value_set_astring(value
, valstr
) == 0) {
596 if (scf_entry_add_value(entry
, value
) != 0) {
597 ret
= SMBC_SMF_SYSTEM_ERR
;
598 scf_value_destroy(value
);
600 /* the value is in the transaction */
603 /* value couldn't be constructed */
604 ret
= SMBC_SMF_SYSTEM_ERR
;
606 /* the entry is in the transaction */
609 ret
= SMBC_SMF_SYSTEM_ERR
;
612 ret
= SMBC_SMF_SYSTEM_ERR
;
614 if (ret
== SMBC_SMF_SYSTEM_ERR
) {
615 switch (scf_error()) {
616 case SCF_ERROR_PERMISSION_DENIED
:
617 ret
= SMBC_SMF_NO_PERMISSION
;
623 * cleanup if there were any errors that didn't leave these
624 * values where they would be cleaned up later.
627 scf_value_destroy(value
);
629 scf_entry_destroy(entry
);
634 * Gets string property value.upto sz size.
635 * Caller is responsible to have enough memory allocated.
638 smb_smf_get_string_property(smb_scfhandle_t
*handle
, char *propname
,
639 char *valstr
, size_t sz
)
641 int ret
= SMBC_SMF_OK
;
643 scf_property_t
*prop
;
645 if (handle
== NULL
) {
646 return (SMBC_SMF_SYSTEM_ERR
);
649 value
= scf_value_create(handle
->scf_handle
);
650 prop
= scf_property_create(handle
->scf_handle
);
652 (scf_pg_get_property(handle
->scf_pg
, propname
, prop
) == 0)) {
653 if (scf_property_get_value(prop
, value
) == 0) {
654 if (scf_value_get_astring(value
, valstr
, sz
) < 0) {
655 ret
= SMBC_SMF_SYSTEM_ERR
;
658 ret
= SMBC_SMF_SYSTEM_ERR
;
661 ret
= SMBC_SMF_SYSTEM_ERR
;
664 scf_value_destroy(value
);
666 scf_property_destroy(prop
);
671 * Get integer value of property.
672 * The value is returned as int64_t value
673 * Caller ensures appropriate translation.
676 smb_smf_set_integer_property(smb_scfhandle_t
*handle
, char *propname
,
679 int ret
= SMBC_SMF_OK
;
680 scf_value_t
*value
= NULL
;
681 scf_transaction_entry_t
*entry
= NULL
;
683 if (handle
== NULL
) {
684 return (SMBC_SMF_SYSTEM_ERR
);
688 * properties must be set in transactions and don't take
689 * effect until the transaction has been ended/committed.
691 value
= scf_value_create(handle
->scf_handle
);
692 entry
= scf_entry_create(handle
->scf_handle
);
693 if (value
!= NULL
&& entry
!= NULL
) {
694 if (scf_transaction_property_change(handle
->scf_trans
, entry
,
695 propname
, SCF_TYPE_INTEGER
) == 0 ||
696 scf_transaction_property_new(handle
->scf_trans
, entry
,
697 propname
, SCF_TYPE_INTEGER
) == 0) {
698 scf_value_set_integer(value
, valint
);
699 if (scf_entry_add_value(entry
, value
) != 0) {
700 ret
= SMBC_SMF_SYSTEM_ERR
;
701 scf_value_destroy(value
);
703 /* the value is in the transaction */
706 /* the entry is in the transaction */
709 ret
= SMBC_SMF_SYSTEM_ERR
;
711 if (ret
== SMBC_SMF_SYSTEM_ERR
) {
712 switch (scf_error()) {
713 case SCF_ERROR_PERMISSION_DENIED
:
714 ret
= SMBC_SMF_NO_PERMISSION
;
719 * cleanup if there were any errors that didn't leave these
720 * values where they would be cleaned up later.
723 scf_value_destroy(value
);
725 scf_entry_destroy(entry
);
730 * Sets integer property value.
731 * Caller is responsible to have enough memory allocated.
734 smb_smf_get_integer_property(smb_scfhandle_t
*handle
, char *propname
,
737 int ret
= SMBC_SMF_OK
;
738 scf_value_t
*value
= NULL
;
739 scf_property_t
*prop
= NULL
;
741 if (handle
== NULL
) {
742 return (SMBC_SMF_SYSTEM_ERR
);
745 value
= scf_value_create(handle
->scf_handle
);
746 prop
= scf_property_create(handle
->scf_handle
);
747 if ((prop
) && (value
) &&
748 (scf_pg_get_property(handle
->scf_pg
, propname
, prop
) == 0)) {
749 if (scf_property_get_value(prop
, value
) == 0) {
750 if (scf_value_get_integer(value
,
752 ret
= SMBC_SMF_SYSTEM_ERR
;
755 ret
= SMBC_SMF_SYSTEM_ERR
;
758 ret
= SMBC_SMF_SYSTEM_ERR
;
761 scf_value_destroy(value
);
763 scf_property_destroy(prop
);
768 * Get boolean value of property.
769 * The value is returned as int64_t value
770 * Caller ensures appropriate translation.
773 smb_smf_set_boolean_property(smb_scfhandle_t
*handle
, char *propname
,
776 int ret
= SMBC_SMF_OK
;
777 scf_value_t
*value
= NULL
;
778 scf_transaction_entry_t
*entry
= NULL
;
780 if (handle
== NULL
) {
781 return (SMBC_SMF_SYSTEM_ERR
);
785 * properties must be set in transactions and don't take
786 * effect until the transaction has been ended/committed.
788 value
= scf_value_create(handle
->scf_handle
);
789 entry
= scf_entry_create(handle
->scf_handle
);
790 if (value
!= NULL
&& entry
!= NULL
) {
791 if (scf_transaction_property_change(handle
->scf_trans
, entry
,
792 propname
, SCF_TYPE_BOOLEAN
) == 0 ||
793 scf_transaction_property_new(handle
->scf_trans
, entry
,
794 propname
, SCF_TYPE_BOOLEAN
) == 0) {
795 scf_value_set_boolean(value
, valbool
);
796 if (scf_entry_add_value(entry
, value
) != 0) {
797 ret
= SMBC_SMF_SYSTEM_ERR
;
798 scf_value_destroy(value
);
800 /* the value is in the transaction */
803 /* the entry is in the transaction */
806 ret
= SMBC_SMF_SYSTEM_ERR
;
808 if (ret
== SMBC_SMF_SYSTEM_ERR
) {
809 switch (scf_error()) {
810 case SCF_ERROR_PERMISSION_DENIED
:
811 ret
= SMBC_SMF_NO_PERMISSION
;
816 * cleanup if there were any errors that didn't leave these
817 * values where they would be cleaned up later.
820 scf_value_destroy(value
);
822 scf_entry_destroy(entry
);
827 * Sets boolean property value.
828 * Caller is responsible to have enough memory allocated.
831 smb_smf_get_boolean_property(smb_scfhandle_t
*handle
, char *propname
,
834 int ret
= SMBC_SMF_OK
;
835 scf_value_t
*value
= NULL
;
836 scf_property_t
*prop
= NULL
;
838 if (handle
== NULL
) {
839 return (SMBC_SMF_SYSTEM_ERR
);
842 value
= scf_value_create(handle
->scf_handle
);
843 prop
= scf_property_create(handle
->scf_handle
);
844 if ((prop
) && (value
) &&
845 (scf_pg_get_property(handle
->scf_pg
, propname
, prop
) == 0)) {
846 if (scf_property_get_value(prop
, value
) == 0) {
847 if (scf_value_get_boolean(value
,
849 ret
= SMBC_SMF_SYSTEM_ERR
;
852 ret
= SMBC_SMF_SYSTEM_ERR
;
855 ret
= SMBC_SMF_SYSTEM_ERR
;
858 scf_value_destroy(value
);
860 scf_property_destroy(prop
);
865 * Sets a blob property value.
868 smb_smf_set_opaque_property(smb_scfhandle_t
*handle
, char *propname
,
869 void *voidval
, size_t sz
)
871 int ret
= SMBC_SMF_OK
;
873 scf_transaction_entry_t
*entry
;
875 if (handle
== NULL
) {
876 return (SMBC_SMF_SYSTEM_ERR
);
880 * properties must be set in transactions and don't take
881 * effect until the transaction has been ended/committed.
883 value
= scf_value_create(handle
->scf_handle
);
884 entry
= scf_entry_create(handle
->scf_handle
);
885 if (value
!= NULL
&& entry
!= NULL
) {
886 if (scf_transaction_property_change(handle
->scf_trans
, entry
,
887 propname
, SCF_TYPE_OPAQUE
) == 0 ||
888 scf_transaction_property_new(handle
->scf_trans
, entry
,
889 propname
, SCF_TYPE_OPAQUE
) == 0) {
890 if (scf_value_set_opaque(value
, voidval
, sz
) == 0) {
891 if (scf_entry_add_value(entry
, value
) != 0) {
892 ret
= SMBC_SMF_SYSTEM_ERR
;
893 scf_value_destroy(value
);
895 /* the value is in the transaction */
898 /* value couldn't be constructed */
899 ret
= SMBC_SMF_SYSTEM_ERR
;
901 /* the entry is in the transaction */
904 ret
= SMBC_SMF_SYSTEM_ERR
;
907 ret
= SMBC_SMF_SYSTEM_ERR
;
909 if (ret
== SMBC_SMF_SYSTEM_ERR
) {
910 switch (scf_error()) {
911 case SCF_ERROR_PERMISSION_DENIED
:
912 ret
= SMBC_SMF_NO_PERMISSION
;
917 * cleanup if there were any errors that didn't leave these
918 * values where they would be cleaned up later.
921 scf_value_destroy(value
);
923 scf_entry_destroy(entry
);
928 * Gets a blob property value.
929 * Caller is responsible to have enough memory allocated.
932 smb_smf_get_opaque_property(smb_scfhandle_t
*handle
, char *propname
,
935 int ret
= SMBC_SMF_OK
;
936 scf_value_t
*value
= NULL
;
937 scf_property_t
*prop
= NULL
;
939 if (handle
== NULL
) {
940 return (SMBC_SMF_SYSTEM_ERR
);
943 value
= scf_value_create(handle
->scf_handle
);
944 prop
= scf_property_create(handle
->scf_handle
);
945 if ((prop
) && (value
) &&
946 (scf_pg_get_property(handle
->scf_pg
, propname
, prop
) == 0)) {
947 if (scf_property_get_value(prop
, value
) == 0) {
948 if (scf_value_get_opaque(value
, (char *)v
, sz
) != sz
) {
949 ret
= SMBC_SMF_SYSTEM_ERR
;
952 ret
= SMBC_SMF_SYSTEM_ERR
;
955 ret
= SMBC_SMF_SYSTEM_ERR
;
958 scf_value_destroy(value
);
960 scf_property_destroy(prop
);
965 * Gets an instance iterator for the service specified.
968 smb_smf_get_iterator(char *svc_name
)
970 smb_scfhandle_t
*handle
= NULL
;
972 handle
= smb_smf_scf_init(svc_name
);
977 handle
->scf_inst_iter
= scf_iter_create(handle
->scf_handle
);
978 if (handle
->scf_inst_iter
) {
979 if (scf_iter_service_instances(handle
->scf_inst_iter
,
980 handle
->scf_service
) != 0) {
981 smb_smf_scf_fini(handle
);
984 handle
->scf_instance
= NULL
;
987 smb_smf_scf_fini(handle
);