xref: /titanic_52/usr/src/uts/common/c2/audit_syscalls.c (revision bdfc6d18da790deeec2e0eb09c625902defe2498)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * This file contains the auditing system call code.
29  *
30  */
31 
32 #pragma ident	"%Z%%M%	%I%	%E% SMI"
33 
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/user.h>
37 #include <sys/vnode.h>
38 #include <sys/vfs.h>
39 #include <sys/session.h>	/* for session structure (auditctl(2) */
40 #include <sys/kmem.h>		/* for KM_SLEEP */
41 #include <sys/cred_impl.h>
42 #include <sys/types.h>
43 #include <sys/proc.h>
44 #include <sys/uio.h>
45 #include <sys/file.h>
46 #include <sys/stat.h>
47 #include <sys/pathname.h>
48 #include <sys/acct.h>
49 #include <sys/stropts.h>
50 #include <sys/exec.h>
51 #include <sys/thread.h>
52 #include <sys/cmn_err.h>
53 #include <sys/debug.h>
54 #include <sys/disp.h>
55 #include <sys/kobj.h>
56 #include <sys/sysmacros.h>
57 #include <sys/policy.h>
58 #include <sys/taskq.h>
59 #include <sys/zone.h>
60 
61 #include <c2/audit.h>
62 #include <c2/audit_kernel.h>
63 #include <c2/audit_record.h>
64 
65 #define	CLEAR_VAL	-1
66 
67 #define	HEADER_SIZE64	1;
68 #define	HEADER_SIZE32	0;
69 #define	AU_MIN_FILE_SZ	0x80000	/* minumum audit file size */
70 #define	AUDIT_REC_SIZE	0x8000	/* maximum user audit record size */
71 
72 extern kmutex_t pidlock;
73 
74 extern pri_t		minclsyspri;		/* priority for taskq */
75 
76 extern int audit_load;		/* defined in audit_start.c */
77 
78 int		au_auditstate = AUC_UNSET;	/* global audit state */
79 int		audit_policy;	/* global audit policies in force */
80 static clock_t	au_resid = 15;	/* wait .15 sec before droping a rec */
81 
82 static int	getauid(caddr_t);
83 static int	setauid(caddr_t);
84 static int	getaudit(caddr_t);
85 static int	getaudit_addr(caddr_t, int);
86 static int	setaudit(caddr_t);
87 static int	setaudit_addr(caddr_t, int);
88 static int	auditdoor(int);
89 static int	auditsvc(int, int);
90 static int	auditctl(int, caddr_t, int);
91 static int	audit_modsysent(char *, int, int (*)());
92 static void	au_output_thread();
93 /*
94  * This is the loadable module wrapper.
95  */
96 #include <sys/modctl.h>
97 #include "sys/syscall.h"
98 
99 static struct sysent auditsysent = {
100 	6,
101 	0,
102 	_auditsys
103 };
104 
105 /*
106  * Module linkage information for the kernel.
107  */
108 extern struct mod_ops mod_syscallops;
109 
110 static struct modlsys modlsys = {
111 	&mod_syscallops, "C2 system call", &auditsysent
112 };
113 
114 static struct modlinkage modlinkage = {
115 	MODREV_1, (void *)&modlsys, 0
116 };
117 
118 int
119 _init()
120 {
121 	int retval;
122 
123 	if (audit_load == 0)
124 		return (-1);
125 
126 	/*
127 	 * We are going to do an ugly thing here.
128 	 *  Because auditsys is already defined as a regular
129 	 *  syscall we have to change the definition for syscall
130 	 *  auditsys. Basically or in the SE_LOADABLE flag for
131 	 *  auditsys. We no have a static loadable syscall. Also
132 	 *  create an rw_lock.
133 	 */
134 
135 	if ((audit_modsysent("c2audit",
136 		SE_LOADABLE|SE_NOUNLOAD,
137 		_auditsys)) == -1)
138 		return (-1);
139 
140 	if ((retval = mod_install(&modlinkage)) != 0)
141 		return (retval);
142 
143 	return (0);
144 }
145 
146 int
147 _fini()
148 {
149 	return (EBUSY);
150 }
151 
152 int
153 _info(struct modinfo *modinfop)
154 {
155 	return (mod_info(&modlinkage, modinfop));
156 }
157 
158 /*
159  * when auditing is updated to allow enable/disable without
160  * reboot (and when the audit stubs are removed) *most* of these
161  * calls should return an error when auditing is off -- some
162  * for local zones only.
163  */
164 
165 int
166 _auditsys(struct auditcalls *uap, rval_t *rvp)
167 {
168 	int result = 0;
169 
170 	switch (uap->code) {
171 	case BSM_GETAUID:
172 		result = getauid((caddr_t)uap->a1);
173 		break;
174 	case BSM_SETAUID:
175 		result = setauid((caddr_t)uap->a1);
176 		break;
177 	case BSM_GETAUDIT:
178 		result = getaudit((caddr_t)uap->a1);
179 		break;
180 	case BSM_GETAUDIT_ADDR:
181 
182 		result = getaudit_addr((caddr_t)uap->a1, (int)uap->a2);
183 		break;
184 	case BSM_SETAUDIT:
185 		result = setaudit((caddr_t)uap->a1);
186 		break;
187 	case BSM_SETAUDIT_ADDR:
188 		result = setaudit_addr((caddr_t)uap->a1, (int)uap->a2);
189 		break;
190 	case BSM_AUDIT:
191 		result = audit((caddr_t)uap->a1, (int)uap->a2);
192 		break;
193 	case BSM_AUDITSVC:
194 		result = auditsvc((int)uap->a1, (int)uap->a2);
195 		break;
196 	case BSM_AUDITDOOR:
197 		result = auditdoor((int)uap->a1);
198 		break;
199 	case BSM_AUDITON:
200 	case BSM_AUDITCTL:
201 		result = auditctl((int)uap->a1, (caddr_t)uap->a2, (int)uap->a3);
202 		break;
203 	default:
204 		result = EINVAL;
205 	}
206 	rvp->r_vals = result;
207 	return (result);
208 }
209 
210 /*
211  * Return the audit user ID for the current process.  Currently only
212  * the privileged processes may see the audit id.  That may change.
213  * If copyout is unsucessful return EFAULT.
214  */
215 static int
216 getauid(caddr_t auid_p)
217 {
218 	const auditinfo_addr_t	*ainfo;
219 
220 	if (secpolicy_audit_getattr(CRED()) != 0)
221 		return (EPERM);
222 
223 	ainfo = crgetauinfo(CRED());
224 	if (ainfo == NULL)
225 		return (EINVAL);
226 
227 	if (copyout(&ainfo->ai_auid, auid_p, sizeof (au_id_t)))
228 		return (EFAULT);
229 
230 	return (0);
231 }
232 
233 /*
234  * Set the audit userid, for a process.  This can only be changed by
235  * privileged processes.  The audit userid is inherited across forks & execs.
236  * Passed in is a pointer to the au_id_t; if copyin unsuccessful return EFAULT.
237  */
238 static int
239 setauid(caddr_t auid_p)
240 {
241 	proc_t *p;
242 	au_id_t	auid;
243 	cred_t *newcred;
244 	auditinfo_addr_t *auinfo;
245 
246 	if (secpolicy_audit_config(CRED()) != 0)
247 		return (EPERM);
248 
249 	if (copyin(auid_p, &auid, sizeof (au_id_t))) {
250 		return (EFAULT);
251 	}
252 
253 	newcred = cralloc();
254 	if ((auinfo = crgetauinfo_modifiable(newcred)) == NULL) {
255 		crfree(newcred);
256 		return (EINVAL);
257 	}
258 
259 	/* grab p_crlock and switch to new cred */
260 	p = curproc;
261 	mutex_enter(&p->p_crlock);
262 	crcopy_to(p->p_cred, newcred);
263 	p->p_cred = newcred;
264 
265 	auinfo->ai_auid = auid;			/* update the auid */
266 
267 	/* unlock and broadcast the cred changes */
268 	mutex_exit(&p->p_crlock);
269 	crset(p, newcred);
270 
271 	return (0);
272 }
273 
274 /*
275  * Get the audit state information from the current process.
276  * Return EFAULT if copyout fails.
277  */
278 static int
279 getaudit(caddr_t info_p)
280 {
281 	STRUCT_DECL(auditinfo, info);
282 	const auditinfo_addr_t	*ainfo;
283 	model_t	model;
284 
285 	if (secpolicy_audit_getattr(CRED()) != 0)
286 		return (EPERM);
287 
288 	model = get_udatamodel();
289 	STRUCT_INIT(info, model);
290 
291 	ainfo = crgetauinfo(CRED());
292 	if (ainfo == NULL)
293 		return (EINVAL);
294 
295 	/* trying to read a process with an IPv6 address? */
296 	if (ainfo->ai_termid.at_type == AU_IPv6)
297 		return (EOVERFLOW);
298 
299 	STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
300 	STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
301 #ifdef _LP64
302 	if (model == DATAMODEL_ILP32) {
303 		dev32_t dev;
304 		/* convert internal 64 bit form to 32 bit version */
305 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
306 			return (EOVERFLOW);
307 		}
308 		STRUCT_FSET(info, ai_termid.port, dev);
309 	} else
310 		STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
311 #else
312 	STRUCT_FSET(info, ai_termid.port, ainfo->ai_termid.at_port);
313 #endif
314 	STRUCT_FSET(info, ai_termid.machine, ainfo->ai_termid.at_addr[0]);
315 	STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
316 
317 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
318 		return (EFAULT);
319 
320 	return (0);
321 }
322 
323 /*
324  * Get the audit state information from the current process.
325  * Return EFAULT if copyout fails.
326  */
327 static int
328 getaudit_addr(caddr_t info_p, int len)
329 {
330 	STRUCT_DECL(auditinfo_addr, info);
331 	const auditinfo_addr_t	*ainfo;
332 	model_t	model;
333 
334 	if (secpolicy_audit_getattr(CRED()) != 0)
335 		return (EPERM);
336 
337 	model = get_udatamodel();
338 	STRUCT_INIT(info, model);
339 
340 	if (len < STRUCT_SIZE(info))
341 		return (EOVERFLOW);
342 
343 	ainfo = crgetauinfo(CRED());
344 
345 	if (ainfo == NULL)
346 		return (EINVAL);
347 
348 	STRUCT_FSET(info, ai_auid, ainfo->ai_auid);
349 	STRUCT_FSET(info, ai_mask, ainfo->ai_mask);
350 #ifdef _LP64
351 	if (model == DATAMODEL_ILP32) {
352 		dev32_t dev;
353 		/* convert internal 64 bit form to 32 bit version */
354 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
355 			return (EOVERFLOW);
356 		}
357 		STRUCT_FSET(info, ai_termid.at_port, dev);
358 	} else
359 		STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
360 #else
361 	STRUCT_FSET(info, ai_termid.at_port, ainfo->ai_termid.at_port);
362 #endif
363 	STRUCT_FSET(info, ai_termid.at_type, ainfo->ai_termid.at_type);
364 	STRUCT_FSET(info, ai_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
365 	STRUCT_FSET(info, ai_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
366 	STRUCT_FSET(info, ai_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
367 	STRUCT_FSET(info, ai_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
368 	STRUCT_FSET(info, ai_asid, ainfo->ai_asid);
369 
370 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
371 		return (EFAULT);
372 
373 	return (0);
374 }
375 
376 /*
377  * Set the audit state information for the current process.
378  * Return EFAULT if copyout fails.
379  */
380 static int
381 setaudit(caddr_t info_p)
382 {
383 	STRUCT_DECL(auditinfo, info);
384 	proc_t *p;
385 	cred_t	*newcred;
386 	model_t	model;
387 	auditinfo_addr_t *ainfo;
388 
389 	if (secpolicy_audit_config(CRED()) != 0)
390 		return (EPERM);
391 
392 	model = get_udatamodel();
393 	STRUCT_INIT(info, model);
394 
395 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
396 		return (EFAULT);
397 
398 	newcred = cralloc();
399 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
400 		crfree(newcred);
401 		return (EINVAL);
402 	}
403 
404 	/* grab p_crlock and switch to new cred */
405 	p = curproc;
406 	mutex_enter(&p->p_crlock);
407 	crcopy_to(p->p_cred, newcred);
408 	p->p_cred = newcred;
409 
410 	/* Set audit mask, id, termid and session id as specified */
411 	ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
412 #ifdef _LP64
413 	/* only convert to 64 bit if coming from a 32 bit binary */
414 	if (model == DATAMODEL_ILP32)
415 		ainfo->ai_termid.at_port =
416 			DEVEXPL(STRUCT_FGET(info, ai_termid.port));
417 	else
418 		ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
419 #else
420 	ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.port);
421 #endif
422 	ainfo->ai_termid.at_type = AU_IPv4;
423 	ainfo->ai_termid.at_addr[0] = STRUCT_FGET(info, ai_termid.machine);
424 	ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
425 	ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
426 
427 	/* unlock and broadcast the cred changes */
428 	mutex_exit(&p->p_crlock);
429 	crset(p, newcred);
430 
431 	return (0);
432 }
433 
434 /*
435  * Set the audit state information for the current process.
436  * Return EFAULT if copyin fails.
437  */
438 static int
439 setaudit_addr(caddr_t info_p, int len)
440 {
441 	STRUCT_DECL(auditinfo_addr, info);
442 	proc_t *p;
443 	cred_t	*newcred;
444 	model_t	model;
445 	int i;
446 	int type;
447 	auditinfo_addr_t *ainfo;
448 
449 	if (secpolicy_audit_config(CRED()) != 0)
450 		return (EPERM);
451 
452 	model = get_udatamodel();
453 	STRUCT_INIT(info, model);
454 
455 	if (len < STRUCT_SIZE(info))
456 		return (EOVERFLOW);
457 
458 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
459 		return (EFAULT);
460 
461 	type = STRUCT_FGET(info, ai_termid.at_type);
462 	if ((type != AU_IPv4) && (type != AU_IPv6))
463 		return (EINVAL);
464 
465 	newcred = cralloc();
466 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
467 		crfree(newcred);
468 		return (EINVAL);
469 	}
470 
471 	/* grab p_crlock and switch to new cred */
472 	p = curproc;
473 	mutex_enter(&p->p_crlock);
474 	crcopy_to(p->p_cred, newcred);
475 	p->p_cred = newcred;
476 
477 	/* Set audit mask, id, termid and session id as specified */
478 	ainfo->ai_auid = STRUCT_FGET(info, ai_auid);
479 	ainfo->ai_mask = STRUCT_FGET(info, ai_mask);
480 #ifdef _LP64
481 	/* only convert to 64 bit if coming from a 32 bit binary */
482 	if (model == DATAMODEL_ILP32)
483 		ainfo->ai_termid.at_port =
484 			DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
485 	else
486 		ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
487 #else
488 	ainfo->ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
489 #endif
490 	ainfo->ai_termid.at_type = type;
491 	bzero(&ainfo->ai_termid.at_addr[0], sizeof (ainfo->ai_termid.at_addr));
492 	for (i = 0; i < (type/sizeof (int)); i++)
493 		ainfo->ai_termid.at_addr[i] =
494 			STRUCT_FGET(info, ai_termid.at_addr[i]);
495 
496 	if (ainfo->ai_termid.at_type == AU_IPv6 &&
497 	    IN6_IS_ADDR_V4MAPPED(((in6_addr_t *)ainfo->ai_termid.at_addr))) {
498 		ainfo->ai_termid.at_type = AU_IPv4;
499 		ainfo->ai_termid.at_addr[0] = ainfo->ai_termid.at_addr[3];
500 		ainfo->ai_termid.at_addr[1] = 0;
501 		ainfo->ai_termid.at_addr[2] = 0;
502 		ainfo->ai_termid.at_addr[3] = 0;
503 	}
504 
505 	ainfo->ai_asid = STRUCT_FGET(info, ai_asid);
506 
507 	/* unlock and broadcast the cred changes */
508 	mutex_exit(&p->p_crlock);
509 	crset(p, newcred);
510 
511 	return (0);
512 }
513 
514 /*
515  * The audit system call. Trust what the user has sent down and save it
516  * away in the audit file. User passes a complete audit record and its
517  * length.  We will fill in the time stamp, check the header and the length
518  * Put a trailer and a sequence token if policy requires.
519  * In the future length might become size_t instead of an int.
520  *
521  * The call is valid whether or not AUDIT_PERZONE is set (think of
522  * login to a zone).  When the local audit state (auk_auditstate) is
523  * AUC_INIT_AUDIT, records are accepted even though auditd isn't
524  * running.
525  */
526 int
527 audit(caddr_t record, int length)
528 {
529 	char	c;
530 	int	count, l;
531 	token_t	*m, *n, *s, *ad;
532 	int	hdrlen, delta;
533 	adr_t	hadr;
534 	adr_t	sadr;
535 	int	size;	/* 0: 32 bit utility  1: 64 bit utility */
536 	int	host_len;
537 	size_t	zlen;
538 	au_kcontext_t	*kctx = SET_KCTX_PZ;
539 
540 	ASSERT(kctx != NULL);
541 
542 	/* if auditing not enabled, then don't generate an audit record */
543 	if (kctx->auk_auditstate != AUC_AUDITING &&
544 	    kctx->auk_auditstate != AUC_INIT_AUDIT)
545 		return (0);
546 
547 	/* Only privileged processes can audit */
548 	if (secpolicy_audit_modify(CRED()) != 0)
549 		return (EPERM);
550 
551 	/* Max user record size is 32K */
552 	if (length > AUDIT_REC_SIZE)
553 		return (E2BIG);
554 
555 	/*
556 	 * The specified length must be at least as big as the smallest
557 	 * possible header token. Later after beginning to scan the
558 	 * header we'll determine the true minimum length according to
559 	 * the header type and attributes.
560 	 */
561 #define	AU_MIN_HEADER_LEN	(sizeof (char) + sizeof (int32_t) + \
562 	sizeof (char) + sizeof (short) + sizeof (short) + \
563 	(sizeof (int32_t) * 2))
564 
565 	if (length < AU_MIN_HEADER_LEN)
566 		return (EINVAL);
567 
568 	/* Read in user's audit record */
569 	count = length;
570 	m = n = s = ad = NULL;
571 	while (count) {
572 		m = au_getclr();
573 		if (!s)
574 			s = n = m;
575 		else {
576 			n->next_buf = m;
577 			n = m;
578 		}
579 		l = MIN(count, AU_BUFSIZE);
580 		if (copyin(record, memtod(m, caddr_t),
581 			(size_t)l)) {
582 				/* copyin failed release au_membuf */
583 				au_free_rec(s);
584 				return (EFAULT);
585 		}
586 		record += l;
587 		count -= l;
588 		m->len = (uchar_t)l;
589 	}
590 
591 	/* Now attach the entire thing to ad */
592 	au_write((caddr_t *)&(ad), s);
593 
594 	/* validate header token type. trust everything following it */
595 	adr_start(&hadr, memtod(s, char *));
596 	(void) adr_getchar(&hadr, &c);
597 	switch (c) {
598 	case AUT_HEADER32:
599 		/* size vers+event_ID+event_modifier fields */
600 		delta = 1 + 2 + 2;
601 		hdrlen = 1 + 4 + delta + (sizeof (int32_t) * 2);
602 		size = HEADER_SIZE32;
603 		break;
604 
605 #ifdef _LP64
606 	case AUT_HEADER64:
607 		/* size vers+event_ID+event_modifier fields */
608 		delta = 1 + 2 + 2;
609 		hdrlen = 1 + 4 + delta + (sizeof (int64_t) * 2);
610 		size = HEADER_SIZE64;
611 		break;
612 #endif
613 
614 	case AUT_HEADER32_EX:
615 		/*
616 		 * Skip over the length/version/type/mod fields and
617 		 * grab the host address type (length), then rewind.
618 		 * This is safe per the previous minimum length check.
619 		 */
620 		hadr.adr_now += 9;
621 		(void) adr_getint32(&hadr, &host_len);
622 		hadr.adr_now -= 9 + sizeof (int32_t);
623 
624 		/* size: vers+event_ID+event_modifier+IP_type+IP_addr_array */
625 		delta = 1 + 2 + 2 + 4 + host_len;
626 		hdrlen = 1 + 4 + delta + (sizeof (int32_t) * 2);
627 		size = HEADER_SIZE32;
628 		break;
629 
630 #ifdef _LP64
631 	case AUT_HEADER64_EX:
632 		/*
633 		 * Skip over the length/version/type/mod fields and grab
634 		 * the host address type (length), then rewind.
635 		 * This is safe per the previous minimum length check.
636 		 */
637 		hadr.adr_now += 9;
638 		(void) adr_getint32(&hadr, &host_len);
639 		hadr.adr_now -= 9 + sizeof (int32_t);
640 
641 		/* size: vers+event_ID+event_modifier+IP_type+IP_addr_array */
642 		delta = 1 + 2 + 2 + 4 + host_len;
643 		hdrlen = 1 + 4 + delta + (sizeof (int64_t) * 2);
644 		size = HEADER_SIZE64;
645 		break;
646 #endif
647 
648 	default:
649 		/* Header is wrong, reject message */
650 		au_free_rec(s);
651 		return (EINVAL);
652 	}
653 
654 	if (length < hdrlen) {
655 		au_free_rec(s);
656 		return (0);
657 	}
658 
659 	/* advance over header token length field */
660 	hadr.adr_now += 4;
661 
662 	/* validate version */
663 	(void) adr_getchar(&hadr, &c);
664 	if (c != TOKEN_VERSION) {
665 		/* version is wrong, reject message */
666 		au_free_rec(s);
667 		return (EINVAL);
668 	}
669 
670 	/* backup to header length field (including version field) */
671 	hadr.adr_now -= 5;
672 
673 	/*
674 	 * add on the zonename token if policy AUDIT_ZONENAME is set
675 	 */
676 	if (kctx->auk_policy & AUDIT_ZONENAME) {
677 		zlen = au_zonename_length();
678 		if (zlen > 0) {
679 			length += zlen;
680 			m = au_to_zonename(zlen);
681 			(void) au_append_rec(ad, m, AU_PACK);
682 		}
683 	}
684 	/* Add an (optional) sequence token. NULL offset if none */
685 	if (kctx->auk_policy & AUDIT_SEQ) {
686 		/* get the sequnce token */
687 		m = au_to_seq();
688 
689 		/* sequence token 5 bytes long */
690 		length += 5;
691 
692 		/* link to audit record (i.e. don't pack the data) */
693 		(void) au_append_rec(ad, m, AU_LINK);
694 
695 		/* advance to count field of token */
696 		adr_start(&sadr, memtod(m, char *));
697 		sadr.adr_now += 1;
698 	} else
699 		sadr.adr_now = (char *)NULL;
700 
701 	/* add the (optional) trailer token */
702 	if (kctx->auk_policy & AUDIT_TRAIL) {
703 		/* trailer token is 7 bytes long */
704 		length += 7;
705 
706 		/* append to audit record */
707 		(void) au_append_rec(ad, au_to_trailer(length), AU_PACK);
708 	}
709 
710 	/* audit record completely assembled. set the length */
711 	adr_int32(&hadr, (int32_t *)&length, 1);
712 
713 	/* advance to date/time field of header */
714 	hadr.adr_now += delta;
715 
716 	/* We are done  put it on the queue */
717 	AS_INC(as_generated, 1, kctx);
718 	AS_INC(as_audit, 1, kctx);
719 
720 	au_enqueue(kctx, s, &hadr, &sadr, size, 0);
721 
722 	AS_INC(as_totalsize, length, kctx);
723 
724 	return (0);
725 }
726 
727 static void
728 audit_dont_stop(void *kctx)
729 {
730 
731 	if ((((au_kcontext_t *)kctx)->auk_valid != AUK_VALID) ||
732 	    (((au_kcontext_t *)kctx)->auk_auditstate == AUC_NOAUDIT))
733 		return;
734 
735 	mutex_enter(&(((au_kcontext_t *)kctx)->auk_queue.lock));
736 	cv_broadcast(&(((au_kcontext_t *)kctx)->auk_queue.write_cv));
737 	mutex_exit(&(((au_kcontext_t *)kctx)->auk_queue.lock));
738 }
739 
740 /*
741  * auditdoor starts a kernel thread to generate output from the audit
742  * queue.  The thread terminates when it detects auditing being turned
743  * off, such as when auditd exits with a SIGTERM.  If a subsequent
744  * auditdoor arrives while the thread is running, the door descriptor
745  * of the last auditdoor in will be used for output.  auditd is responsible
746  * for insuring that multiple copies are not running.
747  */
748 
749 static int
750 auditdoor(int fd)
751 {
752 	struct file	*fp;
753 	struct vnode	*vp;
754 	int		error = 0;
755 	int		do_create = 0;
756 	au_kcontext_t	*kctx;
757 
758 	if (secpolicy_audit_config(CRED()) != 0)
759 		return (EPERM);
760 
761 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
762 		return (EINVAL);
763 
764 	kctx = SET_KCTX_LZ;
765 
766 	/*
767 	 * Prevent a second audit daemon from running this code.
768 	 * auk_svc_busy == 2 until the output thread terminates.
769 	 * Multiple calls to auditdoor() are valid but a call
770 	 * to auditsvc() while au_output_thread() is running
771 	 * or a call to auditdoor() while auditsvc is running
772 	 * is blocked.
773 	 */
774 	mutex_enter(&(kctx->auk_svc_lock));
775 	if (kctx->auk_svc_busy == 1) {		/* active auditsvc? */
776 		mutex_exit(&(kctx->auk_svc_lock));
777 		return (EBUSY);
778 	}
779 	kctx->auk_svc_busy = 2;
780 	mutex_exit(&(kctx->auk_svc_lock));
781 	/*
782 	 * convert file pointer to file descriptor
783 	 *   Note: fd ref count incremented here.
784 	 */
785 	if ((fp = (struct file *)getf(fd)) == NULL) {
786 		error = EBADF;
787 		goto svc_exit;
788 	}
789 	vp = fp->f_vnode;
790 	if (vp->v_type != VDOOR) {
791 		cmn_err(CE_WARN,
792 		    "auditdoor() did not get the expected door descriptor\n");
793 		error = EINVAL;
794 		releasef(fd);
795 		goto svc_exit;
796 	}
797 	/*
798 	 * If the output thread is already running, then replace the
799 	 * door descriptor with the new one and continue; otherwise
800 	 * create the thread too.  Since au_output_thread makes a call
801 	 * to au_doorio() which also does
802 	 * mutex_lock(&(kctx->auk_svc_lock)), the create/dispatch is
803 	 * done after the unlock...
804 	 */
805 	mutex_enter(&(kctx->auk_svc_lock));
806 
807 	if (kctx->auk_current_vp != NULL)
808 		VN_RELE(kctx->auk_current_vp);
809 
810 	kctx->auk_current_vp = vp;
811 	VN_HOLD(kctx->auk_current_vp);
812 	releasef(fd);
813 
814 	if (!kctx->auk_output_active) {
815 		kctx->auk_output_active = 1;
816 		do_create = 1;
817 	}
818 	mutex_exit(&(kctx->auk_svc_lock));
819 	if (do_create) {
820 		kctx->auk_taskq =
821 		    taskq_create("output_master", 1, minclsyspri, 1, 1, 0);
822 		(void) taskq_dispatch(kctx->auk_taskq,
823 		    (task_func_t *)au_output_thread,
824 		    kctx, TQ_SLEEP);
825 	}
826 svc_exit:
827 	if (error) {
828 		mutex_enter(&(kctx->auk_svc_lock));
829 		kctx->auk_svc_busy = 2;
830 		mutex_exit(&(kctx->auk_svc_lock));
831 	}
832 	return (error);
833 }
834 
835 /*
836  * au_queue_kick -- wake up the output queue after delay ticks
837  */
838 static void
839 au_queue_kick(void *kctx)
840 {
841 	/*
842 	 * wakeup reader if its not running and there is something
843 	 * to do.  It also helps that kctx still be valid...
844 	 */
845 
846 	if ((((au_kcontext_t *)kctx)->auk_valid != AUK_VALID) ||
847 	    (((au_kcontext_t *)kctx)->auk_auditstate == AUC_NOAUDIT))
848 		return;
849 
850 	if (((au_kcontext_t *)kctx)->auk_queue.cnt &&
851 	    ((au_kcontext_t *)kctx)->auk_queue.rd_block)
852 		cv_broadcast(&((au_kcontext_t *)kctx)->auk_queue.read_cv);
853 
854 	/* fire off timeout event to kick audit queue awake */
855 	(void) timeout(au_queue_kick, kctx,
856 	    ((au_kcontext_t *)kctx)->auk_queue.delay);
857 }
858 
859 /*
860  * output thread
861  *
862  * this runs "forever" where "forever" means until either auk_auditstate
863  * changes from AUC_AUDITING or if the door descriptor becomes invalid.
864  *
865  * there is one thread per active zone if AUC_PERZONE is set.  Since
866  * there is the possibility that a zone may go down without auditd
867  * terminating properly, a zone shutdown kills its au_output_thread()
868  * via taskq_destroy().
869  */
870 
871 static void
872 au_output_thread(au_kcontext_t *kctx)
873 {
874 	int		error = 0;
875 
876 	(void) timeout(au_queue_kick, kctx, kctx->auk_queue.delay);
877 
878 	/*
879 	 * Wait for work, until a signal arrives,
880 	 * or until auditing is disabled.
881 	 */
882 
883 	while (!error) {
884 	    if (kctx->auk_auditstate == AUC_AUDITING) {
885 		mutex_enter(&(kctx->auk_queue.lock));
886 		while (kctx->auk_queue.head == NULL) {
887 		    /* safety check. kick writer awake */
888 		    if (kctx->auk_queue.wt_block)
889 			cv_broadcast(&(kctx->auk_queue.write_cv));
890 
891 		    kctx->auk_queue.rd_block = 1;
892 		    AS_INC(as_rblocked, 1, kctx);
893 
894 		    cv_wait(&(kctx->auk_queue.read_cv),
895 			&(kctx->auk_queue.lock));
896 
897 		    kctx->auk_queue.rd_block = 0;
898 
899 		    if (kctx->auk_auditstate != AUC_AUDITING) {
900 			mutex_exit(&(kctx->auk_queue.lock));
901 			(void) timeout(audit_dont_stop, kctx, au_resid);
902 			goto output_exit;
903 		    }
904 		    kctx->auk_queue.rd_block = 0;
905 		}
906 		mutex_exit(&(kctx->auk_queue.lock));
907 		/*
908 		 * au_doorio() calls au_door_upcall which holds auk_svc_lock;
909 		 * au_doorio empties the queue before returning.
910 		 */
911 
912 		error = au_doorio(kctx);
913 	    } else	/* auditing turned off while we slept */
914 		break;
915 	}
916 output_exit:
917 	mutex_enter(&(kctx->auk_svc_lock));
918 
919 	VN_RELE(kctx->auk_current_vp);
920 	kctx->auk_current_vp = NULL;
921 
922 	kctx->auk_output_active = 0;
923 	kctx->auk_svc_busy = 0;
924 
925 	mutex_exit(&(kctx->auk_svc_lock));
926 }
927 
928 
929 /*
930  * Get the global policy flag
931  */
932 
933 static int
934 getpolicy(caddr_t data)
935 {
936 	int	policy;
937 	au_kcontext_t	*kctx = SET_KCTX_PZ;
938 
939 	policy = audit_policy | kctx->auk_policy;
940 
941 	if (copyout(&policy, data, sizeof (int)))
942 		return (EFAULT);
943 	return (0);
944 }
945 
946 /*
947  * Set the global and local policy flags
948  *
949  * The global flags only make sense from the global zone;
950  * the local flags depend on the AUDIT_PERZONE policy:
951  * if the perzone policy is set, then policy is set separately
952  * per zone, else held only in the global zone.
953  *
954  * The initial value of a local zone's policy flag is determined
955  * by the value of the global zone's flags at the time the
956  * local zone is created.
957  *
958  * While auditconfig(1M) allows setting and unsetting policies one bit
959  * at a time, the mask passed in from auditconfig() is created by a
960  * syscall to getpolicy and then modified based on the auditconfig()
961  * cmd line, so the input policy value is used to replace the existing
962  * policy.
963  */
964 
965 
966 static int
967 setpolicy(caddr_t data)
968 {
969 	int	policy;
970 	au_kcontext_t	*kctx;
971 
972 	if (copyin(data, &policy, sizeof (int)))
973 		return (EFAULT);
974 
975 	kctx = SET_KCTX_LZ;
976 	ASSERT(kctx != NULL);
977 
978 	if (INGLOBALZONE(curproc)) {
979 		if (policy & ~(AUDIT_GLOBAL | AUDIT_LOCAL))
980 			return (EINVAL);
981 
982 		audit_policy = policy & AUDIT_GLOBAL;
983 	} else {
984 		if (!(audit_policy & AUDIT_PERZONE))
985 			return (EINVAL);
986 
987 		if (policy & ~AUDIT_LOCAL)	/* global bits are a no-no */
988 			return (EINVAL);
989 	}
990 	kctx->auk_policy = policy & AUDIT_LOCAL;
991 
992 	/*
993 	 * auk_current_vp is NULL before auditd starts (or during early
994 	 * auditd starup) or if auditd is halted; in either case,
995 	 * notification of a policy change is not needed, since auditd
996 	 * reads policy as it comes up.  The error return from au_doormsg()
997 	 * is ignored to avoid a race condition -- for example if auditd
998 	 * segv's, the audit state may be "auditing" but the door may
999 	 * be closed.  Returning an error if the door is open makes it
1000 	 * impossible for Greenline to restart auditd.
1001 	 */
1002 	if (kctx->auk_current_vp != NULL)
1003 		(void) au_doormsg(kctx, AU_DBUF_POLICY, &policy);
1004 
1005 	/*
1006 	 * Wake up anyone who might have blocked on full audit
1007 	 * partitions. audit daemons need to set AUDIT_FULL when no
1008 	 * space so we can tell if we should start dropping records.
1009 	 */
1010 	mutex_enter(&(kctx->auk_queue.lock));
1011 
1012 	if ((policy & (AUDIT_CNT | AUDIT_SCNT) &&
1013 	    (kctx->auk_queue.cnt >= kctx->auk_queue.hiwater)))
1014 		cv_broadcast(&(kctx->auk_queue.write_cv));
1015 
1016 	mutex_exit(&(kctx->auk_queue.lock));
1017 
1018 	return (0);
1019 }
1020 
1021 static int
1022 getkmask(caddr_t data)
1023 {
1024 	au_kcontext_t	*kctx;
1025 
1026 	kctx = SET_KCTX_PZ;
1027 
1028 	if (copyout(&kctx->auk_info.ai_mask, data, sizeof (au_mask_t)))
1029 		return (EFAULT);
1030 	return (0);
1031 }
1032 
1033 static int
1034 setkmask(caddr_t data)
1035 {
1036 	au_mask_t	mask;
1037 	au_kcontext_t	*kctx;
1038 
1039 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1040 		return (EINVAL);
1041 
1042 	kctx = SET_KCTX_LZ;
1043 
1044 	if (copyin(data, &mask, sizeof (au_mask_t)))
1045 		return (EFAULT);
1046 
1047 	kctx->auk_info.ai_mask = mask;
1048 	return (0);
1049 }
1050 
1051 static int
1052 getkaudit(caddr_t info_p, int len)
1053 {
1054 	STRUCT_DECL(auditinfo_addr, info);
1055 	model_t model;
1056 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1057 
1058 	model = get_udatamodel();
1059 	STRUCT_INIT(info, model);
1060 
1061 	if (len < STRUCT_SIZE(info))
1062 		return (EOVERFLOW);
1063 
1064 	STRUCT_FSET(info, ai_auid, kctx->auk_info.ai_auid);
1065 	STRUCT_FSET(info, ai_mask, kctx->auk_info.ai_mask);
1066 #ifdef _LP64
1067 	if (model == DATAMODEL_ILP32) {
1068 		dev32_t dev;
1069 		/* convert internal 64 bit form to 32 bit version */
1070 		if (cmpldev(&dev, kctx->auk_info.ai_termid.at_port) == 0) {
1071 			return (EOVERFLOW);
1072 		}
1073 		STRUCT_FSET(info, ai_termid.at_port, dev);
1074 	} else
1075 		STRUCT_FSET(info, ai_termid.at_port,
1076 			kctx->auk_info.ai_termid.at_port);
1077 #else
1078 	STRUCT_FSET(info, ai_termid.at_port,
1079 		kctx->auk_info.ai_termid.at_port);
1080 #endif
1081 	STRUCT_FSET(info, ai_termid.at_type,
1082 	    kctx->auk_info.ai_termid.at_type);
1083 	STRUCT_FSET(info, ai_termid.at_addr[0],
1084 	    kctx->auk_info.ai_termid.at_addr[0]);
1085 	STRUCT_FSET(info, ai_termid.at_addr[1],
1086 	    kctx->auk_info.ai_termid.at_addr[1]);
1087 	STRUCT_FSET(info, ai_termid.at_addr[2],
1088 	    kctx->auk_info.ai_termid.at_addr[2]);
1089 	STRUCT_FSET(info, ai_termid.at_addr[3],
1090 	    kctx->auk_info.ai_termid.at_addr[3]);
1091 	STRUCT_FSET(info, ai_asid, kctx->auk_info.ai_asid);
1092 
1093 	if (copyout(STRUCT_BUF(info), info_p, STRUCT_SIZE(info)))
1094 		return (EFAULT);
1095 
1096 	return (0);
1097 }
1098 
1099 /*
1100  * the host address for AUDIT_PERZONE == 0 is that of the global
1101  * zone and for local zones it is of the current zone.
1102  */
1103 
1104 static int
1105 setkaudit(caddr_t info_p, int len)
1106 {
1107 	STRUCT_DECL(auditinfo_addr, info);
1108 	model_t model;
1109 	au_kcontext_t	*kctx;
1110 
1111 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1112 		return (EINVAL);
1113 
1114 	kctx = SET_KCTX_LZ;
1115 
1116 	model = get_udatamodel();
1117 	STRUCT_INIT(info, model);
1118 
1119 	if (len < STRUCT_SIZE(info))
1120 		return (EOVERFLOW);
1121 
1122 	if (copyin(info_p, STRUCT_BUF(info), STRUCT_SIZE(info)))
1123 		return (EFAULT);
1124 
1125 	if ((STRUCT_FGET(info, ai_termid.at_type) != AU_IPv4) &&
1126 	    (STRUCT_FGET(info, ai_termid.at_type) != AU_IPv6))
1127 		return (EINVAL);
1128 
1129 	/* Set audit mask, termid and session id as specified */
1130 	kctx->auk_info.ai_auid = STRUCT_FGET(info, ai_auid);
1131 	kctx->auk_info.ai_mask = STRUCT_FGET(info, ai_mask);
1132 #ifdef _LP64
1133 	/* only convert to 64 bit if coming from a 32 bit binary */
1134 	if (model == DATAMODEL_ILP32)
1135 		kctx->auk_info.ai_termid.at_port =
1136 			DEVEXPL(STRUCT_FGET(info, ai_termid.at_port));
1137 	else
1138 		kctx->auk_info.ai_termid.at_port =
1139 			STRUCT_FGET(info, ai_termid.at_port);
1140 #else
1141 	kctx->auk_info.ai_termid.at_port = STRUCT_FGET(info, ai_termid.at_port);
1142 #endif
1143 	kctx->auk_info.ai_termid.at_type = STRUCT_FGET(info, ai_termid.at_type);
1144 	bzero(&kctx->auk_info.ai_termid.at_addr[0],
1145 		sizeof (kctx->auk_info.ai_termid.at_addr));
1146 	kctx->auk_info.ai_termid.at_addr[0] =
1147 	    STRUCT_FGET(info, ai_termid.at_addr[0]);
1148 	kctx->auk_info.ai_termid.at_addr[1] =
1149 	    STRUCT_FGET(info, ai_termid.at_addr[1]);
1150 	kctx->auk_info.ai_termid.at_addr[2] =
1151 	    STRUCT_FGET(info, ai_termid.at_addr[2]);
1152 	kctx->auk_info.ai_termid.at_addr[3] =
1153 	    STRUCT_FGET(info, ai_termid.at_addr[3]);
1154 	kctx->auk_info.ai_asid = STRUCT_FGET(info, ai_asid);
1155 
1156 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6 &&
1157 	    IN6_IS_ADDR_V4MAPPED(
1158 	    ((in6_addr_t *)kctx->auk_info.ai_termid.at_addr))) {
1159 		kctx->auk_info.ai_termid.at_type = AU_IPv4;
1160 		kctx->auk_info.ai_termid.at_addr[0] =
1161 		    kctx->auk_info.ai_termid.at_addr[3];
1162 		kctx->auk_info.ai_termid.at_addr[1] = 0;
1163 		kctx->auk_info.ai_termid.at_addr[2] = 0;
1164 		kctx->auk_info.ai_termid.at_addr[3] = 0;
1165 	}
1166 	if (kctx->auk_info.ai_termid.at_type == AU_IPv6)
1167 		kctx->auk_hostaddr_valid = IN6_IS_ADDR_UNSPECIFIED(
1168 		    (in6_addr_t *)kctx->auk_info.ai_termid.at_addr) ? 0 : 1;
1169 	else
1170 		kctx->auk_hostaddr_valid =
1171 		    (kctx->auk_info.ai_termid.at_addr[0] ==
1172 		    htonl(INADDR_ANY)) ? 0 : 1;
1173 
1174 	return (0);
1175 }
1176 
1177 static int
1178 getqctrl(caddr_t data)
1179 {
1180 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1181 	STRUCT_DECL(au_qctrl, qctrl);
1182 	STRUCT_INIT(qctrl, get_udatamodel());
1183 
1184 	mutex_enter(&(kctx->auk_queue.lock));
1185 	STRUCT_FSET(qctrl, aq_hiwater, kctx->auk_queue.hiwater);
1186 	STRUCT_FSET(qctrl, aq_lowater, kctx->auk_queue.lowater);
1187 	STRUCT_FSET(qctrl, aq_bufsz, kctx->auk_queue.bufsz);
1188 	STRUCT_FSET(qctrl, aq_delay, kctx->auk_queue.delay);
1189 	mutex_exit(&(kctx->auk_queue.lock));
1190 
1191 	if (copyout(STRUCT_BUF(qctrl), data, STRUCT_SIZE(qctrl)))
1192 		return (EFAULT);
1193 
1194 	return (0);
1195 }
1196 
1197 static int
1198 setqctrl(caddr_t data)
1199 {
1200 	au_kcontext_t	*kctx;
1201 	struct au_qctrl qctrl_tmp;
1202 	STRUCT_DECL(au_qctrl, qctrl);
1203 	STRUCT_INIT(qctrl, get_udatamodel());
1204 
1205 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1206 		return (EINVAL);
1207 	kctx = SET_KCTX_LZ;
1208 
1209 	if (copyin(data, STRUCT_BUF(qctrl), STRUCT_SIZE(qctrl)))
1210 		return (EFAULT);
1211 
1212 	qctrl_tmp.aq_hiwater = (size_t)STRUCT_FGET(qctrl, aq_hiwater);
1213 	qctrl_tmp.aq_lowater = (size_t)STRUCT_FGET(qctrl, aq_lowater);
1214 	qctrl_tmp.aq_bufsz = (size_t)STRUCT_FGET(qctrl, aq_bufsz);
1215 	qctrl_tmp.aq_delay = (clock_t)STRUCT_FGET(qctrl, aq_delay);
1216 
1217 	/* enforce sane values */
1218 
1219 	if (qctrl_tmp.aq_hiwater <= qctrl_tmp.aq_lowater)
1220 		return (EINVAL);
1221 
1222 	if (qctrl_tmp.aq_hiwater < AQ_LOWATER)
1223 		return (EINVAL);
1224 
1225 	if (qctrl_tmp.aq_hiwater > AQ_MAXHIGH)
1226 		return (EINVAL);
1227 
1228 	if (qctrl_tmp.aq_bufsz < AQ_BUFSZ)
1229 		return (EINVAL);
1230 
1231 	if (qctrl_tmp.aq_bufsz > AQ_MAXBUFSZ)
1232 		return (EINVAL);
1233 
1234 	if (qctrl_tmp.aq_delay == 0)
1235 		return (EINVAL);
1236 
1237 	if (qctrl_tmp.aq_delay > AQ_MAXDELAY)
1238 		return (EINVAL);
1239 
1240 	/* update everything at once so things are consistant */
1241 	mutex_enter(&(kctx->auk_queue.lock));
1242 	kctx->auk_queue.hiwater = qctrl_tmp.aq_hiwater;
1243 	kctx->auk_queue.lowater = qctrl_tmp.aq_lowater;
1244 	kctx->auk_queue.bufsz = qctrl_tmp.aq_bufsz;
1245 	kctx->auk_queue.delay = qctrl_tmp.aq_delay;
1246 
1247 	if (kctx->auk_queue.rd_block &&
1248 	    kctx->auk_queue.cnt > kctx->auk_queue.lowater)
1249 		cv_broadcast(&(kctx->auk_queue.read_cv));
1250 
1251 	if (kctx->auk_queue.wt_block &&
1252 	    kctx->auk_queue.cnt < kctx->auk_queue.hiwater)
1253 		cv_broadcast(&(kctx->auk_queue.write_cv));
1254 
1255 	mutex_exit(&(kctx->auk_queue.lock));
1256 
1257 	return (0);
1258 }
1259 
1260 static int
1261 getcwd(caddr_t data, int length)
1262 {
1263 	struct p_audit_data	*pad;
1264 	struct audit_path	*app;
1265 	int	pathlen;
1266 
1267 	pad = P2A(curproc);
1268 	ASSERT(pad != NULL);
1269 
1270 	mutex_enter(&(pad->pad_lock));
1271 	app = pad->pad_cwd;
1272 	au_pathhold(app);
1273 	mutex_exit(&(pad->pad_lock));
1274 
1275 	pathlen = app->audp_sect[1] - app->audp_sect[0];
1276 	if (pathlen > length) {
1277 		au_pathrele(app);
1278 		return (E2BIG);
1279 	}
1280 
1281 	if (copyout(app->audp_sect[0], data, pathlen)) {
1282 		au_pathrele(app);
1283 		return (EFAULT);
1284 	}
1285 
1286 	au_pathrele(app);
1287 	return (0);
1288 }
1289 
1290 static int
1291 getcar(caddr_t data, int length)
1292 {
1293 	struct p_audit_data	*pad;
1294 	struct audit_path	*app;
1295 	int	pathlen;
1296 
1297 	pad = P2A(curproc);
1298 	ASSERT(pad != NULL);
1299 
1300 	mutex_enter(&(pad->pad_lock));
1301 	app = pad->pad_root;
1302 	au_pathhold(app);
1303 	mutex_exit(&(pad->pad_lock));
1304 
1305 	pathlen = app->audp_sect[1] - app->audp_sect[0];
1306 	if (pathlen > length) {
1307 		au_pathrele(app);
1308 		return (E2BIG);
1309 	}
1310 
1311 	if (copyout(app->audp_sect[0], data, pathlen)) {
1312 		au_pathrele(app);
1313 		return (EFAULT);
1314 	}
1315 
1316 	au_pathrele(app);
1317 	return (0);
1318 }
1319 
1320 static int
1321 getstat(caddr_t data)
1322 {
1323 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1324 
1325 	membar_consumer();
1326 
1327 	if (copyout((caddr_t)&(kctx->auk_statistics), data, sizeof (au_stat_t)))
1328 		return (EFAULT);
1329 	return (0);
1330 }
1331 
1332 
1333 static int
1334 setstat(caddr_t data)
1335 {
1336 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1337 	au_stat_t au_stat;
1338 
1339 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1340 		return (EINVAL);
1341 
1342 	if (copyin(data, &au_stat, sizeof (au_stat_t)))
1343 		return (EFAULT);
1344 
1345 	if (au_stat.as_generated == CLEAR_VAL)
1346 		kctx->auk_statistics.as_generated = 0;
1347 	if (au_stat.as_nonattrib == CLEAR_VAL)
1348 		kctx->auk_statistics.as_nonattrib = 0;
1349 	if (au_stat.as_kernel == CLEAR_VAL)
1350 		kctx->auk_statistics.as_kernel = 0;
1351 	if (au_stat.as_audit == CLEAR_VAL)
1352 		kctx->auk_statistics.as_audit = 0;
1353 	if (au_stat.as_auditctl == CLEAR_VAL)
1354 		kctx->auk_statistics.as_auditctl = 0;
1355 	if (au_stat.as_enqueue == CLEAR_VAL)
1356 		kctx->auk_statistics.as_enqueue = 0;
1357 	if (au_stat.as_written == CLEAR_VAL)
1358 		kctx->auk_statistics.as_written = 0;
1359 	if (au_stat.as_wblocked == CLEAR_VAL)
1360 		kctx->auk_statistics.as_wblocked = 0;
1361 	if (au_stat.as_rblocked == CLEAR_VAL)
1362 		kctx->auk_statistics.as_rblocked = 0;
1363 	if (au_stat.as_dropped == CLEAR_VAL)
1364 		kctx->auk_statistics.as_dropped = 0;
1365 	if (au_stat.as_totalsize == CLEAR_VAL)
1366 		kctx->auk_statistics.as_totalsize = 0;
1367 
1368 	membar_producer();
1369 
1370 	return (0);
1371 
1372 }
1373 
1374 static int
1375 setumask(caddr_t data)
1376 {
1377 	STRUCT_DECL(auditinfo, user_info);
1378 	struct proc *p;
1379 	const auditinfo_addr_t	*ainfo;
1380 	model_t	model;
1381 
1382 	model = get_udatamodel();
1383 	STRUCT_INIT(user_info, model);
1384 
1385 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
1386 		return (EFAULT);
1387 
1388 	mutex_enter(&pidlock);	/* lock the process queue against updates */
1389 	for (p = practive; p != NULL; p = p->p_next) {
1390 		cred_t	*cr;
1391 
1392 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
1393 		mutex_enter(&p->p_crlock);
1394 		crhold(cr = p->p_cred);
1395 		mutex_exit(&p->p_crlock);
1396 		ainfo = crgetauinfo(cr);
1397 		if (ainfo == NULL) {
1398 			mutex_exit(&p->p_lock);
1399 			crfree(cr);
1400 			continue;
1401 		}
1402 
1403 		if (ainfo->ai_auid == STRUCT_FGET(user_info, ai_auid)) {
1404 			au_mask_t	mask;
1405 			int		err;
1406 
1407 			/*
1408 			 * Here's a process which matches the specified auid.
1409 			 * If its mask doesn't already match the new mask,
1410 			 * save the new mask in the pad, to be picked up
1411 			 * next syscall.
1412 			 */
1413 			mask = STRUCT_FGET(user_info, ai_mask);
1414 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
1415 			crfree(cr);
1416 			if (err != 0) {
1417 				struct p_audit_data *pad = P2A(p);
1418 				ASSERT(pad != NULL);
1419 
1420 				mutex_enter(&(pad->pad_lock));
1421 				pad->pad_flags |= PAD_SETMASK;
1422 				pad->pad_newmask = mask;
1423 				mutex_exit(&(pad->pad_lock));
1424 
1425 				/*
1426 				 * No need to call set_proc_pre_sys(), since
1427 				 * t_pre_sys is ALWAYS on when audit is
1428 				 * enabled...due to syscall auditing.
1429 				 */
1430 			}
1431 		} else {
1432 			crfree(cr);
1433 		}
1434 		mutex_exit(&p->p_lock);
1435 	}
1436 	mutex_exit(&pidlock);
1437 
1438 	return (0);
1439 }
1440 
1441 static int
1442 setsmask(caddr_t data)
1443 {
1444 	STRUCT_DECL(auditinfo, user_info);
1445 	struct proc *p;
1446 	const auditinfo_addr_t	*ainfo;
1447 	model_t	model;
1448 
1449 	model = get_udatamodel();
1450 	STRUCT_INIT(user_info, model);
1451 
1452 	if (copyin(data, STRUCT_BUF(user_info), STRUCT_SIZE(user_info)))
1453 		return (EFAULT);
1454 
1455 	mutex_enter(&pidlock);	/* lock the process queue against updates */
1456 	for (p = practive; p != NULL; p = p->p_next) {
1457 		cred_t	*cr;
1458 
1459 		mutex_enter(&p->p_lock);	/* so process doesn't go away */
1460 		mutex_enter(&p->p_crlock);
1461 		crhold(cr = p->p_cred);
1462 		mutex_exit(&p->p_crlock);
1463 		ainfo = crgetauinfo(cr);
1464 		if (ainfo == NULL) {
1465 			mutex_exit(&p->p_lock);
1466 			crfree(cr);
1467 			continue;
1468 		}
1469 
1470 		if (ainfo->ai_asid == STRUCT_FGET(user_info, ai_asid)) {
1471 			au_mask_t	mask;
1472 			int		err;
1473 
1474 			/*
1475 			 * Here's a process which matches the specified asid.
1476 			 * If its mask doesn't already match the new mask,
1477 			 * save the new mask in the pad, to be picked up
1478 			 * next syscall.
1479 			 */
1480 			mask = STRUCT_FGET(user_info, ai_mask);
1481 			err = bcmp(&mask, &ainfo->ai_mask, sizeof (au_mask_t));
1482 			crfree(cr);
1483 			if (err != 0) {
1484 				struct p_audit_data *pad = P2A(p);
1485 				ASSERT(pad != NULL);
1486 
1487 				mutex_enter(&(pad->pad_lock));
1488 				pad->pad_flags |= PAD_SETMASK;
1489 				pad->pad_newmask = mask;
1490 				mutex_exit(&(pad->pad_lock));
1491 
1492 				/*
1493 				 * No need to call set_proc_pre_sys(), since
1494 				 * t_pre_sys is ALWAYS on when audit is
1495 				 * enabled...due to syscall auditing.
1496 				 */
1497 			}
1498 		} else {
1499 			crfree(cr);
1500 		}
1501 		mutex_exit(&p->p_lock);
1502 	}
1503 	mutex_exit(&pidlock);
1504 
1505 	return (0);
1506 }
1507 
1508 /*
1509  * Get the current audit state of the system
1510  */
1511 static int
1512 getcond(caddr_t data)
1513 {
1514 	au_kcontext_t	*kctx;
1515 
1516 	if (au_auditstate == AUC_DISABLED)
1517 		if (copyout(&au_auditstate, data, sizeof (int)))
1518 			return (EFAULT);
1519 
1520 	kctx = SET_KCTX_PZ;
1521 
1522 	if (copyout(&(kctx->auk_auditstate), data, sizeof (int)))
1523 		return (EFAULT);
1524 
1525 	return (0);
1526 }
1527 
1528 /*
1529  * Set the current audit state of the system to on (AUC_AUDITING) or
1530  * off (AUC_NOAUDIT).
1531  */
1532 /* ARGSUSED */
1533 static int
1534 setcond(caddr_t data)
1535 {
1536 	int	auditstate;
1537 	au_kcontext_t	*kctx;
1538 
1539 	if (!(audit_policy & AUDIT_PERZONE) && (!INGLOBALZONE(curproc)))
1540 		return (EINVAL);
1541 
1542 	kctx = SET_KCTX_LZ;
1543 
1544 	if (copyin(data, &auditstate, sizeof (int)))
1545 		return (EFAULT);
1546 
1547 	switch (auditstate) {
1548 	case AUC_AUDITING:		/* Turn auditing on */
1549 		kctx->auk_auditstate = AUC_AUDITING;
1550 		au_auditstate = AUC_ENABLED;
1551 		break;
1552 
1553 	case AUC_NOAUDIT:		/* Turn auditing off */
1554 		if (kctx->auk_auditstate == AUC_NOAUDIT)
1555 			break;
1556 		kctx->auk_auditstate = AUC_NOAUDIT;
1557 
1558 		/* clear out the audit queue */
1559 
1560 		mutex_enter(&(kctx->auk_queue.lock));
1561 		if (kctx->auk_queue.wt_block)
1562 			cv_broadcast(&(kctx->auk_queue.write_cv));
1563 
1564 		/* unblock au_output_thread */
1565 		cv_broadcast(&(kctx->auk_queue.read_cv));
1566 
1567 		mutex_exit(&(kctx->auk_queue.lock));
1568 		break;
1569 
1570 	default:
1571 		return (EINVAL);
1572 	}
1573 
1574 	return (0);
1575 }
1576 
1577 static int
1578 getclass(caddr_t data)
1579 {
1580 	au_evclass_map_t event;
1581 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1582 
1583 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1584 		return (EFAULT);
1585 
1586 	if (event.ec_number < 0 || event.ec_number > (au_naevent - 1))
1587 		return (EINVAL);
1588 
1589 	event.ec_class = kctx->auk_ets[event.ec_number];
1590 
1591 	if (copyout(&event, data, sizeof (au_evclass_map_t)))
1592 		return (EFAULT);
1593 
1594 	return (0);
1595 }
1596 
1597 static int
1598 setclass(caddr_t data)
1599 {
1600 	au_evclass_map_t event;
1601 	au_kcontext_t	*kctx;
1602 
1603 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1604 		return (EINVAL);
1605 
1606 	kctx = SET_KCTX_LZ;
1607 
1608 	if (copyin(data, &event, sizeof (au_evclass_map_t)))
1609 		return (EFAULT);
1610 
1611 	if (event.ec_number < 0 || event.ec_number > (au_naevent - 1))
1612 		return (EINVAL);
1613 
1614 	kctx->auk_ets[event.ec_number] = event.ec_class;
1615 
1616 	return (0);
1617 }
1618 
1619 static int
1620 getpinfo(caddr_t data)
1621 {
1622 	STRUCT_DECL(auditpinfo, apinfo);
1623 	proc_t *proc;
1624 	const auditinfo_addr_t	*ainfo;
1625 	model_t	model;
1626 	cred_t	*cr, *newcred;
1627 
1628 	model = get_udatamodel();
1629 	STRUCT_INIT(apinfo, model);
1630 
1631 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1632 		return (EFAULT);
1633 
1634 	newcred = cralloc();
1635 
1636 	mutex_enter(&pidlock);
1637 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1638 		mutex_exit(&pidlock);
1639 		crfree(newcred);
1640 		return (ESRCH);		/* no such process */
1641 	}
1642 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1643 	mutex_exit(&pidlock);
1644 
1645 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1646 
1647 	mutex_enter(&proc->p_crlock);
1648 	crhold(cr = proc->p_cred);
1649 	mutex_exit(&proc->p_crlock);
1650 	mutex_exit(&proc->p_lock);
1651 
1652 	ainfo = crgetauinfo(cr);
1653 	if (ainfo == NULL) {
1654 		crfree(cr);
1655 		return (EINVAL);
1656 	}
1657 
1658 	/* designated process has an ipv6 address? */
1659 	if (ainfo->ai_termid.at_type == AU_IPv6) {
1660 		crfree(cr);
1661 		return (EOVERFLOW);
1662 	}
1663 
1664 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1665 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1666 #ifdef _LP64
1667 	if (model == DATAMODEL_ILP32) {
1668 		dev32_t dev;
1669 		/* convert internal 64 bit form to 32 bit version */
1670 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1671 			crfree(cr);
1672 			return (EOVERFLOW);
1673 		}
1674 		STRUCT_FSET(apinfo, ap_termid.port, dev);
1675 	} else
1676 		STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1677 #else
1678 	STRUCT_FSET(apinfo, ap_termid.port, ainfo->ai_termid.at_port);
1679 #endif
1680 	STRUCT_FSET(apinfo, ap_termid.machine, ainfo->ai_termid.at_addr[0]);
1681 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1682 
1683 	crfree(cr);
1684 
1685 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1686 		return (EFAULT);
1687 
1688 	return (0);
1689 }
1690 
1691 static int
1692 getpinfo_addr(caddr_t data, int len)
1693 {
1694 	STRUCT_DECL(auditpinfo_addr, apinfo);
1695 	proc_t *proc;
1696 	const auditinfo_addr_t	*ainfo;
1697 	model_t	model;
1698 	cred_t	*cr, *newcred;
1699 
1700 	model = get_udatamodel();
1701 	STRUCT_INIT(apinfo, model);
1702 
1703 	if (len < STRUCT_SIZE(apinfo))
1704 		return (EOVERFLOW);
1705 
1706 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1707 		return (EFAULT);
1708 
1709 	newcred = cralloc();
1710 
1711 	mutex_enter(&pidlock);
1712 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1713 		mutex_exit(&pidlock);
1714 		crfree(newcred);
1715 		return (ESRCH);
1716 	}
1717 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1718 	mutex_exit(&pidlock);
1719 
1720 	audit_update_context(proc, newcred);	/* make sure it's up-to-date */
1721 
1722 	mutex_enter(&proc->p_crlock);
1723 	crhold(cr = proc->p_cred);
1724 	mutex_exit(&proc->p_crlock);
1725 	mutex_exit(&proc->p_lock);
1726 
1727 	ainfo = crgetauinfo(cr);
1728 	if (ainfo == NULL) {
1729 		crfree(cr);
1730 		return (EINVAL);
1731 	}
1732 
1733 	STRUCT_FSET(apinfo, ap_auid, ainfo->ai_auid);
1734 	STRUCT_FSET(apinfo, ap_asid, ainfo->ai_asid);
1735 #ifdef _LP64
1736 	if (model == DATAMODEL_ILP32) {
1737 		dev32_t dev;
1738 		/* convert internal 64 bit form to 32 bit version */
1739 		if (cmpldev(&dev, ainfo->ai_termid.at_port) == 0) {
1740 			crfree(cr);
1741 			return (EOVERFLOW);
1742 		}
1743 		STRUCT_FSET(apinfo, ap_termid.at_port, dev);
1744 	} else
1745 		STRUCT_FSET(apinfo, ap_termid.at_port,
1746 		    ainfo->ai_termid.at_port);
1747 #else
1748 	STRUCT_FSET(apinfo, ap_termid.at_port, ainfo->ai_termid.at_port);
1749 #endif
1750 	STRUCT_FSET(apinfo, ap_termid.at_type, ainfo->ai_termid.at_type);
1751 	STRUCT_FSET(apinfo, ap_termid.at_addr[0], ainfo->ai_termid.at_addr[0]);
1752 	STRUCT_FSET(apinfo, ap_termid.at_addr[1], ainfo->ai_termid.at_addr[1]);
1753 	STRUCT_FSET(apinfo, ap_termid.at_addr[2], ainfo->ai_termid.at_addr[2]);
1754 	STRUCT_FSET(apinfo, ap_termid.at_addr[3], ainfo->ai_termid.at_addr[3]);
1755 	STRUCT_FSET(apinfo, ap_mask, ainfo->ai_mask);
1756 
1757 	crfree(cr);
1758 
1759 	if (copyout(STRUCT_BUF(apinfo), data, STRUCT_SIZE(apinfo)))
1760 		return (EFAULT);
1761 
1762 	return (0);
1763 }
1764 
1765 static int
1766 setpmask(caddr_t data)
1767 {
1768 	STRUCT_DECL(auditpinfo, apinfo);
1769 	proc_t *proc;
1770 	cred_t	*newcred;
1771 	auditinfo_addr_t	*ainfo;
1772 	struct p_audit_data	*pad;
1773 
1774 	model_t	model;
1775 
1776 	model = get_udatamodel();
1777 	STRUCT_INIT(apinfo, model);
1778 
1779 	if (copyin(data, STRUCT_BUF(apinfo), STRUCT_SIZE(apinfo)))
1780 		return (EFAULT);
1781 
1782 	mutex_enter(&pidlock);
1783 	if ((proc = prfind(STRUCT_FGET(apinfo, ap_pid))) == NULL) {
1784 		mutex_exit(&pidlock);
1785 		return (ESRCH);
1786 	}
1787 	mutex_enter(&proc->p_lock);	/* so process doesn't go away */
1788 	mutex_exit(&pidlock);
1789 
1790 	newcred = cralloc();
1791 	if ((ainfo = crgetauinfo_modifiable(newcred)) == NULL) {
1792 		mutex_exit(&proc->p_lock);
1793 		crfree(newcred);
1794 		return (EINVAL);
1795 	}
1796 
1797 	mutex_enter(&proc->p_crlock);
1798 	crcopy_to(proc->p_cred, newcred);
1799 	proc->p_cred = newcred;
1800 
1801 	ainfo->ai_mask = STRUCT_FGET(apinfo, ap_mask);
1802 
1803 	/*
1804 	 * Unlock. No need to broadcast changes via set_proc_pre_sys(),
1805 	 * since t_pre_sys is ALWAYS on when audit is enabled... due to
1806 	 * syscall auditing.
1807 	 */
1808 	crfree(newcred);
1809 	mutex_exit(&proc->p_crlock);
1810 
1811 	/* Reset flag for any previous pending mask change; this supercedes */
1812 	pad = P2A(proc);
1813 	ASSERT(pad != NULL);
1814 	mutex_enter(&(pad->pad_lock));
1815 	pad->pad_flags &= ~PAD_SETMASK;
1816 	mutex_exit(&(pad->pad_lock));
1817 
1818 	mutex_exit(&proc->p_lock);
1819 
1820 	return (0);
1821 }
1822 
1823 static int
1824 getfsize(caddr_t data)
1825 {
1826 	au_fstat_t fstat;
1827 	au_kcontext_t	*kctx = SET_KCTX_PZ;
1828 
1829 	mutex_enter(&(kctx->auk_fstat_lock));
1830 	fstat.af_filesz = kctx->auk_file_stat.af_filesz;
1831 	fstat.af_currsz = kctx->auk_file_stat.af_currsz;
1832 	mutex_exit(&(kctx->auk_fstat_lock));
1833 
1834 	if (copyout(&fstat, data, sizeof (au_fstat_t)))
1835 		return (EFAULT);
1836 
1837 	return (0);
1838 }
1839 
1840 static int
1841 setfsize(caddr_t data)
1842 {
1843 	au_fstat_t fstat;
1844 	au_kcontext_t	*kctx;
1845 
1846 	if (!(audit_policy & AUDIT_PERZONE) && !INGLOBALZONE(curproc))
1847 		return (EINVAL);
1848 
1849 	kctx = SET_KCTX_LZ;
1850 
1851 	if (copyin(data, &fstat, sizeof (au_fstat_t)))
1852 		return (EFAULT);
1853 
1854 	if ((fstat.af_filesz != 0) && (fstat.af_filesz < AU_MIN_FILE_SZ))
1855 		return (EINVAL);
1856 
1857 	mutex_enter(&(kctx->auk_fstat_lock));
1858 	kctx->auk_file_stat.af_filesz = fstat.af_filesz;
1859 	mutex_exit(&(kctx->auk_fstat_lock));
1860 
1861 	return (0);
1862 }
1863 /*
1864  * The out of control system call
1865  * This is audit kitchen sink aka auditadm, aka auditon
1866  */
1867 static int
1868 auditctl(
1869 	int	cmd,
1870 	caddr_t data,
1871 	int	length)
1872 {
1873 	int result;
1874 
1875 	if (!audit_active)
1876 		return (EINVAL);
1877 
1878 	switch (cmd) {
1879 	case A_GETCOND:
1880 		break;
1881 	case A_GETCAR:
1882 	case A_GETCLASS:
1883 	case A_GETCWD:
1884 	case A_GETFSIZE:
1885 	case A_GETKAUDIT:
1886 	case A_GETKMASK:
1887 	case A_GETPINFO:
1888 	case A_GETPINFO_ADDR:
1889 	case A_GETPOLICY:
1890 	case A_GETQCTRL:
1891 	case A_GETSTAT:
1892 		if (secpolicy_audit_getattr(CRED()) != 0)
1893 			return (EPERM);
1894 		break;
1895 	default:
1896 		if (secpolicy_audit_config(CRED()) != 0)
1897 			return (EPERM);
1898 		break;
1899 	}
1900 
1901 	switch (cmd) {
1902 	case A_GETPOLICY:
1903 		result = getpolicy(data);
1904 		break;
1905 	case A_SETPOLICY:
1906 		result = setpolicy(data);
1907 		break;
1908 	case A_GETKMASK:
1909 		result = getkmask(data);
1910 		break;
1911 	case A_SETKMASK:
1912 		result = setkmask(data);
1913 		break;
1914 	case A_GETKAUDIT:
1915 		result = getkaudit(data, length);
1916 		break;
1917 	case A_SETKAUDIT:
1918 		result = setkaudit(data, length);
1919 		break;
1920 	case A_GETQCTRL:
1921 		result = getqctrl(data);
1922 		break;
1923 	case A_SETQCTRL:
1924 		result = setqctrl(data);
1925 		break;
1926 	case A_GETCWD:
1927 		result = getcwd(data, length);
1928 		break;
1929 	case A_GETCAR:
1930 		result = getcar(data, length);
1931 		break;
1932 	case A_GETSTAT:
1933 		result = getstat(data);
1934 		break;
1935 	case A_SETSTAT:
1936 		result = setstat(data);
1937 		break;
1938 	case A_SETUMASK:
1939 		result = setumask(data);
1940 		break;
1941 	case A_SETSMASK:
1942 		result = setsmask(data);
1943 		break;
1944 	case A_GETCOND:
1945 		result = getcond(data);
1946 		break;
1947 	case A_SETCOND:
1948 		result = setcond(data);
1949 		break;
1950 	case A_GETCLASS:
1951 		result = getclass(data);
1952 		break;
1953 	case A_SETCLASS:
1954 		result = setclass(data);
1955 		break;
1956 	case A_GETPINFO:
1957 		result = getpinfo(data);
1958 		break;
1959 	case A_GETPINFO_ADDR:
1960 		result = getpinfo_addr(data, length);
1961 		break;
1962 	case A_SETPMASK:
1963 		result = setpmask(data);
1964 		break;
1965 	case A_SETFSIZE:
1966 		result = setfsize(data);
1967 		break;
1968 	case A_GETFSIZE:
1969 		result = getfsize(data);
1970 		break;
1971 	default:
1972 		result = EINVAL;
1973 		break;
1974 	}
1975 	return (result);
1976 }
1977 
1978 /*
1979  * auditsvc was EOL'd effective Sol 10
1980  */
1981 static int
1982 auditsvc(int fd, int limit)
1983 {
1984 	struct file *fp;
1985 	struct vnode *vp;
1986 	int error = 0;
1987 	au_kcontext_t	*kctx;
1988 
1989 	if (secpolicy_audit_config(CRED()) != 0)
1990 		return (EPERM);
1991 
1992 	if (!INGLOBALZONE(curproc))
1993 		return (EINVAL);
1994 
1995 	kctx = SET_KCTX_GZ;
1996 
1997 	if (limit < 0 ||
1998 	    (!(kctx->auk_auditstate == AUC_AUDITING ||
1999 	    kctx->auk_auditstate == AUC_NOSPACE)))
2000 		return (EINVAL);
2001 
2002 	/*
2003 	 * Prevent a second audit daemon from running this code
2004 	 */
2005 	mutex_enter(&(kctx->auk_svc_lock));
2006 	if (kctx->auk_svc_busy) {
2007 		mutex_exit(&(kctx->auk_svc_lock));
2008 		return (EBUSY);
2009 	}
2010 	kctx->auk_svc_busy = 1;
2011 	mutex_exit(&(kctx->auk_svc_lock));
2012 
2013 	/*
2014 	 * convert file pointer to file descriptor
2015 	 *   Note: fd ref count incremented here.
2016 	 */
2017 	if ((fp = (struct file *)getf(fd)) == NULL) {
2018 		mutex_enter(&(kctx->auk_svc_lock));
2019 		kctx->auk_svc_busy = 0;
2020 		mutex_exit(&(kctx->auk_svc_lock));
2021 		return (EBADF);
2022 	}
2023 
2024 	vp = fp->f_vnode;
2025 
2026 	kctx->auk_file_stat.af_currsz = 0;
2027 
2028 	/*
2029 	 * Wait for work, until a signal arrives,
2030 	 * or until auditing is disabled.
2031 	 */
2032 	while (!error) {
2033 	    if (kctx->auk_auditstate == AUC_AUDITING) {
2034 		mutex_enter(&(kctx->auk_queue.lock));
2035 		    /* nothing on the audit queue */
2036 		while (kctx->auk_queue.head == NULL) {
2037 			/* safety check. kick writer awake */
2038 		    if (kctx->auk_queue.wt_block)
2039 			cv_broadcast(&(kctx->auk_queue.write_cv));
2040 			/* sleep waiting for things to to */
2041 		    kctx->auk_queue.rd_block = 1;
2042 		    AS_INC(as_rblocked, 1, kctx);
2043 		    if (!cv_wait_sig(&(kctx->auk_queue.read_cv),
2044 			&(kctx->auk_queue.lock))) {
2045 				/* interrupted system call */
2046 			kctx->auk_queue.rd_block = 0;
2047 			mutex_exit(&(kctx->auk_queue.lock));
2048 			error = ((kctx->auk_auditstate == AUC_AUDITING) ||
2049 			    (kctx->auk_auditstate == AUC_NOSPACE)) ?
2050 			    EINTR : EINVAL;
2051 			mutex_enter(&(kctx->auk_svc_lock));
2052 			kctx->auk_svc_busy = 0;
2053 			mutex_exit(&(kctx->auk_svc_lock));
2054 
2055 		/* decrement file descriptor reference count */
2056 			releasef(fd);
2057 			(void) timeout(audit_dont_stop, kctx, au_resid);
2058 			return (error);
2059 		    }
2060 		    kctx->auk_queue.rd_block = 0;
2061 		}
2062 		mutex_exit(&(kctx->auk_queue.lock));
2063 
2064 			/* do as much as we can */
2065 		error = au_doio(vp, limit);
2066 
2067 		/* if we ran out of space, be sure to fire off timeout */
2068 		if (error == ENOSPC)
2069 			(void) timeout(audit_dont_stop, kctx, au_resid);
2070 
2071 	    } else	/* auditing turned off while we slept */
2072 		    break;
2073 	}
2074 
2075 	/*
2076 	 * decrement file descriptor reference count
2077 	 */
2078 	releasef(fd);
2079 
2080 	/*
2081 	 * If auditing has been disabled quit processing
2082 	 */
2083 	if (!(kctx->auk_auditstate == AUC_AUDITING ||
2084 	    kctx->auk_auditstate == AUC_NOSPACE))
2085 		error = EINVAL;
2086 
2087 	mutex_enter(&(kctx->auk_svc_lock));
2088 	kctx->auk_svc_busy = 0;
2089 	mutex_exit(&(kctx->auk_svc_lock));
2090 
2091 	return (error);
2092 }
2093 
2094 static int
2095 audit_modsysent(char *modname, int flags, int (*func)())
2096 {
2097 	struct sysent *sysp;
2098 	int sysnum;
2099 	krwlock_t *kl;
2100 
2101 	if ((sysnum = mod_getsysnum(modname)) == -1) {
2102 		cmn_err(CE_WARN, "system call missing from bind file");
2103 		return (-1);
2104 	}
2105 
2106 	kl = (krwlock_t *)kobj_zalloc(sizeof (krwlock_t), KM_SLEEP);
2107 
2108 	sysp = &sysent[sysnum];
2109 	sysp->sy_narg = auditsysent.sy_narg;
2110 #ifdef _LP64
2111 	sysp->sy_flags = (unsigned short)flags;
2112 #else
2113 	sysp->sy_flags = (unsigned char)flags;
2114 #endif
2115 	sysp->sy_call = func;
2116 	sysp->sy_lock = kl;
2117 
2118 #ifdef _SYSCALL32_IMPL
2119 	sysp = &sysent32[sysnum];
2120 	sysp->sy_narg = auditsysent.sy_narg;
2121 	sysp->sy_flags = (unsigned short)flags;
2122 	sysp->sy_call = func;
2123 	sysp->sy_lock = kl;
2124 #endif
2125 
2126 	rw_init(sysp->sy_lock, NULL, RW_DEFAULT, NULL);
2127 
2128 	return (0);
2129 }
2130