xref: /freebsd/sys/security/audit/audit_bsm.c (revision 0bb263df82e129f5f8c82da6deb55dfe10daa677)
1 /*
2  * Copyright (c) 1999-2005 Apple Computer, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 
32 #include <sys/param.h>
33 #include <sys/vnode.h>
34 #include <sys/ipc.h>
35 #include <sys/lock.h>
36 #include <sys/malloc.h>
37 #include <sys/mutex.h>
38 #include <sys/socket.h>
39 #include <sys/extattr.h>
40 #include <sys/fcntl.h>
41 #include <sys/user.h>
42 #include <sys/systm.h>
43 
44 #include <bsm/audit.h>
45 #include <bsm/audit_internal.h>
46 #include <bsm/audit_record.h>
47 #include <bsm/audit_kevents.h>
48 
49 #include <security/audit/audit.h>
50 #include <security/audit/audit_private.h>
51 
52 #include <netinet/in_systm.h>
53 #include <netinet/in.h>
54 #include <netinet/ip.h>
55 
56 MALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
57 
58 static void	audit_sys_auditon(struct audit_record *ar,
59 		    struct au_record *rec);
60 
61 /*
62  * Initialize the BSM auditing subsystem.
63  */
64 void
65 kau_init(void)
66 {
67 
68 	printf("BSM auditing present\n");
69 	au_evclassmap_init();
70 }
71 
72 /*
73  * This call reserves memory for the audit record.  Memory must be guaranteed
74  * before any auditable event can be generated.  The au_record structure
75  * maintains a reference to the memory allocated above and also the list of
76  * tokens associated with this record
77  */
78 static struct au_record *
79 kau_open(void)
80 {
81 	struct au_record *rec;
82 
83 	rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK);
84 	rec->data = NULL;
85 	TAILQ_INIT(&rec->token_q);
86 	rec->len = 0;
87 	rec->used = 1;
88 
89 	return (rec);
90 }
91 
92 /*
93  * Store the token with the record descriptor.
94  */
95 static void
96 kau_write(struct au_record *rec, struct au_token *tok)
97 {
98 
99 	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
100 
101 	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
102 	rec->len += tok->len;
103 }
104 
105 /*
106  * Close out the audit record by adding the header token, identifying any
107  * missing tokens.  Write out the tokens to the record memory.
108  */
109 static void
110 kau_close(struct au_record *rec, struct timespec *ctime, short event)
111 {
112 	u_char *dptr;
113 	size_t tot_rec_size;
114 	token_t *cur, *hdr, *trail;
115 	struct timeval tm;
116 
117 	tot_rec_size = rec->len + AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE;
118 	rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO);
119 
120 	tm.tv_usec = ctime->tv_nsec / 1000;
121 	tm.tv_sec = ctime->tv_sec;
122 	hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
123 	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
124 
125 	trail = au_to_trailer(tot_rec_size);
126 	TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
127 
128 	rec->len = tot_rec_size;
129 	dptr = rec->data;
130 	TAILQ_FOREACH(cur, &rec->token_q, tokens) {
131 		memcpy(dptr, cur->t_data, cur->len);
132 		dptr += cur->len;
133 	}
134 }
135 
136 /*
137  * Free a BSM audit record by releasing all the tokens and clearing the audit
138  * record information.
139  */
140 void
141 kau_free(struct au_record *rec)
142 {
143 	struct au_token *tok;
144 
145 	/* Free the token list. */
146 	while ((tok = TAILQ_FIRST(&rec->token_q))) {
147 		TAILQ_REMOVE(&rec->token_q, tok, tokens);
148 		free(tok->t_data, M_AUDITBSM);
149 		free(tok, M_AUDITBSM);
150 	}
151 
152 	rec->used = 0;
153 	rec->len = 0;
154 	free(rec->data, M_AUDITBSM);
155 	free(rec, M_AUDITBSM);
156 }
157 
158 /*
159  * XXX: May want turn some (or all) of these macros into functions in order
160  * to reduce the generated code sized.
161  *
162  * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
163  * caller are OK with this.
164  */
165 #define UPATH1_TOKENS do {						\
166 	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
167 		tok = au_to_path(ar->ar_arg_upath1);			\
168 		kau_write(rec, tok);					\
169 	}								\
170 } while (0)
171 
172 #define UPATH2_TOKENS do {						\
173 	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
174 		tok = au_to_path(ar->ar_arg_upath2);			\
175 		kau_write(rec, tok);					\
176 	}								\
177 } while (0)
178 
179 #define VNODE1_TOKENS do {						\
180 	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
181 		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
182 		kau_write(rec, tok);					\
183 	}								\
184 } while (0)
185 
186 #define UPATH1_VNODE1_TOKENS do {					\
187 	if (ARG_IS_VALID(kar, ARG_UPATH1)) {  				\
188 		UPATH1_TOKENS;						\
189 	}								\
190 	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
191 		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
192 		kau_write(rec, tok);					\
193 	}								\
194 } while (0)
195 
196 #define VNODE2_TOKENS do {						\
197 	if (ARG_IS_VALID(kar, ARG_VNODE2)) {  				\
198 		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
199 		kau_write(rec, tok);					\
200 	}								\
201 } while (0)
202 
203 #define FD_VNODE1_TOKENS	do {					\
204 	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
205 		if (ARG_IS_VALID(kar, ARG_FD)) {			\
206 			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
207 			kau_write(rec, tok);				\
208 		}							\
209 		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
210 		kau_write(rec, tok);					\
211 	} else {							\
212 		if (ARG_IS_VALID(kar, ARG_FD)) {			\
213 			tok = au_to_arg32(1, "non-file: fd",		\
214 			    ar->ar_arg_fd);				\
215 			kau_write(rec, tok);				\
216 		}							\
217 	}								\
218 } while (0)
219 
220 #define PROCESS_PID_TOKENS(argn) do {					\
221 	if ((ar->ar_arg_pid > 0) /* Reference a single process */	\
222 	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {			\
223 		tok = au_to_process(ar->ar_arg_auid,			\
224 		    ar->ar_arg_euid, ar->ar_arg_egid,			\
225 		    ar->ar_arg_ruid, ar->ar_arg_rgid,			\
226 		    ar->ar_arg_pid, ar->ar_arg_asid,			\
227 		    &ar->ar_arg_termid);				\
228 		kau_write(rec, tok);					\
229 	} else if (ARG_IS_VALID(kar, ARG_PID)) {			\
230 		tok = au_to_arg32(argn, "process", ar->ar_arg_pid);	\
231 		kau_write(rec, tok);					\
232 	}								\
233 } while (0)								\
234 
235 #define EXTATTR_TOKENS	do {						\
236 	if (ARG_IS_VALID(kar, ARG_VALUE)) {				\
237 		switch (ar->ar_arg_value) {				\
238 		case EXTATTR_NAMESPACE_USER:				\
239 			tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
240 			break;						\
241 		case EXTATTR_NAMESPACE_SYSTEM:				\
242 			tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
243 			break;						\
244 		default:						\
245 			tok = au_to_arg32(3, "attrnamespace",		\
246 			    ar->ar_arg_value);				\
247 			break;						\
248 		}							\
249 		kau_write(rec, tok);					\
250 	}								\
251 	/* attrname is in the text field */				\
252 	if (ARG_IS_VALID(kar, ARG_TEXT)) {				\
253 		tok = au_to_text(ar->ar_arg_text);			\
254 		kau_write(rec, tok);					\
255 	}								\
256 } while (0)
257 
258 /*
259  * Implement auditing for the auditon() system call. The audit tokens that
260  * are generated depend on the command that was sent into the auditon()
261  * system call.
262  */
263 static void
264 audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
265 {
266 	struct au_token *tok;
267 
268 	switch (ar->ar_arg_cmd) {
269 	case A_SETPOLICY:
270 		if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
271 			tok = au_to_arg64(1, "policy",
272 			    ar->ar_arg_auditon.au_flags);
273 		else
274 			tok = au_to_arg32(1, "policy",
275 			    ar->ar_arg_auditon.au_flags);
276 		kau_write(rec, tok);
277 		break;
278 
279 	case A_SETKMASK:
280 		tok = au_to_arg32(2, "setkmask:as_success",
281 		    ar->ar_arg_auditon.au_mask.am_success);
282 		kau_write(rec, tok);
283 		tok = au_to_arg32(2, "setkmask:as_failure",
284 		    ar->ar_arg_auditon.au_mask.am_failure);
285 		kau_write(rec, tok);
286 		break;
287 
288 	case A_SETQCTRL:
289 		tok = au_to_arg32(3, "setqctrl:aq_hiwater",
290 		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
291 		kau_write(rec, tok);
292 		tok = au_to_arg32(3, "setqctrl:aq_lowater",
293 		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
294 		kau_write(rec, tok);
295 		tok = au_to_arg32(3, "setqctrl:aq_bufsz",
296 		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
297 		kau_write(rec, tok);
298 		tok = au_to_arg32(3, "setqctrl:aq_delay",
299 		    ar->ar_arg_auditon.au_qctrl.aq_delay);
300 		kau_write(rec, tok);
301 		tok = au_to_arg32(3, "setqctrl:aq_minfree",
302 		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
303 		kau_write(rec, tok);
304 		break;
305 
306 	case A_SETUMASK:
307 		tok = au_to_arg32(3, "setumask:as_success",
308 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
309 		kau_write(rec, tok);
310 		tok = au_to_arg32(3, "setumask:as_failure",
311 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
312 		kau_write(rec, tok);
313 		break;
314 
315 	case A_SETSMASK:
316 		tok = au_to_arg32(3, "setsmask:as_success",
317 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
318 		kau_write(rec, tok);
319 		tok = au_to_arg32(3, "setsmask:as_failure",
320 		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
321 		kau_write(rec, tok);
322 		break;
323 
324 	case A_SETCOND:
325 		if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
326 			tok = au_to_arg64(3, "setcond",
327 			    ar->ar_arg_auditon.au_cond);
328 		else
329 			tok = au_to_arg32(3, "setcond",
330 			    ar->ar_arg_auditon.au_cond);
331 		kau_write(rec, tok);
332 		break;
333 
334 	case A_SETCLASS:
335 		tok = au_to_arg32(2, "setclass:ec_event",
336 		    ar->ar_arg_auditon.au_evclass.ec_number);
337 		kau_write(rec, tok);
338 		tok = au_to_arg32(3, "setclass:ec_class",
339 		    ar->ar_arg_auditon.au_evclass.ec_class);
340 		kau_write(rec, tok);
341 		break;
342 
343 	case A_SETPMASK:
344 		tok = au_to_arg32(2, "setpmask:as_success",
345 		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
346 		kau_write(rec, tok);
347 		tok = au_to_arg32(2, "setpmask:as_failure",
348 		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
349 		kau_write(rec, tok);
350 		break;
351 
352 	case A_SETFSIZE:
353 		tok = au_to_arg32(2, "setfsize:filesize",
354 		    ar->ar_arg_auditon.au_fstat.af_filesz);
355 		kau_write(rec, tok);
356 		break;
357 
358 	default:
359 		break;
360 	}
361 }
362 
363 /*
364  * Convert an internal kernel audit record to a BSM record and return a
365  * success/failure indicator. The BSM record is passed as an out parameter to
366  * this function.
367  *
368  * Return conditions:
369  *   BSM_SUCCESS: The BSM record is valid
370  *   BSM_FAILURE: Failure; the BSM record is NULL.
371  *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
372  */
373 int
374 kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
375 {
376 	struct au_token *tok, *subj_tok;
377 	struct au_record *rec;
378 	au_tid_t tid;
379 	struct audit_record *ar;
380 	int ctr;
381 
382 	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
383 
384 	*pau = NULL;
385 	ar = &kar->k_ar;
386 	rec = kau_open();
387 
388 	/* Create the subject token */
389 	switch (ar->ar_subj_term_addr.at_type) {
390 	case AU_IPv4:
391 		tid.port = ar->ar_subj_term_addr.at_port;
392 		tid.machine = ar->ar_subj_term_addr.at_addr[0];
393 		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
394 		    ar->ar_subj_cred.cr_uid, /* eff uid */
395 		    ar->ar_subj_egid,	/* eff group id */
396 		    ar->ar_subj_ruid, 	/* real uid */
397 		    ar->ar_subj_rgid, 	/* real group id */
398 		    ar->ar_subj_pid,	/* process id */
399 		    ar->ar_subj_asid,	/* session ID */
400 		    &tid);
401 		break;
402 	case AU_IPv6:
403 		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
404 		    ar->ar_subj_cred.cr_uid,
405 		    ar->ar_subj_egid,
406 		    ar->ar_subj_ruid,
407 		    ar->ar_subj_rgid,
408 		    ar->ar_subj_pid,
409 		    ar->ar_subj_asid,
410 		    &ar->ar_subj_term_addr);
411 		break;
412 	default:
413 		bzero(&tid, sizeof(tid));
414 		subj_tok = au_to_subject32(ar->ar_subj_auid,
415 		    ar->ar_subj_cred.cr_uid,
416 		    ar->ar_subj_egid,
417 		    ar->ar_subj_ruid,
418 		    ar->ar_subj_rgid,
419 		    ar->ar_subj_pid,
420 		    ar->ar_subj_asid,
421 		    &tid);
422 	}
423 
424 	/*
425 	 * The logic inside each case fills in the tokens required for the
426 	 * event, except for the header, trailer, and return tokens.  The
427 	 * header and trailer tokens are added by the kau_close() function.
428 	 * The return token is added outside of the switch statement.
429 	 */
430 	switch(ar->ar_event) {
431 	case AUE_ACCEPT:
432 	case AUE_BIND:
433 	case AUE_CONNECT:
434 	case AUE_RECV:
435 	case AUE_RECVFROM:
436 	case AUE_RECVMSG:
437 	case AUE_SEND:
438 	case AUE_SENDFILE:
439 	case AUE_SENDMSG:
440 	case AUE_SENDTO:
441 		/*
442 		 * Socket-related events.
443 		 */
444 		if (ARG_IS_VALID(kar, ARG_FD)) {
445 			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
446 			kau_write(rec, tok);
447 		}
448 		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
449 			tok = au_to_sock_inet((struct sockaddr_in *)
450 			    &ar->ar_arg_sockaddr);
451 			kau_write(rec, tok);
452 		}
453 		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
454 			tok = au_to_sock_unix((struct sockaddr_un *)
455 			    &ar->ar_arg_sockaddr);
456 			kau_write(rec, tok);
457 			UPATH1_TOKENS;
458 		}
459 		/* XXX Need to handle ARG_SADDRINET6 */
460 		break;
461 
462 	case AUE_SOCKET:
463 	case AUE_SOCKETPAIR:
464 		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
465 			tok = au_to_arg32(1,"domain",
466 			    ar->ar_arg_sockinfo.so_domain);
467 			kau_write(rec, tok);
468 			tok = au_to_arg32(2,"type",
469 			    ar->ar_arg_sockinfo.so_type);
470 			kau_write(rec, tok);
471 			tok = au_to_arg32(3,"protocol",
472 			    ar->ar_arg_sockinfo.so_protocol);
473 			kau_write(rec, tok);
474 		}
475 		break;
476 
477 	case AUE_SETSOCKOPT:
478 	case AUE_SHUTDOWN:
479 		if (ARG_IS_VALID(kar, ARG_FD)) {
480 			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
481 			kau_write(rec, tok);
482 		}
483 		break;
484 
485 	case AUE_ACCT:
486 		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
487 			UPATH1_VNODE1_TOKENS;
488 		} else {
489 			tok = au_to_arg32(1, "accounting off", 0);
490 			kau_write(rec, tok);
491 		}
492 		break;
493 
494 	case AUE_SETAUID:
495 		if (ARG_IS_VALID(kar, ARG_AUID)) {
496 			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
497 			kau_write(rec, tok);
498 		}
499 		break;
500 
501 	case AUE_SETAUDIT:
502 		if (ARG_IS_VALID(kar, ARG_AUID)) {
503 			tok = au_to_arg32(1, "setaudit:auid",
504 			    ar->ar_arg_auid);
505 			kau_write(rec, tok);
506 			tok = au_to_arg32(1, "setaudit:port",
507 			    ar->ar_arg_termid.port);
508 			kau_write(rec, tok);
509 			tok = au_to_arg32(1, "setaudit:machine",
510 			    ar->ar_arg_termid.machine);
511 			kau_write(rec, tok);
512 			tok = au_to_arg32(1, "setaudit:as_success",
513 			    ar->ar_arg_amask.am_success);
514 			kau_write(rec, tok);
515 			tok = au_to_arg32(1, "setaudit:as_failure",
516 			    ar->ar_arg_amask.am_failure);
517 			kau_write(rec, tok);
518 			tok = au_to_arg32(1, "setaudit:asid",
519 			    ar->ar_arg_asid);
520 			kau_write(rec, tok);
521 		}
522 		break;
523 
524 	case AUE_SETAUDIT_ADDR:
525 		break;		/* XXX need to add arguments */
526 
527 	case AUE_AUDITON:
528 		/*
529 		 * For AUDITON commands without own event, audit the cmd.
530 		 */
531 		if (ARG_IS_VALID(kar, ARG_CMD)) {
532 			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
533 			kau_write(rec, tok);
534 		}
535 		/* fall thru */
536 
537 	case AUE_AUDITON_GETCAR:
538 	case AUE_AUDITON_GETCLASS:
539 	case AUE_AUDITON_GETCOND:
540 	case AUE_AUDITON_GETCWD:
541 	case AUE_AUDITON_GETKMASK:
542 	case AUE_AUDITON_GETSTAT:
543 	case AUE_AUDITON_GPOLICY:
544 	case AUE_AUDITON_GQCTRL:
545 	case AUE_AUDITON_SETCLASS:
546 	case AUE_AUDITON_SETCOND:
547 	case AUE_AUDITON_SETKMASK:
548 	case AUE_AUDITON_SETSMASK:
549 	case AUE_AUDITON_SETSTAT:
550 	case AUE_AUDITON_SETUMASK:
551 	case AUE_AUDITON_SPOLICY:
552 	case AUE_AUDITON_SQCTRL:
553 		if (ARG_IS_VALID(kar, ARG_AUDITON))
554 			audit_sys_auditon(ar, rec);
555 		break;
556 
557 	case AUE_AUDITCTL:
558 		UPATH1_VNODE1_TOKENS;
559 		break;
560 
561 	case AUE_EXIT:
562 		if (ARG_IS_VALID(kar, ARG_EXIT)) {
563 			tok = au_to_exit(ar->ar_arg_exitretval,
564 			    ar->ar_arg_exitstatus);
565 			kau_write(rec, tok);
566 		}
567 		break;
568 
569 	case AUE_ADJTIME:
570 	case AUE_CLOCK_SETTIME:
571 	case AUE_AUDIT:
572 	case AUE_DUP2:
573 	case AUE_GETAUDIT:
574 	case AUE_GETAUDIT_ADDR:
575 	case AUE_GETAUID:
576 	case AUE_GETCWD:
577 	case AUE_GETFSSTAT:
578 	case AUE_GETRESUID:
579 	case AUE_GETRESGID:
580 	case AUE_KQUEUE:
581 	case AUE_LSEEK:
582 	case AUE_MODLOAD:
583 	case AUE_MODUNLOAD:
584 	case AUE_MSGSYS:
585 	case AUE_NFS_SVC:
586 	case AUE_NTP_ADJTIME:
587 	case AUE_PIPE:
588 	case AUE_PROFILE:
589 	case AUE_RTPRIO:
590 	case AUE_SEMSYS:
591 	case AUE_SHMSYS:
592 	case AUE_SETPGRP:
593 	case AUE_SETRLIMIT:
594 	case AUE_SETSID:
595 	case AUE_SETTIMEOFDAY:
596 	case AUE_SYSARCH:
597 
598 		/*
599 		 * Header, subject, and return tokens added at end.
600 		 */
601 		break;
602 
603 	case AUE_MKFIFO:
604 		if (ARG_IS_VALID(kar, ARG_MODE)) {
605 			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
606 			kau_write(rec, tok);
607 		}
608 		/* fall through */
609 	case AUE_ACCESS:
610 	case AUE_CHDIR:
611 	case AUE_CHROOT:
612 	case AUE_EACCESS:
613 	case AUE_GETATTRLIST:
614 	case AUE_JAIL:
615 	case AUE_LUTIMES:
616 	case AUE_NFS_GETFH:
617 	case AUE_LSTAT:
618 	case AUE_PATHCONF:
619 	case AUE_READLINK:
620 	case AUE_REVOKE:
621 	case AUE_RMDIR:
622 	case AUE_SEARCHFS:
623 	case AUE_SETATTRLIST:
624 	case AUE_STAT:
625 	case AUE_STATFS:
626 	case AUE_SWAPON:
627 	case AUE_SWAPOFF:
628 	case AUE_TRUNCATE:
629 	case AUE_UNDELETE:
630 	case AUE_UNLINK:
631 	case AUE_UTIMES:
632 		UPATH1_VNODE1_TOKENS;
633 		break;
634 
635 	case AUE_FHSTATFS:
636 	case AUE_FHOPEN:
637 	case AUE_FHSTAT:
638 		/* XXXRW: Need to audit vnode argument. */
639 		break;
640 
641 	case AUE_CHFLAGS:
642 	case AUE_LCHFLAGS:
643 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
644 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
645 			kau_write(rec, tok);
646 		}
647 		UPATH1_VNODE1_TOKENS;
648 		break;
649 
650 	case AUE_CHMOD:
651 	case AUE_LCHMOD:
652 		if (ARG_IS_VALID(kar, ARG_MODE)) {
653 			tok = au_to_arg32(2, "new file mode",
654 			    ar->ar_arg_mode);
655 			kau_write(rec, tok);
656 		}
657 		UPATH1_VNODE1_TOKENS;
658 		break;
659 
660 	case AUE_CHOWN:
661 	case AUE_LCHOWN:
662 		if (ARG_IS_VALID(kar, ARG_UID)) {
663 			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
664 			kau_write(rec, tok);
665 		}
666 		if (ARG_IS_VALID(kar, ARG_GID)) {
667 			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
668 			kau_write(rec, tok);
669 		}
670 		UPATH1_VNODE1_TOKENS;
671 		break;
672 
673 	case AUE_EXCHANGEDATA:
674 		UPATH1_VNODE1_TOKENS;
675 		UPATH2_TOKENS;
676 		break;
677 
678 	case AUE_CLOSE:
679 		if (ARG_IS_VALID(kar, ARG_FD)) {
680 			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
681 			kau_write(rec, tok);
682 		}
683 		UPATH1_VNODE1_TOKENS;
684 		break;
685 
686 	case AUE_EXTATTRCTL:
687 		UPATH1_VNODE1_TOKENS;
688 		if (ARG_IS_VALID(kar, ARG_CMD)) {
689 			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
690 			kau_write(rec, tok);
691 		}
692 		/* extattrctl(2) filename parameter is in upath2/vnode2 */
693 		UPATH2_TOKENS;
694 		VNODE2_TOKENS;
695 		EXTATTR_TOKENS;
696 		break;
697 
698 	case AUE_EXTATTR_GET_FILE:
699 	case AUE_EXTATTR_SET_FILE:
700 	case AUE_EXTATTR_LIST_FILE:
701 	case AUE_EXTATTR_DELETE_FILE:
702 	case AUE_EXTATTR_GET_LINK:
703 	case AUE_EXTATTR_SET_LINK:
704 	case AUE_EXTATTR_LIST_LINK:
705 	case AUE_EXTATTR_DELETE_LINK:
706 		UPATH1_VNODE1_TOKENS;
707 		EXTATTR_TOKENS;
708 		break;
709 
710 	case AUE_EXTATTR_GET_FD:
711 	case AUE_EXTATTR_SET_FD:
712 	case AUE_EXTATTR_LIST_FD:
713 	case AUE_EXTATTR_DELETE_FD:
714 		if (ARG_IS_VALID(kar, ARG_FD)) {
715 			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
716 			kau_write(rec, tok);
717 		}
718 		EXTATTR_TOKENS;
719 		break;
720 
721 	case AUE_EXECVE:
722 		if (ARG_IS_VALID(kar, ARG_ARGV)) {
723 			tok = au_to_exec_args(ar->ar_arg_argv,
724 			    ar->ar_arg_argc);
725 			kau_write(rec, tok);
726 		}
727 		if (ARG_IS_VALID(kar, ARG_ENVV)) {
728 			tok = au_to_exec_env(ar->ar_arg_envv,
729 			    ar->ar_arg_envc);
730 			kau_write(rec, tok);
731 		}
732 		UPATH1_VNODE1_TOKENS;
733 		break;
734 
735 	case AUE_FCHMOD:
736 		if (ARG_IS_VALID(kar, ARG_MODE)) {
737 			tok = au_to_arg32(2, "new file mode",
738 			    ar->ar_arg_mode);
739 			kau_write(rec, tok);
740 		}
741 		FD_VNODE1_TOKENS;
742 		break;
743 
744 	/*
745 	 * XXXRW: Some of these need to handle non-vnode cases as well.
746 	 */
747 	case AUE_FCHDIR:
748 	case AUE_FPATHCONF:
749 	case AUE_FSTAT:
750 	case AUE_FSTATFS:
751 	case AUE_FSYNC:
752 	case AUE_FTRUNCATE:
753 	case AUE_FUTIMES:
754 	case AUE_GETDIRENTRIES:
755 	case AUE_GETDIRENTRIESATTR:
756 	case AUE_POLL:
757 	case AUE_READ:
758 	case AUE_READV:
759 	case AUE_WRITE:
760 	case AUE_WRITEV:
761 		FD_VNODE1_TOKENS;
762 		break;
763 
764 	case AUE_FCHOWN:
765 		if (ARG_IS_VALID(kar, ARG_UID)) {
766 			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
767 			kau_write(rec, tok);
768 		}
769 		if (ARG_IS_VALID(kar, ARG_GID)) {
770 			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
771 			kau_write(rec, tok);
772 		}
773 		FD_VNODE1_TOKENS;
774 		break;
775 
776 	case AUE_FCNTL:
777 		if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
778 			ar->ar_arg_cmd == F_SETLKW) {
779 			if (ARG_IS_VALID(kar, ARG_CMD)) {
780 				tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
781 				kau_write(rec, tok);
782 			}
783 			FD_VNODE1_TOKENS;
784 		}
785 		break;
786 
787 	case AUE_FCHFLAGS:
788 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
789 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
790 			kau_write(rec, tok);
791 		}
792 		FD_VNODE1_TOKENS;
793 		break;
794 
795 	case AUE_FLOCK:
796 		if (ARG_IS_VALID(kar, ARG_CMD)) {
797 			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
798 			kau_write(rec, tok);
799 		}
800 		FD_VNODE1_TOKENS;
801 		break;
802 
803 	case AUE_RFORK:
804 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
805 			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
806 			kau_write(rec, tok);
807 		}
808 		/* fall through */
809 	case AUE_FORK:
810 	case AUE_VFORK:
811 		if (ARG_IS_VALID(kar, ARG_PID)) {
812 			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
813 			kau_write(rec, tok);
814 		}
815 		break;
816 
817 	case AUE_IOCTL:
818 		if (ARG_IS_VALID(kar, ARG_CMD)) {
819 			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
820 			kau_write(rec, tok);
821 		}
822 		if (ARG_IS_VALID(kar, ARG_ADDR)) {
823 			tok = au_to_arg32(1, "arg",
824 			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
825 			kau_write(rec, tok);
826 		}
827 		if (ARG_IS_VALID(kar, ARG_VNODE1))
828 			FD_VNODE1_TOKENS;
829 		else {
830 			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
831 				tok = kau_to_socket(&ar->ar_arg_sockinfo);
832 				kau_write(rec, tok);
833 			} else {
834 				if (ARG_IS_VALID(kar, ARG_FD)) {
835 					tok = au_to_arg32(1, "fd",
836 					    ar->ar_arg_fd);
837 			    		kau_write(rec, tok);
838 				}
839 			}
840 		}
841 		break;
842 
843 	case AUE_KILL:
844 	case AUE_KILLPG:
845 		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
846 			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
847 			kau_write(rec, tok);
848 		}
849 		PROCESS_PID_TOKENS(1);
850 		break;
851 
852 	case AUE_KTRACE:
853 		if (ARG_IS_VALID(kar, ARG_CMD)) {
854 			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
855 			kau_write(rec, tok);
856 		}
857 		if (ARG_IS_VALID(kar, ARG_VALUE)) {
858 			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
859 			kau_write(rec, tok);
860 		}
861 		PROCESS_PID_TOKENS(4);
862 		UPATH1_VNODE1_TOKENS;
863 		break;
864 
865 	case AUE_LINK:
866 	case AUE_RENAME:
867 		UPATH1_VNODE1_TOKENS;
868 		UPATH2_TOKENS;
869 		break;
870 
871 	case AUE_LOADSHFILE:
872 		if (ARG_IS_VALID(kar, ARG_ADDR)) {
873 			tok = au_to_arg32(4, "base addr",
874 			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
875 			kau_write(rec, tok);
876 		}
877 		UPATH1_VNODE1_TOKENS;
878 		break;
879 
880 	case AUE_MKDIR:
881 		if (ARG_IS_VALID(kar, ARG_MODE)) {
882 			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
883 			kau_write(rec, tok);
884 		}
885 		UPATH1_VNODE1_TOKENS;
886 		break;
887 
888 	case AUE_MKNOD:
889 		if (ARG_IS_VALID(kar, ARG_MODE)) {
890 			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
891 			kau_write(rec, tok);
892 		}
893 		if (ARG_IS_VALID(kar, ARG_DEV)) {
894 			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
895 			kau_write(rec, tok);
896 		}
897 		UPATH1_VNODE1_TOKENS;
898 		break;
899 
900 	case AUE_MMAP:
901 	case AUE_MUNMAP:
902 	case AUE_MPROTECT:
903 	case AUE_MLOCK:
904 	case AUE_MUNLOCK:
905 	case AUE_MINHERIT:
906 		if (ARG_IS_VALID(kar, ARG_ADDR)) {
907 			tok = au_to_arg32(1, "addr",
908 			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
909 			kau_write(rec, tok);
910 		}
911 		if (ARG_IS_VALID(kar, ARG_LEN)) {
912 			tok = au_to_arg32(2, "len", ar->ar_arg_len);
913 			kau_write(rec, tok);
914 		}
915 		if (ar->ar_event == AUE_MMAP)
916 			FD_VNODE1_TOKENS;
917 		if (ar->ar_event == AUE_MPROTECT) {
918 			if (ARG_IS_VALID(kar, ARG_VALUE)) {
919 				tok = au_to_arg32(3, "protection",
920 				    ar->ar_arg_value);
921 				kau_write(rec, tok);
922 			}
923 		}
924 		if (ar->ar_event == AUE_MINHERIT) {
925 			if (ARG_IS_VALID(kar, ARG_VALUE)) {
926 				tok = au_to_arg32(3, "inherit",
927 				    ar->ar_arg_value);
928 				kau_write(rec, tok);
929 			}
930 		}
931 		break;
932 
933 	case AUE_MOUNT:
934 	case AUE_NMOUNT:
935 		/* XXX Need to handle NFS mounts */
936 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
937 			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
938 			kau_write(rec, tok);
939 		}
940 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
941 			tok = au_to_text(ar->ar_arg_text);
942 			kau_write(rec, tok);
943 		}
944 		/* fall through */
945 
946 	case AUE_UMOUNT:
947 		UPATH1_VNODE1_TOKENS;
948 		break;
949 
950 	case AUE_MSGCTL:
951 		ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd);
952 		/* Fall through */
953 
954 	case AUE_MSGRCV:
955 	case AUE_MSGSND:
956 		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
957 		kau_write(rec, tok);
958 		if (ar->ar_errno != EINVAL) {
959 			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
960 			kau_write(rec, tok);
961 		}
962 		break;
963 
964 	case AUE_MSGGET:
965 		if (ar->ar_errno == 0) {
966 			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
967 				tok = au_to_ipc(AT_IPC_MSG,
968 				    ar->ar_arg_svipc_id);
969 				kau_write(rec, tok);
970 			}
971 		}
972 		break;
973 
974 	case AUE_RESETSHFILE:
975 		if (ARG_IS_VALID(kar, ARG_ADDR)) {
976 			tok = au_to_arg32(1, "base addr",
977 			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
978 			kau_write(rec, tok);
979 		}
980 		break;
981 
982 	case AUE_OPEN_RC:
983 	case AUE_OPEN_RTC:
984 	case AUE_OPEN_RWC:
985 	case AUE_OPEN_RWTC:
986 	case AUE_OPEN_WC:
987 	case AUE_OPEN_WTC:
988 	case AUE_CREAT:
989 		if (ARG_IS_VALID(kar, ARG_MODE)) {
990 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
991 			kau_write(rec, tok);
992 		}
993 		/* fall through */
994 
995 	case AUE_OPEN_R:
996 	case AUE_OPEN_RT:
997 	case AUE_OPEN_RW:
998 	case AUE_OPEN_RWT:
999 	case AUE_OPEN_W:
1000 	case AUE_OPEN_WT:
1001 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1002 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1003 			kau_write(rec, tok);
1004 		}
1005 		UPATH1_VNODE1_TOKENS;
1006 		break;
1007 
1008 	case AUE_PTRACE:
1009 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1010 			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1011 			kau_write(rec, tok);
1012 		}
1013 		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1014 			tok = au_to_arg32(3, "addr",
1015 			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1016 			kau_write(rec, tok);
1017 		}
1018 		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1019 			tok = au_to_arg32(4, "data", ar->ar_arg_value);
1020 			kau_write(rec, tok);
1021 		}
1022 		PROCESS_PID_TOKENS(2);
1023 		break;
1024 
1025 	case AUE_QUOTACTL:
1026 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1027 			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1028 			kau_write(rec, tok);
1029 		}
1030 		if (ARG_IS_VALID(kar, ARG_UID)) {
1031 			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1032 			kau_write(rec, tok);
1033 		}
1034 		UPATH1_VNODE1_TOKENS;
1035 		break;
1036 
1037 	case AUE_REBOOT:
1038 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1039 			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1040 			kau_write(rec, tok);
1041 		}
1042 		break;
1043 
1044 	case AUE_SEMCTL:
1045 		ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd);
1046 		/* Fall through */
1047 
1048 	case AUE_SEMOP:
1049 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1050 			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1051 			kau_write(rec, tok);
1052 			if (ar->ar_errno != EINVAL) {
1053 				tok = au_to_ipc(AT_IPC_SEM,
1054 				    ar->ar_arg_svipc_id);
1055 				kau_write(rec, tok);
1056 			}
1057 		}
1058 		break;
1059 
1060 	case AUE_SEMGET:
1061 		if (ar->ar_errno == 0) {
1062 			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1063 				tok = au_to_ipc(AT_IPC_SEM,
1064 				    ar->ar_arg_svipc_id);
1065 				kau_write(rec, tok);
1066 			}
1067 		}
1068 		break;
1069 
1070 	case AUE_SETEGID:
1071 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1072 			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
1073 			kau_write(rec, tok);
1074 		}
1075 		break;
1076 
1077 	case AUE_SETEUID:
1078 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1079 			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
1080 			kau_write(rec, tok);
1081 		}
1082 		break;
1083 
1084 	case AUE_SETREGID:
1085 		if (ARG_IS_VALID(kar, ARG_RGID)) {
1086 			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1087 			kau_write(rec, tok);
1088 		}
1089 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1090 			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1091 			kau_write(rec, tok);
1092 		}
1093 		break;
1094 
1095 	case AUE_SETREUID:
1096 		if (ARG_IS_VALID(kar, ARG_RUID)) {
1097 			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1098 			kau_write(rec, tok);
1099 		}
1100 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1101 			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1102 			kau_write(rec, tok);
1103 		}
1104 		break;
1105 
1106 	case AUE_SETRESGID:
1107 		if (ARG_IS_VALID(kar, ARG_RGID)) {
1108 			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1109 			kau_write(rec, tok);
1110 		}
1111 		if (ARG_IS_VALID(kar, ARG_EGID)) {
1112 			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1113 			kau_write(rec, tok);
1114 		}
1115 		if (ARG_IS_VALID(kar, ARG_SGID)) {
1116 			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
1117 			kau_write(rec, tok);
1118 		}
1119 		break;
1120 
1121 	case AUE_SETRESUID:
1122 		if (ARG_IS_VALID(kar, ARG_RUID)) {
1123 			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1124 			kau_write(rec, tok);
1125 		}
1126 		if (ARG_IS_VALID(kar, ARG_EUID)) {
1127 			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1128 			kau_write(rec, tok);
1129 		}
1130 		if (ARG_IS_VALID(kar, ARG_SUID)) {
1131 			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
1132 			kau_write(rec, tok);
1133 		}
1134 		break;
1135 
1136 	case AUE_SETGID:
1137 		if (ARG_IS_VALID(kar, ARG_GID)) {
1138 			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1139 			kau_write(rec, tok);
1140 		}
1141 		break;
1142 
1143 	case AUE_SETUID:
1144 		if (ARG_IS_VALID(kar, ARG_UID)) {
1145 			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1146 			kau_write(rec, tok);
1147 		}
1148 		break;
1149 
1150 	case AUE_SETGROUPS:
1151 		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1152 			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1153 			{
1154 				tok = au_to_arg32(1, "setgroups", 							ar->ar_arg_groups.gidset[ctr]);
1155 				kau_write(rec, tok);
1156 			}
1157 		}
1158 		break;
1159 
1160 	case AUE_SETLOGIN:
1161 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1162 			tok = au_to_text(ar->ar_arg_text);
1163 			kau_write(rec, tok);
1164 		}
1165 		break;
1166 
1167 	case AUE_SETPRIORITY:
1168 		if (ARG_IS_VALID(kar, ARG_CMD)) {
1169 			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1170 			kau_write(rec, tok);
1171 		}
1172 		if (ARG_IS_VALID(kar, ARG_UID)) {
1173 			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1174 			kau_write(rec, tok);
1175 		}
1176 		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1177 			tok = au_to_arg32(2, "priority", ar->ar_arg_value);
1178 			kau_write(rec, tok);
1179 		}
1180 		break;
1181 
1182 	case AUE_SETPRIVEXEC:
1183 		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1184 			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1185 			kau_write(rec, tok);
1186 		}
1187 		break;
1188 
1189 	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1190 	case AUE_SHMAT:
1191 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1192 			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1193 			kau_write(rec, tok);
1194 			/* XXXAUDIT: Does having the ipc token make sense? */
1195 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1196 			kau_write(rec, tok);
1197 		}
1198 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1199 			tok = au_to_arg32(2, "shmaddr",
1200 			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1201 			kau_write(rec, tok);
1202 		}
1203 		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1204 			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1205 			kau_write(rec, tok);
1206 		}
1207 		break;
1208 
1209 	case AUE_SHMCTL:
1210 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1211 			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1212 			kau_write(rec, tok);
1213 			/* XXXAUDIT: Does having the ipc token make sense? */
1214 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1215 			kau_write(rec, tok);
1216 		}
1217 		switch (ar->ar_arg_svipc_cmd) {
1218 		case IPC_STAT:
1219 			ar->ar_event = AUE_SHMCTL_STAT;
1220 			break;
1221 		case IPC_RMID:
1222 			ar->ar_event = AUE_SHMCTL_RMID;
1223 			break;
1224 		case IPC_SET:
1225 			ar->ar_event = AUE_SHMCTL_SET;
1226 			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1227 				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1228 				kau_write(rec, tok);
1229 			}
1230 			break;
1231 		default:
1232 			break;	/* We will audit a bad command */
1233 		}
1234 		break;
1235 
1236 	case AUE_SHMDT:
1237 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1238 			tok = au_to_arg32(1, "shmaddr",
1239 			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1240 			kau_write(rec, tok);
1241 		}
1242 		break;
1243 
1244 	case AUE_SHMGET:
1245 		/* This is unusual; the return value is in an argument token */
1246 		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1247 			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1248 			kau_write(rec, tok);
1249 			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1250 			kau_write(rec, tok);
1251 		}
1252 		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1253 			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1254 			kau_write(rec, tok);
1255 		}
1256 		break;
1257 
1258 	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1259 	 * and AUE_SEMUNLINK are Posix IPC */
1260 	case AUE_SHMOPEN:
1261 		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1262 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1263 			kau_write(rec, tok);
1264 		}
1265 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1266 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1267 			kau_write(rec, tok);
1268 		}
1269 	case AUE_SHMUNLINK:
1270 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1271 			tok = au_to_text(ar->ar_arg_text);
1272 			kau_write(rec, tok);
1273 		}
1274 		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1275 		/* Create an ipc_perm token */
1276 			struct ipc_perm perm;
1277 			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1278 			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1279 			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1280 			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1281 			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1282 			perm.seq = 0;
1283 			perm.key = 0;
1284 			tok = au_to_ipc_perm(&perm);
1285 			kau_write(rec, tok);
1286 		}
1287 		break;
1288 
1289 	case AUE_SEMOPEN:
1290 		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1291 			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1292 			kau_write(rec, tok);
1293 		}
1294 		if (ARG_IS_VALID(kar, ARG_MODE)) {
1295 			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1296 			kau_write(rec, tok);
1297 		}
1298 		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1299 			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1300 			kau_write(rec, tok);
1301 		}
1302 		/* fall through */
1303 
1304 	case AUE_SEMUNLINK:
1305 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1306 			tok = au_to_text(ar->ar_arg_text);
1307 			kau_write(rec, tok);
1308 		}
1309 		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1310 		/* Create an ipc_perm token */
1311 			struct ipc_perm perm;
1312 			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1313 			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1314 			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1315 			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1316 			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1317 			perm.seq = 0;
1318 			perm.key = 0;
1319 			tok = au_to_ipc_perm(&perm);
1320 			kau_write(rec, tok);
1321 		}
1322 		break;
1323 
1324 	case AUE_SEMCLOSE:
1325 		if (ARG_IS_VALID(kar, ARG_FD)) {
1326 			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1327 			kau_write(rec, tok);
1328 		}
1329 		break;
1330 
1331 	case AUE_SYMLINK:
1332 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1333 			tok = au_to_text(ar->ar_arg_text);
1334 			kau_write(rec, tok);
1335 		}
1336 		UPATH1_VNODE1_TOKENS;
1337 		break;
1338 
1339 	case AUE_SYSCTL:
1340 		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1341 			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1342 				tok = au_to_arg32(1, "name",
1343 				    ar->ar_arg_ctlname[ctr]);
1344 				kau_write(rec, tok);
1345 			}
1346 		}
1347 		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1348 			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1349 			kau_write(rec, tok);
1350 		}
1351 		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1352 			tok = au_to_text(ar->ar_arg_text);
1353 			kau_write(rec, tok);
1354 		}
1355 		break;
1356 
1357 	case AUE_UMASK:
1358 		if (ARG_IS_VALID(kar, ARG_MASK)) {
1359 			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1360 			kau_write(rec, tok);
1361 		}
1362 		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1363 		kau_write(rec, tok);
1364 		break;
1365 
1366 	case AUE_WAIT4:
1367 		if (ARG_IS_VALID(kar, ARG_PID)) {
1368 			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1369 			kau_write(rec, tok);
1370 		}
1371 		break;
1372 
1373 	case AUE_NULL:
1374 	default:
1375 		printf("BSM conversion requested for unknown event %d\n",
1376 		    ar->ar_event);
1377 		/* Write the subject token so it is properly freed here. */
1378 		kau_write(rec, subj_tok);
1379 		kau_free(rec);
1380 		return (BSM_NOAUDIT);
1381 	}
1382 
1383 	kau_write(rec, subj_tok);
1384 	tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
1385 	kau_write(rec, tok);  /* Every record gets a return token */
1386 
1387 	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1388 
1389 	*pau = rec;
1390 	return (BSM_SUCCESS);
1391 }
1392 
1393 /*
1394  * Verify that a record is a valid BSM record. This verification is simple
1395  * now, but may be expanded on sometime in the future.  Return 1 if the
1396  * record is good, 0 otherwise.
1397  */
1398 int
1399 bsm_rec_verify(void *rec)
1400 {
1401 	char c = *(char *)rec;
1402 
1403 	/*
1404 	 * Check the token ID of the first token; it has to be a header
1405 	 * token.
1406 	 *
1407 	 * XXXAUDIT There needs to be a token structure to map a token.
1408 	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1409 	 */
1410 	if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) &&
1411 	    (c != AUT_HEADER64) && (c != AUT_HEADER64_EX))
1412 		return (0);
1413 	return (1);
1414 }
1415