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