1f8994074SJan Friedel /*
2f8994074SJan Friedel  * CDDL HEADER START
3f8994074SJan Friedel  *
4f8994074SJan Friedel  * The contents of this file are subject to the terms of the
5f8994074SJan Friedel  * Common Development and Distribution License (the "License").
6f8994074SJan Friedel  * You may not use this file except in compliance with the License.
7f8994074SJan Friedel  *
8f8994074SJan Friedel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f8994074SJan Friedel  * or http://www.opensolaris.org/os/licensing.
10f8994074SJan Friedel  * See the License for the specific language governing permissions
11f8994074SJan Friedel  * and limitations under the License.
12f8994074SJan Friedel  *
13f8994074SJan Friedel  * When distributing Covered Code, include this CDDL HEADER in each
14f8994074SJan Friedel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f8994074SJan Friedel  * If applicable, add the following below this CDDL HEADER, with the
16f8994074SJan Friedel  * fields enclosed by brackets "[]" replaced with your own identifying
17f8994074SJan Friedel  * information: Portions Copyright [yyyy] [name of copyright owner]
18f8994074SJan Friedel  *
19f8994074SJan Friedel  * CDDL HEADER END
20f8994074SJan Friedel  */
21f8994074SJan Friedel /*
22f8994074SJan Friedel  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23f8994074SJan Friedel  */
24f8994074SJan Friedel 
25*bbf21555SRichard Lowe /* auditd smf(7)/libscf(3LIB) interface - set and display audit parameters */
26f8994074SJan Friedel #include <audit_scf.h>
27f8994074SJan Friedel #include <audit_policy.h>
28f8994074SJan Friedel 
29f8994074SJan Friedel /* propvec array must be NULL terminated */
30f8994074SJan Friedel scf_propvec_t	prop_vect[MAX_PROPVECS + 1];
31f8994074SJan Friedel 
32f8994074SJan Friedel /*
33f8994074SJan Friedel  * prt_error() - prt_error_va() wrapper; see prt_error_va() for more contextual
34f8994074SJan Friedel  * information. Note, that the function disregards errno; if you need to print
35f8994074SJan Friedel  * out strerror()/errno use directly prt_error_va().
36f8994074SJan Friedel  * Inputs - program error format and message.
37f8994074SJan Friedel  */
38f8994074SJan Friedel /*PRINTFLIKE1*/
39f8994074SJan Friedel static void
prt_error(char * fmt,...)40f8994074SJan Friedel prt_error(char *fmt, ...)
41f8994074SJan Friedel {
42f8994074SJan Friedel 	va_list 	args;
43f8994074SJan Friedel 
44f8994074SJan Friedel 	errno = 0;
45f8994074SJan Friedel 
46f8994074SJan Friedel 	va_start(args, fmt);
47f8994074SJan Friedel 	prt_error_va(fmt, args);
48f8994074SJan Friedel 	va_end(args);
49f8994074SJan Friedel }
50f8994074SJan Friedel 
51f8994074SJan Friedel /*
52f8994074SJan Friedel  * prt_error_va() - prints an error message along with corresponding system
53f8994074SJan Friedel  * error number. Inputs - program error format and the va_list already prepared
54f8994074SJan Friedel  * by the preceding functions.
55f8994074SJan Friedel  *
56f8994074SJan Friedel  */
57f8994074SJan Friedel /*PRINTFLIKE1*/
58f8994074SJan Friedel void
prt_error_va(char * fmt,va_list args)59f8994074SJan Friedel prt_error_va(char *fmt, va_list args)
60f8994074SJan Friedel {
61f8994074SJan Friedel 	(void) vfprintf(stderr, fmt, args);
62f8994074SJan Friedel 	(void) fputc('\n', stderr);
63f8994074SJan Friedel 	if (errno)
64f8994074SJan Friedel 		(void) fprintf(stderr, "error: %s(%d)\n",
65f8994074SJan Friedel 		    strerror(errno), errno);
66f8994074SJan Friedel 	(void) fflush(stderr);
67f8994074SJan Friedel }
68f8994074SJan Friedel 
69f8994074SJan Friedel /*
70f8994074SJan Friedel  * prt_scf_err() - scf_error()/scf_strerror() wrapper.
71f8994074SJan Friedel  */
72f8994074SJan Friedel static void
prt_scf_err(void)73f8994074SJan Friedel prt_scf_err(void)
74f8994074SJan Friedel {
75f8994074SJan Friedel 	(void) fprintf(stderr, "error: %s\n", scf_strerror(scf_error()));
76f8994074SJan Friedel }
77f8994074SJan Friedel 
78f8994074SJan Friedel /*
79f8994074SJan Friedel  * add_prop_vect_scf() - adds vector to the array of vectors later passed to
80f8994074SJan Friedel  * get_/set_val_scf(). The first argument (vector) points to particular position
81f8994074SJan Friedel  * in the vector of properties.
82f8994074SJan Friedel  */
83f8994074SJan Friedel static void
add_prop_vect_scf(scf_propvec_t * vector,const char * prop_str,scf_type_t prop_type,void * prop_val_ptr)84f8994074SJan Friedel add_prop_vect_scf(scf_propvec_t *vector, const char *prop_str,
85f8994074SJan Friedel     scf_type_t prop_type, void *prop_val_ptr)
86f8994074SJan Friedel {
87f8994074SJan Friedel 	vector->pv_prop = prop_str;
88f8994074SJan Friedel 	vector->pv_type = prop_type;
89f8994074SJan Friedel 	vector->pv_ptr = prop_val_ptr;
90f8994074SJan Friedel }
91f8994074SJan Friedel 
92f8994074SJan Friedel /*
93f8994074SJan Friedel  * get_val_scf() - get a property values from the audit service
94f8994074SJan Friedel  *
95f8994074SJan Friedel  * Arguments:	vector = pointers to the head end of array of property vectors
96f8994074SJan Friedel  * 		pgroup_str = property group of property in AUDITD_FMRI
97f8994074SJan Friedel  *
98f8994074SJan Friedel  */
99f8994074SJan Friedel static boolean_t
get_val_scf(scf_propvec_t * vector,char * pgroup_str)100f8994074SJan Friedel get_val_scf(scf_propvec_t *vector, char *pgroup_str)
101f8994074SJan Friedel {
102f8994074SJan Friedel 	scf_propvec_t	*bad_prop_vec = NULL;
103f8994074SJan Friedel 
104f8994074SJan Friedel 	/*
105f8994074SJan Friedel 	 * Get the property vector from the editing snapshot (B_FALSE).
106f8994074SJan Friedel 	 * For documentation on property vectors see <libscf_priv.h>.
107f8994074SJan Friedel 	 */
108f8994074SJan Friedel 	if (scf_read_propvec(AUDITD_FMRI, pgroup_str, B_FALSE, vector,
109f8994074SJan Friedel 	    &bad_prop_vec) != SCF_SUCCESS) {
110f8994074SJan Friedel 		prt_scf_err();
111f8994074SJan Friedel 		if (bad_prop_vec != NULL) {
112f8994074SJan Friedel 			prt_error(gettext("Reading the %s property in the %s "
113f8994074SJan Friedel 			    "property group failed.\n"), bad_prop_vec->pv_prop,
114f8994074SJan Friedel 			    pgroup_str);
115f8994074SJan Friedel 		}
116f8994074SJan Friedel 		return (B_FALSE);
117f8994074SJan Friedel 	}
118f8994074SJan Friedel 
119f8994074SJan Friedel 	return (B_TRUE);
120f8994074SJan Friedel }
121f8994074SJan Friedel 
122f8994074SJan Friedel /*
123f8994074SJan Friedel  * set_val_scf() - set property values of the audit service.
124f8994074SJan Friedel  *
125f8994074SJan Friedel  * arguments:	vector = pointers to the head end of array of property vectors
126f8994074SJan Friedel  * 		pgroup_str = property group of property in AUDITD_FMRI
127f8994074SJan Friedel  *
128f8994074SJan Friedel  */
129f8994074SJan Friedel static boolean_t
set_val_scf(scf_propvec_t * vector,char * pgroup_str)130f8994074SJan Friedel set_val_scf(scf_propvec_t *vector, char *pgroup_str)
131f8994074SJan Friedel {
132f8994074SJan Friedel 	scf_propvec_t	*bad_prop_vec = NULL;
133f8994074SJan Friedel 
134f8994074SJan Friedel 	/* for documentation on property vectors see <libscf_priv.h> */
135f8994074SJan Friedel 	if (scf_write_propvec(AUDITD_FMRI, pgroup_str, vector,
136f8994074SJan Friedel 	    &bad_prop_vec) != SCF_SUCCESS) {
137f8994074SJan Friedel 		prt_scf_err();
138f8994074SJan Friedel 		if (bad_prop_vec != NULL) {
139f8994074SJan Friedel 			prt_error(gettext("Setting the %s property in the %s "
140f8994074SJan Friedel 			    "property group failed.\n"), bad_prop_vec->pv_prop,
141f8994074SJan Friedel 			    pgroup_str);
142f8994074SJan Friedel 		}
143f8994074SJan Friedel 		return (B_FALSE);
144f8994074SJan Friedel 	}
145f8994074SJan Friedel 
146f8994074SJan Friedel 	return (B_TRUE);
147f8994074SJan Friedel }
148f8994074SJan Friedel 
149f8994074SJan Friedel /*
150f8994074SJan Friedel  * free_prop_vect() - deallocate heap memory used for propvect values.
151f8994074SJan Friedel  */
152f8994074SJan Friedel static void
free_prop_vect(void)153f8994074SJan Friedel free_prop_vect(void)
154f8994074SJan Friedel {
155f8994074SJan Friedel 	scf_propvec_t	*prop_vect_ptr;
156f8994074SJan Friedel 
157f8994074SJan Friedel 	prop_vect_ptr = prop_vect;
158f8994074SJan Friedel 
159f8994074SJan Friedel 	while (prop_vect_ptr->pv_prop != NULL) {
160f8994074SJan Friedel 		if (stack_inbounds(prop_vect_ptr->pv_ptr) == 0) {
161f8994074SJan Friedel 			free(prop_vect_ptr->pv_ptr);
162f8994074SJan Friedel 		}
163f8994074SJan Friedel 		prop_vect_ptr++;
164f8994074SJan Friedel 	}
165f8994074SJan Friedel }
166f8994074SJan Friedel 
167f8994074SJan Friedel /*
168f8994074SJan Friedel  * chk_prop_vect() - check for prop_vect boundaries and possibly process
169f8994074SJan Friedel  * (typically) full prop_vect.
170f8994074SJan Friedel  */
171f8994074SJan Friedel static boolean_t
chk_prop_vect(scf_propvec_t ** prop_vect_ptr,char * pgrp_str)172f8994074SJan Friedel chk_prop_vect(scf_propvec_t **prop_vect_ptr, char *pgrp_str)
173f8994074SJan Friedel {
174f8994074SJan Friedel 	if (*prop_vect_ptr < prop_vect ||
175f8994074SJan Friedel 	    *prop_vect_ptr >= (prop_vect + MAX_PROPVECS)) {
176f8994074SJan Friedel 		DPRINT((dbfp, "prop_vect is full; flushing\n"));
177f8994074SJan Friedel 		if (!set_val_scf(prop_vect, pgrp_str)) {
178f8994074SJan Friedel 			return (B_FALSE);
179f8994074SJan Friedel 		}
180f8994074SJan Friedel 		free_prop_vect();
181f8994074SJan Friedel 		bzero(prop_vect, sizeof (prop_vect));
182f8994074SJan Friedel 		*prop_vect_ptr = prop_vect;
183f8994074SJan Friedel 	}
184f8994074SJan Friedel 	return (B_TRUE);
185f8994074SJan Friedel }
186f8994074SJan Friedel 
187f8994074SJan Friedel /*
188f8994074SJan Friedel  * get_props_kva_all() - get all properties and fill in the plugin_kva.
189f8994074SJan Friedel  */
190f8994074SJan Friedel static boolean_t
get_props_kva_all(asi_scfhandle_t * handle,asi_scfhandle_iter_t * handle_iter,kva_t ** plugin_kva)191f8994074SJan Friedel get_props_kva_all(asi_scfhandle_t *handle, asi_scfhandle_iter_t *handle_iter,
192f8994074SJan Friedel     kva_t **plugin_kva)
193f8994074SJan Friedel {
194f8994074SJan Friedel 	char		key_buf[PLUGIN_MAXKEY];
195f8994074SJan Friedel 	char		val_buf[PLUGIN_MAXVAL];
196f8994074SJan Friedel 	char		attr_string[PLUGIN_MAXATT];
197f8994074SJan Friedel 	char		attr_buf[PLUGIN_MAXATT];
198f8994074SJan Friedel 	int		len = 0;
199f8994074SJan Friedel 	scf_type_t	prop_type;
200f8994074SJan Friedel 
201f8994074SJan Friedel 	attr_string[0] = 0;
202f8994074SJan Friedel 	attr_buf[0] = 0;
203f8994074SJan Friedel 
204f8994074SJan Friedel 	while (scf_iter_next_property(handle_iter->prop, handle->prop) == 1) {
205f8994074SJan Friedel 		if (scf_property_get_name(handle->prop, key_buf,
206f8994074SJan Friedel 		    PLUGIN_MAXKEY) == -1) {
207f8994074SJan Friedel 			prt_scf_err();
208f8994074SJan Friedel 			return (B_FALSE);
209f8994074SJan Friedel 		}
210f8994074SJan Friedel 
211f8994074SJan Friedel 		/*
212f8994074SJan Friedel 		 * We do not fully support multi-valued properties.
213f8994074SJan Friedel 		 * scf_property_get_value() only supports single-valued
214f8994074SJan Friedel 		 * properties. It returns SCF_ERROR_CONSTRAINT_VIOLATED and one
215f8994074SJan Friedel 		 * of the property values. The audit service configuration
216f8994074SJan Friedel 		 * values are all single-valued properties. The authorizations
217f8994074SJan Friedel 		 * to configure and read the audit service properties may be
218f8994074SJan Friedel 		 * multi-valued, these may safely be ignored here as not an
219f8994074SJan Friedel 		 * error.
220f8994074SJan Friedel 		 */
221f8994074SJan Friedel 		if (scf_property_get_value(handle->prop,
222f8994074SJan Friedel 		    handle_iter->prop_val) != 0 &&
223f8994074SJan Friedel 		    scf_error() != SCF_ERROR_CONSTRAINT_VIOLATED) {
224f8994074SJan Friedel 			prt_scf_err();
225f8994074SJan Friedel 			return (B_FALSE);
226f8994074SJan Friedel 		}
227f8994074SJan Friedel 		if (scf_property_type(handle->prop, &prop_type) == -1) {
228f8994074SJan Friedel 			prt_scf_err();
229f8994074SJan Friedel 			return (B_FALSE);
230f8994074SJan Friedel 		}
231f8994074SJan Friedel 		switch (prop_type) {
232f8994074SJan Friedel 		case SCF_TYPE_BOOLEAN: {
233f8994074SJan Friedel 			uint8_t	pval_bool;
234f8994074SJan Friedel 			if (scf_value_get_boolean(handle_iter->prop_val,
235f8994074SJan Friedel 			    &pval_bool) == -1) {
236f8994074SJan Friedel 				prt_scf_err();
237f8994074SJan Friedel 				return (B_FALSE);
238f8994074SJan Friedel 			}
239f8994074SJan Friedel 			len = snprintf(attr_buf, PLUGIN_MAXATT, "%s=%d;",
240f8994074SJan Friedel 			    key_buf, pval_bool);
241f8994074SJan Friedel 			if (len < 0 || len >= PLUGIN_MAXATT) {
242f8994074SJan Friedel 				prt_error(gettext("Too long attribute: %s\n"),
243f8994074SJan Friedel 				    key_buf);
244f8994074SJan Friedel 				return (B_FALSE);
245f8994074SJan Friedel 			}
246f8994074SJan Friedel 			if (strlcat(attr_string, attr_buf, PLUGIN_MAXATT) >=
247f8994074SJan Friedel 			    PLUGIN_MAXATT) {
248f8994074SJan Friedel 				prt_error(gettext("Too long attribute string: "
249f8994074SJan Friedel 				    "%s\n"), key_buf);
250f8994074SJan Friedel 				return (B_FALSE);
251f8994074SJan Friedel 			}
252f8994074SJan Friedel 			break;
253f8994074SJan Friedel 		}
254f8994074SJan Friedel 		case SCF_TYPE_ASTRING: {
255f8994074SJan Friedel 			if (scf_value_get_as_string(handle_iter->prop_val,
256f8994074SJan Friedel 			    val_buf, PLUGIN_MAXATT) == -1) {
257f8994074SJan Friedel 				prt_scf_err();
258f8994074SJan Friedel 				return (B_FALSE);
259f8994074SJan Friedel 			}
260f8994074SJan Friedel 			len = snprintf(attr_buf, PLUGIN_MAXATT, "%s=%s;",
261f8994074SJan Friedel 			    key_buf, val_buf);
262f8994074SJan Friedel 			if (len < 0 || len >= PLUGIN_MAXATT) {
263f8994074SJan Friedel 				prt_error(gettext("Too long attribute: %s\n"),
264f8994074SJan Friedel 				    key_buf);
265f8994074SJan Friedel 				return (B_FALSE);
266f8994074SJan Friedel 			}
267f8994074SJan Friedel 			if (strlcat(attr_string, attr_buf, PLUGIN_MAXATT) >=
268f8994074SJan Friedel 			    PLUGIN_MAXATT) {
269f8994074SJan Friedel 				prt_error(gettext("Too long attribute string: "
270f8994074SJan Friedel 				    "%s\n"), key_buf);
271f8994074SJan Friedel 				return (B_FALSE);
272f8994074SJan Friedel 			}
273f8994074SJan Friedel 			break;
274f8994074SJan Friedel 		}
275f8994074SJan Friedel 		case SCF_TYPE_COUNT: {
276f8994074SJan Friedel 			uint64_t	pval_count;
277f8994074SJan Friedel 			if (scf_value_get_count(handle_iter->prop_val,
278f8994074SJan Friedel 			    &pval_count) == -1) {
279f8994074SJan Friedel 				prt_scf_err();
280f8994074SJan Friedel 				return (B_FALSE);
281f8994074SJan Friedel 			}
282f8994074SJan Friedel 			len = snprintf(attr_buf, PLUGIN_MAXATT, "%s=%llu;",
283f8994074SJan Friedel 			    key_buf, pval_count);
284f8994074SJan Friedel 			if (len < 0 || len >= PLUGIN_MAXATT) {
285f8994074SJan Friedel 				prt_error(gettext("Too long attribute: %s\n"),
286f8994074SJan Friedel 				    key_buf);
287f8994074SJan Friedel 				return (B_FALSE);
288f8994074SJan Friedel 			}
289f8994074SJan Friedel 			if (strlcat(attr_string, attr_buf, PLUGIN_MAXATT) >=
290f8994074SJan Friedel 			    PLUGIN_MAXATT) {
291f8994074SJan Friedel 				prt_error(gettext("Too long attribute string: "
292f8994074SJan Friedel 				    "%s\n"), key_buf);
293f8994074SJan Friedel 				return (B_FALSE);
294f8994074SJan Friedel 			}
295f8994074SJan Friedel 			break;
296f8994074SJan Friedel 		}
297f8994074SJan Friedel 		default:
298f8994074SJan Friedel 			(void) printf("Unsupported value type %s [%d]\n",
299f8994074SJan Friedel 			    key_buf, prop_type);
300f8994074SJan Friedel 			break;
301f8994074SJan Friedel 		}
302f8994074SJan Friedel 	}
303f8994074SJan Friedel 
304f8994074SJan Friedel 	if (*attr_string == '\0' ||
305f8994074SJan Friedel 	    (*plugin_kva = _str2kva(attr_string, "=", ";")) == NULL) {
306f8994074SJan Friedel 		prt_error(gettext("Empty or invalid attribute string."));
307f8994074SJan Friedel 		return (B_FALSE);
308f8994074SJan Friedel 	}
309f8994074SJan Friedel 
310f8994074SJan Friedel 	return (B_TRUE);
311f8994074SJan Friedel }
312f8994074SJan Friedel 
313f8994074SJan Friedel /*
314f8994074SJan Friedel  * get_plugin_kva() - get and save config attributes of given plugin plugin_str
315f8994074SJan Friedel  * (or all plugins in case plugin_str == NULL) into scf_plugin_kva_node_t.
316f8994074SJan Friedel  */
317f8994074SJan Friedel static boolean_t
get_plugin_kva(asi_scfhandle_t * handle,asi_scfhandle_iter_t * handle_iter,scf_plugin_kva_node_t ** plugin_kva_ll,char * plugin_str)318f8994074SJan Friedel get_plugin_kva(asi_scfhandle_t *handle, asi_scfhandle_iter_t *handle_iter,
319f8994074SJan Friedel     scf_plugin_kva_node_t **plugin_kva_ll, char *plugin_str)
320f8994074SJan Friedel {
321f8994074SJan Friedel 
322f8994074SJan Friedel 	scf_plugin_kva_node_t	*node = NULL;
323f8994074SJan Friedel 	scf_plugin_kva_node_t	*node_prev = NULL;
324f8994074SJan Friedel 	scf_plugin_kva_node_t	*node_head = NULL;
325f8994074SJan Friedel 	char			plugin_str_tmp[PLUGIN_MAXBUF];
326f8994074SJan Friedel 
327f8994074SJan Friedel 	bzero(plugin_str_tmp, PLUGIN_MAXBUF);
328f8994074SJan Friedel 
329f8994074SJan Friedel 	if (scf_iter_instance_pgs_typed(handle_iter->pgrp, handle->inst,
330f8994074SJan Friedel 	    (const char *)"plugin") == -1) {
331f8994074SJan Friedel 		prt_scf_err();
332f8994074SJan Friedel 		return (B_FALSE);
333f8994074SJan Friedel 	}
334f8994074SJan Friedel 
335f8994074SJan Friedel 	while (scf_iter_next_pg(handle_iter->pgrp, handle->pgrp) == 1) {
336f8994074SJan Friedel 		if (scf_pg_get_name(handle->pgrp, plugin_str_tmp,
337f8994074SJan Friedel 		    PLUGIN_MAXBUF) == -1) {
338f8994074SJan Friedel 			prt_scf_err();
339f8994074SJan Friedel 			plugin_kva_ll_free(node);
340f8994074SJan Friedel 			return (B_FALSE);
341f8994074SJan Friedel 		}
342f8994074SJan Friedel 
343f8994074SJan Friedel 		if (plugin_str != NULL &&
344f8994074SJan Friedel 		    strcmp(plugin_str_tmp, plugin_str) != 0) {
345f8994074SJan Friedel 			continue;
346f8994074SJan Friedel 		}
347f8994074SJan Friedel 
348f8994074SJan Friedel 		if ((node =
349f8994074SJan Friedel 		    calloc(1, sizeof (scf_plugin_kva_node_t))) == NULL) {
350f8994074SJan Friedel 			prt_error(gettext("No available memory."));
351f8994074SJan Friedel 			plugin_kva_ll_free(node_prev);
352f8994074SJan Friedel 			return (B_FALSE);
353f8994074SJan Friedel 		}
354f8994074SJan Friedel 		if (node_head == NULL) {
355f8994074SJan Friedel 			node_head = node;
356f8994074SJan Friedel 		}
357f8994074SJan Friedel 		if (node_prev != NULL) {
358f8994074SJan Friedel 			node_prev->next = node;
359f8994074SJan Friedel 			node->prev = node_prev;
360f8994074SJan Friedel 		}
361f8994074SJan Friedel 		node_prev = node;
362f8994074SJan Friedel 
363f8994074SJan Friedel 		(void) strlcat((char *)&(node->plugin_name), plugin_str_tmp,
364f8994074SJan Friedel 		    PLUGIN_MAXBUF);
365f8994074SJan Friedel 
366f8994074SJan Friedel 		if (scf_iter_pg_properties(handle_iter->prop,
367f8994074SJan Friedel 		    handle->pgrp) != 0) {
368f8994074SJan Friedel 			prt_scf_err();
369f8994074SJan Friedel 			plugin_kva_ll_free(node);
370f8994074SJan Friedel 			return (B_FALSE);
371f8994074SJan Friedel 		}
372f8994074SJan Friedel 
373f8994074SJan Friedel 		if (!get_props_kva_all(handle, handle_iter,
374f8994074SJan Friedel 		    &(node->plugin_kva))) {
375f8994074SJan Friedel 			plugin_kva_ll_free(node);
376f8994074SJan Friedel 			return (B_FALSE);
377f8994074SJan Friedel 		}
378f8994074SJan Friedel 	}
379f8994074SJan Friedel 
380f8994074SJan Friedel #if DEBUG
381f8994074SJan Friedel 	{
382f8994074SJan Friedel 		scf_plugin_kva_node_t	*node_debug = node_head;
383f8994074SJan Friedel 		char			attr_string[PLUGIN_MAXATT];
384f8994074SJan Friedel 
385f8994074SJan Friedel 		while (node_debug != NULL) {
386f8994074SJan Friedel 			if (_kva2str(node_debug->plugin_kva, attr_string,
387f8994074SJan Friedel 			    PLUGIN_MAXATT, "=", ";") == 0) {
388f8994074SJan Friedel 				DPRINT((dbfp, "Found plugin - %s: %s\n",
389f8994074SJan Friedel 				    node_debug->plugin_name, attr_string));
390f8994074SJan Friedel 			} else {
391f8994074SJan Friedel 				DPRINT((dbfp, "Could not get attribute string "
392f8994074SJan Friedel 				    "for %s\n", node_debug->plugin_name));
393f8994074SJan Friedel 			}
394f8994074SJan Friedel 			node_debug = node_debug->prev;
395f8994074SJan Friedel 		}
396f8994074SJan Friedel 	}
397f8994074SJan Friedel #endif
398f8994074SJan Friedel 
399f8994074SJan Friedel 	*plugin_kva_ll = node_head;
400f8994074SJan Friedel 
401f8994074SJan Friedel 	return (B_TRUE);
402f8994074SJan Friedel }
403f8994074SJan Friedel 
404f8994074SJan Friedel /*
405f8994074SJan Friedel  * scf_free() - free scf handles
406f8994074SJan Friedel  */
407f8994074SJan Friedel static void
scf_free(asi_scfhandle_t * handle)408f8994074SJan Friedel scf_free(asi_scfhandle_t *handle)
409f8994074SJan Friedel {
410f8994074SJan Friedel 	if (handle == NULL) {
411f8994074SJan Friedel 		return;
412f8994074SJan Friedel 	}
413f8994074SJan Friedel 
414f8994074SJan Friedel 	if (handle->prop != NULL) {
415f8994074SJan Friedel 		scf_property_destroy(handle->prop);
416f8994074SJan Friedel 	}
417f8994074SJan Friedel 	if (handle->pgrp != NULL) {
418f8994074SJan Friedel 		scf_pg_destroy(handle->pgrp);
419f8994074SJan Friedel 	}
420f8994074SJan Friedel 	if (handle->inst != NULL) {
421f8994074SJan Friedel 		scf_instance_destroy(handle->inst);
422f8994074SJan Friedel 	}
423f8994074SJan Friedel 	if (handle->hndl != NULL) {
424f8994074SJan Friedel 		if (scf_handle_unbind(handle->hndl) == -1) {
425f8994074SJan Friedel 			prt_error(gettext("Internal error."));
426f8994074SJan Friedel 			prt_scf_err();
427f8994074SJan Friedel 		}
428f8994074SJan Friedel 		scf_handle_destroy(handle->hndl);
429f8994074SJan Friedel 	}
430f8994074SJan Friedel }
431f8994074SJan Friedel 
432f8994074SJan Friedel /*
433f8994074SJan Friedel  * scf_init() - initiate scf handles
434f8994074SJan Friedel  */
435f8994074SJan Friedel static boolean_t
scf_init(asi_scfhandle_t * handle)436f8994074SJan Friedel scf_init(asi_scfhandle_t *handle)
437f8994074SJan Friedel {
438f8994074SJan Friedel 	bzero(handle, sizeof (asi_scfhandle_t));
439f8994074SJan Friedel 
440f8994074SJan Friedel 	if ((handle->hndl = scf_handle_create(SCF_VERSION)) == NULL ||
441f8994074SJan Friedel 	    scf_handle_bind(handle->hndl) != 0) {
442f8994074SJan Friedel 		goto err_out;
443f8994074SJan Friedel 	}
444f8994074SJan Friedel 	if ((handle->inst = scf_instance_create(handle->hndl)) == NULL) {
445f8994074SJan Friedel 		goto err_out;
446f8994074SJan Friedel 	}
447f8994074SJan Friedel 	if ((handle->pgrp = scf_pg_create(handle->hndl)) == NULL) {
448f8994074SJan Friedel 		goto err_out;
449f8994074SJan Friedel 	}
450f8994074SJan Friedel 	if ((handle->prop = scf_property_create(handle->hndl)) == NULL) {
451f8994074SJan Friedel 		goto err_out;
452f8994074SJan Friedel 	}
453f8994074SJan Friedel 
454f8994074SJan Friedel 	return (B_TRUE);
455f8994074SJan Friedel 
456f8994074SJan Friedel err_out:
457f8994074SJan Friedel 	prt_scf_err();
458f8994074SJan Friedel 	scf_free(handle);
459f8994074SJan Friedel 	return (B_FALSE);
460f8994074SJan Friedel }
461f8994074SJan Friedel 
462f8994074SJan Friedel /*
463f8994074SJan Friedel  * scf_free_iter() - free scf iter handles
464f8994074SJan Friedel  */
465f8994074SJan Friedel static void
scf_free_iter(asi_scfhandle_iter_t * handle_iter)466f8994074SJan Friedel scf_free_iter(asi_scfhandle_iter_t *handle_iter)
467f8994074SJan Friedel {
468f8994074SJan Friedel 	if (handle_iter == NULL) {
469f8994074SJan Friedel 		return;
470f8994074SJan Friedel 	}
471f8994074SJan Friedel 
472f8994074SJan Friedel 	if (handle_iter->pgrp != NULL) {
473f8994074SJan Friedel 		scf_iter_destroy(handle_iter->pgrp);
474f8994074SJan Friedel 	}
475f8994074SJan Friedel 	if (handle_iter->prop != NULL) {
476f8994074SJan Friedel 		scf_iter_destroy(handle_iter->prop);
477f8994074SJan Friedel 	}
478f8994074SJan Friedel 	if (handle_iter->prop_val != NULL) {
479f8994074SJan Friedel 		scf_value_destroy(handle_iter->prop_val);
480f8994074SJan Friedel 	}
481f8994074SJan Friedel }
482f8994074SJan Friedel 
483f8994074SJan Friedel /*
484f8994074SJan Friedel  * scf_init_iter() - initiate scf iter handles
485f8994074SJan Friedel  */
486f8994074SJan Friedel static boolean_t
scf_init_iter(asi_scfhandle_iter_t * handle_iter,asi_scfhandle_t * handle)487f8994074SJan Friedel scf_init_iter(asi_scfhandle_iter_t *handle_iter,
488f8994074SJan Friedel     asi_scfhandle_t *handle)
489f8994074SJan Friedel {
490f8994074SJan Friedel 	bzero(handle_iter, sizeof (asi_scfhandle_iter_t));
491f8994074SJan Friedel 
492f8994074SJan Friedel 	if ((handle_iter->pgrp = scf_iter_create(handle->hndl)) == NULL) {
493f8994074SJan Friedel 		goto err_out;
494f8994074SJan Friedel 	}
495f8994074SJan Friedel 	if ((handle_iter->prop = scf_iter_create(handle->hndl)) == NULL) {
496f8994074SJan Friedel 		goto err_out;
497f8994074SJan Friedel 	}
498f8994074SJan Friedel 	if ((handle_iter->prop_val = scf_value_create(handle->hndl)) == NULL) {
499f8994074SJan Friedel 		goto err_out;
500f8994074SJan Friedel 	}
501f8994074SJan Friedel 
502f8994074SJan Friedel 	return (B_TRUE);
503f8994074SJan Friedel 
504f8994074SJan Friedel err_out:
505f8994074SJan Friedel 	prt_scf_err();
506f8994074SJan Friedel 	scf_free_iter(handle_iter);
507f8994074SJan Friedel 	return (B_FALSE);
508f8994074SJan Friedel }
509f8994074SJan Friedel 
510f8994074SJan Friedel /*
511f8994074SJan Friedel  * chk_policy_context() - does some policy based checks, checks the context
512f8994074SJan Friedel  * (zone, smf) in which the policy could make some sense.
513f8994074SJan Friedel  */
514f8994074SJan Friedel static boolean_t
chk_policy_context(char * policy_str)515f8994074SJan Friedel chk_policy_context(char *policy_str)
516f8994074SJan Friedel {
517f8994074SJan Friedel 
518f8994074SJan Friedel 	/*
519f8994074SJan Friedel 	 * "all" and "none" policy flags, since they represent
520f8994074SJan Friedel 	 * sub/set of auditing policies, are not stored in the
521f8994074SJan Friedel 	 * AUDITD_FMRI service instance configuration.
522f8994074SJan Friedel 	 */
523f8994074SJan Friedel 	DPRINT((dbfp, "Walking policy - %s: ", policy_str));
524f8994074SJan Friedel 	if (strcmp("all", policy_str) == 0 ||
525f8994074SJan Friedel 	    strcmp("none", policy_str) == 0) {
526f8994074SJan Friedel 		DPRINT((dbfp, "skipped\n"));
527f8994074SJan Friedel 		return (B_FALSE);
528f8994074SJan Friedel 	}
529f8994074SJan Friedel 	/*
530f8994074SJan Friedel 	 * In the local zone (!= GLOBAL_ZONEID) we do not touch
531f8994074SJan Friedel 	 * "ahlt" and "perzone" policy flags, since these are
532f8994074SJan Friedel 	 * relevant only in the global zone.
533f8994074SJan Friedel 	 */
534f8994074SJan Friedel 	if ((getzoneid() != GLOBAL_ZONEID) &&
535f8994074SJan Friedel 	    (strcmp("ahlt", policy_str) == 0 ||
536f8994074SJan Friedel 	    strcmp("perzone", policy_str) == 0)) {
537f8994074SJan Friedel 		DPRINT((dbfp, "skipped\n"));
538f8994074SJan Friedel 		return (B_FALSE);
539f8994074SJan Friedel 	}
540f8994074SJan Friedel 
541f8994074SJan Friedel 	return (B_TRUE);
542f8994074SJan Friedel }
543f8994074SJan Friedel 
544f8994074SJan Friedel /*
545f8994074SJan Friedel  * free_static_att_kva() - free hardcoded/static plugin attributes (key/value
546f8994074SJan Friedel  * pairs) from the kva plugin structure.
547f8994074SJan Friedel  */
548f8994074SJan Friedel void
free_static_att_kva(kva_t * plugin_kva)549f8994074SJan Friedel free_static_att_kva(kva_t *plugin_kva)
550f8994074SJan Friedel {
551f8994074SJan Friedel 	_kva_free_value(plugin_kva, PLUGIN_ACTIVE);
552f8994074SJan Friedel 	_kva_free_value(plugin_kva, PLUGIN_PATH);
553f8994074SJan Friedel 	_kva_free_value(plugin_kva, PLUGIN_QSIZE);
554f8994074SJan Friedel 	_kva_free_value(plugin_kva, "read_authorization");
555f8994074SJan Friedel 	_kva_free_value(plugin_kva, "value_authorization");
556f8994074SJan Friedel }
557f8994074SJan Friedel 
558f8994074SJan Friedel 
559f8994074SJan Friedel /*
560f8994074SJan Friedel  * do_getqctrl_scf() - get the values of qctrl properties of the audit service
561f8994074SJan Friedel  */
562f8994074SJan Friedel boolean_t
do_getqctrl_scf(struct au_qctrl * cval)563f8994074SJan Friedel do_getqctrl_scf(struct au_qctrl *cval)
564f8994074SJan Friedel {
565f8994074SJan Friedel 	scf_propvec_t   	*prop_vect_ptr;
566f8994074SJan Friedel 	scf_qctrl_t		cval_scf;
567f8994074SJan Friedel 
568f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
569f8994074SJan Friedel 
570f8994074SJan Friedel 	prop_vect_ptr = prop_vect;
571f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QHIWATER,
572f8994074SJan Friedel 	    SCF_TYPE_COUNT, &cval_scf.scf_qhiwater);
573f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QLOWATER,
574f8994074SJan Friedel 	    SCF_TYPE_COUNT, &cval_scf.scf_qlowater);
575f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QBUFSZ,
576f8994074SJan Friedel 	    SCF_TYPE_COUNT, &cval_scf.scf_qbufsz);
577f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr, QUEUECTRL_QDELAY,
578f8994074SJan Friedel 	    SCF_TYPE_COUNT, &cval_scf.scf_qdelay);
579f8994074SJan Friedel 
580f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
581f8994074SJan Friedel 		return (B_FALSE);
582f8994074SJan Friedel 	}
583f8994074SJan Friedel 
584f8994074SJan Friedel 	cval->aq_hiwater = (size_t)cval_scf.scf_qhiwater;
585f8994074SJan Friedel 	cval->aq_lowater = (size_t)cval_scf.scf_qlowater;
586f8994074SJan Friedel 	cval->aq_bufsz = (size_t)cval_scf.scf_qbufsz;
587f8994074SJan Friedel 	cval->aq_delay = (clock_t)cval_scf.scf_qdelay;
588f8994074SJan Friedel 
589f8994074SJan Friedel 	scf_clean_propvec(prop_vect);
590f8994074SJan Friedel 
591f8994074SJan Friedel 	return (B_TRUE);
592f8994074SJan Friedel }
593f8994074SJan Friedel 
594f8994074SJan Friedel /*
595f8994074SJan Friedel  * do_getqbufsz_scf() - get the qbufsz audit service property value
596f8994074SJan Friedel  */
597f8994074SJan Friedel boolean_t
do_getqbufsz_scf(size_t * cval)598f8994074SJan Friedel do_getqbufsz_scf(size_t *cval)
599f8994074SJan Friedel {
600f8994074SJan Friedel 	uint64_t	cval_l;
601f8994074SJan Friedel 
602f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
603f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT, &cval_l);
604f8994074SJan Friedel 
605f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
606f8994074SJan Friedel 		return (B_FALSE);
607f8994074SJan Friedel 	}
608f8994074SJan Friedel 
609f8994074SJan Friedel 	*cval = (size_t)cval_l;
610f8994074SJan Friedel 
611f8994074SJan Friedel 	return (B_TRUE);
612f8994074SJan Friedel }
613f8994074SJan Friedel 
614f8994074SJan Friedel /*
615f8994074SJan Friedel  * do_getqdelay_scf() - get the qdelay audit service property value
616f8994074SJan Friedel  */
617f8994074SJan Friedel boolean_t
do_getqdelay_scf(clock_t * cval)618f8994074SJan Friedel do_getqdelay_scf(clock_t *cval)
619f8994074SJan Friedel {
620f8994074SJan Friedel 	uint64_t	cval_l;
621f8994074SJan Friedel 
622f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
623f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QDELAY, SCF_TYPE_COUNT, &cval_l);
624f8994074SJan Friedel 
625f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
626f8994074SJan Friedel 		return (B_FALSE);
627f8994074SJan Friedel 	}
628f8994074SJan Friedel 
629f8994074SJan Friedel 	*cval = (clock_t)cval_l;
630f8994074SJan Friedel 
631f8994074SJan Friedel 	return (B_TRUE);
632f8994074SJan Friedel }
633f8994074SJan Friedel 
634f8994074SJan Friedel /*
635f8994074SJan Friedel  * do_getqhiwater_scf() - get the qhiwater audit service property value
636f8994074SJan Friedel  */
637f8994074SJan Friedel boolean_t
do_getqhiwater_scf(size_t * cval)638f8994074SJan Friedel do_getqhiwater_scf(size_t *cval)
639f8994074SJan Friedel {
640f8994074SJan Friedel 	uint64_t	cval_l;
641f8994074SJan Friedel 
642f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
643f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
644f8994074SJan Friedel 	    &cval_l);
645f8994074SJan Friedel 
646f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
647f8994074SJan Friedel 		return (B_FALSE);
648f8994074SJan Friedel 	}
649f8994074SJan Friedel 
650f8994074SJan Friedel 	*cval = (size_t)cval_l;
651f8994074SJan Friedel 
652f8994074SJan Friedel 	return (B_TRUE);
653f8994074SJan Friedel }
654f8994074SJan Friedel 
655f8994074SJan Friedel /*
656f8994074SJan Friedel  * do_getqlowater_scf() - get the qlowater audit service property value
657f8994074SJan Friedel  */
658f8994074SJan Friedel boolean_t
do_getqlowater_scf(size_t * cval)659f8994074SJan Friedel do_getqlowater_scf(size_t *cval)
660f8994074SJan Friedel {
661f8994074SJan Friedel 	uint64_t	cval_l;
662f8994074SJan Friedel 
663f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
664f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
665f8994074SJan Friedel 	    &cval_l);
666f8994074SJan Friedel 
667f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL)) {
668f8994074SJan Friedel 		return (B_FALSE);
669f8994074SJan Friedel 	}
670f8994074SJan Friedel 
671f8994074SJan Friedel 	*cval = (size_t)cval_l;
672f8994074SJan Friedel 
673f8994074SJan Friedel 	return (B_TRUE);
674f8994074SJan Friedel }
675f8994074SJan Friedel 
676f8994074SJan Friedel /*
677f8994074SJan Friedel  * do_getpolicy_scf() - get the audit policy flags from service
678f8994074SJan Friedel  */
679f8994074SJan Friedel boolean_t
do_getpolicy_scf(uint32_t * policy_mask)680f8994074SJan Friedel do_getpolicy_scf(uint32_t *policy_mask)
681f8994074SJan Friedel {
682f8994074SJan Friedel 	int			i;
683f8994074SJan Friedel 	scf_propvec_t		*prop_vect_ptr;
684f8994074SJan Friedel 	char			*cur_policy_str;
685f8994074SJan Friedel 	policy_sw_t		policy_arr[POLICY_TBL_SZ + 1];
686f8994074SJan Friedel 	policy_sw_t		*policy_arr_ptr;
687f8994074SJan Friedel 
688f8994074SJan Friedel 	prop_vect_ptr = prop_vect;
689f8994074SJan Friedel 	policy_arr_ptr = policy_arr;
690f8994074SJan Friedel 
691f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
692f8994074SJan Friedel 	bzero(policy_arr, sizeof (policy_arr));
693f8994074SJan Friedel 
694*bbf21555SRichard Lowe 	/* prepare the smf(7) query */
695f8994074SJan Friedel 	for (i = 0; i < POLICY_TBL_SZ; i++) {
696f8994074SJan Friedel 
697f8994074SJan Friedel 		cur_policy_str = policy_table[i].policy_str;
698f8994074SJan Friedel 
699f8994074SJan Friedel 		/* Do some basic policy dependent checks */
700f8994074SJan Friedel 		if (!chk_policy_context(cur_policy_str)) {
701f8994074SJan Friedel 			continue;
702f8994074SJan Friedel 		}
703f8994074SJan Friedel 		DPRINT((dbfp, "will be queried\n"));
704f8994074SJan Friedel 
705f8994074SJan Friedel 		add_prop_vect_scf(prop_vect_ptr++, cur_policy_str,
706f8994074SJan Friedel 		    SCF_TYPE_BOOLEAN, &policy_arr_ptr->flag);
707f8994074SJan Friedel 
708f8994074SJan Friedel 		policy_arr_ptr->policy = cur_policy_str;
709f8994074SJan Friedel 		policy_arr_ptr++;
710f8994074SJan Friedel 
711f8994074SJan Friedel 	}
712f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_POLICY)) {
713f8994074SJan Friedel 		return (B_FALSE);
714f8994074SJan Friedel 	}
715f8994074SJan Friedel 
716f8994074SJan Friedel 	/* set the policy mask */
717f8994074SJan Friedel 	policy_arr_ptr = policy_arr;
718f8994074SJan Friedel 	*policy_mask = 0;
719f8994074SJan Friedel 	while (policy_arr_ptr->policy != NULL) {
720f8994074SJan Friedel 		if (policy_arr_ptr->flag) {
721f8994074SJan Friedel 			*policy_mask |= get_policy(policy_arr_ptr->policy);
722f8994074SJan Friedel 		}
723f8994074SJan Friedel 		policy_arr_ptr++;
724f8994074SJan Friedel 	}
725f8994074SJan Friedel 
726f8994074SJan Friedel 	return (B_TRUE);
727f8994074SJan Friedel }
728f8994074SJan Friedel 
729f8994074SJan Friedel /*
730f8994074SJan Friedel  * do_setpolicy_scf() - sets the policy flags in audit service configuration
731f8994074SJan Friedel  */
732f8994074SJan Friedel boolean_t
do_setpolicy_scf(uint32_t policy)733f8994074SJan Friedel do_setpolicy_scf(uint32_t policy)
734f8994074SJan Friedel {
735f8994074SJan Friedel 	int		i;
736f8994074SJan Friedel 	char		*cur_policy_str;
737f8994074SJan Friedel 	scf_propvec_t	*prop_vect_ptr;
738f8994074SJan Friedel 	boolean_t	bool_arr[POLICY_TBL_SZ];
739f8994074SJan Friedel 	boolean_t	*bool_arr_ptr;
740f8994074SJan Friedel 
741f8994074SJan Friedel 	prop_vect_ptr = prop_vect;
742f8994074SJan Friedel 	bool_arr_ptr = bool_arr;
743f8994074SJan Friedel 
744f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
745f8994074SJan Friedel 	bzero(bool_arr, sizeof (bool_arr));
746f8994074SJan Friedel 
747f8994074SJan Friedel 	for (i = 0; i < POLICY_TBL_SZ; i++) {
748f8994074SJan Friedel 
749f8994074SJan Friedel 		cur_policy_str = policy_table[i].policy_str;
750f8994074SJan Friedel 
751f8994074SJan Friedel 		/* Do some basic policy dependent checks */
752f8994074SJan Friedel 		if (!chk_policy_context(cur_policy_str)) {
753f8994074SJan Friedel 			continue;
754f8994074SJan Friedel 		}
755f8994074SJan Friedel 
756f8994074SJan Friedel 		if (policy_table[i].policy_mask & policy) {
757f8994074SJan Friedel 			*bool_arr_ptr = B_TRUE;
758f8994074SJan Friedel 		} else {
759f8994074SJan Friedel 			*bool_arr_ptr = B_FALSE;
760f8994074SJan Friedel 		}
761f8994074SJan Friedel 
762f8994074SJan Friedel 		DPRINT((dbfp, "%s%s\n", (*bool_arr_ptr == B_TRUE ? "+" : "-"),
763f8994074SJan Friedel 		    cur_policy_str));
764f8994074SJan Friedel 
765f8994074SJan Friedel 		add_prop_vect_scf(prop_vect_ptr++, cur_policy_str,
766f8994074SJan Friedel 		    SCF_TYPE_BOOLEAN, bool_arr_ptr++);
767f8994074SJan Friedel 
768f8994074SJan Friedel 	}
769f8994074SJan Friedel 
770f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_POLICY));
771f8994074SJan Friedel }
772f8994074SJan Friedel 
773f8994074SJan Friedel /*
774f8994074SJan Friedel  * do_setqctrl_scf() - set the values of qctrl properties of the audit service
775f8994074SJan Friedel  */
776f8994074SJan Friedel boolean_t
do_setqctrl_scf(struct au_qctrl * cval)777f8994074SJan Friedel do_setqctrl_scf(struct au_qctrl *cval)
778f8994074SJan Friedel {
779f8994074SJan Friedel 	scf_propvec_t		*prop_vect_ptr;
780f8994074SJan Friedel 	scf_qctrl_t		cval_scf;
781f8994074SJan Friedel 
782f8994074SJan Friedel 	if (!CHK_BDRY_QHIWATER(cval->aq_lowater, cval->aq_hiwater) &&
783f8994074SJan Friedel 	    cval->aq_hiwater != 0) {
784f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue hiwater mark is "
785f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
786f8994074SJan Friedel 		return (B_FALSE);
787f8994074SJan Friedel 	}
788f8994074SJan Friedel 	if (!CHK_BDRY_QLOWATER(cval->aq_lowater, cval->aq_hiwater) &&
789f8994074SJan Friedel 	    cval->aq_lowater != 0) {
790f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue lowater mark is "
791f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
792f8994074SJan Friedel 		return (B_FALSE);
793f8994074SJan Friedel 	}
794f8994074SJan Friedel 	if (!CHK_BDRY_QBUFSZ(cval->aq_bufsz) && cval->aq_bufsz != 0) {
795f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue buffer size is "
796f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
797f8994074SJan Friedel 		return (B_FALSE);
798f8994074SJan Friedel 	}
799f8994074SJan Friedel 	if (!CHK_BDRY_QDELAY(cval->aq_delay) && cval->aq_delay != 0) {
800f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue delay is "
801f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
802f8994074SJan Friedel 		return (B_FALSE);
803f8994074SJan Friedel 	}
804f8994074SJan Friedel 
805f8994074SJan Friedel 	cval_scf.scf_qhiwater = (uint64_t)cval->aq_hiwater;
806f8994074SJan Friedel 	cval_scf.scf_qlowater = (uint64_t)cval->aq_lowater;
807f8994074SJan Friedel 	cval_scf.scf_qbufsz = (uint64_t)cval->aq_bufsz;
808f8994074SJan Friedel 	cval_scf.scf_qdelay = (uint64_t)cval->aq_delay;
809f8994074SJan Friedel 
810f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
811f8994074SJan Friedel 
812f8994074SJan Friedel 	prop_vect_ptr = prop_vect;
813f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
814f8994074SJan Friedel 	    &cval_scf.scf_qhiwater);
815f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
816f8994074SJan Friedel 	    &cval_scf.scf_qlowater);
817f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT,
818f8994074SJan Friedel 	    &cval_scf.scf_qbufsz);
819f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr, QUEUECTRL_QDELAY, SCF_TYPE_COUNT,
820f8994074SJan Friedel 	    &cval_scf.scf_qdelay);
821f8994074SJan Friedel 
822f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
823f8994074SJan Friedel }
824f8994074SJan Friedel 
825f8994074SJan Friedel /*
826f8994074SJan Friedel  * do_setqbufsz_scf() - set the qbufsz property value of the audit service
827f8994074SJan Friedel  */
828f8994074SJan Friedel boolean_t
do_setqbufsz_scf(size_t * cval)829f8994074SJan Friedel do_setqbufsz_scf(size_t *cval)
830f8994074SJan Friedel {
831f8994074SJan Friedel 	uint64_t	cval_l;
832f8994074SJan Friedel 
833f8994074SJan Friedel 	if (!CHK_BDRY_QBUFSZ(*cval) && *cval != 0) {
834f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue buffer size is "
835f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
836f8994074SJan Friedel 		return (B_FALSE);
837f8994074SJan Friedel 	}
838f8994074SJan Friedel 
839f8994074SJan Friedel 	cval_l = (uint64_t)*cval;
840f8994074SJan Friedel 
841f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
842f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QBUFSZ, SCF_TYPE_COUNT, &cval_l);
843f8994074SJan Friedel 
844f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
845f8994074SJan Friedel }
846f8994074SJan Friedel 
847f8994074SJan Friedel /*
848f8994074SJan Friedel  * do_setqdelay_scf() - set the qdelay property value of the audit service
849f8994074SJan Friedel  */
850f8994074SJan Friedel boolean_t
do_setqdelay_scf(clock_t * cval)851f8994074SJan Friedel do_setqdelay_scf(clock_t *cval)
852f8994074SJan Friedel {
853f8994074SJan Friedel 	uint64_t	cval_l;
854f8994074SJan Friedel 
855f8994074SJan Friedel 	if (!CHK_BDRY_QDELAY(*cval) && *cval != 0) {
856f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue delay is "
857f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
858f8994074SJan Friedel 		return (B_FALSE);
859f8994074SJan Friedel 	}
860f8994074SJan Friedel 
861f8994074SJan Friedel 	cval_l = (uint64_t)*cval;
862f8994074SJan Friedel 
863f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
864f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QDELAY, SCF_TYPE_COUNT, &cval_l);
865f8994074SJan Friedel 
866f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
867f8994074SJan Friedel }
868f8994074SJan Friedel 
869f8994074SJan Friedel /*
870f8994074SJan Friedel  * do_setqhiwater_scf() - set the qhiwater property value of the audit service
871f8994074SJan Friedel  */
872f8994074SJan Friedel boolean_t
do_setqhiwater_scf(size_t * cval)873f8994074SJan Friedel do_setqhiwater_scf(size_t *cval)
874f8994074SJan Friedel {
875f8994074SJan Friedel 	uint64_t	cval_l;
876f8994074SJan Friedel 	size_t		cval_lowater;
877f8994074SJan Friedel 
878f8994074SJan Friedel 	if (!do_getqlowater_scf(&cval_lowater)) {
879f8994074SJan Friedel 		(void) printf(gettext("Could not get configured value of "
880f8994074SJan Friedel 		    "queue lowater mark.\n"));
881f8994074SJan Friedel 		return (B_FALSE);
882f8994074SJan Friedel 	}
883f8994074SJan Friedel 	if (cval_lowater == 0) {
884f8994074SJan Friedel 		cval_lowater = AQ_MINLOW;
885f8994074SJan Friedel 	}
886f8994074SJan Friedel 	if (!CHK_BDRY_QHIWATER(cval_lowater, *cval) && *cval != 0) {
887f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue hiwater mark is "
888f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
889f8994074SJan Friedel 		return (B_FALSE);
890f8994074SJan Friedel 	}
891f8994074SJan Friedel 
892f8994074SJan Friedel 	cval_l = (uint64_t)*cval;
893f8994074SJan Friedel 
894f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
895f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QHIWATER, SCF_TYPE_COUNT,
896f8994074SJan Friedel 	    &cval_l);
897f8994074SJan Friedel 
898f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
899f8994074SJan Friedel }
900f8994074SJan Friedel 
901f8994074SJan Friedel /*
902f8994074SJan Friedel  * do_setqlowater_scf() - set the qlowater property value of the audit service
903f8994074SJan Friedel  */
904f8994074SJan Friedel boolean_t
do_setqlowater_scf(size_t * cval)905f8994074SJan Friedel do_setqlowater_scf(size_t *cval)
906f8994074SJan Friedel {
907f8994074SJan Friedel 	uint64_t	cval_l;
908f8994074SJan Friedel 	size_t		cval_hiwater;
909f8994074SJan Friedel 
910f8994074SJan Friedel 	if (!do_getqhiwater_scf(&cval_hiwater)) {
911f8994074SJan Friedel 		(void) printf(gettext("Could not get configured value of "
912f8994074SJan Friedel 		    "queue hiwater mark.\n"));
913f8994074SJan Friedel 		return (B_FALSE);
914f8994074SJan Friedel 	}
915f8994074SJan Friedel 	if (cval_hiwater == 0) {
916f8994074SJan Friedel 		cval_hiwater = AQ_MAXHIGH;
917f8994074SJan Friedel 	}
918f8994074SJan Friedel 	if (!CHK_BDRY_QLOWATER(*cval, cval_hiwater) && *cval != 0) {
919f8994074SJan Friedel 		(void) printf(gettext("Specified audit queue lowater mark is "
920f8994074SJan Friedel 		    "outside of allowed boundaries.\n"));
921f8994074SJan Friedel 		return (B_FALSE);
922f8994074SJan Friedel 	}
923f8994074SJan Friedel 
924f8994074SJan Friedel 	cval_l = (uint64_t)*cval;
925f8994074SJan Friedel 
926f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
927f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, QUEUECTRL_QLOWATER, SCF_TYPE_COUNT,
928f8994074SJan Friedel 	    &cval_l);
929f8994074SJan Friedel 
930f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_QUEUECTRL));
931f8994074SJan Friedel }
932f8994074SJan Friedel 
933f8994074SJan Friedel /*
934f8994074SJan Friedel  * do_getflags_scf() - get the audit attributable flags from service
935f8994074SJan Friedel  */
936f8994074SJan Friedel boolean_t
do_getflags_scf(char ** flags)937f8994074SJan Friedel do_getflags_scf(char **flags)
938f8994074SJan Friedel {
939f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
940f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, PRESELECTION_FLAGS, SCF_TYPE_ASTRING,
941f8994074SJan Friedel 	    flags);
942f8994074SJan Friedel 
943f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_PRESELECTION)) {
944f8994074SJan Friedel 		return (B_FALSE);
945f8994074SJan Friedel 	}
946f8994074SJan Friedel 
947f8994074SJan Friedel 	return (B_TRUE);
948f8994074SJan Friedel }
949f8994074SJan Friedel 
950f8994074SJan Friedel /*
951f8994074SJan Friedel  * do_getnaflags_scf() - get the audit non-attributable flags from service
952f8994074SJan Friedel  */
953f8994074SJan Friedel boolean_t
do_getnaflags_scf(char ** naflags)954f8994074SJan Friedel do_getnaflags_scf(char **naflags)
955f8994074SJan Friedel {
956f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
957f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, PRESELECTION_NAFLAGS, SCF_TYPE_ASTRING,
958f8994074SJan Friedel 	    naflags);
959f8994074SJan Friedel 
960f8994074SJan Friedel 	if (!get_val_scf(prop_vect, ASI_PGROUP_PRESELECTION)) {
961f8994074SJan Friedel 		return (B_FALSE);
962f8994074SJan Friedel 	}
963f8994074SJan Friedel 
964f8994074SJan Friedel 	return (B_TRUE);
965f8994074SJan Friedel }
966f8994074SJan Friedel 
967f8994074SJan Friedel /*
968f8994074SJan Friedel  * do_setflags_scf() - set the attributable mask property value of the audit
969f8994074SJan Friedel  * service
970f8994074SJan Friedel  */
971f8994074SJan Friedel boolean_t
do_setflags_scf(char * flags)972f8994074SJan Friedel do_setflags_scf(char *flags)
973f8994074SJan Friedel {
974f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
975f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, PRESELECTION_FLAGS, SCF_TYPE_ASTRING,
976f8994074SJan Friedel 	    flags);
977f8994074SJan Friedel 
978f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_PRESELECTION));
979f8994074SJan Friedel }
980f8994074SJan Friedel 
981f8994074SJan Friedel /*
982f8994074SJan Friedel  * do_setnaflags_scf() - set the attributable mask property value of the audit
983f8994074SJan Friedel  * service
984f8994074SJan Friedel  */
985f8994074SJan Friedel boolean_t
do_setnaflags_scf(char * naflags)986f8994074SJan Friedel do_setnaflags_scf(char *naflags)
987f8994074SJan Friedel {
988f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
989f8994074SJan Friedel 	add_prop_vect_scf(prop_vect, PRESELECTION_NAFLAGS, SCF_TYPE_ASTRING,
990f8994074SJan Friedel 	    naflags);
991f8994074SJan Friedel 
992f8994074SJan Friedel 	return (set_val_scf(prop_vect, ASI_PGROUP_PRESELECTION));
993f8994074SJan Friedel }
994f8994074SJan Friedel 
995f8994074SJan Friedel /*
996f8994074SJan Friedel  * plugin_avail_scf() - look for the plugin in the audit service configuration
997f8994074SJan Friedel  */
998f8994074SJan Friedel boolean_t
plugin_avail_scf(const char * plugin_str)999f8994074SJan Friedel plugin_avail_scf(const char *plugin_str)
1000f8994074SJan Friedel {
1001f8994074SJan Friedel 	scf_simple_handle_t	*sh;
1002f8994074SJan Friedel 
1003f8994074SJan Friedel 	if (plugin_str == NULL || *plugin_str == '\0') {
1004f8994074SJan Friedel 		return (B_FALSE);
1005f8994074SJan Friedel 	}
1006f8994074SJan Friedel 
1007f8994074SJan Friedel 	if ((sh = scf_general_pg_setup(AUDITD_FMRI, plugin_str)) == NULL) {
1008f8994074SJan Friedel 		DPRINT((dbfp, "No such plugin found: %s (%s)\n", plugin_str,
1009f8994074SJan Friedel 		    scf_strerror(scf_error())));
1010f8994074SJan Friedel 		return (B_FALSE);
1011f8994074SJan Friedel 	}
1012f8994074SJan Friedel 
1013f8994074SJan Friedel 	scf_simple_handle_destroy(sh);
1014f8994074SJan Friedel 	return (B_TRUE);
1015f8994074SJan Friedel }
1016f8994074SJan Friedel 
1017f8994074SJan Friedel /*
1018f8994074SJan Friedel  * do_getpluginconfig_scf() - get plugin configuration from the audit service
1019f8994074SJan Friedel  * configuration.
1020f8994074SJan Friedel  */
1021f8994074SJan Friedel boolean_t
do_getpluginconfig_scf(char * plugin_str,scf_plugin_kva_node_t ** plugin_kva_ll)1022f8994074SJan Friedel do_getpluginconfig_scf(char *plugin_str, scf_plugin_kva_node_t **plugin_kva_ll)
1023f8994074SJan Friedel {
1024f8994074SJan Friedel 
1025f8994074SJan Friedel 	char			*asi_fmri;
1026f8994074SJan Friedel 	asi_scfhandle_t		handle;
1027f8994074SJan Friedel 	asi_scfhandle_iter_t	handle_iter;
1028f8994074SJan Friedel 	boolean_t		plugin_all = B_FALSE;
1029f8994074SJan Friedel 	boolean_t		rv = B_TRUE;
1030f8994074SJan Friedel 
1031f8994074SJan Friedel 	if (plugin_str == NULL || *plugin_str == '\0') {
1032f8994074SJan Friedel 		if (asprintf(&asi_fmri, "%s", AUDITD_FMRI) == -1) {
1033f8994074SJan Friedel 			prt_error(gettext("Out of memory."));
1034f8994074SJan Friedel 			return (B_FALSE);
1035f8994074SJan Friedel 		}
1036f8994074SJan Friedel 		plugin_all = B_TRUE;
1037f8994074SJan Friedel 	} else {
1038f8994074SJan Friedel 		if (asprintf(&asi_fmri, "%s%s%s", AUDITD_FMRI,
1039f8994074SJan Friedel 		    SCF_FMRI_PROPERTYGRP_PREFIX, plugin_str) == -1) {
1040f8994074SJan Friedel 			prt_error(gettext("Out of memory."));
1041f8994074SJan Friedel 			return (B_FALSE);
1042f8994074SJan Friedel 		}
1043f8994074SJan Friedel 	}
1044f8994074SJan Friedel 	DPRINT((dbfp, "%s will be decoded\n", asi_fmri));
1045f8994074SJan Friedel 
1046f8994074SJan Friedel 	if (!scf_init(&handle)) {
1047f8994074SJan Friedel 		prt_error(gettext("Unable to initialize scf handles."));
1048f8994074SJan Friedel 		free(asi_fmri);
1049f8994074SJan Friedel 		return (B_FALSE);
1050f8994074SJan Friedel 	}
1051f8994074SJan Friedel 
1052f8994074SJan Friedel 	if (scf_handle_decode_fmri(handle.hndl, asi_fmri, NULL, NULL,
1053f8994074SJan Friedel 	    handle.inst, plugin_all ? NULL : handle.pgrp, NULL,
1054f8994074SJan Friedel 	    SCF_DECODE_FMRI_EXACT) == -1) {
1055f8994074SJan Friedel 		prt_scf_err();
1056f8994074SJan Friedel 		scf_free(&handle);
1057f8994074SJan Friedel 		free(asi_fmri);
1058f8994074SJan Friedel 		return (B_FALSE);
1059f8994074SJan Friedel 	}
1060f8994074SJan Friedel 
1061f8994074SJan Friedel 	if (!scf_init_iter(&handle_iter, &handle)) {
1062f8994074SJan Friedel 		prt_error(gettext("Unable to initialize scf iter handles."));
1063f8994074SJan Friedel 		scf_free(&handle);
1064f8994074SJan Friedel 		free(asi_fmri);
1065f8994074SJan Friedel 		return (B_FALSE);
1066f8994074SJan Friedel 	}
1067f8994074SJan Friedel 
1068f8994074SJan Friedel 
1069f8994074SJan Friedel 	if (plugin_all) {
1070f8994074SJan Friedel 		rv = get_plugin_kva(&handle, &handle_iter, plugin_kva_ll, NULL);
1071f8994074SJan Friedel 	} else {
1072f8994074SJan Friedel 		rv = get_plugin_kva(&handle, &handle_iter, plugin_kva_ll,
1073f8994074SJan Friedel 		    plugin_str);
1074f8994074SJan Friedel 	}
1075f8994074SJan Friedel 
1076f8994074SJan Friedel 	scf_free(&handle);
1077f8994074SJan Friedel 	scf_free_iter(&handle_iter);
1078f8994074SJan Friedel 	free(asi_fmri);
1079f8994074SJan Friedel 	return (rv);
1080f8994074SJan Friedel }
1081f8994074SJan Friedel 
1082f8994074SJan Friedel /*
1083f8994074SJan Friedel  * do_setpluginconfig_scf() - set plugin configuration in the audit service
1084f8994074SJan Friedel  * configuration.
1085f8994074SJan Friedel  */
1086f8994074SJan Friedel boolean_t
do_setpluginconfig_scf(char * plugin_str,boolean_t plugin_state,char * plugin_att,int plugin_qsize)1087f8994074SJan Friedel do_setpluginconfig_scf(char *plugin_str, boolean_t plugin_state,
1088f8994074SJan Friedel     char *plugin_att, int plugin_qsize)
1089f8994074SJan Friedel {
1090f8994074SJan Friedel 	kva_t			*plugin_att_kva = NULL;
1091f8994074SJan Friedel 	char			*plugin_att_ptr = plugin_att;
1092f8994074SJan Friedel 	char			*plugin_att_clr_ptr = plugin_att;
1093f8994074SJan Friedel 	scf_simple_prop_t	*plugin_prop;
1094f8994074SJan Friedel 	scf_type_t		plugin_prop_type;
1095f8994074SJan Friedel 	scf_propvec_t		*prop_vect_ptr;
1096f8994074SJan Friedel 	int			cnt = 0;
1097f8994074SJan Friedel 	kv_t			*data;
1098f8994074SJan Friedel 	boolean_t		rval = B_TRUE;
1099f8994074SJan Friedel 	uint64_t		plugin_qsize_l = (uint64_t)plugin_qsize;
1100f8994074SJan Friedel 
1101f8994074SJan Friedel 	DPRINT((dbfp, "Auditd plugin configuration to be set:\n\tplugin=%s\n\t"
1102f8994074SJan Friedel 	    "state=%d (%s)\n\tattributes=%s\n\tqsize=%d%s\n", plugin_str,
1103f8994074SJan Friedel 	    plugin_state, plugin_state == B_TRUE ? "active" : "inactive",
1104f8994074SJan Friedel 	    plugin_att == NULL ? " (unspecified)" : plugin_att,
1105f8994074SJan Friedel 	    plugin_qsize, plugin_qsize == -1 ? " (unspecified)" : ""));
1106f8994074SJan Friedel 
1107f8994074SJan Friedel 	bzero(prop_vect, sizeof (prop_vect));
1108f8994074SJan Friedel 	prop_vect_ptr = prop_vect;
1109f8994074SJan Friedel 
1110f8994074SJan Friedel 	if (plugin_att != NULL) {
1111f8994074SJan Friedel 
1112f8994074SJan Friedel 		/* get rid of white-space chars */
1113f8994074SJan Friedel 		if (*plugin_att_ptr != '\0') {
1114f8994074SJan Friedel 			while (*plugin_att_ptr != '\0') {
1115f8994074SJan Friedel 				if (isspace(*plugin_att_ptr) == 0) {
1116f8994074SJan Friedel 					*plugin_att_clr_ptr++ = *plugin_att_ptr;
1117f8994074SJan Friedel 				}
1118f8994074SJan Friedel 				plugin_att_ptr++;
1119f8994074SJan Friedel 			}
1120f8994074SJan Friedel 			*plugin_att_clr_ptr = '\0';
1121f8994074SJan Friedel 		}
1122f8994074SJan Friedel 		DPRINT((dbfp, "attributes (no white-space): %s\n", plugin_att));
1123f8994074SJan Friedel 
1124f8994074SJan Friedel 		/* allow empty plugin_att */
1125f8994074SJan Friedel 		if (*plugin_att == '\0') {
1126f8994074SJan Friedel 			cnt = 0;
1127f8994074SJan Friedel 			data = NULL;
1128f8994074SJan Friedel 		} else {
1129f8994074SJan Friedel 			plugin_att_kva = _str2kva(plugin_att, "=", ";");
1130f8994074SJan Friedel 			if (plugin_att_kva == NULL) {
1131f8994074SJan Friedel 				prt_error(gettext("Could not parse plugin "
1132f8994074SJan Friedel 				    "attributes."));
1133f8994074SJan Friedel 				return (B_FALSE);
1134f8994074SJan Friedel 			}
1135f8994074SJan Friedel 
1136f8994074SJan Friedel 			free_static_att_kva(plugin_att_kva);
1137f8994074SJan Friedel 			cnt = plugin_att_kva->length;
1138f8994074SJan Friedel 			data = plugin_att_kva->data;
1139f8994074SJan Friedel 		}
1140f8994074SJan Friedel 	}
1141f8994074SJan Friedel 
1142f8994074SJan Friedel 	/* set state */
1143f8994074SJan Friedel 	add_prop_vect_scf(prop_vect_ptr++, PLUGIN_ACTIVE, SCF_TYPE_BOOLEAN,
1144f8994074SJan Friedel 	    &plugin_state);
1145f8994074SJan Friedel 	DPRINT((dbfp, "Prepared active -> %d\n", plugin_state));
1146f8994074SJan Friedel 
1147f8994074SJan Friedel 	/* set attributes */
1148f8994074SJan Friedel 	while (cnt) {
1149f8994074SJan Friedel 		if (data->value == NULL) {
1150f8994074SJan Friedel 			cnt--;
1151f8994074SJan Friedel 			data++;
1152f8994074SJan Friedel 			continue;
1153f8994074SJan Friedel 		}
1154f8994074SJan Friedel 		if (!chk_prop_vect(&prop_vect_ptr, plugin_str)) {
1155f8994074SJan Friedel 			rval = B_FALSE;
1156f8994074SJan Friedel 			goto err_out;
1157f8994074SJan Friedel 		}
1158f8994074SJan Friedel 
1159f8994074SJan Friedel 		if ((plugin_prop = scf_simple_prop_get(NULL,
1160f8994074SJan Friedel 		    AUDITD_FMRI, plugin_str, data->key)) == NULL) {
1161f8994074SJan Friedel 			prt_error(gettext("Could not get configuration for "
1162f8994074SJan Friedel 			    "attribute: %s"), data->key);
1163f8994074SJan Friedel 			prt_scf_err();
1164f8994074SJan Friedel 			rval = B_FALSE;
1165f8994074SJan Friedel 			goto err_out;
1166f8994074SJan Friedel 		}
1167f8994074SJan Friedel 		if ((plugin_prop_type = scf_simple_prop_type(plugin_prop))
1168f8994074SJan Friedel 		    == -1) {
1169f8994074SJan Friedel 			prt_error(gettext("Could not get property type: %s"),
1170f8994074SJan Friedel 			    data->key);
1171f8994074SJan Friedel 			prt_scf_err();
1172f8994074SJan Friedel 			rval = B_FALSE;
1173f8994074SJan Friedel 			goto err_out;
1174f8994074SJan Friedel 		}
1175f8994074SJan Friedel 
1176f8994074SJan Friedel 		switch (plugin_prop_type) {
1177f8994074SJan Friedel 		case SCF_TYPE_BOOLEAN: {
1178f8994074SJan Friedel 			uint8_t	*pval_bool;
1179f8994074SJan Friedel 			pval_bool = (uint8_t *)malloc(sizeof (uint8_t));
1180f8994074SJan Friedel 			if (pval_bool == NULL) {
1181f8994074SJan Friedel 				prt_error(gettext("No free memory available."));
1182f8994074SJan Friedel 				rval = B_FALSE;
1183f8994074SJan Friedel 				goto err_out;
1184f8994074SJan Friedel 			}
1185f8994074SJan Friedel 			*pval_bool = (uint8_t)atoi(data->value);
1186f8994074SJan Friedel 			add_prop_vect_scf(prop_vect_ptr++, data->key,
1187f8994074SJan Friedel 			    SCF_TYPE_BOOLEAN, pval_bool);
1188f8994074SJan Friedel 			break;
1189f8994074SJan Friedel 		}
1190f8994074SJan Friedel 		case SCF_TYPE_ASTRING: {
1191f8994074SJan Friedel 			char	*pval_str;
1192f8994074SJan Friedel 			if ((pval_str = strdup(data->value)) == NULL) {
1193f8994074SJan Friedel 				prt_error(gettext("No free memory available."));
1194f8994074SJan Friedel 				rval = B_FALSE;
1195f8994074SJan Friedel 				goto err_out;
1196f8994074SJan Friedel 			}
1197f8994074SJan Friedel 			add_prop_vect_scf(prop_vect_ptr++, data->key,
1198f8994074SJan Friedel 			    SCF_TYPE_ASTRING, pval_str);
1199f8994074SJan Friedel 			break;
1200f8994074SJan Friedel 		}
1201f8994074SJan Friedel 		case SCF_TYPE_COUNT: {
1202f8994074SJan Friedel 			uint64_t	*pval_count;
1203f8994074SJan Friedel 			pval_count = (uint64_t *)malloc(sizeof (uint64_t));
1204f8994074SJan Friedel 			if (pval_count == NULL) {
1205f8994074SJan Friedel 				prt_error(gettext("No free memory available."));
1206f8994074SJan Friedel 				rval = B_FALSE;
1207f8994074SJan Friedel 				goto err_out;
1208f8994074SJan Friedel 			}
1209f8994074SJan Friedel 			*pval_count = (uint64_t)atoll(data->value);
1210f8994074SJan Friedel 			add_prop_vect_scf(prop_vect_ptr++, data->key,
1211f8994074SJan Friedel 			    SCF_TYPE_COUNT, pval_count);
1212f8994074SJan Friedel 			break;
1213f8994074SJan Friedel 		}
1214f8994074SJan Friedel 		default:
1215f8994074SJan Friedel 			prt_error(gettext("Unsupported property type: %s (%d)"),
1216f8994074SJan Friedel 			    data->key, plugin_prop_type);
1217f8994074SJan Friedel 			break;
1218f8994074SJan Friedel 		}
1219f8994074SJan Friedel 
1220f8994074SJan Friedel 		DPRINT((dbfp, "Prepared %s -> %s\n", data->key, data->value));
1221f8994074SJan Friedel 		scf_simple_prop_free(plugin_prop);
1222f8994074SJan Friedel 		data++;
1223f8994074SJan Friedel 		cnt--;
1224f8994074SJan Friedel 	}
1225f8994074SJan Friedel 
1226f8994074SJan Friedel 	if (!chk_prop_vect(&prop_vect_ptr, plugin_str)) {
1227f8994074SJan Friedel 		rval = B_FALSE;
1228f8994074SJan Friedel 		goto err_out;
1229f8994074SJan Friedel 	}
1230f8994074SJan Friedel 
1231f8994074SJan Friedel 	/* set qsize */
1232f8994074SJan Friedel 	if (plugin_qsize != -1) {
1233f8994074SJan Friedel 		add_prop_vect_scf(prop_vect_ptr, PLUGIN_QSIZE, SCF_TYPE_COUNT,
1234f8994074SJan Friedel 		    &plugin_qsize_l);
1235f8994074SJan Friedel 		DPRINT((dbfp, "Prepared qsize -> %d\n", plugin_qsize));
1236f8994074SJan Friedel 	}
1237f8994074SJan Friedel 
1238f8994074SJan Friedel 	if (!set_val_scf(prop_vect, plugin_str)) {
1239f8994074SJan Friedel 		rval = B_FALSE;
1240f8994074SJan Friedel 	}
1241f8994074SJan Friedel 
1242f8994074SJan Friedel err_out:
1243f8994074SJan Friedel 	free_prop_vect();
1244f8994074SJan Friedel 	_kva_free(plugin_att_kva);
1245f8994074SJan Friedel 	return (rval);
1246f8994074SJan Friedel }
1247f8994074SJan Friedel 
1248f8994074SJan Friedel /*
1249f8994074SJan Friedel  * plugin_kva_ll_free() - free the memory used by plugin kva linked list.
1250f8994074SJan Friedel  */
1251f8994074SJan Friedel void
plugin_kva_ll_free(scf_plugin_kva_node_t * node)1252f8994074SJan Friedel plugin_kva_ll_free(scf_plugin_kva_node_t *node)
1253f8994074SJan Friedel {
1254f8994074SJan Friedel 	scf_plugin_kva_node_t *node_next;
1255f8994074SJan Friedel 
1256f8994074SJan Friedel 	if (node == NULL) {
1257f8994074SJan Friedel 		return;
1258f8994074SJan Friedel 	}
1259f8994074SJan Friedel 
1260f8994074SJan Friedel 	while (node->prev != NULL) {
1261f8994074SJan Friedel 		node = node->prev;
1262f8994074SJan Friedel 	}
1263f8994074SJan Friedel 	while (node != NULL) {
1264f8994074SJan Friedel 		_kva_free(node->plugin_kva);
1265f8994074SJan Friedel 		node_next = node->next;
1266f8994074SJan Friedel 		free(node);
1267f8994074SJan Friedel 		node = node_next;
1268f8994074SJan Friedel 	}
1269f8994074SJan Friedel }
1270f8994074SJan Friedel 
1271f8994074SJan Friedel /*
1272f8994074SJan Friedel  * get_policy() - get policy mask entry
1273f8994074SJan Friedel  */
1274f8994074SJan Friedel uint32_t
get_policy(char * policy)1275f8994074SJan Friedel get_policy(char *policy)
1276f8994074SJan Friedel {
1277f8994074SJan Friedel 	int i;
1278f8994074SJan Friedel 
1279f8994074SJan Friedel 	for (i = 0; i < POLICY_TBL_SZ; i++) {
1280f8994074SJan Friedel 		if (strcasecmp(policy, policy_table[i].policy_str) == 0) {
1281f8994074SJan Friedel 			return (policy_table[i].policy_mask);
1282f8994074SJan Friedel 		}
1283f8994074SJan Friedel 	}
1284f8994074SJan Friedel 
1285f8994074SJan Friedel 	return (0);
1286f8994074SJan Friedel }
1287