xref: /titanic_51/usr/src/uts/common/syscall/auditsys.c (revision 005d3feb53a9a10272d4a24b03991575d6a9bcb3)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5405e5d68Stz204579  * Common Development and Distribution License (the "License").
6405e5d68Stz204579  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*005d3febSMarek Pospisil  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/systm.h>
277c478bd9Sstevel@tonic-gate #include <sys/errno.h>
287c478bd9Sstevel@tonic-gate #include <sys/policy.h>
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <c2/audit.h>
31*005d3febSMarek Pospisil #include <c2/audit_kernel.h>
32*005d3febSMarek Pospisil #include <c2/audit_record.h>
33*005d3febSMarek Pospisil 
34*005d3febSMarek Pospisil #define	CLEAR_VAL -1
35*005d3febSMarek Pospisil 
36*005d3febSMarek Pospisil extern kmutex_t pidlock;
37*005d3febSMarek Pospisil 
38*005d3febSMarek Pospisil int audit_policy; /* global audit policies in force */
39*005d3febSMarek Pospisil 
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*ARGSUSED1*/
427c478bd9Sstevel@tonic-gate int
437c478bd9Sstevel@tonic-gate auditsys(struct auditcalls *uap, rval_t *rvp)
447c478bd9Sstevel@tonic-gate {
457c478bd9Sstevel@tonic-gate 	int err;
46*005d3febSMarek Pospisil 	int result = 0;
477c478bd9Sstevel@tonic-gate 
48*005d3febSMarek Pospisil 	if (audit_active == C2AUDIT_DISABLED)
49405e5d68Stz204579 		return (ENOTSUP);
50405e5d68Stz204579 
517c478bd9Sstevel@tonic-gate 	switch (uap->code) {
527c478bd9Sstevel@tonic-gate 	case BSM_GETAUID:
53*005d3febSMarek Pospisil 		result = getauid((caddr_t)uap->a1);
54*005d3febSMarek Pospisil 		break;
557c478bd9Sstevel@tonic-gate 	case BSM_SETAUID:
56*005d3febSMarek Pospisil 		result = setauid((caddr_t)uap->a1);
57*005d3febSMarek Pospisil 		break;
587c478bd9Sstevel@tonic-gate 	case BSM_GETAUDIT:
59*005d3febSMarek Pospisil 		result = getaudit((caddr_t)uap->a1);
60*005d3febSMarek Pospisil 		break;
61*005d3febSMarek Pospisil 	case BSM_GETAUDIT_ADDR:
62*005d3febSMarek Pospisil 		result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
63*005d3febSMarek Pospisil 		break;
647c478bd9Sstevel@tonic-gate 	case BSM_SETAUDIT:
65*005d3febSMarek Pospisil 		result = setaudit((caddr_t)uap->a1);
66*005d3febSMarek Pospisil 		break;
67*005d3febSMarek Pospisil 	case BSM_SETAUDIT_ADDR:
68*005d3febSMarek Pospisil 		result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
69*005d3febSMarek Pospisil 		break;
707c478bd9Sstevel@tonic-gate 	case BSM_AUDITCTL:
71*005d3febSMarek Pospisil 		result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
72*005d3febSMarek Pospisil 		break;
73*005d3febSMarek Pospisil 	case BSM_AUDIT:
74*005d3febSMarek Pospisil 		if (audit_active == C2AUDIT_UNLOADED)
75*005d3febSMarek Pospisil 			return (0);
76*005d3febSMarek Pospisil 		result = audit((caddr_t)uap->a1, (int)uap->a2);
77*005d3febSMarek Pospisil 		break;
78*005d3febSMarek Pospisil 	case BSM_AUDITDOOR:
79*005d3febSMarek Pospisil 		if (audit_active == C2AUDIT_LOADED) {
80*005d3febSMarek Pospisil 			result = auditdoor((int)uap->a1);
81*005d3febSMarek Pospisil 			break;
82*005d3febSMarek Pospisil 		}
837c478bd9Sstevel@tonic-gate 	default:
84*005d3febSMarek Pospisil 		if (audit_active == C2AUDIT_LOADED) {
85*005d3febSMarek Pospisil 			result = EINVAL;
86*005d3febSMarek Pospisil 			break;
87*005d3febSMarek Pospisil 		}
887c478bd9Sstevel@tonic-gate 		/* Return a different error when not privileged */
897c478bd9Sstevel@tonic-gate 		err = secpolicy_audit_config(CRED());
907c478bd9Sstevel@tonic-gate 		if (err == 0)
917c478bd9Sstevel@tonic-gate 			return (EINVAL);
927c478bd9Sstevel@tonic-gate 		else
937c478bd9Sstevel@tonic-gate 			return (err);
947c478bd9Sstevel@tonic-gate 	}
95*005d3febSMarek Pospisil 	rvp->r_vals = result;
96*005d3febSMarek Pospisil 	return (result);
97*005d3febSMarek Pospisil }
98*005d3febSMarek Pospisil 
99*005d3febSMarek Pospisil /*
100*005d3febSMarek Pospisil  * Return the audit user ID for the current process.  Currently only
101*005d3febSMarek Pospisil  * the privileged processes may see the audit id.  That may change.
102*005d3febSMarek Pospisil  * If copyout is unsucessful return EFAULT.
103*005d3febSMarek Pospisil  */
104*005d3febSMarek Pospisil int
105*005d3febSMarek Pospisil getauid(caddr_t auid_p)
106*005d3febSMarek Pospisil {
107*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
108*005d3febSMarek Pospisil 
109*005d3febSMarek Pospisil 	if (secpolicy_audit_getattr(CRED()) != 0)
110*005d3febSMarek Pospisil 		return (EPERM);
111*005d3febSMarek Pospisil 
112*005d3febSMarek Pospisil 	ainfo = crgetauinfo(CRED());
113*005d3febSMarek Pospisil 	if (ainfo == NULL)
114*005d3febSMarek Pospisil 		return (EINVAL);
115*005d3febSMarek Pospisil 
116*005d3febSMarek Pospisil 	if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
117*005d3febSMarek Pospisil 		return (EFAULT);
118*005d3febSMarek Pospisil 
119*005d3febSMarek Pospisil 	return (0);
120*005d3febSMarek Pospisil }
121*005d3febSMarek Pospisil 
122*005d3febSMarek Pospisil /*
123*005d3febSMarek Pospisil  * Set the audit userid, for a process.  This can only be changed by
124*005d3febSMarek Pospisil  * privileged processes.  The audit userid is inherited across forks & execs.
125*005d3febSMarek Pospisil  * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
126*005d3febSMarek Pospisil  */
127*005d3febSMarek Pospisil int
128*005d3febSMarek Pospisil setauid(caddr_t auid_p)
129*005d3febSMarek Pospisil {
130*005d3febSMarek Pospisil 	proc_t *p;
131*005d3febSMarek Pospisil 	au_id_t	auid;
132*005d3febSMarek Pospisil 	cred_t *newcred;
133*005d3febSMarek Pospisil 	auditinfo_addr_t *auinfo;
134*005d3febSMarek Pospisil 
135*005d3febSMarek Pospisil 	if (secpolicy_audit_config(CRED()) != 0)
136*005d3febSMarek Pospisil 		return (EPERM);
137*005d3febSMarek Pospisil 
138*005d3febSMarek Pospisil 	if (copyin(auid_p, &auid, sizeof (au_id_t))) {
139*005d3febSMarek Pospisil 		return (EFAULT);
140*005d3febSMarek Pospisil 	}
141*005d3febSMarek Pospisil 
142*005d3febSMarek Pospisil 	newcred = cralloc();
143*005d3febSMarek Pospisil 	if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
144*005d3febSMarek Pospisil 		crfree(newcred);
145*005d3febSMarek Pospisil 		return (EINVAL);
146*005d3febSMarek Pospisil 	}
147*005d3febSMarek Pospisil 
148*005d3febSMarek Pospisil 	/* grab p_crlock and switch to new cred */
149*005d3febSMarek Pospisil 	p = curproc;
150*005d3febSMarek Pospisil 	mutex_enter(&p->p_crlock);
151*005d3febSMarek Pospisil 	crcopy_to(p->p_cred, newcred);
152*005d3febSMarek Pospisil 	p->p_cred = newcred;
153*005d3febSMarek Pospisil 
154*005d3febSMarek Pospisil 	auinfo->ai_auid = auid;			/* update the auid */
155*005d3febSMarek Pospisil 
156*005d3febSMarek Pospisil 	/* unlock and broadcast the cred changes */
157*005d3febSMarek Pospisil 	mutex_exit(&p->p_crlock);
158*005d3febSMarek Pospisil 	crset(p, newcred);
159*005d3febSMarek Pospisil 
160*005d3febSMarek Pospisil 	return (0);
161*005d3febSMarek Pospisil }
162*005d3febSMarek Pospisil 
163*005d3febSMarek Pospisil /*
164*005d3febSMarek Pospisil  * Get the audit state information from the current process.
165*005d3febSMarek Pospisil  * Return EFAULT if copyout fails.
166*005d3febSMarek Pospisil  */
167*005d3febSMarek Pospisil int
168*005d3febSMarek Pospisil getaudit(caddr_t info_p)
169*005d3febSMarek Pospisil {
170*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo, info);
171*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
172*005d3febSMarek Pospisil 	model_t	model;
173*005d3febSMarek Pospisil 
174*005d3febSMarek Pospisil 	if (secpolicy_audit_getattr(CRED()) != 0)
175*005d3febSMarek Pospisil 		return (EPERM);
176*005d3febSMarek Pospisil 
177*005d3febSMarek Pospisil 	model = get_udatamodel();
178*005d3febSMarek Pospisil 	STRUCT_INIT(info, model);
179*005d3febSMarek Pospisil 
180*005d3febSMarek Pospisil 	ainfo = crgetauinfo(CRED());
181*005d3febSMarek Pospisil 	if (ainfo == NULL)
182*005d3febSMarek Pospisil 		return (EINVAL);
183*005d3febSMarek Pospisil 
184*005d3febSMarek Pospisil 	/* trying to read a process with an IPv6 address? */
185*005d3febSMarek Pospisil 	if (ainfo->ai_termid.at_type == AU_IPv6)
186*005d3febSMarek Pospisil 		return (EOVERFLOW);
187*005d3febSMarek Pospisil 
188*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
189*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
190*005d3febSMarek Pospisil #ifdef _LP64
191*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32) {
192*005d3febSMarek Pospisil 		dev32_t dev;
193*005d3febSMarek Pospisil 		/* convert internal 64 bit form to 32 bit version */
194*005d3febSMarek Pospisil 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
195*005d3febSMarek Pospisil 			return (EOVERFLOW);
196*005d3febSMarek Pospisil 		}
197*005d3febSMarek Pospisil 		STRUCT_FSET(info, ai_termid.port, dev);
198*005d3febSMarek Pospisil 	} else
199*005d3febSMarek Pospisil 		STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
200*005d3febSMarek Pospisil #else
201*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
202*005d3febSMarek Pospisil #endif
203*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
204*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
205*005d3febSMarek Pospisil 
206*005d3febSMarek Pospisil 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
207*005d3febSMarek Pospisil 		return (EFAULT);
208*005d3febSMarek Pospisil 
209*005d3febSMarek Pospisil 	return (0);
210*005d3febSMarek Pospisil }
211*005d3febSMarek Pospisil 
212*005d3febSMarek Pospisil /*
213*005d3febSMarek Pospisil  * Get the audit state information from the current process.
214*005d3febSMarek Pospisil  * Return EFAULT if copyout fails.
215*005d3febSMarek Pospisil  */
216*005d3febSMarek Pospisil int
217*005d3febSMarek Pospisil getaudit_addr(caddr_t info_p, int len)
218*005d3febSMarek Pospisil {
219*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo_addr, info);
220*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
221*005d3febSMarek Pospisil 	model_t	model;
222*005d3febSMarek Pospisil 
223*005d3febSMarek Pospisil 	if (secpolicy_audit_getattr(CRED()) != 0)
224*005d3febSMarek Pospisil 		return (EPERM);
225*005d3febSMarek Pospisil 
226*005d3febSMarek Pospisil 	model = get_udatamodel();
227*005d3febSMarek Pospisil 	STRUCT_INIT(info, model);
228*005d3febSMarek Pospisil 
229*005d3febSMarek Pospisil 	if (len < STRUCT_SIZE(info))
230*005d3febSMarek Pospisil 		return (EOVERFLOW);
231*005d3febSMarek Pospisil 
232*005d3febSMarek Pospisil 	ainfo = crgetauinfo(CRED());
233*005d3febSMarek Pospisil 
234*005d3febSMarek Pospisil 	if (ainfo == NULL)
235*005d3febSMarek Pospisil 		return (EINVAL);
236*005d3febSMarek Pospisil 
237*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
238*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
239*005d3febSMarek Pospisil #ifdef _LP64
240*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32) {
241*005d3febSMarek Pospisil 		dev32_t dev;
242*005d3febSMarek Pospisil 		/* convert internal 64 bit form to 32 bit version */
243*005d3febSMarek Pospisil 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
244*005d3febSMarek Pospisil 			return (EOVERFLOW);
245*005d3febSMarek Pospisil 		}
246*005d3febSMarek Pospisil 		STRUCT_FSET(info, ai_termid.at_port, dev);
247*005d3febSMarek Pospisil 	} else
248*005d3febSMarek Pospisil 		STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
249*005d3febSMarek Pospisil #else
250*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
251*005d3febSMarek Pospisil #endif
252*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
253*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
254*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
255*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
256*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
257*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
258*005d3febSMarek Pospisil 
259*005d3febSMarek Pospisil 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
260*005d3febSMarek Pospisil 		return (EFAULT);
261*005d3febSMarek Pospisil 
262*005d3febSMarek Pospisil 	return (0);
263*005d3febSMarek Pospisil }
264*005d3febSMarek Pospisil 
265*005d3febSMarek Pospisil /*
266*005d3febSMarek Pospisil  * Set the audit state information for the current process.
267*005d3febSMarek Pospisil  * Return EFAULT if copyout fails.
268*005d3febSMarek Pospisil  */
269*005d3febSMarek Pospisil int
270*005d3febSMarek Pospisil setaudit(caddr_t info_p)
271*005d3febSMarek Pospisil {
272*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo, info);
273*005d3febSMarek Pospisil 	proc_t *p;
274*005d3febSMarek Pospisil 	cred_t	*newcred;
275*005d3febSMarek Pospisil 	model_t	model;
276*005d3febSMarek Pospisil 	auditinfo_addr_t *ainfo;
277*005d3febSMarek Pospisil 
278*005d3febSMarek Pospisil 	if (secpolicy_audit_config(CRED()) != 0)
279*005d3febSMarek Pospisil 		return (EPERM);
280*005d3febSMarek Pospisil 
281*005d3febSMarek Pospisil 	model = get_udatamodel();
282*005d3febSMarek Pospisil 	STRUCT_INIT(info, model);
283*005d3febSMarek Pospisil 
284*005d3febSMarek Pospisil 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
285*005d3febSMarek Pospisil 		return (EFAULT);
286*005d3febSMarek Pospisil 
287*005d3febSMarek Pospisil 	newcred = cralloc();
288*005d3febSMarek Pospisil 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
289*005d3febSMarek Pospisil 		crfree(newcred);
290*005d3febSMarek Pospisil 		return (EINVAL);
291*005d3febSMarek Pospisil 	}
292*005d3febSMarek Pospisil 
293*005d3febSMarek Pospisil 	/* grab p_crlock and switch to new cred */
294*005d3febSMarek Pospisil 	p = curproc;
295*005d3febSMarek Pospisil 	mutex_enter(&p->p_crlock);
296*005d3febSMarek Pospisil 	crcopy_to(p->p_cred, newcred);
297*005d3febSMarek Pospisil 	p->p_cred = newcred;
298*005d3febSMarek Pospisil 
299*005d3febSMarek Pospisil 	/* Set audit mask, id, termid and session id as specified */
300*005d3febSMarek Pospisil 	ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
301*005d3febSMarek Pospisil #ifdef _LP64
302*005d3febSMarek Pospisil 	/* only convert to 64 bit if coming from a 32 bit binary */
303*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32)
304*005d3febSMarek Pospisil 		ainfo->ai_termid.at_port =
305*005d3febSMarek Pospisil 		    DEVEXPL(STRUCT_FGET(info, ai_termid.port));
306*005d3febSMarek Pospisil 	else
307*005d3febSMarek Pospisil 		ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
308*005d3febSMarek Pospisil #else
309*005d3febSMarek Pospisil 	ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
310*005d3febSMarek Pospisil #endif
311*005d3febSMarek Pospisil 	ainfo->ai_termid.at_type = AU_IPv4;
312*005d3febSMarek Pospisil 	ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
313*005d3febSMarek Pospisil 	ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
314*005d3febSMarek Pospisil 	ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
315*005d3febSMarek Pospisil 
316*005d3febSMarek Pospisil 	/* unlock and broadcast the cred changes */
317*005d3febSMarek Pospisil 	mutex_exit(&p->p_crlock);
318*005d3febSMarek Pospisil 	crset(p, newcred);
319*005d3febSMarek Pospisil 
320*005d3febSMarek Pospisil 	return (0);
321*005d3febSMarek Pospisil }
322*005d3febSMarek Pospisil 
323*005d3febSMarek Pospisil /*
324*005d3febSMarek Pospisil  * Set the audit state information for the current process.
325*005d3febSMarek Pospisil  * Return EFAULT if copyin fails.
326*005d3febSMarek Pospisil  */
327*005d3febSMarek Pospisil int
328*005d3febSMarek Pospisil setaudit_addr(caddr_t info_p, int len)
329*005d3febSMarek Pospisil {
330*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo_addr, info);
331*005d3febSMarek Pospisil 	proc_t *p;
332*005d3febSMarek Pospisil 	cred_t	*newcred;
333*005d3febSMarek Pospisil 	model_t	model;
334*005d3febSMarek Pospisil 	int i;
335*005d3febSMarek Pospisil 	int type;
336*005d3febSMarek Pospisil 	auditinfo_addr_t *ainfo;
337*005d3febSMarek Pospisil 
338*005d3febSMarek Pospisil 	if (secpolicy_audit_config(CRED()) != 0)
339*005d3febSMarek Pospisil 		return (EPERM);
340*005d3febSMarek Pospisil 
341*005d3febSMarek Pospisil 	model = get_udatamodel();
342*005d3febSMarek Pospisil 	STRUCT_INIT(info, model);
343*005d3febSMarek Pospisil 
344*005d3febSMarek Pospisil 	if (len < STRUCT_SIZE(info))
345*005d3febSMarek Pospisil 		return (EOVERFLOW);
346*005d3febSMarek Pospisil 
347*005d3febSMarek Pospisil 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
348*005d3febSMarek Pospisil 		return (EFAULT);
349*005d3febSMarek Pospisil 
350*005d3febSMarek Pospisil 	type = STRUCT_FGET(info, ai_termid.at_type);
351*005d3febSMarek Pospisil 	if ((type != AU_IPv4) && (type != AU_IPv6))
352*005d3febSMarek Pospisil 		return (EINVAL);
353*005d3febSMarek Pospisil 
354*005d3febSMarek Pospisil 	newcred = cralloc();
355*005d3febSMarek Pospisil 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
356*005d3febSMarek Pospisil 		crfree(newcred);
357*005d3febSMarek Pospisil 		return (EINVAL);
358*005d3febSMarek Pospisil 	}
359*005d3febSMarek Pospisil 
360*005d3febSMarek Pospisil 	/* grab p_crlock and switch to new cred */
361*005d3febSMarek Pospisil 	p = curproc;
362*005d3febSMarek Pospisil 	mutex_enter(&p->p_crlock);
363*005d3febSMarek Pospisil 	crcopy_to(p->p_cred, newcred);
364*005d3febSMarek Pospisil 	p->p_cred = newcred;
365*005d3febSMarek Pospisil 
366*005d3febSMarek Pospisil 	/* Set audit mask, id, termid and session id as specified */
367*005d3febSMarek Pospisil 	ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
368*005d3febSMarek Pospisil 	ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
369*005d3febSMarek Pospisil #ifdef _LP64
370*005d3febSMarek Pospisil 	/* only convert to 64 bit if coming from a 32 bit binary */
371*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32)
372*005d3febSMarek Pospisil 		ainfo->ai_termid.at_port =
373*005d3febSMarek Pospisil 		    DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
374*005d3febSMarek Pospisil 	else
375*005d3febSMarek Pospisil 		ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
376*005d3febSMarek Pospisil #else
377*005d3febSMarek Pospisil 	ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
378*005d3febSMarek Pospisil #endif
379*005d3febSMarek Pospisil 	ainfo->ai_termid.at_type = type;
380*005d3febSMarek Pospisil 	bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
381*005d3febSMarek Pospisil 	for (i = 0; i < (type/sizeof (int)); i++)
382*005d3febSMarek Pospisil 		ainfo->ai_termid.at_addr[i] =
383*005d3febSMarek Pospisil 		    STRUCT_FGET(info, ai_termid.at_addr[i]);
384*005d3febSMarek Pospisil 
385*005d3febSMarek Pospisil 	if (ainfo->ai_termid.at_type == AU_IPv6 &&
386*005d3febSMarek Pospisil 	    IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
387*005d3febSMarek Pospisil 		ainfo->ai_termid.at_type = AU_IPv4;
388*005d3febSMarek Pospisil 		ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
389*005d3febSMarek Pospisil 		ainfo->ai_termid.at_addr[1] = 0;
390*005d3febSMarek Pospisil 		ainfo->ai_termid.at_addr[2] = 0;
391*005d3febSMarek Pospisil 		ainfo->ai_termid.at_addr[3] = 0;
392*005d3febSMarek Pospisil 	}
393*005d3febSMarek Pospisil 
394*005d3febSMarek Pospisil 	ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
395*005d3febSMarek Pospisil 
396*005d3febSMarek Pospisil 	/* unlock and broadcast the cred changes */
397*005d3febSMarek Pospisil 	mutex_exit(&p->p_crlock);
398*005d3febSMarek Pospisil 	crset(p, newcred);
399*005d3febSMarek Pospisil 
400*005d3febSMarek Pospisil 	return (0);
401*005d3febSMarek Pospisil }
402*005d3febSMarek Pospisil 
403*005d3febSMarek Pospisil /*
404*005d3febSMarek Pospisil  * Get the global policy flag
405*005d3febSMarek Pospisil  */
406*005d3febSMarek Pospisil static int
407*005d3febSMarek Pospisil getpolicy(caddr_t data)
408*005d3febSMarek Pospisil {
409*005d3febSMarek Pospisil 	int	policy;
410*005d3febSMarek Pospisil 	au_kcontext_t	*kctx = GET_KCTX_PZ;
411*005d3febSMarek Pospisil 
412*005d3febSMarek Pospisil 	policy = audit_policy | kctx->auk_policy;
413*005d3febSMarek Pospisil 
414*005d3febSMarek Pospisil 	if (copyout(&policy, data, sizeof (int)))
415*005d3febSMarek Pospisil 		return (EFAULT);
416*005d3febSMarek Pospisil 	return (0);
417*005d3febSMarek Pospisil }
418*005d3febSMarek Pospisil 
419*005d3febSMarek Pospisil /*
420*005d3febSMarek Pospisil  * Set the global and local policy flags
421*005d3febSMarek Pospisil  *
422*005d3febSMarek Pospisil  * The global flags only make sense from the global zone;
423*005d3febSMarek Pospisil  * the local flags depend on the AUDIT_PERZONE policy:
424*005d3febSMarek Pospisil  * if the perzone policy is set, then policy is set separately
425*005d3febSMarek Pospisil  * per zone, else held only in the global zone.
426*005d3febSMarek Pospisil  *
427*005d3febSMarek Pospisil  * The initial value of a local zone's policy flag is determined
428*005d3febSMarek Pospisil  * by the value of the global zone's flags at the time the
429*005d3febSMarek Pospisil  * local zone is created.
430*005d3febSMarek Pospisil  *
431*005d3febSMarek Pospisil  * While auditconfig(1M) allows setting and unsetting policies one bit
432*005d3febSMarek Pospisil  * at a time, the mask passed in from auditconfig() is created by a
433*005d3febSMarek Pospisil  * syscall to getpolicy and then modified based on the auditconfig()
434*005d3febSMarek Pospisil  * cmd line, so the input policy value is used to replace the existing
435*005d3febSMarek Pospisil  * policy.
436*005d3febSMarek Pospisil  */
437*005d3febSMarek Pospisil static int
438*005d3febSMarek Pospisil setpolicy(caddr_t data)
439*005d3febSMarek Pospisil {
440*005d3febSMarek Pospisil 	int	policy;
441*005d3febSMarek Pospisil 	au_kcontext_t	*kctx;
442*005d3febSMarek Pospisil 
443*005d3febSMarek Pospisil 	if (copyin(data, &policy, sizeof (int)))
444*005d3febSMarek Pospisil 		return (EFAULT);
445*005d3febSMarek Pospisil 
446*005d3febSMarek Pospisil 	kctx = GET_KCTX_NGZ;
447*005d3febSMarek Pospisil 
448*005d3febSMarek Pospisil 	if (INGLOBALZONE(curproc)) {
449*005d3febSMarek Pospisil 		if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
450*005d3febSMarek Pospisil 			return (EINVAL);
451*005d3febSMarek Pospisil 
452*005d3febSMarek Pospisil 		audit_policy = policy & AUDIT_GLOBAL;
453*005d3febSMarek Pospisil 	} else {
454*005d3febSMarek Pospisil 		if (!(audit_policy & AUDIT_PERZONE))
455*005d3febSMarek Pospisil 			return (EINVAL);
456*005d3febSMarek Pospisil 
457*005d3febSMarek Pospisil 		if (policy & ~AUDIT_LOCAL)	/* global bits are a no-no */
458*005d3febSMarek Pospisil 			return (EINVAL);
459*005d3febSMarek Pospisil 	}
460*005d3febSMarek Pospisil 	kctx->auk_policy = policy & AUDIT_LOCAL;
461*005d3febSMarek Pospisil 
462*005d3febSMarek Pospisil 	/*
463*005d3febSMarek Pospisil 	 * auk_current_vp is NULL before auditd starts (or during early
464*005d3febSMarek Pospisil 	 * auditd starup) or if auditd is halted; in either case,
465*005d3febSMarek Pospisil 	 * notification of a policy change is not needed, since auditd
466*005d3febSMarek Pospisil 	 * reads policy as it comes up.  The error return from au_doormsg()
467*005d3febSMarek Pospisil 	 * is ignored to avoid a race condition -- for example if auditd
468*005d3febSMarek Pospisil 	 * segv's, the audit state may be "auditing" but the door may
469*005d3febSMarek Pospisil 	 * be closed.  Returning an error if the door is open makes it
470*005d3febSMarek Pospisil 	 * impossible for Greenline to restart auditd.
471*005d3febSMarek Pospisil 	 */
472*005d3febSMarek Pospisil 	if (kctx->auk_current_vp != NULL)
473*005d3febSMarek Pospisil 		(void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
474*005d3febSMarek Pospisil 
475*005d3febSMarek Pospisil 	/*
476*005d3febSMarek Pospisil 	 * Wake up anyone who might have blocked on full audit
477*005d3febSMarek Pospisil 	 * partitions. audit daemons need to set AUDIT_FULL when no
478*005d3febSMarek Pospisil 	 * space so we can tell if we should start dropping records.
479*005d3febSMarek Pospisil 	 */
480*005d3febSMarek Pospisil 	mutex_enter(&(kctx->auk_queue.lock));
481*005d3febSMarek Pospisil 
482*005d3febSMarek Pospisil 	if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
483*005d3febSMarek Pospisil 	    (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
484*005d3febSMarek Pospisil 		cv_broadcast(&(kctx->auk_queue.write_cv));
485*005d3febSMarek Pospisil 
486*005d3febSMarek Pospisil 	mutex_exit(&(kctx->auk_queue.lock));
487*005d3febSMarek Pospisil 
488*005d3febSMarek Pospisil 	return (0);
489*005d3febSMarek Pospisil }
490*005d3febSMarek Pospisil 
491*005d3febSMarek Pospisil static int
492*005d3febSMarek Pospisil getkmask(caddr_t data)
493*005d3febSMarek Pospisil {
494*005d3febSMarek Pospisil 	au_kcontext_t	*kctx;
495*005d3febSMarek Pospisil 
496*005d3febSMarek Pospisil 	kctx = GET_KCTX_PZ;
497*005d3febSMarek Pospisil 
498*005d3febSMarek Pospisil 	if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t)))
499*005d3febSMarek Pospisil 		return (EFAULT);
500*005d3febSMarek Pospisil 	return (0);
501*005d3febSMarek Pospisil }
502*005d3febSMarek Pospisil 
503*005d3febSMarek Pospisil static int
504*005d3febSMarek Pospisil setkmask(caddr_t data)
505*005d3febSMarek Pospisil {
506*005d3febSMarek Pospisil 	au_mask_t	mask;
507*005d3febSMarek Pospisil 	au_kcontext_t	*kctx;
508*005d3febSMarek Pospisil 
509*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
510*005d3febSMarek Pospisil 		return (EINVAL);
511*005d3febSMarek Pospisil 
512*005d3febSMarek Pospisil 	kctx = GET_KCTX_NGZ;
513*005d3febSMarek Pospisil 
514*005d3febSMarek Pospisil 	if (copyin(data, &mask, sizeof (au_mask_t)))
515*005d3febSMarek Pospisil 		return (EFAULT);
516*005d3febSMarek Pospisil 
517*005d3febSMarek Pospisil 	kctx->auk_info.ai_mask = mask;
518*005d3febSMarek Pospisil 	return (0);
519*005d3febSMarek Pospisil }
520*005d3febSMarek Pospisil 
521*005d3febSMarek Pospisil static int
522*005d3febSMarek Pospisil getkaudit(caddr_t info_p, int len)
523*005d3febSMarek Pospisil {
524*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo_addr, info);
525*005d3febSMarek Pospisil 	model_t model;
526*005d3febSMarek Pospisil 	au_kcontext_t	*kctx = GET_KCTX_PZ;
527*005d3febSMarek Pospisil 
528*005d3febSMarek Pospisil 	model = get_udatamodel();
529*005d3febSMarek Pospisil 	STRUCT_INIT(info, model);
530*005d3febSMarek Pospisil 
531*005d3febSMarek Pospisil 	if (len < STRUCT_SIZE(info))
532*005d3febSMarek Pospisil 		return (EOVERFLOW);
533*005d3febSMarek Pospisil 
534*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
535*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask);
536*005d3febSMarek Pospisil #ifdef _LP64
537*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32) {
538*005d3febSMarek Pospisil 		dev32_t dev;
539*005d3febSMarek Pospisil 		/* convert internal 64 bit form to 32 bit version */
540*005d3febSMarek Pospisil 		if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
541*005d3febSMarek Pospisil 			return (EOVERFLOW);
542*005d3febSMarek Pospisil 		}
543*005d3febSMarek Pospisil 		STRUCT_FSET(info, ai_termid.at_port, dev);
544*005d3febSMarek Pospisil 	} else {
545*005d3febSMarek Pospisil 		STRUCT_FSET(info, ai_termid.at_port,
546*005d3febSMarek Pospisil 		    kctx->auk_info.ai_termid.at_port);
547*005d3febSMarek Pospisil 	}
548*005d3febSMarek Pospisil #else
549*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_port,
550*005d3febSMarek Pospisil 	    kctx->auk_info.ai_termid.at_port);
551*005d3febSMarek Pospisil #endif
552*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_type,
553*005d3febSMarek Pospisil 	    kctx->auk_info.ai_termid.at_type);
554*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[0],
555*005d3febSMarek Pospisil 	    kctx->auk_info.ai_termid.at_addr[0]);
556*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[1],
557*005d3febSMarek Pospisil 	    kctx->auk_info.ai_termid.at_addr[1]);
558*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[2],
559*005d3febSMarek Pospisil 	    kctx->auk_info.ai_termid.at_addr[2]);
560*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_termid.at_addr[3],
561*005d3febSMarek Pospisil 	    kctx->auk_info.ai_termid.at_addr[3]);
562*005d3febSMarek Pospisil 	STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
563*005d3febSMarek Pospisil 
564*005d3febSMarek Pospisil 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
565*005d3febSMarek Pospisil 		return (EFAULT);
566*005d3febSMarek Pospisil 
567*005d3febSMarek Pospisil 	return (0);
568*005d3febSMarek Pospisil }
569*005d3febSMarek Pospisil 
570*005d3febSMarek Pospisil /*
571*005d3febSMarek Pospisil  * the host address for AUDIT_PERZONE == 0 is that of the global
572*005d3febSMarek Pospisil  * zone and for local zones it is of the current zone.
573*005d3febSMarek Pospisil  */
574*005d3febSMarek Pospisil static int
575*005d3febSMarek Pospisil setkaudit(caddr_t info_p, int len)
576*005d3febSMarek Pospisil {
577*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo_addr, info);
578*005d3febSMarek Pospisil 	model_t model;
579*005d3febSMarek Pospisil 	au_kcontext_t	*kctx;
580*005d3febSMarek Pospisil 
581*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
582*005d3febSMarek Pospisil 		return (EINVAL);
583*005d3febSMarek Pospisil 
584*005d3febSMarek Pospisil 	kctx = GET_KCTX_NGZ;
585*005d3febSMarek Pospisil 
586*005d3febSMarek Pospisil 	model = get_udatamodel();
587*005d3febSMarek Pospisil 	STRUCT_INIT(info, model);
588*005d3febSMarek Pospisil 
589*005d3febSMarek Pospisil 	if (len < STRUCT_SIZE(info))
590*005d3febSMarek Pospisil 		return (EOVERFLOW);
591*005d3febSMarek Pospisil 
592*005d3febSMarek Pospisil 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
593*005d3febSMarek Pospisil 		return (EFAULT);
594*005d3febSMarek Pospisil 
595*005d3febSMarek Pospisil 	if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
596*005d3febSMarek Pospisil 	    (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
597*005d3febSMarek Pospisil 		return (EINVAL);
598*005d3febSMarek Pospisil 
599*005d3febSMarek Pospisil 	/* Set audit mask, termid and session id as specified */
600*005d3febSMarek Pospisil 	kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
601*005d3febSMarek Pospisil 	kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask);
602*005d3febSMarek Pospisil #ifdef _LP64
603*005d3febSMarek Pospisil 	/* only convert to 64 bit if coming from a 32 bit binary */
604*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32)
605*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_port =
606*005d3febSMarek Pospisil 		    DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
607*005d3febSMarek Pospisil 	else
608*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_port =
609*005d3febSMarek Pospisil 		    STRUCT_FGET(info, ai_termid.at_port);
610*005d3febSMarek Pospisil #else
611*005d3febSMarek Pospisil 	kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
612*005d3febSMarek Pospisil #endif
613*005d3febSMarek Pospisil 	kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
614*005d3febSMarek Pospisil 	bzero(&kctx->auk_info.ai_termid.at_addr[0],
615*005d3febSMarek Pospisil 	    sizeof (kctx->auk_info.ai_termid.at_addr));
616*005d3febSMarek Pospisil 	kctx->auk_info.ai_termid.at_addr[0] =
617*005d3febSMarek Pospisil 	    STRUCT_FGET(info, ai_termid.at_addr[0]);
618*005d3febSMarek Pospisil 	kctx->auk_info.ai_termid.at_addr[1] =
619*005d3febSMarek Pospisil 	    STRUCT_FGET(info, ai_termid.at_addr[1]);
620*005d3febSMarek Pospisil 	kctx->auk_info.ai_termid.at_addr[2] =
621*005d3febSMarek Pospisil 	    STRUCT_FGET(info, ai_termid.at_addr[2]);
622*005d3febSMarek Pospisil 	kctx->auk_info.ai_termid.at_addr[3] =
623*005d3febSMarek Pospisil 	    STRUCT_FGET(info, ai_termid.at_addr[3]);
624*005d3febSMarek Pospisil 	kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
625*005d3febSMarek Pospisil 
626*005d3febSMarek Pospisil 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
627*005d3febSMarek Pospisil 	    IN6_IS_ADDR_V4MAPPED(
628*005d3febSMarek Pospisil 	    ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
629*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_type = AU_IPv4;
630*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_addr[0] =
631*005d3febSMarek Pospisil 		    kctx->auk_info.ai_termid.at_addr[3];
632*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_addr[1] = 0;
633*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_addr[2] = 0;
634*005d3febSMarek Pospisil 		kctx->auk_info.ai_termid.at_addr[3] = 0;
635*005d3febSMarek Pospisil 	}
636*005d3febSMarek Pospisil 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
637*005d3febSMarek Pospisil 		kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
638*005d3febSMarek Pospisil 		    (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
639*005d3febSMarek Pospisil 	else
640*005d3febSMarek Pospisil 		kctx->auk_hostaddr_valid =
641*005d3febSMarek Pospisil 		    (kctx->auk_info.ai_termid.at_addr[0] ==
642*005d3febSMarek Pospisil 		    htonl(INADDR_ANY)) ? 0 : 1;
643*005d3febSMarek Pospisil 
644*005d3febSMarek Pospisil 	return (0);
645*005d3febSMarek Pospisil }
646*005d3febSMarek Pospisil 
647*005d3febSMarek Pospisil static int
648*005d3febSMarek Pospisil getqctrl(caddr_t data)
649*005d3febSMarek Pospisil {
650*005d3febSMarek Pospisil 	au_kcontext_t	*kctx = GET_KCTX_PZ;
651*005d3febSMarek Pospisil 	STRUCT_DECL(au_qctrl, qctrl);
652*005d3febSMarek Pospisil 	STRUCT_INIT(qctrl, get_udatamodel());
653*005d3febSMarek Pospisil 
654*005d3febSMarek Pospisil 	mutex_enter(&(kctx->auk_queue.lock));
655*005d3febSMarek Pospisil 	STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
656*005d3febSMarek Pospisil 	STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
657*005d3febSMarek Pospisil 	STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
658*005d3febSMarek Pospisil 	STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
659*005d3febSMarek Pospisil 	mutex_exit(&(kctx->auk_queue.lock));
660*005d3febSMarek Pospisil 
661*005d3febSMarek Pospisil 	if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
662*005d3febSMarek Pospisil 		return (EFAULT);
663*005d3febSMarek Pospisil 
664*005d3febSMarek Pospisil 	return (0);
665*005d3febSMarek Pospisil }
666*005d3febSMarek Pospisil 
667*005d3febSMarek Pospisil static int
668*005d3febSMarek Pospisil setqctrl(caddr_t data)
669*005d3febSMarek Pospisil {
670*005d3febSMarek Pospisil 	au_kcontext_t	*kctx;
671*005d3febSMarek Pospisil 	struct au_qctrl qctrl_tmp;
672*005d3febSMarek Pospisil 	STRUCT_DECL(au_qctrl, qctrl);
673*005d3febSMarek Pospisil 	STRUCT_INIT(qctrl, get_udatamodel());
674*005d3febSMarek Pospisil 
675*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
676*005d3febSMarek Pospisil 		return (EINVAL);
677*005d3febSMarek Pospisil 	kctx = GET_KCTX_NGZ;
678*005d3febSMarek Pospisil 
679*005d3febSMarek Pospisil 	if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
680*005d3febSMarek Pospisil 		return (EFAULT);
681*005d3febSMarek Pospisil 
682*005d3febSMarek Pospisil 	qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
683*005d3febSMarek Pospisil 	qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
684*005d3febSMarek Pospisil 	qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
685*005d3febSMarek Pospisil 	qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
686*005d3febSMarek Pospisil 
687*005d3febSMarek Pospisil 	/* enforce sane values */
688*005d3febSMarek Pospisil 
689*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
690*005d3febSMarek Pospisil 		return (EINVAL);
691*005d3febSMarek Pospisil 
692*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
693*005d3febSMarek Pospisil 		return (EINVAL);
694*005d3febSMarek Pospisil 
695*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
696*005d3febSMarek Pospisil 		return (EINVAL);
697*005d3febSMarek Pospisil 
698*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
699*005d3febSMarek Pospisil 		return (EINVAL);
700*005d3febSMarek Pospisil 
701*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
702*005d3febSMarek Pospisil 		return (EINVAL);
703*005d3febSMarek Pospisil 
704*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_delay == 0)
705*005d3febSMarek Pospisil 		return (EINVAL);
706*005d3febSMarek Pospisil 
707*005d3febSMarek Pospisil 	if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
708*005d3febSMarek Pospisil 		return (EINVAL);
709*005d3febSMarek Pospisil 
710*005d3febSMarek Pospisil 	/* update everything at once so things are consistant */
711*005d3febSMarek Pospisil 	mutex_enter(&(kctx->auk_queue.lock));
712*005d3febSMarek Pospisil 	kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
713*005d3febSMarek Pospisil 	kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
714*005d3febSMarek Pospisil 	kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
715*005d3febSMarek Pospisil 	kctx->auk_queue.delay = qctrl_tmp.aq_delay;
716*005d3febSMarek Pospisil 
717*005d3febSMarek Pospisil 	if (kctx->auk_queue.rd_block &&
718*005d3febSMarek Pospisil 	    kctx->auk_queue.cnt > kctx->auk_queue.lowater)
719*005d3febSMarek Pospisil 		cv_broadcast(&(kctx->auk_queue.read_cv));
720*005d3febSMarek Pospisil 
721*005d3febSMarek Pospisil 	if (kctx->auk_queue.wt_block &&
722*005d3febSMarek Pospisil 	    kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
723*005d3febSMarek Pospisil 		cv_broadcast(&(kctx->auk_queue.write_cv));
724*005d3febSMarek Pospisil 
725*005d3febSMarek Pospisil 	mutex_exit(&(kctx->auk_queue.lock));
726*005d3febSMarek Pospisil 
727*005d3febSMarek Pospisil 	return (0);
728*005d3febSMarek Pospisil }
729*005d3febSMarek Pospisil 
730*005d3febSMarek Pospisil static int
731*005d3febSMarek Pospisil getcwd(caddr_t data, int length)
732*005d3febSMarek Pospisil {
733*005d3febSMarek Pospisil 	struct p_audit_data	*pad;
734*005d3febSMarek Pospisil 	struct audit_path	*app;
735*005d3febSMarek Pospisil 	int	pathlen;
736*005d3febSMarek Pospisil 
737*005d3febSMarek Pospisil 	pad = P2A(curproc);
738*005d3febSMarek Pospisil 	ASSERT(pad != NULL);
739*005d3febSMarek Pospisil 
740*005d3febSMarek Pospisil 	mutex_enter(&(pad->pad_lock));
741*005d3febSMarek Pospisil 	app = pad->pad_cwd;
742*005d3febSMarek Pospisil 	au_pathhold(app);
743*005d3febSMarek Pospisil 	mutex_exit(&(pad->pad_lock));
744*005d3febSMarek Pospisil 
745*005d3febSMarek Pospisil 	pathlen = app->audp_sect[1] - app->audp_sect[0];
746*005d3febSMarek Pospisil 	if (pathlen > length) {
747*005d3febSMarek Pospisil 		au_pathrele(app);
748*005d3febSMarek Pospisil 		return (E2BIG);
749*005d3febSMarek Pospisil 	}
750*005d3febSMarek Pospisil 
751*005d3febSMarek Pospisil 	if (copyout(app->audp_sect[0], data, pathlen)) {
752*005d3febSMarek Pospisil 		au_pathrele(app);
753*005d3febSMarek Pospisil 		return (EFAULT);
754*005d3febSMarek Pospisil 	}
755*005d3febSMarek Pospisil 
756*005d3febSMarek Pospisil 	au_pathrele(app);
757*005d3febSMarek Pospisil 	return (0);
758*005d3febSMarek Pospisil }
759*005d3febSMarek Pospisil 
760*005d3febSMarek Pospisil static int
761*005d3febSMarek Pospisil getcar(caddr_t data, int length)
762*005d3febSMarek Pospisil {
763*005d3febSMarek Pospisil 	struct p_audit_data	*pad;
764*005d3febSMarek Pospisil 	struct audit_path	*app;
765*005d3febSMarek Pospisil 	int	pathlen;
766*005d3febSMarek Pospisil 
767*005d3febSMarek Pospisil 	pad = P2A(curproc);
768*005d3febSMarek Pospisil 	ASSERT(pad != NULL);
769*005d3febSMarek Pospisil 
770*005d3febSMarek Pospisil 	mutex_enter(&(pad->pad_lock));
771*005d3febSMarek Pospisil 	app = pad->pad_root;
772*005d3febSMarek Pospisil 	au_pathhold(app);
773*005d3febSMarek Pospisil 	mutex_exit(&(pad->pad_lock));
774*005d3febSMarek Pospisil 
775*005d3febSMarek Pospisil 	pathlen = app->audp_sect[1] - app->audp_sect[0];
776*005d3febSMarek Pospisil 	if (pathlen > length) {
777*005d3febSMarek Pospisil 		au_pathrele(app);
778*005d3febSMarek Pospisil 		return (E2BIG);
779*005d3febSMarek Pospisil 	}
780*005d3febSMarek Pospisil 
781*005d3febSMarek Pospisil 	if (copyout(app->audp_sect[0], data, pathlen)) {
782*005d3febSMarek Pospisil 		au_pathrele(app);
783*005d3febSMarek Pospisil 		return (EFAULT);
784*005d3febSMarek Pospisil 	}
785*005d3febSMarek Pospisil 
786*005d3febSMarek Pospisil 	au_pathrele(app);
787*005d3febSMarek Pospisil 	return (0);
788*005d3febSMarek Pospisil }
789*005d3febSMarek Pospisil 
790*005d3febSMarek Pospisil static int
791*005d3febSMarek Pospisil getstat(caddr_t data)
792*005d3febSMarek Pospisil {
793*005d3febSMarek Pospisil 	au_kcontext_t	*kctx = GET_KCTX_PZ;
794*005d3febSMarek Pospisil 
795*005d3febSMarek Pospisil 	membar_consumer();
796*005d3febSMarek Pospisil 
797*005d3febSMarek Pospisil 	if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
798*005d3febSMarek Pospisil 		return (EFAULT);
799*005d3febSMarek Pospisil 	return (0);
800*005d3febSMarek Pospisil }
801*005d3febSMarek Pospisil 
802*005d3febSMarek Pospisil static int
803*005d3febSMarek Pospisil setstat(caddr_t data)
804*005d3febSMarek Pospisil {
805*005d3febSMarek Pospisil 	au_kcontext_t *kctx = GET_KCTX_PZ;
806*005d3febSMarek Pospisil 	au_stat_t au_stat;
807*005d3febSMarek Pospisil 
808*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
809*005d3febSMarek Pospisil 		return (EINVAL);
810*005d3febSMarek Pospisil 
811*005d3febSMarek Pospisil 	if (copyin(data, &au_stat, sizeof (au_stat_t)))
812*005d3febSMarek Pospisil 		return (EFAULT);
813*005d3febSMarek Pospisil 
814*005d3febSMarek Pospisil 	if (au_stat.as_generated == CLEAR_VAL)
815*005d3febSMarek Pospisil 		kctx->auk_statistics.as_generated = 0;
816*005d3febSMarek Pospisil 	if (au_stat.as_nonattrib == CLEAR_VAL)
817*005d3febSMarek Pospisil 		kctx->auk_statistics.as_nonattrib = 0;
818*005d3febSMarek Pospisil 	if (au_stat.as_kernel == CLEAR_VAL)
819*005d3febSMarek Pospisil 		kctx->auk_statistics.as_kernel = 0;
820*005d3febSMarek Pospisil 	if (au_stat.as_audit == CLEAR_VAL)
821*005d3febSMarek Pospisil 		kctx->auk_statistics.as_audit = 0;
822*005d3febSMarek Pospisil 	if (au_stat.as_auditctl == CLEAR_VAL)
823*005d3febSMarek Pospisil 		kctx->auk_statistics.as_auditctl = 0;
824*005d3febSMarek Pospisil 	if (au_stat.as_enqueue == CLEAR_VAL)
825*005d3febSMarek Pospisil 		kctx->auk_statistics.as_enqueue = 0;
826*005d3febSMarek Pospisil 	if (au_stat.as_written == CLEAR_VAL)
827*005d3febSMarek Pospisil 		kctx->auk_statistics.as_written = 0;
828*005d3febSMarek Pospisil 	if (au_stat.as_wblocked == CLEAR_VAL)
829*005d3febSMarek Pospisil 		kctx->auk_statistics.as_wblocked = 0;
830*005d3febSMarek Pospisil 	if (au_stat.as_rblocked == CLEAR_VAL)
831*005d3febSMarek Pospisil 		kctx->auk_statistics.as_rblocked = 0;
832*005d3febSMarek Pospisil 	if (au_stat.as_dropped == CLEAR_VAL)
833*005d3febSMarek Pospisil 		kctx->auk_statistics.as_dropped = 0;
834*005d3febSMarek Pospisil 	if (au_stat.as_totalsize == CLEAR_VAL)
835*005d3febSMarek Pospisil 		kctx->auk_statistics.as_totalsize = 0;
836*005d3febSMarek Pospisil 
837*005d3febSMarek Pospisil 	membar_producer();
838*005d3febSMarek Pospisil 
839*005d3febSMarek Pospisil 	return (0);
840*005d3febSMarek Pospisil 
841*005d3febSMarek Pospisil }
842*005d3febSMarek Pospisil 
843*005d3febSMarek Pospisil static int
844*005d3febSMarek Pospisil setumask(caddr_t data)
845*005d3febSMarek Pospisil {
846*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo, user_info);
847*005d3febSMarek Pospisil 	struct proc *p;
848*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
849*005d3febSMarek Pospisil 	model_t	model;
850*005d3febSMarek Pospisil 
851*005d3febSMarek Pospisil 	/* setumask not applicable in non-global zones without perzone policy */
852*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
853*005d3febSMarek Pospisil 		return (EINVAL);
854*005d3febSMarek Pospisil 
855*005d3febSMarek Pospisil 	model = get_udatamodel();
856*005d3febSMarek Pospisil 	STRUCT_INIT(user_info, model);
857*005d3febSMarek Pospisil 
858*005d3febSMarek Pospisil 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
859*005d3febSMarek Pospisil 		return (EFAULT);
860*005d3febSMarek Pospisil 
861*005d3febSMarek Pospisil 	mutex_enter(&pidlock);	/* lock the process queue against updates */
862*005d3febSMarek Pospisil 	for (p = practive; p != NULL; p = p->p_next) {
863*005d3febSMarek Pospisil 		cred_t	*cr;
864*005d3febSMarek Pospisil 
865*005d3febSMarek Pospisil 		/* if in non-global zone only modify processes in same zone */
866*005d3febSMarek Pospisil 		if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
867*005d3febSMarek Pospisil 			continue;
868*005d3febSMarek Pospisil 
869*005d3febSMarek Pospisil 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
870*005d3febSMarek Pospisil 
871*005d3febSMarek Pospisil 		/* skip system processes and ones being created or going away */
872*005d3febSMarek Pospisil 		if (p->p_stat == SIDL || p->p_stat == SZOMB ||
873*005d3febSMarek Pospisil 		    (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
874*005d3febSMarek Pospisil 			mutex_exit(&p->p_lock);
875*005d3febSMarek Pospisil 			continue;
876*005d3febSMarek Pospisil 		}
877*005d3febSMarek Pospisil 
878*005d3febSMarek Pospisil 		mutex_enter(&p->p_crlock);
879*005d3febSMarek Pospisil 		crhold(cr = p->p_cred);
880*005d3febSMarek Pospisil 		mutex_exit(&p->p_crlock);
881*005d3febSMarek Pospisil 		ainfo = crgetauinfo(cr);
882*005d3febSMarek Pospisil 		if (ainfo == NULL) {
883*005d3febSMarek Pospisil 			mutex_exit(&p->p_lock);
884*005d3febSMarek Pospisil 			crfree(cr);
885*005d3febSMarek Pospisil 			continue;
886*005d3febSMarek Pospisil 		}
887*005d3febSMarek Pospisil 
888*005d3febSMarek Pospisil 		if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
889*005d3febSMarek Pospisil 			au_mask_t	mask;
890*005d3febSMarek Pospisil 			int		err;
891*005d3febSMarek Pospisil 
892*005d3febSMarek Pospisil 			/*
893*005d3febSMarek Pospisil 			 * Here's a process which matches the specified auid.
894*005d3febSMarek Pospisil 			 * If its mask doesn't already match the new mask,
895*005d3febSMarek Pospisil 			 * save the new mask in the pad, to be picked up
896*005d3febSMarek Pospisil 			 * next syscall.
897*005d3febSMarek Pospisil 			 */
898*005d3febSMarek Pospisil 			mask = STRUCT_FGET(user_info, ai_mask);
899*005d3febSMarek Pospisil 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
900*005d3febSMarek Pospisil 			crfree(cr);
901*005d3febSMarek Pospisil 			if (err != 0) {
902*005d3febSMarek Pospisil 				struct p_audit_data *pad = P2A(p);
903*005d3febSMarek Pospisil 				ASSERT(pad != NULL);
904*005d3febSMarek Pospisil 
905*005d3febSMarek Pospisil 				mutex_enter(&(pad->pad_lock));
906*005d3febSMarek Pospisil 				pad->pad_flags |= PAD_SETMASK;
907*005d3febSMarek Pospisil 				pad->pad_newmask = mask;
908*005d3febSMarek Pospisil 				mutex_exit(&(pad->pad_lock));
909*005d3febSMarek Pospisil 
910*005d3febSMarek Pospisil 				/*
911*005d3febSMarek Pospisil 				 * No need to call set_proc_pre_sys(), since
912*005d3febSMarek Pospisil 				 * t_pre_sys is ALWAYS on when audit is
913*005d3febSMarek Pospisil 				 * enabled...due to syscall auditing.
914*005d3febSMarek Pospisil 				 */
915*005d3febSMarek Pospisil 			}
916*005d3febSMarek Pospisil 		} else {
917*005d3febSMarek Pospisil 			crfree(cr);
918*005d3febSMarek Pospisil 		}
919*005d3febSMarek Pospisil 		mutex_exit(&p->p_lock);
920*005d3febSMarek Pospisil 	}
921*005d3febSMarek Pospisil 	mutex_exit(&pidlock);
922*005d3febSMarek Pospisil 
923*005d3febSMarek Pospisil 	return (0);
924*005d3febSMarek Pospisil }
925*005d3febSMarek Pospisil 
926*005d3febSMarek Pospisil static int
927*005d3febSMarek Pospisil setsmask(caddr_t data)
928*005d3febSMarek Pospisil {
929*005d3febSMarek Pospisil 	STRUCT_DECL(auditinfo, user_info);
930*005d3febSMarek Pospisil 	struct proc *p;
931*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
932*005d3febSMarek Pospisil 	model_t	model;
933*005d3febSMarek Pospisil 
934*005d3febSMarek Pospisil 	/* setsmask not applicable in non-global zones without perzone policy */
935*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
936*005d3febSMarek Pospisil 		return (EINVAL);
937*005d3febSMarek Pospisil 
938*005d3febSMarek Pospisil 	model = get_udatamodel();
939*005d3febSMarek Pospisil 	STRUCT_INIT(user_info, model);
940*005d3febSMarek Pospisil 
941*005d3febSMarek Pospisil 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
942*005d3febSMarek Pospisil 		return (EFAULT);
943*005d3febSMarek Pospisil 
944*005d3febSMarek Pospisil 	mutex_enter(&pidlock);	/* lock the process queue against updates */
945*005d3febSMarek Pospisil 	for (p = practive; p != NULL; p = p->p_next) {
946*005d3febSMarek Pospisil 		cred_t	*cr;
947*005d3febSMarek Pospisil 
948*005d3febSMarek Pospisil 		/* if in non-global zone only modify processes in same zone */
949*005d3febSMarek Pospisil 		if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
950*005d3febSMarek Pospisil 			continue;
951*005d3febSMarek Pospisil 
952*005d3febSMarek Pospisil 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
953*005d3febSMarek Pospisil 
954*005d3febSMarek Pospisil 		/* skip system processes and ones being created or going away */
955*005d3febSMarek Pospisil 		if (p->p_stat == SIDL || p->p_stat == SZOMB ||
956*005d3febSMarek Pospisil 		    (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
957*005d3febSMarek Pospisil 			mutex_exit(&p->p_lock);
958*005d3febSMarek Pospisil 			continue;
959*005d3febSMarek Pospisil 		}
960*005d3febSMarek Pospisil 
961*005d3febSMarek Pospisil 		mutex_enter(&p->p_crlock);
962*005d3febSMarek Pospisil 		crhold(cr = p->p_cred);
963*005d3febSMarek Pospisil 		mutex_exit(&p->p_crlock);
964*005d3febSMarek Pospisil 		ainfo = crgetauinfo(cr);
965*005d3febSMarek Pospisil 		if (ainfo == NULL) {
966*005d3febSMarek Pospisil 			mutex_exit(&p->p_lock);
967*005d3febSMarek Pospisil 			crfree(cr);
968*005d3febSMarek Pospisil 			continue;
969*005d3febSMarek Pospisil 		}
970*005d3febSMarek Pospisil 
971*005d3febSMarek Pospisil 		if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
972*005d3febSMarek Pospisil 			au_mask_t	mask;
973*005d3febSMarek Pospisil 			int		err;
974*005d3febSMarek Pospisil 
975*005d3febSMarek Pospisil 			/*
976*005d3febSMarek Pospisil 			 * Here's a process which matches the specified asid.
977*005d3febSMarek Pospisil 			 * If its mask doesn't already match the new mask,
978*005d3febSMarek Pospisil 			 * save the new mask in the pad, to be picked up
979*005d3febSMarek Pospisil 			 * next syscall.
980*005d3febSMarek Pospisil 			 */
981*005d3febSMarek Pospisil 			mask = STRUCT_FGET(user_info, ai_mask);
982*005d3febSMarek Pospisil 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
983*005d3febSMarek Pospisil 			crfree(cr);
984*005d3febSMarek Pospisil 			if (err != 0) {
985*005d3febSMarek Pospisil 				struct p_audit_data *pad = P2A(p);
986*005d3febSMarek Pospisil 				ASSERT(pad != NULL);
987*005d3febSMarek Pospisil 
988*005d3febSMarek Pospisil 				mutex_enter(&(pad->pad_lock));
989*005d3febSMarek Pospisil 				pad->pad_flags |= PAD_SETMASK;
990*005d3febSMarek Pospisil 				pad->pad_newmask = mask;
991*005d3febSMarek Pospisil 				mutex_exit(&(pad->pad_lock));
992*005d3febSMarek Pospisil 
993*005d3febSMarek Pospisil 				/*
994*005d3febSMarek Pospisil 				 * No need to call set_proc_pre_sys(), since
995*005d3febSMarek Pospisil 				 * t_pre_sys is ALWAYS on when audit is
996*005d3febSMarek Pospisil 				 * enabled...due to syscall auditing.
997*005d3febSMarek Pospisil 				 */
998*005d3febSMarek Pospisil 			}
999*005d3febSMarek Pospisil 		} else {
1000*005d3febSMarek Pospisil 			crfree(cr);
1001*005d3febSMarek Pospisil 		}
1002*005d3febSMarek Pospisil 		mutex_exit(&p->p_lock);
1003*005d3febSMarek Pospisil 	}
1004*005d3febSMarek Pospisil 	mutex_exit(&pidlock);
1005*005d3febSMarek Pospisil 
1006*005d3febSMarek Pospisil 	return (0);
1007*005d3febSMarek Pospisil }
1008*005d3febSMarek Pospisil 
1009*005d3febSMarek Pospisil /*
1010*005d3febSMarek Pospisil  * Get the current audit state of the system
1011*005d3febSMarek Pospisil  */
1012*005d3febSMarek Pospisil static int
1013*005d3febSMarek Pospisil getcond(caddr_t data)
1014*005d3febSMarek Pospisil {
1015*005d3febSMarek Pospisil 	au_kcontext_t *kctx = GET_KCTX_PZ;
1016*005d3febSMarek Pospisil 
1017*005d3febSMarek Pospisil 	if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
1018*005d3febSMarek Pospisil 		return (EFAULT);
1019*005d3febSMarek Pospisil 
1020*005d3febSMarek Pospisil 	return (0);
1021*005d3febSMarek Pospisil }
1022*005d3febSMarek Pospisil 
1023*005d3febSMarek Pospisil /*
1024*005d3febSMarek Pospisil  * Set the current audit state of the system to on (AUC_AUDITING) or
1025*005d3febSMarek Pospisil  * off (AUC_NOAUDIT).
1026*005d3febSMarek Pospisil  */
1027*005d3febSMarek Pospisil /* ARGSUSED */
1028*005d3febSMarek Pospisil static int
1029*005d3febSMarek Pospisil setcond(caddr_t data)
1030*005d3febSMarek Pospisil {
1031*005d3febSMarek Pospisil 	int auditstate;
1032*005d3febSMarek Pospisil 	au_kcontext_t *kctx;
1033*005d3febSMarek Pospisil 
1034*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
1035*005d3febSMarek Pospisil 		return (EINVAL);
1036*005d3febSMarek Pospisil 
1037*005d3febSMarek Pospisil 	kctx = GET_KCTX_NGZ;
1038*005d3febSMarek Pospisil 
1039*005d3febSMarek Pospisil 	if (copyin(data, &auditstate, sizeof (int)))
1040*005d3febSMarek Pospisil 		return (EFAULT);
1041*005d3febSMarek Pospisil 
1042*005d3febSMarek Pospisil 	switch (auditstate) {
1043*005d3febSMarek Pospisil 	case AUC_AUDITING:		/* Turn auditing on */
1044*005d3febSMarek Pospisil 		if (audit_active == C2AUDIT_UNLOADED)
1045*005d3febSMarek Pospisil 			audit_init_module();
1046*005d3febSMarek Pospisil 		kctx->auk_auditstate = AUC_AUDITING;
1047*005d3febSMarek Pospisil 		if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc))
1048*005d3febSMarek Pospisil 			set_all_zone_usr_proc_sys(ALL_ZONES);
1049*005d3febSMarek Pospisil 		else
1050*005d3febSMarek Pospisil 			set_all_zone_usr_proc_sys(curproc->p_zone->zone_id);
1051*005d3febSMarek Pospisil 		break;
1052*005d3febSMarek Pospisil 
1053*005d3febSMarek Pospisil 	case AUC_NOAUDIT:		/* Turn auditing off */
1054*005d3febSMarek Pospisil 		if (kctx->auk_auditstate == AUC_NOAUDIT)
1055*005d3febSMarek Pospisil 			break;
1056*005d3febSMarek Pospisil 		kctx->auk_auditstate = AUC_NOAUDIT;
1057*005d3febSMarek Pospisil 
1058*005d3febSMarek Pospisil 		/* clear out the audit queue */
1059*005d3febSMarek Pospisil 
1060*005d3febSMarek Pospisil 		mutex_enter(&(kctx->auk_queue.lock));
1061*005d3febSMarek Pospisil 		if (kctx->auk_queue.wt_block)
1062*005d3febSMarek Pospisil 			cv_broadcast(&(kctx->auk_queue.write_cv));
1063*005d3febSMarek Pospisil 
1064*005d3febSMarek Pospisil 		/* unblock au_output_thread */
1065*005d3febSMarek Pospisil 		cv_broadcast(&(kctx->auk_queue.read_cv));
1066*005d3febSMarek Pospisil 
1067*005d3febSMarek Pospisil 		mutex_exit(&(kctx->auk_queue.lock));
1068*005d3febSMarek Pospisil 		break;
1069*005d3febSMarek Pospisil 
1070*005d3febSMarek Pospisil 	default:
1071*005d3febSMarek Pospisil 		return (EINVAL);
1072*005d3febSMarek Pospisil 	}
1073*005d3febSMarek Pospisil 
1074*005d3febSMarek Pospisil 	return (0);
1075*005d3febSMarek Pospisil }
1076*005d3febSMarek Pospisil 
1077*005d3febSMarek Pospisil static int
1078*005d3febSMarek Pospisil getclass(caddr_t data)
1079*005d3febSMarek Pospisil {
1080*005d3febSMarek Pospisil 	au_evclass_map_t event;
1081*005d3febSMarek Pospisil 	au_kcontext_t	*kctx = GET_KCTX_PZ;
1082*005d3febSMarek Pospisil 
1083*005d3febSMarek Pospisil 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1084*005d3febSMarek Pospisil 		return (EFAULT);
1085*005d3febSMarek Pospisil 
1086*005d3febSMarek Pospisil 	if (event.ec_number > MAX_KEVENTS)
1087*005d3febSMarek Pospisil 		return (EINVAL);
1088*005d3febSMarek Pospisil 
1089*005d3febSMarek Pospisil 	event.ec_class = kctx->auk_ets[event.ec_number];
1090*005d3febSMarek Pospisil 
1091*005d3febSMarek Pospisil 	if (copyout(&event, data, sizeof (au_evclass_map_t)))
1092*005d3febSMarek Pospisil 		return (EFAULT);
1093*005d3febSMarek Pospisil 
1094*005d3febSMarek Pospisil 	return (0);
1095*005d3febSMarek Pospisil }
1096*005d3febSMarek Pospisil 
1097*005d3febSMarek Pospisil static int
1098*005d3febSMarek Pospisil setclass(caddr_t data)
1099*005d3febSMarek Pospisil {
1100*005d3febSMarek Pospisil 	au_evclass_map_t event;
1101*005d3febSMarek Pospisil 	au_kcontext_t	*kctx;
1102*005d3febSMarek Pospisil 
1103*005d3febSMarek Pospisil 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1104*005d3febSMarek Pospisil 		return (EINVAL);
1105*005d3febSMarek Pospisil 
1106*005d3febSMarek Pospisil 	kctx = GET_KCTX_NGZ;
1107*005d3febSMarek Pospisil 
1108*005d3febSMarek Pospisil 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1109*005d3febSMarek Pospisil 		return (EFAULT);
1110*005d3febSMarek Pospisil 
1111*005d3febSMarek Pospisil 	if (event.ec_number > MAX_KEVENTS)
1112*005d3febSMarek Pospisil 		return (EINVAL);
1113*005d3febSMarek Pospisil 
1114*005d3febSMarek Pospisil 	kctx->auk_ets[event.ec_number] = event.ec_class;
1115*005d3febSMarek Pospisil 
1116*005d3febSMarek Pospisil 	return (0);
1117*005d3febSMarek Pospisil }
1118*005d3febSMarek Pospisil 
1119*005d3febSMarek Pospisil static int
1120*005d3febSMarek Pospisil getpinfo(caddr_t data)
1121*005d3febSMarek Pospisil {
1122*005d3febSMarek Pospisil 	STRUCT_DECL(auditpinfo, apinfo);
1123*005d3febSMarek Pospisil 	proc_t *proc;
1124*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
1125*005d3febSMarek Pospisil 	model_t	model;
1126*005d3febSMarek Pospisil 	cred_t	*cr, *newcred;
1127*005d3febSMarek Pospisil 
1128*005d3febSMarek Pospisil 	model = get_udatamodel();
1129*005d3febSMarek Pospisil 	STRUCT_INIT(apinfo, model);
1130*005d3febSMarek Pospisil 
1131*005d3febSMarek Pospisil 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1132*005d3febSMarek Pospisil 		return (EFAULT);
1133*005d3febSMarek Pospisil 
1134*005d3febSMarek Pospisil 	newcred = cralloc();
1135*005d3febSMarek Pospisil 
1136*005d3febSMarek Pospisil 	mutex_enter(&pidlock);
1137*005d3febSMarek Pospisil 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1138*005d3febSMarek Pospisil 		mutex_exit(&pidlock);
1139*005d3febSMarek Pospisil 		crfree(newcred);
1140*005d3febSMarek Pospisil 		return (ESRCH);		/* no such process */
1141*005d3febSMarek Pospisil 	}
1142*005d3febSMarek Pospisil 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1143*005d3febSMarek Pospisil 	mutex_exit(&pidlock);
1144*005d3febSMarek Pospisil 
1145*005d3febSMarek Pospisil 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1146*005d3febSMarek Pospisil 
1147*005d3febSMarek Pospisil 	mutex_enter(&proc->p_crlock);
1148*005d3febSMarek Pospisil 	crhold(cr = proc->p_cred);
1149*005d3febSMarek Pospisil 	mutex_exit(&proc->p_crlock);
1150*005d3febSMarek Pospisil 	mutex_exit(&proc->p_lock);
1151*005d3febSMarek Pospisil 
1152*005d3febSMarek Pospisil 	ainfo = crgetauinfo(cr);
1153*005d3febSMarek Pospisil 	if (ainfo == NULL) {
1154*005d3febSMarek Pospisil 		crfree(cr);
1155*005d3febSMarek Pospisil 		return (EINVAL);
1156*005d3febSMarek Pospisil 	}
1157*005d3febSMarek Pospisil 
1158*005d3febSMarek Pospisil 	/* designated process has an ipv6 address? */
1159*005d3febSMarek Pospisil 	if (ainfo->ai_termid.at_type == AU_IPv6) {
1160*005d3febSMarek Pospisil 		crfree(cr);
1161*005d3febSMarek Pospisil 		return (EOVERFLOW);
1162*005d3febSMarek Pospisil 	}
1163*005d3febSMarek Pospisil 
1164*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1165*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1166*005d3febSMarek Pospisil #ifdef _LP64
1167*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32) {
1168*005d3febSMarek Pospisil 		dev32_t dev;
1169*005d3febSMarek Pospisil 		/* convert internal 64 bit form to 32 bit version */
1170*005d3febSMarek Pospisil 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1171*005d3febSMarek Pospisil 			crfree(cr);
1172*005d3febSMarek Pospisil 			return (EOVERFLOW);
1173*005d3febSMarek Pospisil 		}
1174*005d3febSMarek Pospisil 		STRUCT_FSET(apinfo, ap_termid.port, dev);
1175*005d3febSMarek Pospisil 	} else
1176*005d3febSMarek Pospisil 		STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1177*005d3febSMarek Pospisil #else
1178*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1179*005d3febSMarek Pospisil #endif
1180*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
1181*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1182*005d3febSMarek Pospisil 
1183*005d3febSMarek Pospisil 	crfree(cr);
1184*005d3febSMarek Pospisil 
1185*005d3febSMarek Pospisil 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1186*005d3febSMarek Pospisil 		return (EFAULT);
1187*005d3febSMarek Pospisil 
1188*005d3febSMarek Pospisil 	return (0);
1189*005d3febSMarek Pospisil }
1190*005d3febSMarek Pospisil 
1191*005d3febSMarek Pospisil static int
1192*005d3febSMarek Pospisil getpinfo_addr(caddr_t data, int len)
1193*005d3febSMarek Pospisil {
1194*005d3febSMarek Pospisil 	STRUCT_DECL(auditpinfo_addr, apinfo);
1195*005d3febSMarek Pospisil 	proc_t *proc;
1196*005d3febSMarek Pospisil 	const auditinfo_addr_t	*ainfo;
1197*005d3febSMarek Pospisil 	model_t	model;
1198*005d3febSMarek Pospisil 	cred_t	*cr, *newcred;
1199*005d3febSMarek Pospisil 
1200*005d3febSMarek Pospisil 	model = get_udatamodel();
1201*005d3febSMarek Pospisil 	STRUCT_INIT(apinfo, model);
1202*005d3febSMarek Pospisil 
1203*005d3febSMarek Pospisil 	if (len < STRUCT_SIZE(apinfo))
1204*005d3febSMarek Pospisil 		return (EOVERFLOW);
1205*005d3febSMarek Pospisil 
1206*005d3febSMarek Pospisil 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1207*005d3febSMarek Pospisil 		return (EFAULT);
1208*005d3febSMarek Pospisil 
1209*005d3febSMarek Pospisil 	newcred = cralloc();
1210*005d3febSMarek Pospisil 
1211*005d3febSMarek Pospisil 	mutex_enter(&pidlock);
1212*005d3febSMarek Pospisil 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1213*005d3febSMarek Pospisil 		mutex_exit(&pidlock);
1214*005d3febSMarek Pospisil 		crfree(newcred);
1215*005d3febSMarek Pospisil 		return (ESRCH);
1216*005d3febSMarek Pospisil 	}
1217*005d3febSMarek Pospisil 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1218*005d3febSMarek Pospisil 	mutex_exit(&pidlock);
1219*005d3febSMarek Pospisil 
1220*005d3febSMarek Pospisil 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1221*005d3febSMarek Pospisil 
1222*005d3febSMarek Pospisil 	mutex_enter(&proc->p_crlock);
1223*005d3febSMarek Pospisil 	crhold(cr = proc->p_cred);
1224*005d3febSMarek Pospisil 	mutex_exit(&proc->p_crlock);
1225*005d3febSMarek Pospisil 	mutex_exit(&proc->p_lock);
1226*005d3febSMarek Pospisil 
1227*005d3febSMarek Pospisil 	ainfo = crgetauinfo(cr);
1228*005d3febSMarek Pospisil 	if (ainfo == NULL) {
1229*005d3febSMarek Pospisil 		crfree(cr);
1230*005d3febSMarek Pospisil 		return (EINVAL);
1231*005d3febSMarek Pospisil 	}
1232*005d3febSMarek Pospisil 
1233*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1234*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1235*005d3febSMarek Pospisil #ifdef _LP64
1236*005d3febSMarek Pospisil 	if (model == DATAMODEL_ILP32) {
1237*005d3febSMarek Pospisil 		dev32_t dev;
1238*005d3febSMarek Pospisil 		/* convert internal 64 bit form to 32 bit version */
1239*005d3febSMarek Pospisil 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1240*005d3febSMarek Pospisil 			crfree(cr);
1241*005d3febSMarek Pospisil 			return (EOVERFLOW);
1242*005d3febSMarek Pospisil 		}
1243*005d3febSMarek Pospisil 		STRUCT_FSET(apinfo, ap_termid.at_port, dev);
1244*005d3febSMarek Pospisil 	} else
1245*005d3febSMarek Pospisil 		STRUCT_FSET(apinfo, ap_termid.at_port,
1246*005d3febSMarek Pospisil 		    ainfo->ai_termid.at_port);
1247*005d3febSMarek Pospisil #else
1248*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
1249*005d3febSMarek Pospisil #endif
1250*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
1251*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
1252*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
1253*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
1254*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
1255*005d3febSMarek Pospisil 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1256*005d3febSMarek Pospisil 
1257*005d3febSMarek Pospisil 	crfree(cr);
1258*005d3febSMarek Pospisil 
1259*005d3febSMarek Pospisil 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1260*005d3febSMarek Pospisil 		return (EFAULT);
1261*005d3febSMarek Pospisil 
1262*005d3febSMarek Pospisil 	return (0);
1263*005d3febSMarek Pospisil }
1264*005d3febSMarek Pospisil 
1265*005d3febSMarek Pospisil static int
1266*005d3febSMarek Pospisil setpmask(caddr_t data)
1267*005d3febSMarek Pospisil {
1268*005d3febSMarek Pospisil 	STRUCT_DECL(auditpinfo, apinfo);
1269*005d3febSMarek Pospisil 	proc_t *proc;
1270*005d3febSMarek Pospisil 	cred_t	*newcred;
1271*005d3febSMarek Pospisil 	auditinfo_addr_t	*ainfo;
1272*005d3febSMarek Pospisil 	struct p_audit_data	*pad;
1273*005d3febSMarek Pospisil 
1274*005d3febSMarek Pospisil 	model_t	model;
1275*005d3febSMarek Pospisil 
1276*005d3febSMarek Pospisil 	model = get_udatamodel();
1277*005d3febSMarek Pospisil 	STRUCT_INIT(apinfo, model);
1278*005d3febSMarek Pospisil 
1279*005d3febSMarek Pospisil 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1280*005d3febSMarek Pospisil 		return (EFAULT);
1281*005d3febSMarek Pospisil 
1282*005d3febSMarek Pospisil 	mutex_enter(&pidlock);
1283*005d3febSMarek Pospisil 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1284*005d3febSMarek Pospisil 		mutex_exit(&pidlock);
1285*005d3febSMarek Pospisil 		return (ESRCH);
1286*005d3febSMarek Pospisil 	}
1287*005d3febSMarek Pospisil 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1288*005d3febSMarek Pospisil 	mutex_exit(&pidlock);
1289*005d3febSMarek Pospisil 
1290*005d3febSMarek Pospisil 	newcred = cralloc();
1291*005d3febSMarek Pospisil 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
1292*005d3febSMarek Pospisil 		mutex_exit(&proc->p_lock);
1293*005d3febSMarek Pospisil 		crfree(newcred);
1294*005d3febSMarek Pospisil 		return (EINVAL);
1295*005d3febSMarek Pospisil 	}
1296*005d3febSMarek Pospisil 
1297*005d3febSMarek Pospisil 	mutex_enter(&proc->p_crlock);
1298*005d3febSMarek Pospisil 	crcopy_to(proc->p_cred, newcred);
1299*005d3febSMarek Pospisil 	proc->p_cred = newcred;
1300*005d3febSMarek Pospisil 
1301*005d3febSMarek Pospisil 	ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
1302*005d3febSMarek Pospisil 
1303*005d3febSMarek Pospisil 	/*
1304*005d3febSMarek Pospisil 	 * Unlock. No need to broadcast changes via set_proc_pre_sys(),
1305*005d3febSMarek Pospisil 	 * since t_pre_sys is ALWAYS on when audit is enabled... due to
1306*005d3febSMarek Pospisil 	 * syscall auditing.
1307*005d3febSMarek Pospisil 	 */
1308*005d3febSMarek Pospisil 	crfree(newcred);
1309*005d3febSMarek Pospisil 	mutex_exit(&proc->p_crlock);
1310*005d3febSMarek Pospisil 
1311*005d3febSMarek Pospisil 	/* Reset flag for any previous pending mask change; this supercedes */
1312*005d3febSMarek Pospisil 	pad = P2A(proc);
1313*005d3febSMarek Pospisil 	ASSERT(pad != NULL);
1314*005d3febSMarek Pospisil 	mutex_enter(&(pad->pad_lock));
1315*005d3febSMarek Pospisil 	pad->pad_flags &= ~PAD_SETMASK;
1316*005d3febSMarek Pospisil 	mutex_exit(&(pad->pad_lock));
1317*005d3febSMarek Pospisil 
1318*005d3febSMarek Pospisil 	mutex_exit(&proc->p_lock);
1319*005d3febSMarek Pospisil 
1320*005d3febSMarek Pospisil 	return (0);
1321*005d3febSMarek Pospisil }
1322*005d3febSMarek Pospisil 
1323*005d3febSMarek Pospisil /*
1324*005d3febSMarek Pospisil  * The out of control system call
1325*005d3febSMarek Pospisil  * This is audit kitchen sink aka auditadm, aka auditon
1326*005d3febSMarek Pospisil  */
1327*005d3febSMarek Pospisil int
1328*005d3febSMarek Pospisil auditctl(
1329*005d3febSMarek Pospisil 	int	cmd,
1330*005d3febSMarek Pospisil 	caddr_t data,
1331*005d3febSMarek Pospisil 	int	length)
1332*005d3febSMarek Pospisil {
1333*005d3febSMarek Pospisil 	int result;
1334*005d3febSMarek Pospisil 
1335*005d3febSMarek Pospisil 	switch (cmd) {
1336*005d3febSMarek Pospisil 	case A_GETCOND:
1337*005d3febSMarek Pospisil 	case A_GETCAR:
1338*005d3febSMarek Pospisil 	case A_GETCLASS:
1339*005d3febSMarek Pospisil 	case A_GETCWD:
1340*005d3febSMarek Pospisil 	case A_GETKAUDIT:
1341*005d3febSMarek Pospisil 	case A_GETKMASK:
1342*005d3febSMarek Pospisil 	case A_GETPINFO:
1343*005d3febSMarek Pospisil 	case A_GETPINFO_ADDR:
1344*005d3febSMarek Pospisil 	case A_GETPOLICY:
1345*005d3febSMarek Pospisil 	case A_GETQCTRL:
1346*005d3febSMarek Pospisil 	case A_GETSTAT:
1347*005d3febSMarek Pospisil 		if (secpolicy_audit_getattr(CRED()) != 0)
1348*005d3febSMarek Pospisil 			return (EPERM);
1349*005d3febSMarek Pospisil 		break;
1350*005d3febSMarek Pospisil 	default:
1351*005d3febSMarek Pospisil 		if (secpolicy_audit_config(CRED()) != 0)
1352*005d3febSMarek Pospisil 			return (EPERM);
1353*005d3febSMarek Pospisil 		break;
1354*005d3febSMarek Pospisil 	}
1355*005d3febSMarek Pospisil 
1356*005d3febSMarek Pospisil 	switch (cmd) {
1357*005d3febSMarek Pospisil 	case A_GETPOLICY:
1358*005d3febSMarek Pospisil 		result = getpolicy(data);
1359*005d3febSMarek Pospisil 		break;
1360*005d3febSMarek Pospisil 	case A_SETPOLICY:
1361*005d3febSMarek Pospisil 		result = setpolicy(data);
1362*005d3febSMarek Pospisil 		break;
1363*005d3febSMarek Pospisil 	case A_GETKMASK:
1364*005d3febSMarek Pospisil 		result = getkmask(data);
1365*005d3febSMarek Pospisil 		break;
1366*005d3febSMarek Pospisil 	case A_SETKMASK:
1367*005d3febSMarek Pospisil 		result = setkmask(data);
1368*005d3febSMarek Pospisil 		break;
1369*005d3febSMarek Pospisil 	case A_GETKAUDIT:
1370*005d3febSMarek Pospisil 		result = getkaudit(data, length);
1371*005d3febSMarek Pospisil 		break;
1372*005d3febSMarek Pospisil 	case A_SETKAUDIT:
1373*005d3febSMarek Pospisil 		result = setkaudit(data, length);
1374*005d3febSMarek Pospisil 		break;
1375*005d3febSMarek Pospisil 	case A_GETQCTRL:
1376*005d3febSMarek Pospisil 		result = getqctrl(data);
1377*005d3febSMarek Pospisil 		break;
1378*005d3febSMarek Pospisil 	case A_SETQCTRL:
1379*005d3febSMarek Pospisil 		result = setqctrl(data);
1380*005d3febSMarek Pospisil 		break;
1381*005d3febSMarek Pospisil 	case A_GETCWD:
1382*005d3febSMarek Pospisil 		result = getcwd(data, length);
1383*005d3febSMarek Pospisil 		break;
1384*005d3febSMarek Pospisil 	case A_GETCAR:
1385*005d3febSMarek Pospisil 		result = getcar(data, length);
1386*005d3febSMarek Pospisil 		break;
1387*005d3febSMarek Pospisil 	case A_GETSTAT:
1388*005d3febSMarek Pospisil 		result = getstat(data);
1389*005d3febSMarek Pospisil 		break;
1390*005d3febSMarek Pospisil 	case A_SETSTAT:
1391*005d3febSMarek Pospisil 		result = setstat(data);
1392*005d3febSMarek Pospisil 		break;
1393*005d3febSMarek Pospisil 	case A_SETUMASK:
1394*005d3febSMarek Pospisil 		result = setumask(data);
1395*005d3febSMarek Pospisil 		break;
1396*005d3febSMarek Pospisil 	case A_SETSMASK:
1397*005d3febSMarek Pospisil 		result = setsmask(data);
1398*005d3febSMarek Pospisil 		break;
1399*005d3febSMarek Pospisil 	case A_GETCOND:
1400*005d3febSMarek Pospisil 		result = getcond(data);
1401*005d3febSMarek Pospisil 		break;
1402*005d3febSMarek Pospisil 	case A_SETCOND:
1403*005d3febSMarek Pospisil 		result = setcond(data);
1404*005d3febSMarek Pospisil 		break;
1405*005d3febSMarek Pospisil 	case A_GETCLASS:
1406*005d3febSMarek Pospisil 		result = getclass(data);
1407*005d3febSMarek Pospisil 		break;
1408*005d3febSMarek Pospisil 	case A_SETCLASS:
1409*005d3febSMarek Pospisil 		result = setclass(data);
1410*005d3febSMarek Pospisil 		break;
1411*005d3febSMarek Pospisil 	case A_GETPINFO:
1412*005d3febSMarek Pospisil 		result = getpinfo(data);
1413*005d3febSMarek Pospisil 		break;
1414*005d3febSMarek Pospisil 	case A_GETPINFO_ADDR:
1415*005d3febSMarek Pospisil 		result = getpinfo_addr(data, length);
1416*005d3febSMarek Pospisil 		break;
1417*005d3febSMarek Pospisil 	case A_SETPMASK:
1418*005d3febSMarek Pospisil 		result = setpmask(data);
1419*005d3febSMarek Pospisil 		break;
1420*005d3febSMarek Pospisil 	default:
1421*005d3febSMarek Pospisil 		result = EINVAL;
1422*005d3febSMarek Pospisil 		break;
1423*005d3febSMarek Pospisil 	}
1424*005d3febSMarek Pospisil 	return (result);
14257c478bd9Sstevel@tonic-gate }
1426