audit_bsm.c revision 170585
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 170585 2007-06-11 22:10:54Z rwatson $
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
58static void	audit_sys_auditon(struct audit_record *ar,
59		    struct au_record *rec);
60
61/*
62 * Initialize the BSM auditing subsystem.
63 */
64void
65kau_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 */
78static struct au_record *
79kau_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 */
95static void
96kau_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 */
109static void
110kau_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 */
140void
141kau_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 */
263static void
264audit_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 */
373int
374kaudit_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 */
1398int
1399bsm_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