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