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