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