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