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]
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
25 /* auditd smf(5)/libscf(3LIB) interface - set and display audit parameters */
26 #include <audit_scf.h>
27 #include <audit_policy.h>
29 /* propvec array must be NULL terminated */
30 scf_propvec_t prop_vect
[MAX_PROPVECS
+ 1];
33 * prt_error() - prt_error_va() wrapper; see prt_error_va() for more contextual
34 * information. Note, that the function disregards errno; if you need to print
35 * out strerror()/errno use directly prt_error_va().
36 * Inputs - program error format and message.
40 prt_error(char *fmt
, ...)
47 prt_error_va(fmt
, args
);
52 * prt_error_va() - prints an error message along with corresponding system
53 * error number. Inputs - program error format and the va_list already prepared
54 * by the preceding functions.
59 prt_error_va(char *fmt
, va_list args
)
61 (void) vfprintf(stderr
, fmt
, args
);
62 (void) fputc('\n', stderr
);
64 (void) fprintf(stderr
, "error: %s(%d)\n",
65 strerror(errno
), errno
);
66 (void) fflush(stderr
);
70 * prt_scf_err() - scf_error()/scf_strerror() wrapper.
75 (void) fprintf(stderr
, "error: %s\n", scf_strerror(scf_error()));
79 * add_prop_vect_scf() - adds vector to the array of vectors later passed to
80 * get_/set_val_scf(). The first argument (vector) points to particular position
81 * in the vector of properties.
84 add_prop_vect_scf(scf_propvec_t
*vector
, const char *prop_str
,
85 scf_type_t prop_type
, void *prop_val_ptr
)
87 vector
->pv_prop
= prop_str
;
88 vector
->pv_type
= prop_type
;
89 vector
->pv_ptr
= prop_val_ptr
;
93 * get_val_scf() - get a property values from the audit service
95 * Arguments: vector = pointers to the head end of array of property vectors
96 * pgroup_str = property group of property in AUDITD_FMRI
100 get_val_scf(scf_propvec_t
*vector
, char *pgroup_str
)
102 scf_propvec_t
*bad_prop_vec
= NULL
;
105 * Get the property vector from the editing snapshot (B_FALSE).
106 * For documentation on property vectors see <libscf_priv.h>.
108 if (scf_read_propvec(AUDITD_FMRI
, pgroup_str
, B_FALSE
, vector
,
109 &bad_prop_vec
) != SCF_SUCCESS
) {
111 if (bad_prop_vec
!= NULL
) {
112 prt_error(gettext("Reading the %s property in the %s "
113 "property group failed.\n"), bad_prop_vec
->pv_prop
,
123 * set_val_scf() - set property values of the audit service.
125 * arguments: vector = pointers to the head end of array of property vectors
126 * pgroup_str = property group of property in AUDITD_FMRI
130 set_val_scf(scf_propvec_t
*vector
, char *pgroup_str
)
132 scf_propvec_t
*bad_prop_vec
= NULL
;
134 /* for documentation on property vectors see <libscf_priv.h> */
135 if (scf_write_propvec(AUDITD_FMRI
, pgroup_str
, vector
,
136 &bad_prop_vec
) != SCF_SUCCESS
) {
138 if (bad_prop_vec
!= NULL
) {
139 prt_error(gettext("Setting the %s property in the %s "
140 "property group failed.\n"), bad_prop_vec
->pv_prop
,
150 * free_prop_vect() - deallocate heap memory used for propvect values.
155 scf_propvec_t
*prop_vect_ptr
;
157 prop_vect_ptr
= prop_vect
;
159 while (prop_vect_ptr
->pv_prop
!= NULL
) {
160 if (stack_inbounds(prop_vect_ptr
->pv_ptr
) == 0) {
161 free(prop_vect_ptr
->pv_ptr
);
168 * chk_prop_vect() - check for prop_vect boundaries and possibly process
169 * (typically) full prop_vect.
172 chk_prop_vect(scf_propvec_t
**prop_vect_ptr
, char *pgrp_str
)
174 if (*prop_vect_ptr
< prop_vect
||
175 *prop_vect_ptr
>= (prop_vect
+ MAX_PROPVECS
)) {
176 DPRINT((dbfp
, "prop_vect is full; flushing\n"));
177 if (!set_val_scf(prop_vect
, pgrp_str
)) {
181 bzero(prop_vect
, sizeof (prop_vect
));
182 *prop_vect_ptr
= prop_vect
;
188 * get_props_kva_all() - get all properties and fill in the plugin_kva.
191 get_props_kva_all(asi_scfhandle_t
*handle
, asi_scfhandle_iter_t
*handle_iter
,
194 char key_buf
[PLUGIN_MAXKEY
];
195 char val_buf
[PLUGIN_MAXVAL
];
196 char attr_string
[PLUGIN_MAXATT
];
197 char attr_buf
[PLUGIN_MAXATT
];
199 scf_type_t prop_type
;
204 while (scf_iter_next_property(handle_iter
->prop
, handle
->prop
) == 1) {
205 if (scf_property_get_name(handle
->prop
, key_buf
,
206 PLUGIN_MAXKEY
) == -1) {
212 * We do not fully support multi-valued properties.
213 * scf_property_get_value() only supports single-valued
214 * properties. It returns SCF_ERROR_CONSTRAINT_VIOLATED and one
215 * of the property values. The audit service configuration
216 * values are all single-valued properties. The authorizations
217 * to configure and read the audit service properties may be
218 * multi-valued, these may safely be ignored here as not an
221 if (scf_property_get_value(handle
->prop
,
222 handle_iter
->prop_val
) != 0 &&
223 scf_error() != SCF_ERROR_CONSTRAINT_VIOLATED
) {
227 if (scf_property_type(handle
->prop
, &prop_type
) == -1) {
232 case SCF_TYPE_BOOLEAN
: {
234 if (scf_value_get_boolean(handle_iter
->prop_val
,
239 len
= snprintf(attr_buf
, PLUGIN_MAXATT
, "%s=%d;",
241 if (len
< 0 || len
>= PLUGIN_MAXATT
) {
242 prt_error(gettext("Too long attribute: %s\n"),
246 if (strlcat(attr_string
, attr_buf
, PLUGIN_MAXATT
) >=
248 prt_error(gettext("Too long attribute string: "
254 case SCF_TYPE_ASTRING
: {
255 if (scf_value_get_as_string(handle_iter
->prop_val
,
256 val_buf
, PLUGIN_MAXATT
) == -1) {
260 len
= snprintf(attr_buf
, PLUGIN_MAXATT
, "%s=%s;",
262 if (len
< 0 || len
>= PLUGIN_MAXATT
) {
263 prt_error(gettext("Too long attribute: %s\n"),
267 if (strlcat(attr_string
, attr_buf
, PLUGIN_MAXATT
) >=
269 prt_error(gettext("Too long attribute string: "
275 case SCF_TYPE_COUNT
: {
277 if (scf_value_get_count(handle_iter
->prop_val
,
278 &pval_count
) == -1) {
282 len
= snprintf(attr_buf
, PLUGIN_MAXATT
, "%s=%llu;",
283 key_buf
, pval_count
);
284 if (len
< 0 || len
>= PLUGIN_MAXATT
) {
285 prt_error(gettext("Too long attribute: %s\n"),
289 if (strlcat(attr_string
, attr_buf
, PLUGIN_MAXATT
) >=
291 prt_error(gettext("Too long attribute string: "
298 (void) printf("Unsupported value type %s [%d]\n",
304 if (*attr_string
== '\0' ||
305 (*plugin_kva
= _str2kva(attr_string
, "=", ";")) == NULL
) {
306 prt_error(gettext("Empty or invalid attribute string."));
314 * get_plugin_kva() - get and save config attributes of given plugin plugin_str
315 * (or all plugins in case plugin_str == NULL) into scf_plugin_kva_node_t.
318 get_plugin_kva(asi_scfhandle_t
*handle
, asi_scfhandle_iter_t
*handle_iter
,
319 scf_plugin_kva_node_t
**plugin_kva_ll
, char *plugin_str
)
322 scf_plugin_kva_node_t
*node
= NULL
;
323 scf_plugin_kva_node_t
*node_prev
= NULL
;
324 scf_plugin_kva_node_t
*node_head
= NULL
;
325 char plugin_str_tmp
[PLUGIN_MAXBUF
];
327 bzero(plugin_str_tmp
, PLUGIN_MAXBUF
);
329 if (scf_iter_instance_pgs_typed(handle_iter
->pgrp
, handle
->inst
,
330 (const char *)"plugin") == -1) {
335 while (scf_iter_next_pg(handle_iter
->pgrp
, handle
->pgrp
) == 1) {
336 if (scf_pg_get_name(handle
->pgrp
, plugin_str_tmp
,
337 PLUGIN_MAXBUF
) == -1) {
339 plugin_kva_ll_free(node
);
343 if (plugin_str
!= NULL
&&
344 strcmp(plugin_str_tmp
, plugin_str
) != 0) {
349 calloc(1, sizeof (scf_plugin_kva_node_t
))) == NULL
) {
350 prt_error(gettext("No available memory."));
351 plugin_kva_ll_free(node_prev
);
354 if (node_head
== NULL
) {
357 if (node_prev
!= NULL
) {
358 node_prev
->next
= node
;
359 node
->prev
= node_prev
;
363 (void) strlcat((char *)&(node
->plugin_name
), plugin_str_tmp
,
366 if (scf_iter_pg_properties(handle_iter
->prop
,
367 handle
->pgrp
) != 0) {
369 plugin_kva_ll_free(node
);
373 if (!get_props_kva_all(handle
, handle_iter
,
374 &(node
->plugin_kva
))) {
375 plugin_kva_ll_free(node
);
382 scf_plugin_kva_node_t
*node_debug
= node_head
;
383 char attr_string
[PLUGIN_MAXATT
];
385 while (node_debug
!= NULL
) {
386 if (_kva2str(node_debug
->plugin_kva
, attr_string
,
387 PLUGIN_MAXATT
, "=", ";") == 0) {
388 DPRINT((dbfp
, "Found plugin - %s: %s\n",
389 node_debug
->plugin_name
, attr_string
));
391 DPRINT((dbfp
, "Could not get attribute string "
392 "for %s\n", node_debug
->plugin_name
));
394 node_debug
= node_debug
->prev
;
399 *plugin_kva_ll
= node_head
;
405 * scf_free() - free scf handles
408 scf_free(asi_scfhandle_t
*handle
)
410 if (handle
== NULL
) {
414 if (handle
->prop
!= NULL
) {
415 scf_property_destroy(handle
->prop
);
417 if (handle
->pgrp
!= NULL
) {
418 scf_pg_destroy(handle
->pgrp
);
420 if (handle
->inst
!= NULL
) {
421 scf_instance_destroy(handle
->inst
);
423 if (handle
->hndl
!= NULL
) {
424 if (scf_handle_unbind(handle
->hndl
) == -1) {
425 prt_error(gettext("Internal error."));
428 scf_handle_destroy(handle
->hndl
);
433 * scf_init() - initiate scf handles
436 scf_init(asi_scfhandle_t
*handle
)
438 bzero(handle
, sizeof (asi_scfhandle_t
));
440 if ((handle
->hndl
= scf_handle_create(SCF_VERSION
)) == NULL
||
441 scf_handle_bind(handle
->hndl
) != 0) {
444 if ((handle
->inst
= scf_instance_create(handle
->hndl
)) == NULL
) {
447 if ((handle
->pgrp
= scf_pg_create(handle
->hndl
)) == NULL
) {
450 if ((handle
->prop
= scf_property_create(handle
->hndl
)) == NULL
) {
463 * scf_free_iter() - free scf iter handles
466 scf_free_iter(asi_scfhandle_iter_t
*handle_iter
)
468 if (handle_iter
== NULL
) {
472 if (handle_iter
->pgrp
!= NULL
) {
473 scf_iter_destroy(handle_iter
->pgrp
);
475 if (handle_iter
->prop
!= NULL
) {
476 scf_iter_destroy(handle_iter
->prop
);
478 if (handle_iter
->prop_val
!= NULL
) {
479 scf_value_destroy(handle_iter
->prop_val
);
484 * scf_init_iter() - initiate scf iter handles
487 scf_init_iter(asi_scfhandle_iter_t
*handle_iter
,
488 asi_scfhandle_t
*handle
)
490 bzero(handle_iter
, sizeof (asi_scfhandle_iter_t
));
492 if ((handle_iter
->pgrp
= scf_iter_create(handle
->hndl
)) == NULL
) {
495 if ((handle_iter
->prop
= scf_iter_create(handle
->hndl
)) == NULL
) {
498 if ((handle_iter
->prop_val
= scf_value_create(handle
->hndl
)) == NULL
) {
506 scf_free_iter(handle_iter
);
511 * chk_policy_context() - does some policy based checks, checks the context
512 * (zone, smf) in which the policy could make some sense.
515 chk_policy_context(char *policy_str
)
519 * "all" and "none" policy flags, since they represent
520 * sub/set of auditing policies, are not stored in the
521 * AUDITD_FMRI service instance configuration.
523 DPRINT((dbfp
, "Walking policy - %s: ", policy_str
));
524 if (strcmp("all", policy_str
) == 0 ||
525 strcmp("none", policy_str
) == 0) {
526 DPRINT((dbfp
, "skipped\n"));
530 * In the local zone (!= GLOBAL_ZONEID) we do not touch
531 * "ahlt" and "perzone" policy flags, since these are
532 * relevant only in the global zone.
534 if ((getzoneid() != GLOBAL_ZONEID
) &&
535 (strcmp("ahlt", policy_str
) == 0 ||
536 strcmp("perzone", policy_str
) == 0)) {
537 DPRINT((dbfp
, "skipped\n"));
545 * free_static_att_kva() - free hardcoded/static plugin attributes (key/value
546 * pairs) from the kva plugin structure.
549 free_static_att_kva(kva_t
*plugin_kva
)
551 _kva_free_value(plugin_kva
, PLUGIN_ACTIVE
);
552 _kva_free_value(plugin_kva
, PLUGIN_PATH
);
553 _kva_free_value(plugin_kva
, PLUGIN_QSIZE
);
554 _kva_free_value(plugin_kva
, "read_authorization");
555 _kva_free_value(plugin_kva
, "value_authorization");
560 * do_getqctrl_scf() - get the values of qctrl properties of the audit service
563 do_getqctrl_scf(struct au_qctrl
*cval
)
565 scf_propvec_t
*prop_vect_ptr
;
566 scf_qctrl_t cval_scf
;
568 bzero(prop_vect
, sizeof (prop_vect
));
570 prop_vect_ptr
= prop_vect
;
571 add_prop_vect_scf(prop_vect_ptr
++, QUEUECTRL_QHIWATER
,
572 SCF_TYPE_COUNT
, &cval_scf
.scf_qhiwater
);
573 add_prop_vect_scf(prop_vect_ptr
++, QUEUECTRL_QLOWATER
,
574 SCF_TYPE_COUNT
, &cval_scf
.scf_qlowater
);
575 add_prop_vect_scf(prop_vect_ptr
++, QUEUECTRL_QBUFSZ
,
576 SCF_TYPE_COUNT
, &cval_scf
.scf_qbufsz
);
577 add_prop_vect_scf(prop_vect_ptr
, QUEUECTRL_QDELAY
,
578 SCF_TYPE_COUNT
, &cval_scf
.scf_qdelay
);
580 if (!get_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
)) {
584 cval
->aq_hiwater
= (size_t)cval_scf
.scf_qhiwater
;
585 cval
->aq_lowater
= (size_t)cval_scf
.scf_qlowater
;
586 cval
->aq_bufsz
= (size_t)cval_scf
.scf_qbufsz
;
587 cval
->aq_delay
= (clock_t)cval_scf
.scf_qdelay
;
589 scf_clean_propvec(prop_vect
);
595 * do_getqbufsz_scf() - get the qbufsz audit service property value
598 do_getqbufsz_scf(size_t *cval
)
602 bzero(prop_vect
, sizeof (prop_vect
));
603 add_prop_vect_scf(prop_vect
, QUEUECTRL_QBUFSZ
, SCF_TYPE_COUNT
, &cval_l
);
605 if (!get_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
)) {
609 *cval
= (size_t)cval_l
;
615 * do_getqdelay_scf() - get the qdelay audit service property value
618 do_getqdelay_scf(clock_t *cval
)
622 bzero(prop_vect
, sizeof (prop_vect
));
623 add_prop_vect_scf(prop_vect
, QUEUECTRL_QDELAY
, SCF_TYPE_COUNT
, &cval_l
);
625 if (!get_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
)) {
629 *cval
= (clock_t)cval_l
;
635 * do_getqhiwater_scf() - get the qhiwater audit service property value
638 do_getqhiwater_scf(size_t *cval
)
642 bzero(prop_vect
, sizeof (prop_vect
));
643 add_prop_vect_scf(prop_vect
, QUEUECTRL_QHIWATER
, SCF_TYPE_COUNT
,
646 if (!get_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
)) {
650 *cval
= (size_t)cval_l
;
656 * do_getqlowater_scf() - get the qlowater audit service property value
659 do_getqlowater_scf(size_t *cval
)
663 bzero(prop_vect
, sizeof (prop_vect
));
664 add_prop_vect_scf(prop_vect
, QUEUECTRL_QLOWATER
, SCF_TYPE_COUNT
,
667 if (!get_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
)) {
671 *cval
= (size_t)cval_l
;
677 * do_getpolicy_scf() - get the audit policy flags from service
680 do_getpolicy_scf(uint32_t *policy_mask
)
683 scf_propvec_t
*prop_vect_ptr
;
684 char *cur_policy_str
;
685 policy_sw_t policy_arr
[POLICY_TBL_SZ
+ 1];
686 policy_sw_t
*policy_arr_ptr
;
688 prop_vect_ptr
= prop_vect
;
689 policy_arr_ptr
= policy_arr
;
691 bzero(prop_vect
, sizeof (prop_vect
));
692 bzero(policy_arr
, sizeof (policy_arr
));
694 /* prepare the smf(5) query */
695 for (i
= 0; i
< POLICY_TBL_SZ
; i
++) {
697 cur_policy_str
= policy_table
[i
].policy_str
;
699 /* Do some basic policy dependent checks */
700 if (!chk_policy_context(cur_policy_str
)) {
703 DPRINT((dbfp
, "will be queried\n"));
705 add_prop_vect_scf(prop_vect_ptr
++, cur_policy_str
,
706 SCF_TYPE_BOOLEAN
, &policy_arr_ptr
->flag
);
708 policy_arr_ptr
->policy
= cur_policy_str
;
712 if (!get_val_scf(prop_vect
, ASI_PGROUP_POLICY
)) {
716 /* set the policy mask */
717 policy_arr_ptr
= policy_arr
;
719 while (policy_arr_ptr
->policy
!= NULL
) {
720 if (policy_arr_ptr
->flag
) {
721 *policy_mask
|= get_policy(policy_arr_ptr
->policy
);
730 * do_setpolicy_scf() - sets the policy flags in audit service configuration
733 do_setpolicy_scf(uint32_t policy
)
736 char *cur_policy_str
;
737 scf_propvec_t
*prop_vect_ptr
;
738 boolean_t bool_arr
[POLICY_TBL_SZ
];
739 boolean_t
*bool_arr_ptr
;
741 prop_vect_ptr
= prop_vect
;
742 bool_arr_ptr
= bool_arr
;
744 bzero(prop_vect
, sizeof (prop_vect
));
745 bzero(bool_arr
, sizeof (bool_arr
));
747 for (i
= 0; i
< POLICY_TBL_SZ
; i
++) {
749 cur_policy_str
= policy_table
[i
].policy_str
;
751 /* Do some basic policy dependent checks */
752 if (!chk_policy_context(cur_policy_str
)) {
756 if (policy_table
[i
].policy_mask
& policy
) {
757 *bool_arr_ptr
= B_TRUE
;
759 *bool_arr_ptr
= B_FALSE
;
762 DPRINT((dbfp
, "%s%s\n", (*bool_arr_ptr
== B_TRUE
? "+" : "-"),
765 add_prop_vect_scf(prop_vect_ptr
++, cur_policy_str
,
766 SCF_TYPE_BOOLEAN
, bool_arr_ptr
++);
770 return (set_val_scf(prop_vect
, ASI_PGROUP_POLICY
));
774 * do_setqctrl_scf() - set the values of qctrl properties of the audit service
777 do_setqctrl_scf(struct au_qctrl
*cval
)
779 scf_propvec_t
*prop_vect_ptr
;
780 scf_qctrl_t cval_scf
;
782 if (!CHK_BDRY_QHIWATER(cval
->aq_lowater
, cval
->aq_hiwater
) &&
783 cval
->aq_hiwater
!= 0) {
784 (void) printf(gettext("Specified audit queue hiwater mark is "
785 "outside of allowed boundaries.\n"));
788 if (!CHK_BDRY_QLOWATER(cval
->aq_lowater
, cval
->aq_hiwater
) &&
789 cval
->aq_lowater
!= 0) {
790 (void) printf(gettext("Specified audit queue lowater mark is "
791 "outside of allowed boundaries.\n"));
794 if (!CHK_BDRY_QBUFSZ(cval
->aq_bufsz
) && cval
->aq_bufsz
!= 0) {
795 (void) printf(gettext("Specified audit queue buffer size is "
796 "outside of allowed boundaries.\n"));
799 if (!CHK_BDRY_QDELAY(cval
->aq_delay
) && cval
->aq_delay
!= 0) {
800 (void) printf(gettext("Specified audit queue delay is "
801 "outside of allowed boundaries.\n"));
805 cval_scf
.scf_qhiwater
= (uint64_t)cval
->aq_hiwater
;
806 cval_scf
.scf_qlowater
= (uint64_t)cval
->aq_lowater
;
807 cval_scf
.scf_qbufsz
= (uint64_t)cval
->aq_bufsz
;
808 cval_scf
.scf_qdelay
= (uint64_t)cval
->aq_delay
;
810 bzero(prop_vect
, sizeof (prop_vect
));
812 prop_vect_ptr
= prop_vect
;
813 add_prop_vect_scf(prop_vect_ptr
++, QUEUECTRL_QHIWATER
, SCF_TYPE_COUNT
,
814 &cval_scf
.scf_qhiwater
);
815 add_prop_vect_scf(prop_vect_ptr
++, QUEUECTRL_QLOWATER
, SCF_TYPE_COUNT
,
816 &cval_scf
.scf_qlowater
);
817 add_prop_vect_scf(prop_vect_ptr
++, QUEUECTRL_QBUFSZ
, SCF_TYPE_COUNT
,
818 &cval_scf
.scf_qbufsz
);
819 add_prop_vect_scf(prop_vect_ptr
, QUEUECTRL_QDELAY
, SCF_TYPE_COUNT
,
820 &cval_scf
.scf_qdelay
);
822 return (set_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
));
826 * do_setqbufsz_scf() - set the qbufsz property value of the audit service
829 do_setqbufsz_scf(size_t *cval
)
833 if (!CHK_BDRY_QBUFSZ(*cval
) && *cval
!= 0) {
834 (void) printf(gettext("Specified audit queue buffer size is "
835 "outside of allowed boundaries.\n"));
839 cval_l
= (uint64_t)*cval
;
841 bzero(prop_vect
, sizeof (prop_vect
));
842 add_prop_vect_scf(prop_vect
, QUEUECTRL_QBUFSZ
, SCF_TYPE_COUNT
, &cval_l
);
844 return (set_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
));
848 * do_setqdelay_scf() - set the qdelay property value of the audit service
851 do_setqdelay_scf(clock_t *cval
)
855 if (!CHK_BDRY_QDELAY(*cval
) && *cval
!= 0) {
856 (void) printf(gettext("Specified audit queue delay is "
857 "outside of allowed boundaries.\n"));
861 cval_l
= (uint64_t)*cval
;
863 bzero(prop_vect
, sizeof (prop_vect
));
864 add_prop_vect_scf(prop_vect
, QUEUECTRL_QDELAY
, SCF_TYPE_COUNT
, &cval_l
);
866 return (set_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
));
870 * do_setqhiwater_scf() - set the qhiwater property value of the audit service
873 do_setqhiwater_scf(size_t *cval
)
878 if (!do_getqlowater_scf(&cval_lowater
)) {
879 (void) printf(gettext("Could not get configured value of "
880 "queue lowater mark.\n"));
883 if (cval_lowater
== 0) {
884 cval_lowater
= AQ_MINLOW
;
886 if (!CHK_BDRY_QHIWATER(cval_lowater
, *cval
) && *cval
!= 0) {
887 (void) printf(gettext("Specified audit queue hiwater mark is "
888 "outside of allowed boundaries.\n"));
892 cval_l
= (uint64_t)*cval
;
894 bzero(prop_vect
, sizeof (prop_vect
));
895 add_prop_vect_scf(prop_vect
, QUEUECTRL_QHIWATER
, SCF_TYPE_COUNT
,
898 return (set_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
));
902 * do_setqlowater_scf() - set the qlowater property value of the audit service
905 do_setqlowater_scf(size_t *cval
)
910 if (!do_getqhiwater_scf(&cval_hiwater
)) {
911 (void) printf(gettext("Could not get configured value of "
912 "queue hiwater mark.\n"));
915 if (cval_hiwater
== 0) {
916 cval_hiwater
= AQ_MAXHIGH
;
918 if (!CHK_BDRY_QLOWATER(*cval
, cval_hiwater
) && *cval
!= 0) {
919 (void) printf(gettext("Specified audit queue lowater mark is "
920 "outside of allowed boundaries.\n"));
924 cval_l
= (uint64_t)*cval
;
926 bzero(prop_vect
, sizeof (prop_vect
));
927 add_prop_vect_scf(prop_vect
, QUEUECTRL_QLOWATER
, SCF_TYPE_COUNT
,
930 return (set_val_scf(prop_vect
, ASI_PGROUP_QUEUECTRL
));
934 * do_getflags_scf() - get the audit attributable flags from service
937 do_getflags_scf(char **flags
)
939 bzero(prop_vect
, sizeof (prop_vect
));
940 add_prop_vect_scf(prop_vect
, PRESELECTION_FLAGS
, SCF_TYPE_ASTRING
,
943 if (!get_val_scf(prop_vect
, ASI_PGROUP_PRESELECTION
)) {
951 * do_getnaflags_scf() - get the audit non-attributable flags from service
954 do_getnaflags_scf(char **naflags
)
956 bzero(prop_vect
, sizeof (prop_vect
));
957 add_prop_vect_scf(prop_vect
, PRESELECTION_NAFLAGS
, SCF_TYPE_ASTRING
,
960 if (!get_val_scf(prop_vect
, ASI_PGROUP_PRESELECTION
)) {
968 * do_setflags_scf() - set the attributable mask property value of the audit
972 do_setflags_scf(char *flags
)
974 bzero(prop_vect
, sizeof (prop_vect
));
975 add_prop_vect_scf(prop_vect
, PRESELECTION_FLAGS
, SCF_TYPE_ASTRING
,
978 return (set_val_scf(prop_vect
, ASI_PGROUP_PRESELECTION
));
982 * do_setnaflags_scf() - set the attributable mask property value of the audit
986 do_setnaflags_scf(char *naflags
)
988 bzero(prop_vect
, sizeof (prop_vect
));
989 add_prop_vect_scf(prop_vect
, PRESELECTION_NAFLAGS
, SCF_TYPE_ASTRING
,
992 return (set_val_scf(prop_vect
, ASI_PGROUP_PRESELECTION
));
996 * plugin_avail_scf() - look for the plugin in the audit service configuration
999 plugin_avail_scf(const char *plugin_str
)
1001 scf_simple_handle_t
*sh
;
1003 if (plugin_str
== NULL
|| *plugin_str
== '\0') {
1007 if ((sh
= scf_general_pg_setup(AUDITD_FMRI
, plugin_str
)) == NULL
) {
1008 DPRINT((dbfp
, "No such plugin found: %s (%s)\n", plugin_str
,
1009 scf_strerror(scf_error())));
1013 scf_simple_handle_destroy(sh
);
1018 * do_getpluginconfig_scf() - get plugin configuration from the audit service
1022 do_getpluginconfig_scf(char *plugin_str
, scf_plugin_kva_node_t
**plugin_kva_ll
)
1026 asi_scfhandle_t handle
;
1027 asi_scfhandle_iter_t handle_iter
;
1028 boolean_t plugin_all
= B_FALSE
;
1029 boolean_t rv
= B_TRUE
;
1031 if (plugin_str
== NULL
|| *plugin_str
== '\0') {
1032 if (asprintf(&asi_fmri
, "%s", AUDITD_FMRI
) == -1) {
1033 prt_error(gettext("Out of memory."));
1036 plugin_all
= B_TRUE
;
1038 if (asprintf(&asi_fmri
, "%s%s%s", AUDITD_FMRI
,
1039 SCF_FMRI_PROPERTYGRP_PREFIX
, plugin_str
) == -1) {
1040 prt_error(gettext("Out of memory."));
1044 DPRINT((dbfp
, "%s will be decoded\n", asi_fmri
));
1046 if (!scf_init(&handle
)) {
1047 prt_error(gettext("Unable to initialize scf handles."));
1052 if (scf_handle_decode_fmri(handle
.hndl
, asi_fmri
, NULL
, NULL
,
1053 handle
.inst
, plugin_all
? NULL
: handle
.pgrp
, NULL
,
1054 SCF_DECODE_FMRI_EXACT
) == -1) {
1061 if (!scf_init_iter(&handle_iter
, &handle
)) {
1062 prt_error(gettext("Unable to initialize scf iter handles."));
1070 rv
= get_plugin_kva(&handle
, &handle_iter
, plugin_kva_ll
, NULL
);
1072 rv
= get_plugin_kva(&handle
, &handle_iter
, plugin_kva_ll
,
1077 scf_free_iter(&handle_iter
);
1083 * do_setpluginconfig_scf() - set plugin configuration in the audit service
1087 do_setpluginconfig_scf(char *plugin_str
, boolean_t plugin_state
,
1088 char *plugin_att
, int plugin_qsize
)
1090 kva_t
*plugin_att_kva
= NULL
;
1091 char *plugin_att_ptr
= plugin_att
;
1092 char *plugin_att_clr_ptr
= plugin_att
;
1093 scf_simple_prop_t
*plugin_prop
;
1094 scf_type_t plugin_prop_type
;
1095 scf_propvec_t
*prop_vect_ptr
;
1098 boolean_t rval
= B_TRUE
;
1099 uint64_t plugin_qsize_l
= (uint64_t)plugin_qsize
;
1101 DPRINT((dbfp
, "Auditd plugin configuration to be set:\n\tplugin=%s\n\t"
1102 "state=%d (%s)\n\tattributes=%s\n\tqsize=%d%s\n", plugin_str
,
1103 plugin_state
, plugin_state
== B_TRUE
? "active" : "inactive",
1104 plugin_att
== NULL
? " (unspecified)" : plugin_att
,
1105 plugin_qsize
, plugin_qsize
== -1 ? " (unspecified)" : ""));
1107 bzero(prop_vect
, sizeof (prop_vect
));
1108 prop_vect_ptr
= prop_vect
;
1110 if (plugin_att
!= NULL
) {
1112 /* get rid of white-space chars */
1113 if (*plugin_att_ptr
!= '\0') {
1114 while (*plugin_att_ptr
!= '\0') {
1115 if (isspace(*plugin_att_ptr
) == 0) {
1116 *plugin_att_clr_ptr
++ = *plugin_att_ptr
;
1120 *plugin_att_clr_ptr
= '\0';
1122 DPRINT((dbfp
, "attributes (no white-space): %s\n", plugin_att
));
1124 /* allow empty plugin_att */
1125 if (*plugin_att
== '\0') {
1129 plugin_att_kva
= _str2kva(plugin_att
, "=", ";");
1130 if (plugin_att_kva
== NULL
) {
1131 prt_error(gettext("Could not parse plugin "
1136 free_static_att_kva(plugin_att_kva
);
1137 cnt
= plugin_att_kva
->length
;
1138 data
= plugin_att_kva
->data
;
1143 add_prop_vect_scf(prop_vect_ptr
++, PLUGIN_ACTIVE
, SCF_TYPE_BOOLEAN
,
1145 DPRINT((dbfp
, "Prepared active -> %d\n", plugin_state
));
1147 /* set attributes */
1149 if (data
->value
== NULL
) {
1154 if (!chk_prop_vect(&prop_vect_ptr
, plugin_str
)) {
1159 if ((plugin_prop
= scf_simple_prop_get(NULL
,
1160 AUDITD_FMRI
, plugin_str
, data
->key
)) == NULL
) {
1161 prt_error(gettext("Could not get configuration for "
1162 "attribute: %s"), data
->key
);
1167 if ((plugin_prop_type
= scf_simple_prop_type(plugin_prop
))
1169 prt_error(gettext("Could not get property type: %s"),
1176 switch (plugin_prop_type
) {
1177 case SCF_TYPE_BOOLEAN
: {
1179 pval_bool
= (uint8_t *)malloc(sizeof (uint8_t));
1180 if (pval_bool
== NULL
) {
1181 prt_error(gettext("No free memory available."));
1185 *pval_bool
= (uint8_t)atoi(data
->value
);
1186 add_prop_vect_scf(prop_vect_ptr
++, data
->key
,
1187 SCF_TYPE_BOOLEAN
, pval_bool
);
1190 case SCF_TYPE_ASTRING
: {
1192 if ((pval_str
= strdup(data
->value
)) == NULL
) {
1193 prt_error(gettext("No free memory available."));
1197 add_prop_vect_scf(prop_vect_ptr
++, data
->key
,
1198 SCF_TYPE_ASTRING
, pval_str
);
1201 case SCF_TYPE_COUNT
: {
1202 uint64_t *pval_count
;
1203 pval_count
= (uint64_t *)malloc(sizeof (uint64_t));
1204 if (pval_count
== NULL
) {
1205 prt_error(gettext("No free memory available."));
1209 *pval_count
= (uint64_t)atoll(data
->value
);
1210 add_prop_vect_scf(prop_vect_ptr
++, data
->key
,
1211 SCF_TYPE_COUNT
, pval_count
);
1215 prt_error(gettext("Unsupported property type: %s (%d)"),
1216 data
->key
, plugin_prop_type
);
1220 DPRINT((dbfp
, "Prepared %s -> %s\n", data
->key
, data
->value
));
1221 scf_simple_prop_free(plugin_prop
);
1226 if (!chk_prop_vect(&prop_vect_ptr
, plugin_str
)) {
1232 if (plugin_qsize
!= -1) {
1233 add_prop_vect_scf(prop_vect_ptr
, PLUGIN_QSIZE
, SCF_TYPE_COUNT
,
1235 DPRINT((dbfp
, "Prepared qsize -> %d\n", plugin_qsize
));
1238 if (!set_val_scf(prop_vect
, plugin_str
)) {
1244 _kva_free(plugin_att_kva
);
1249 * plugin_kva_ll_free() - free the memory used by plugin kva linked list.
1252 plugin_kva_ll_free(scf_plugin_kva_node_t
*node
)
1254 scf_plugin_kva_node_t
*node_next
;
1260 while (node
->prev
!= NULL
) {
1263 while (node
!= NULL
) {
1264 _kva_free(node
->plugin_kva
);
1265 node_next
= node
->next
;
1272 * get_policy() - get policy mask entry
1275 get_policy(char *policy
)
1279 for (i
= 0; i
< POLICY_TBL_SZ
; i
++) {
1280 if (strcasecmp(policy
, policy_table
[i
].policy_str
) == 0) {
1281 return (policy_table
[i
].policy_mask
);