xref: /illumos-gate/usr/src/uts/common/syscall/auditsys.c (revision 8a2b682e57a046b828f37bcde1776f131ef4629f)
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 		/* FALLTHROUGH */
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(), B_FALSE) != 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(), B_FALSE) != 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(), B_FALSE) != 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 getamask(caddr_t data)
493 {
494 	au_kcontext_t	*kctx;
495 
496 	kctx = GET_KCTX_PZ;
497 
498 	if (copyout(&kctx->auk_info.ai_amask, data, sizeof (au_mask_t)))
499 		return (EFAULT);
500 
501 	return (0);
502 }
503 
504 static int
505 setamask(caddr_t data)
506 {
507 	au_mask_t	mask;
508 	au_kcontext_t	*kctx;
509 
510 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
511 		return (EINVAL);
512 
513 	kctx = GET_KCTX_NGZ;
514 
515 	if (copyin(data, &mask, sizeof (au_mask_t)))
516 		return (EFAULT);
517 
518 	kctx->auk_info.ai_amask = mask;
519 	return (0);
520 }
521 
522 static int
523 getkmask(caddr_t data)
524 {
525 	au_kcontext_t	*kctx;
526 
527 	kctx = GET_KCTX_PZ;
528 
529 	if (copyout(&kctx->auk_info.ai_namask, data, sizeof (au_mask_t)))
530 		return (EFAULT);
531 	return (0);
532 }
533 
534 static int
535 setkmask(caddr_t data)
536 {
537 	au_mask_t	mask;
538 	au_kcontext_t	*kctx;
539 
540 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
541 		return (EINVAL);
542 
543 	kctx = GET_KCTX_NGZ;
544 
545 	if (copyin(data, &mask, sizeof (au_mask_t)))
546 		return (EFAULT);
547 
548 	kctx->auk_info.ai_namask = mask;
549 	return (0);
550 }
551 
552 static int
553 getkaudit(caddr_t info_p, int len)
554 {
555 	STRUCT_DECL(auditinfo_addr, info);
556 	model_t model;
557 	au_kcontext_t	*kctx = GET_KCTX_PZ;
558 
559 	model = get_udatamodel();
560 	STRUCT_INIT(info, model);
561 
562 	if (len < STRUCT_SIZE(info))
563 		return (EOVERFLOW);
564 
565 	STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
566 	STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_namask);
567 #ifdef _LP64
568 	if (model == DATAMODEL_ILP32) {
569 		dev32_t dev;
570 		/* convert internal 64 bit form to 32 bit version */
571 		if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
572 			return (EOVERFLOW);
573 		}
574 		STRUCT_FSET(info, ai_termid.at_port, dev);
575 	} else {
576 		STRUCT_FSET(info, ai_termid.at_port,
577 		    kctx->auk_info.ai_termid.at_port);
578 	}
579 #else
580 	STRUCT_FSET(info, ai_termid.at_port,
581 	    kctx->auk_info.ai_termid.at_port);
582 #endif
583 	STRUCT_FSET(info, ai_termid.at_type,
584 	    kctx->auk_info.ai_termid.at_type);
585 	STRUCT_FSET(info, ai_termid.at_addr[0],
586 	    kctx->auk_info.ai_termid.at_addr[0]);
587 	STRUCT_FSET(info, ai_termid.at_addr[1],
588 	    kctx->auk_info.ai_termid.at_addr[1]);
589 	STRUCT_FSET(info, ai_termid.at_addr[2],
590 	    kctx->auk_info.ai_termid.at_addr[2]);
591 	STRUCT_FSET(info, ai_termid.at_addr[3],
592 	    kctx->auk_info.ai_termid.at_addr[3]);
593 	STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
594 
595 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
596 		return (EFAULT);
597 
598 	return (0);
599 }
600 
601 /*
602  * the host address for AUDIT_PERZONE == 0 is that of the global
603  * zone and for local zones it is of the current zone.
604  */
605 static int
606 setkaudit(caddr_t info_p, int len)
607 {
608 	STRUCT_DECL(auditinfo_addr, info);
609 	model_t model;
610 	au_kcontext_t	*kctx;
611 
612 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
613 		return (EINVAL);
614 
615 	kctx = GET_KCTX_NGZ;
616 
617 	model = get_udatamodel();
618 	STRUCT_INIT(info, model);
619 
620 	if (len < STRUCT_SIZE(info))
621 		return (EOVERFLOW);
622 
623 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
624 		return (EFAULT);
625 
626 	if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
627 	    (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
628 		return (EINVAL);
629 
630 	/* Set audit mask, termid and session id as specified */
631 	kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
632 	kctx->auk_info.ai_namask = STRUCT_FGET(info, ai_mask);
633 #ifdef _LP64
634 	/* only convert to 64 bit if coming from a 32 bit binary */
635 	if (model == DATAMODEL_ILP32)
636 		kctx->auk_info.ai_termid.at_port =
637 		    DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
638 	else
639 		kctx->auk_info.ai_termid.at_port =
640 		    STRUCT_FGET(info, ai_termid.at_port);
641 #else
642 	kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
643 #endif
644 	kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
645 	bzero(&kctx->auk_info.ai_termid.at_addr[0],
646 	    sizeof (kctx->auk_info.ai_termid.at_addr));
647 	kctx->auk_info.ai_termid.at_addr[0] =
648 	    STRUCT_FGET(info, ai_termid.at_addr[0]);
649 	kctx->auk_info.ai_termid.at_addr[1] =
650 	    STRUCT_FGET(info, ai_termid.at_addr[1]);
651 	kctx->auk_info.ai_termid.at_addr[2] =
652 	    STRUCT_FGET(info, ai_termid.at_addr[2]);
653 	kctx->auk_info.ai_termid.at_addr[3] =
654 	    STRUCT_FGET(info, ai_termid.at_addr[3]);
655 	kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
656 
657 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
658 	    IN6_IS_ADDR_V4MAPPED(
659 	    ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
660 		kctx->auk_info.ai_termid.at_type = AU_IPv4;
661 		kctx->auk_info.ai_termid.at_addr[0] =
662 		    kctx->auk_info.ai_termid.at_addr[3];
663 		kctx->auk_info.ai_termid.at_addr[1] = 0;
664 		kctx->auk_info.ai_termid.at_addr[2] = 0;
665 		kctx->auk_info.ai_termid.at_addr[3] = 0;
666 	}
667 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
668 		kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
669 		    (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
670 	else
671 		kctx->auk_hostaddr_valid =
672 		    (kctx->auk_info.ai_termid.at_addr[0] ==
673 		    htonl(INADDR_ANY)) ? 0 : 1;
674 
675 	return (0);
676 }
677 
678 static int
679 getqctrl(caddr_t data)
680 {
681 	au_kcontext_t	*kctx = GET_KCTX_PZ;
682 	STRUCT_DECL(au_qctrl, qctrl);
683 	STRUCT_INIT(qctrl, get_udatamodel());
684 
685 	mutex_enter(&(kctx->auk_queue.lock));
686 	STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
687 	STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
688 	STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
689 	STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
690 	mutex_exit(&(kctx->auk_queue.lock));
691 
692 	if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
693 		return (EFAULT);
694 
695 	return (0);
696 }
697 
698 static int
699 setqctrl(caddr_t data)
700 {
701 	au_kcontext_t	*kctx;
702 	struct au_qctrl qctrl_tmp;
703 	STRUCT_DECL(au_qctrl, qctrl);
704 	STRUCT_INIT(qctrl, get_udatamodel());
705 
706 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
707 		return (EINVAL);
708 	kctx = GET_KCTX_NGZ;
709 
710 	if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
711 		return (EFAULT);
712 
713 	qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
714 	qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
715 	qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
716 	qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
717 
718 	/* enforce sane values */
719 
720 	if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
721 		return (EINVAL);
722 
723 	if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
724 		return (EINVAL);
725 
726 	if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
727 		return (EINVAL);
728 
729 	if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
730 		return (EINVAL);
731 
732 	if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
733 		return (EINVAL);
734 
735 	if (qctrl_tmp.aq_delay == 0)
736 		return (EINVAL);
737 
738 	if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
739 		return (EINVAL);
740 
741 	/* update everything at once so things are consistant */
742 	mutex_enter(&(kctx->auk_queue.lock));
743 	kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
744 	kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
745 	kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
746 	kctx->auk_queue.delay = qctrl_tmp.aq_delay;
747 
748 	if (kctx->auk_queue.rd_block &&
749 	    kctx->auk_queue.cnt > kctx->auk_queue.lowater)
750 		cv_broadcast(&(kctx->auk_queue.read_cv));
751 
752 	if (kctx->auk_queue.wt_block &&
753 	    kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
754 		cv_broadcast(&(kctx->auk_queue.write_cv));
755 
756 	mutex_exit(&(kctx->auk_queue.lock));
757 
758 	return (0);
759 }
760 
761 static int
762 getcwd(caddr_t data, int length)
763 {
764 	struct p_audit_data	*pad;
765 	struct audit_path	*app;
766 	int	pathlen;
767 
768 	pad = P2A(curproc);
769 	ASSERT(pad != NULL);
770 
771 	mutex_enter(&(pad->pad_lock));
772 	app = pad->pad_cwd;
773 	au_pathhold(app);
774 	mutex_exit(&(pad->pad_lock));
775 
776 	pathlen = app->audp_sect[1] - app->audp_sect[0];
777 	if (pathlen > length) {
778 		au_pathrele(app);
779 		return (E2BIG);
780 	}
781 
782 	if (copyout(app->audp_sect[0], data, pathlen)) {
783 		au_pathrele(app);
784 		return (EFAULT);
785 	}
786 
787 	au_pathrele(app);
788 	return (0);
789 }
790 
791 static int
792 getcar(caddr_t data, int length)
793 {
794 	struct p_audit_data	*pad;
795 	struct audit_path	*app;
796 	int	pathlen;
797 
798 	pad = P2A(curproc);
799 	ASSERT(pad != NULL);
800 
801 	mutex_enter(&(pad->pad_lock));
802 	app = pad->pad_root;
803 	au_pathhold(app);
804 	mutex_exit(&(pad->pad_lock));
805 
806 	pathlen = app->audp_sect[1] - app->audp_sect[0];
807 	if (pathlen > length) {
808 		au_pathrele(app);
809 		return (E2BIG);
810 	}
811 
812 	if (copyout(app->audp_sect[0], data, pathlen)) {
813 		au_pathrele(app);
814 		return (EFAULT);
815 	}
816 
817 	au_pathrele(app);
818 	return (0);
819 }
820 
821 static int
822 getstat(caddr_t data)
823 {
824 	au_kcontext_t	*kctx = GET_KCTX_PZ;
825 
826 	membar_consumer();
827 
828 	if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
829 		return (EFAULT);
830 	return (0);
831 }
832 
833 static int
834 setstat(caddr_t data)
835 {
836 	au_kcontext_t *kctx = GET_KCTX_PZ;
837 	au_stat_t au_stat;
838 
839 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
840 		return (EINVAL);
841 
842 	if (copyin(data, &au_stat, sizeof (au_stat_t)))
843 		return (EFAULT);
844 
845 	if (au_stat.as_generated == CLEAR_VAL)
846 		kctx->auk_statistics.as_generated = 0;
847 	if (au_stat.as_nonattrib == CLEAR_VAL)
848 		kctx->auk_statistics.as_nonattrib = 0;
849 	if (au_stat.as_kernel == CLEAR_VAL)
850 		kctx->auk_statistics.as_kernel = 0;
851 	if (au_stat.as_audit == CLEAR_VAL)
852 		kctx->auk_statistics.as_audit = 0;
853 	if (au_stat.as_auditctl == CLEAR_VAL)
854 		kctx->auk_statistics.as_auditctl = 0;
855 	if (au_stat.as_enqueue == CLEAR_VAL)
856 		kctx->auk_statistics.as_enqueue = 0;
857 	if (au_stat.as_written == CLEAR_VAL)
858 		kctx->auk_statistics.as_written = 0;
859 	if (au_stat.as_wblocked == CLEAR_VAL)
860 		kctx->auk_statistics.as_wblocked = 0;
861 	if (au_stat.as_rblocked == CLEAR_VAL)
862 		kctx->auk_statistics.as_rblocked = 0;
863 	if (au_stat.as_dropped == CLEAR_VAL)
864 		kctx->auk_statistics.as_dropped = 0;
865 	if (au_stat.as_totalsize == CLEAR_VAL)
866 		kctx->auk_statistics.as_totalsize = 0;
867 
868 	membar_producer();
869 
870 	return (0);
871 
872 }
873 
874 static int
875 setumask(caddr_t data)
876 {
877 	STRUCT_DECL(auditinfo, user_info);
878 	struct proc *p;
879 	const auditinfo_addr_t	*ainfo;
880 	model_t	model;
881 
882 	/* setumask not applicable in non-global zones without perzone policy */
883 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
884 		return (EINVAL);
885 
886 	model = get_udatamodel();
887 	STRUCT_INIT(user_info, model);
888 
889 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
890 		return (EFAULT);
891 
892 	mutex_enter(&pidlock);	/* lock the process queue against updates */
893 	for (p = practive; p != NULL; p = p->p_next) {
894 		cred_t	*cr;
895 
896 		/* if in non-global zone only modify processes in same zone */
897 		if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
898 			continue;
899 
900 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
901 
902 		/* skip system processes and ones being created or going away */
903 		if (p->p_stat == SIDL || p->p_stat == SZOMB ||
904 		    (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
905 			mutex_exit(&p->p_lock);
906 			continue;
907 		}
908 
909 		mutex_enter(&p->p_crlock);
910 		crhold(cr = p->p_cred);
911 		mutex_exit(&p->p_crlock);
912 		ainfo = crgetauinfo(cr);
913 		if (ainfo == NULL) {
914 			mutex_exit(&p->p_lock);
915 			crfree(cr);
916 			continue;
917 		}
918 
919 		if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
920 			au_mask_t	mask;
921 			int		err;
922 
923 			/*
924 			 * Here's a process which matches the specified auid.
925 			 * If its mask doesn't already match the new mask,
926 			 * save the new mask in the pad, to be picked up
927 			 * next syscall.
928 			 */
929 			mask = STRUCT_FGET(user_info, ai_mask);
930 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
931 			crfree(cr);
932 			if (err != 0) {
933 				struct p_audit_data *pad = P2A(p);
934 				ASSERT(pad != NULL);
935 
936 				mutex_enter(&(pad->pad_lock));
937 				pad->pad_flags |= PAD_SETMASK;
938 				pad->pad_newmask = mask;
939 				mutex_exit(&(pad->pad_lock));
940 
941 				/*
942 				 * No need to call set_proc_pre_sys(), since
943 				 * t_pre_sys is ALWAYS on when audit is
944 				 * enabled...due to syscall auditing.
945 				 */
946 			}
947 		} else {
948 			crfree(cr);
949 		}
950 		mutex_exit(&p->p_lock);
951 	}
952 	mutex_exit(&pidlock);
953 
954 	return (0);
955 }
956 
957 static int
958 setsmask(caddr_t data)
959 {
960 	STRUCT_DECL(auditinfo, user_info);
961 	struct proc *p;
962 	const auditinfo_addr_t	*ainfo;
963 	model_t	model;
964 
965 	/* setsmask not applicable in non-global zones without perzone policy */
966 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
967 		return (EINVAL);
968 
969 	model = get_udatamodel();
970 	STRUCT_INIT(user_info, model);
971 
972 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
973 		return (EFAULT);
974 
975 	mutex_enter(&pidlock);	/* lock the process queue against updates */
976 	for (p = practive; p != NULL; p = p->p_next) {
977 		cred_t	*cr;
978 
979 		/* if in non-global zone only modify processes in same zone */
980 		if (!HASZONEACCESS(curproc, p->p_zone->zone_id))
981 			continue;
982 
983 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
984 
985 		/* skip system processes and ones being created or going away */
986 		if (p->p_stat == SIDL || p->p_stat == SZOMB ||
987 		    (p->p_flag & (SSYS | SEXITING | SEXITLWPS))) {
988 			mutex_exit(&p->p_lock);
989 			continue;
990 		}
991 
992 		mutex_enter(&p->p_crlock);
993 		crhold(cr = p->p_cred);
994 		mutex_exit(&p->p_crlock);
995 		ainfo = crgetauinfo(cr);
996 		if (ainfo == NULL) {
997 			mutex_exit(&p->p_lock);
998 			crfree(cr);
999 			continue;
1000 		}
1001 
1002 		if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
1003 			au_mask_t	mask;
1004 			int		err;
1005 
1006 			/*
1007 			 * Here's a process which matches the specified asid.
1008 			 * If its mask doesn't already match the new mask,
1009 			 * save the new mask in the pad, to be picked up
1010 			 * next syscall.
1011 			 */
1012 			mask = STRUCT_FGET(user_info, ai_mask);
1013 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
1014 			crfree(cr);
1015 			if (err != 0) {
1016 				struct p_audit_data *pad = P2A(p);
1017 				ASSERT(pad != NULL);
1018 
1019 				mutex_enter(&(pad->pad_lock));
1020 				pad->pad_flags |= PAD_SETMASK;
1021 				pad->pad_newmask = mask;
1022 				mutex_exit(&(pad->pad_lock));
1023 
1024 				/*
1025 				 * No need to call set_proc_pre_sys(), since
1026 				 * t_pre_sys is ALWAYS on when audit is
1027 				 * enabled...due to syscall auditing.
1028 				 */
1029 			}
1030 		} else {
1031 			crfree(cr);
1032 		}
1033 		mutex_exit(&p->p_lock);
1034 	}
1035 	mutex_exit(&pidlock);
1036 
1037 	return (0);
1038 }
1039 
1040 /*
1041  * Get the current audit state of the system
1042  */
1043 static int
1044 getcond(caddr_t data)
1045 {
1046 	au_kcontext_t *kctx = GET_KCTX_PZ;
1047 
1048 	if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
1049 		return (EFAULT);
1050 
1051 	return (0);
1052 }
1053 
1054 /*
1055  * Set the current audit state of the system to on (AUC_AUDITING) or
1056  * off (AUC_NOAUDIT).
1057  */
1058 /* ARGSUSED */
1059 static int
1060 setcond(caddr_t data)
1061 {
1062 	int auditstate;
1063 	au_kcontext_t *kctx;
1064 
1065 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
1066 		return (EINVAL);
1067 
1068 	kctx = GET_KCTX_NGZ;
1069 
1070 	if (copyin(data, &auditstate, sizeof (int)))
1071 		return (EFAULT);
1072 
1073 	switch (auditstate) {
1074 	case AUC_AUDITING:		/* Turn auditing on */
1075 		if (audit_active == C2AUDIT_UNLOADED)
1076 			audit_init_module();
1077 		kctx->auk_auditstate = AUC_AUDITING;
1078 		if (!(audit_policy & AUDIT_PERZONE) && INGLOBALZONE(curproc))
1079 			set_all_zone_usr_proc_sys(ALL_ZONES);
1080 		else
1081 			set_all_zone_usr_proc_sys(curproc->p_zone->zone_id);
1082 		break;
1083 
1084 	case AUC_NOAUDIT:		/* Turn auditing off */
1085 		if (kctx->auk_auditstate == AUC_NOAUDIT)
1086 			break;
1087 		kctx->auk_auditstate = AUC_NOAUDIT;
1088 
1089 		/* clear out the audit queue */
1090 
1091 		mutex_enter(&(kctx->auk_queue.lock));
1092 		if (kctx->auk_queue.wt_block)
1093 			cv_broadcast(&(kctx->auk_queue.write_cv));
1094 
1095 		/* unblock au_output_thread */
1096 		cv_broadcast(&(kctx->auk_queue.read_cv));
1097 
1098 		mutex_exit(&(kctx->auk_queue.lock));
1099 		break;
1100 
1101 	default:
1102 		return (EINVAL);
1103 	}
1104 
1105 	return (0);
1106 }
1107 
1108 static int
1109 getclass(caddr_t data)
1110 {
1111 	au_evclass_map_t event;
1112 	au_kcontext_t	*kctx = GET_KCTX_PZ;
1113 
1114 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1115 		return (EFAULT);
1116 
1117 	if (event.ec_number > MAX_KEVENTS)
1118 		return (EINVAL);
1119 
1120 	event.ec_class = kctx->auk_ets[event.ec_number];
1121 
1122 	if (copyout(&event, data, sizeof (au_evclass_map_t)))
1123 		return (EFAULT);
1124 
1125 	return (0);
1126 }
1127 
1128 static int
1129 setclass(caddr_t data)
1130 {
1131 	au_evclass_map_t event;
1132 	au_kcontext_t	*kctx;
1133 
1134 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1135 		return (EINVAL);
1136 
1137 	kctx = GET_KCTX_NGZ;
1138 
1139 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1140 		return (EFAULT);
1141 
1142 	if (event.ec_number > MAX_KEVENTS)
1143 		return (EINVAL);
1144 
1145 	kctx->auk_ets[event.ec_number] = event.ec_class;
1146 
1147 	return (0);
1148 }
1149 
1150 static int
1151 getpinfo(caddr_t data)
1152 {
1153 	STRUCT_DECL(auditpinfo, apinfo);
1154 	proc_t *proc;
1155 	const auditinfo_addr_t	*ainfo;
1156 	model_t	model;
1157 	cred_t	*cr, *newcred;
1158 
1159 	model = get_udatamodel();
1160 	STRUCT_INIT(apinfo, model);
1161 
1162 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1163 		return (EFAULT);
1164 
1165 	newcred = cralloc();
1166 
1167 	mutex_enter(&pidlock);
1168 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1169 		mutex_exit(&pidlock);
1170 		crfree(newcred);
1171 		return (ESRCH);		/* no such process */
1172 	}
1173 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1174 	mutex_exit(&pidlock);
1175 
1176 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1177 
1178 	mutex_enter(&proc->p_crlock);
1179 	crhold(cr = proc->p_cred);
1180 	mutex_exit(&proc->p_crlock);
1181 	mutex_exit(&proc->p_lock);
1182 
1183 	ainfo = crgetauinfo(cr);
1184 	if (ainfo == NULL) {
1185 		crfree(cr);
1186 		return (EINVAL);
1187 	}
1188 
1189 	/* designated process has an ipv6 address? */
1190 	if (ainfo->ai_termid.at_type == AU_IPv6) {
1191 		crfree(cr);
1192 		return (EOVERFLOW);
1193 	}
1194 
1195 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1196 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1197 #ifdef _LP64
1198 	if (model == DATAMODEL_ILP32) {
1199 		dev32_t dev;
1200 		/* convert internal 64 bit form to 32 bit version */
1201 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1202 			crfree(cr);
1203 			return (EOVERFLOW);
1204 		}
1205 		STRUCT_FSET(apinfo, ap_termid.port, dev);
1206 	} else
1207 		STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1208 #else
1209 	STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1210 #endif
1211 	STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
1212 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1213 
1214 	crfree(cr);
1215 
1216 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1217 		return (EFAULT);
1218 
1219 	return (0);
1220 }
1221 
1222 static int
1223 getpinfo_addr(caddr_t data, int len)
1224 {
1225 	STRUCT_DECL(auditpinfo_addr, apinfo);
1226 	proc_t *proc;
1227 	const auditinfo_addr_t	*ainfo;
1228 	model_t	model;
1229 	cred_t	*cr, *newcred;
1230 
1231 	model = get_udatamodel();
1232 	STRUCT_INIT(apinfo, model);
1233 
1234 	if (len < STRUCT_SIZE(apinfo))
1235 		return (EOVERFLOW);
1236 
1237 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1238 		return (EFAULT);
1239 
1240 	newcred = cralloc();
1241 
1242 	mutex_enter(&pidlock);
1243 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1244 		mutex_exit(&pidlock);
1245 		crfree(newcred);
1246 		return (ESRCH);
1247 	}
1248 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1249 	mutex_exit(&pidlock);
1250 
1251 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1252 
1253 	mutex_enter(&proc->p_crlock);
1254 	crhold(cr = proc->p_cred);
1255 	mutex_exit(&proc->p_crlock);
1256 	mutex_exit(&proc->p_lock);
1257 
1258 	ainfo = crgetauinfo(cr);
1259 	if (ainfo == NULL) {
1260 		crfree(cr);
1261 		return (EINVAL);
1262 	}
1263 
1264 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1265 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1266 #ifdef _LP64
1267 	if (model == DATAMODEL_ILP32) {
1268 		dev32_t dev;
1269 		/* convert internal 64 bit form to 32 bit version */
1270 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1271 			crfree(cr);
1272 			return (EOVERFLOW);
1273 		}
1274 		STRUCT_FSET(apinfo, ap_termid.at_port, dev);
1275 	} else
1276 		STRUCT_FSET(apinfo, ap_termid.at_port,
1277 		    ainfo->ai_termid.at_port);
1278 #else
1279 	STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
1280 #endif
1281 	STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
1282 	STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
1283 	STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
1284 	STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
1285 	STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
1286 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1287 
1288 	crfree(cr);
1289 
1290 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1291 		return (EFAULT);
1292 
1293 	return (0);
1294 }
1295 
1296 static int
1297 setpmask(caddr_t data)
1298 {
1299 	STRUCT_DECL(auditpinfo, apinfo);
1300 	proc_t *proc;
1301 	cred_t	*newcred;
1302 	auditinfo_addr_t	*ainfo;
1303 	struct p_audit_data	*pad;
1304 
1305 	model_t	model;
1306 
1307 	model = get_udatamodel();
1308 	STRUCT_INIT(apinfo, model);
1309 
1310 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1311 		return (EFAULT);
1312 
1313 	mutex_enter(&pidlock);
1314 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1315 		mutex_exit(&pidlock);
1316 		return (ESRCH);
1317 	}
1318 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1319 	mutex_exit(&pidlock);
1320 
1321 	newcred = cralloc();
1322 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
1323 		mutex_exit(&proc->p_lock);
1324 		crfree(newcred);
1325 		return (EINVAL);
1326 	}
1327 
1328 	mutex_enter(&proc->p_crlock);
1329 	crcopy_to(proc->p_cred, newcred);
1330 	proc->p_cred = newcred;
1331 
1332 	ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
1333 
1334 	/*
1335 	 * Unlock. No need to broadcast changes via set_proc_pre_sys(),
1336 	 * since t_pre_sys is ALWAYS on when audit is enabled... due to
1337 	 * syscall auditing.
1338 	 */
1339 	crfree(newcred);
1340 	mutex_exit(&proc->p_crlock);
1341 
1342 	/* Reset flag for any previous pending mask change; this supercedes */
1343 	pad = P2A(proc);
1344 	ASSERT(pad != NULL);
1345 	mutex_enter(&(pad->pad_lock));
1346 	pad->pad_flags &= ~PAD_SETMASK;
1347 	mutex_exit(&(pad->pad_lock));
1348 
1349 	mutex_exit(&proc->p_lock);
1350 
1351 	return (0);
1352 }
1353 
1354 /*
1355  * The out of control system call
1356  * This is audit kitchen sink aka auditadm, aka auditon
1357  */
1358 int
1359 auditctl(
1360 	int	cmd,
1361 	caddr_t data,
1362 	int	length)
1363 {
1364 	int result;
1365 
1366 	switch (cmd) {
1367 	case A_GETAMASK:
1368 	case A_GETCOND:
1369 	case A_GETCAR:
1370 	case A_GETCLASS:
1371 	case A_GETCWD:
1372 	case A_GETKAUDIT:
1373 	case A_GETKMASK:
1374 	case A_GETPINFO:
1375 	case A_GETPINFO_ADDR:
1376 	case A_GETPOLICY:
1377 	case A_GETQCTRL:
1378 	case A_GETSTAT:
1379 		if (secpolicy_audit_getattr(CRED(), B_FALSE) != 0)
1380 			return (EPERM);
1381 		break;
1382 	default:
1383 		if (secpolicy_audit_config(CRED()) != 0)
1384 			return (EPERM);
1385 		break;
1386 	}
1387 
1388 	switch (cmd) {
1389 	case A_GETPOLICY:
1390 		result = getpolicy(data);
1391 		break;
1392 	case A_SETPOLICY:
1393 		result = setpolicy(data);
1394 		break;
1395 	case A_GETAMASK:
1396 		result = getamask(data);
1397 		break;
1398 	case A_SETAMASK:
1399 		result = setamask(data);
1400 		break;
1401 	case A_GETKMASK:
1402 		result = getkmask(data);
1403 		break;
1404 	case A_SETKMASK:
1405 		result = setkmask(data);
1406 		break;
1407 	case A_GETKAUDIT:
1408 		result = getkaudit(data, length);
1409 		break;
1410 	case A_SETKAUDIT:
1411 		result = setkaudit(data, length);
1412 		break;
1413 	case A_GETQCTRL:
1414 		result = getqctrl(data);
1415 		break;
1416 	case A_SETQCTRL:
1417 		result = setqctrl(data);
1418 		break;
1419 	case A_GETCWD:
1420 		result = getcwd(data, length);
1421 		break;
1422 	case A_GETCAR:
1423 		result = getcar(data, length);
1424 		break;
1425 	case A_GETSTAT:
1426 		result = getstat(data);
1427 		break;
1428 	case A_SETSTAT:
1429 		result = setstat(data);
1430 		break;
1431 	case A_SETUMASK:
1432 		result = setumask(data);
1433 		break;
1434 	case A_SETSMASK:
1435 		result = setsmask(data);
1436 		break;
1437 	case A_GETCOND:
1438 		result = getcond(data);
1439 		break;
1440 	case A_SETCOND:
1441 		result = setcond(data);
1442 		break;
1443 	case A_GETCLASS:
1444 		result = getclass(data);
1445 		break;
1446 	case A_SETCLASS:
1447 		result = setclass(data);
1448 		break;
1449 	case A_GETPINFO:
1450 		result = getpinfo(data);
1451 		break;
1452 	case A_GETPINFO_ADDR:
1453 		result = getpinfo_addr(data, length);
1454 		break;
1455 	case A_SETPMASK:
1456 		result = setpmask(data);
1457 		break;
1458 	default:
1459 		result = EINVAL;
1460 		break;
1461 	}
1462 	return (result);
1463 }
1464