1/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 *
4 * Copyright (c) 1999-2009 Apple Inc.
5 * Copyright (c) 2016-2017 Robert N. M. Watson
6 * All rights reserved.
7 *
8 * Portions of this software were developed by BAE Systems, the University of
9 * Cambridge Computer Laboratory, and Memorial University under DARPA/AFRL
10 * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
11 * Computing (TC) research program.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1.  Redistributions of source code must retain the above copyright
17 *     notice, this list of conditions and the following disclaimer.
18 * 2.  Redistributions in binary form must reproduce the above copyright
19 *     notice, this list of conditions and the following disclaimer in the
20 *     documentation and/or other materials provided with the distribution.
21 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
22 *     its contributors may be used to endorse or promote products derived
23 *     from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
29 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
34 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD$");
40
41#include <sys/param.h>
42#include <sys/vnode.h>
43#include <sys/ipc.h>
44#include <sys/lock.h>
45#include <sys/malloc.h>
46#include <sys/mutex.h>
47#include <sys/socket.h>
48#include <sys/extattr.h>
49#include <sys/fcntl.h>
50#include <sys/user.h>
51#include <sys/systm.h>
52
53#include <bsm/audit.h>
54#include <bsm/audit_internal.h>
55#include <bsm/audit_record.h>
56#include <bsm/audit_kevents.h>
57
58#include <security/audit/audit.h>
59#include <security/audit/audit_private.h>
60
61#include <netinet/in_systm.h>
62#include <netinet/in.h>
63#include <netinet/ip.h>
64
65MALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
66
67static void	audit_sys_auditon(struct audit_record *ar,
68		    struct au_record *rec);
69
70/*
71 * Initialize the BSM auditing subsystem.
72 */
73void
74kau_init(void)
75{
76
77	au_evclassmap_init();
78	au_evnamemap_init();
79}
80
81/*
82 * This call reserves memory for the audit record.  Memory must be guaranteed
83 * before any auditable event can be generated.  The au_record structure
84 * maintains a reference to the memory allocated above and also the list of
85 * tokens associated with this record.
86 */
87static struct au_record *
88kau_open(void)
89{
90	struct au_record *rec;
91
92	rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK);
93	rec->data = NULL;
94	TAILQ_INIT(&rec->token_q);
95	rec->len = 0;
96	rec->used = 1;
97
98	return (rec);
99}
100
101/*
102 * Store the token with the record descriptor.
103 */
104static void
105kau_write(struct au_record *rec, struct au_token *tok)
106{
107
108	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
109
110	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
111	rec->len += tok->len;
112}
113
114/*
115 * Close out the audit record by adding the header token, identifying any
116 * missing tokens.  Write out the tokens to the record memory.
117 */
118static void
119kau_close(struct au_record *rec, struct timespec *ctime, short event)
120{
121	u_char *dptr;
122	size_t tot_rec_size;
123	token_t *cur, *hdr, *trail;
124	struct timeval tm;
125	size_t hdrsize;
126	struct auditinfo_addr ak;
127	struct in6_addr *ap;
128
129	audit_get_kinfo(&ak);
130	hdrsize = 0;
131	switch (ak.ai_termid.at_type) {
132	case AU_IPv4:
133		hdrsize = (ak.ai_termid.at_addr[0] == INADDR_ANY) ?
134		    AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak);
135		break;
136	case AU_IPv6:
137		ap = (struct in6_addr *)&ak.ai_termid.at_addr[0];
138		hdrsize = (IN6_IS_ADDR_UNSPECIFIED(ap)) ? AUDIT_HEADER_SIZE :
139		    AUDIT_HEADER_EX_SIZE(&ak);
140		break;
141	default:
142		panic("kau_close: invalid address family");
143	}
144	tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE;
145	rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO);
146
147	tm.tv_usec = ctime->tv_nsec / 1000;
148	tm.tv_sec = ctime->tv_sec;
149	if (hdrsize != AUDIT_HEADER_SIZE)
150		hdr = au_to_header32_ex_tm(tot_rec_size, event, 0, tm, &ak);
151	else
152		hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
153	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
154
155	trail = au_to_trailer(tot_rec_size);
156	TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
157
158	rec->len = tot_rec_size;
159	dptr = rec->data;
160	TAILQ_FOREACH(cur, &rec->token_q, tokens) {
161		memcpy(dptr, cur->t_data, cur->len);
162		dptr += cur->len;
163	}
164}
165
166/*
167 * Free a BSM audit record by releasing all the tokens and clearing the audit
168 * record information.
169 */
170void
171kau_free(struct au_record *rec)
172{
173	struct au_token *tok;
174
175	/* Free the token list. */
176	while ((tok = TAILQ_FIRST(&rec->token_q))) {
177		TAILQ_REMOVE(&rec->token_q, tok, tokens);
178		free(tok->t_data, M_AUDITBSM);
179		free(tok, M_AUDITBSM);
180	}
181
182	rec->used = 0;
183	rec->len = 0;
184	free(rec->data, M_AUDITBSM);
185	free(rec, M_AUDITBSM);
186}
187
188/*
189 * XXX: May want turn some (or all) of these macros into functions in order
190 * to reduce the generated code size.
191 *
192 * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
193 * caller are OK with this.
194 */
195#define	ATFD1_TOKENS(argnum) do {					\
196	if (ARG_IS_VALID(kar, ARG_ATFD1)) {				\
197		tok = au_to_arg32(argnum, "at fd 1", ar->ar_arg_atfd1);	\
198		kau_write(rec, tok);					\
199	}								\
200} while (0)
201
202#define	ATFD2_TOKENS(argnum) do {					\
203	if (ARG_IS_VALID(kar, ARG_ATFD2)) {				\
204		tok = au_to_arg32(argnum, "at fd 2", ar->ar_arg_atfd2);	\
205		kau_write(rec, tok);					\
206	}								\
207} while (0)
208
209#define	UPATH1_TOKENS do {						\
210	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
211		tok = au_to_path(ar->ar_arg_upath1);			\
212		kau_write(rec, tok);					\
213	}								\
214} while (0)
215
216#define	UPATH2_TOKENS do {						\
217	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
218		tok = au_to_path(ar->ar_arg_upath2);			\
219		kau_write(rec, tok);					\
220	}								\
221} while (0)
222
223#define	VNODE1_TOKENS do {						\
224	if (ARG_IS_VALID(kar, ARG_ATFD)) {				\
225		tok = au_to_arg32(1, "at fd", ar->ar_arg_atfd);		\
226		kau_write(rec, tok);					\
227	}								\
228	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
229		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
230		kau_write(rec, tok);					\
231	}								\
232} while (0)
233
234#define	UPATH1_VNODE1_TOKENS do {					\
235	UPATH1_TOKENS;							\
236	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
237		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
238		kau_write(rec, tok);					\
239	}								\
240} while (0)
241
242#define	VNODE2_TOKENS do {						\
243	if (ARG_IS_VALID(kar, ARG_VNODE2)) {				\
244		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
245		kau_write(rec, tok);					\
246	}								\
247} while (0)
248
249#define	FD_VNODE1_TOKENS do {						\
250	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
251		if (ARG_IS_VALID(kar, ARG_FD)) {			\
252			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
253			kau_write(rec, tok);				\
254		}							\
255		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
256		kau_write(rec, tok);					\
257	} else {							\
258		if (ARG_IS_VALID(kar, ARG_FD)) {			\
259			tok = au_to_arg32(1, "non-file: fd",		\
260			    ar->ar_arg_fd);				\
261			kau_write(rec, tok);				\
262		}							\
263	}								\
264} while (0)
265
266#define	PROCESS_PID_TOKENS(argn) do {					\
267	if ((ar->ar_arg_pid > 0) /* Reference a single process */	\
268	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {			\
269		tok = au_to_process32_ex(ar->ar_arg_auid,		\
270		    ar->ar_arg_euid, ar->ar_arg_egid,			\
271		    ar->ar_arg_ruid, ar->ar_arg_rgid,			\
272		    ar->ar_arg_pid, ar->ar_arg_asid,			\
273		    &ar->ar_arg_termid_addr);				\
274		kau_write(rec, tok);					\
275	} else if (ARG_IS_VALID(kar, ARG_PID)) {			\
276		tok = au_to_arg32(argn, "process", ar->ar_arg_pid);	\
277		kau_write(rec, tok);					\
278	}								\
279} while (0)
280
281#define	EXTATTR_TOKENS(namespace_argnum) do {				\
282	if (ARG_IS_VALID(kar, ARG_VALUE)) {				\
283		switch (ar->ar_arg_value) {				\
284		case EXTATTR_NAMESPACE_USER:				\
285			tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
286			break;						\
287		case EXTATTR_NAMESPACE_SYSTEM:				\
288			tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
289			break;						\
290		default:						\
291			tok = au_to_arg32((namespace_argnum),		\
292			    "attrnamespace", ar->ar_arg_value);		\
293			break;						\
294		}							\
295		kau_write(rec, tok);					\
296	}								\
297	/* attrname is in the text field */				\
298	if (ARG_IS_VALID(kar, ARG_TEXT)) {				\
299		tok = au_to_text(ar->ar_arg_text);			\
300		kau_write(rec, tok);					\
301	}								\
302} while (0)
303
304/*
305 * Not all pointer arguments to system calls are of interest, but in some
306 * cases they reflect delegation of rights, such as mmap(2) followed by
307 * minherit(2) before execve(2), so do the best we can.
308 */
309#define	ADDR_TOKEN(argnum, argname) do {				\
310	if (ARG_IS_VALID(kar, ARG_ADDR)) {				\
311		if (sizeof(void *) == sizeof(uint32_t))			\
312			tok = au_to_arg32((argnum), (argname),		\
313			    (uint32_t)(uintptr_t)ar->ar_arg_addr);	\
314		else							\
315			tok = au_to_arg64((argnum), (argname),		\
316			    (uint64_t)(uintptr_t)ar->ar_arg_addr);	\
317		kau_write(rec, tok);					\
318	}								\
319} while (0)
320
321/*
322 * Implement auditing for the auditon() system call. The audit tokens that
323 * are generated depend on the command that was sent into the auditon()
324 * system call.
325 */
326static void
327audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
328{
329	struct au_token *tok;
330
331	tok = au_to_arg32(3, "length", ar->ar_arg_len);
332	kau_write(rec, tok);
333	switch (ar->ar_arg_cmd) {
334	case A_OLDSETPOLICY:
335		if ((size_t)ar->ar_arg_len == sizeof(int64_t)) {
336			tok = au_to_arg64(2, "policy",
337			    ar->ar_arg_auditon.au_policy64);
338			kau_write(rec, tok);
339			break;
340		}
341		/* FALLTHROUGH */
342
343	case A_SETPOLICY:
344		tok = au_to_arg32(2, "policy", ar->ar_arg_auditon.au_policy);
345		kau_write(rec, tok);
346		break;
347
348	case A_SETKMASK:
349		tok = au_to_arg32(2, "setkmask:as_success",
350		    ar->ar_arg_auditon.au_mask.am_success);
351		kau_write(rec, tok);
352		tok = au_to_arg32(2, "setkmask:as_failure",
353		    ar->ar_arg_auditon.au_mask.am_failure);
354		kau_write(rec, tok);
355		break;
356
357	case A_OLDSETQCTRL:
358		if ((size_t)ar->ar_arg_len == sizeof(au_qctrl64_t)) {
359			tok = au_to_arg64(2, "setqctrl:aq_hiwater",
360			    ar->ar_arg_auditon.au_qctrl64.aq64_hiwater);
361			kau_write(rec, tok);
362			tok = au_to_arg64(2, "setqctrl:aq_lowater",
363			    ar->ar_arg_auditon.au_qctrl64.aq64_lowater);
364			kau_write(rec, tok);
365			tok = au_to_arg64(2, "setqctrl:aq_bufsz",
366			    ar->ar_arg_auditon.au_qctrl64.aq64_bufsz);
367			kau_write(rec, tok);
368			tok = au_to_arg64(2, "setqctrl:aq_delay",
369			    ar->ar_arg_auditon.au_qctrl64.aq64_delay);
370			kau_write(rec, tok);
371			tok = au_to_arg64(2, "setqctrl:aq_minfree",
372			    ar->ar_arg_auditon.au_qctrl64.aq64_minfree);
373			kau_write(rec, tok);
374			break;
375		}
376		/* FALLTHROUGH */
377
378	case A_SETQCTRL:
379		tok = au_to_arg32(2, "setqctrl:aq_hiwater",
380		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
381		kau_write(rec, tok);
382		tok = au_to_arg32(2, "setqctrl:aq_lowater",
383		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
384		kau_write(rec, tok);
385		tok = au_to_arg32(2, "setqctrl:aq_bufsz",
386		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
387		kau_write(rec, tok);
388		tok = au_to_arg32(2, "setqctrl:aq_delay",
389		    ar->ar_arg_auditon.au_qctrl.aq_delay);
390		kau_write(rec, tok);
391		tok = au_to_arg32(2, "setqctrl:aq_minfree",
392		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
393		kau_write(rec, tok);
394		break;
395
396	case A_SETUMASK:
397		tok = au_to_arg32(2, "setumask:as_success",
398		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
399		kau_write(rec, tok);
400		tok = au_to_arg32(2, "setumask:as_failure",
401		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
402		kau_write(rec, tok);
403		break;
404
405	case A_SETSMASK:
406		tok = au_to_arg32(2, "setsmask:as_success",
407		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
408		kau_write(rec, tok);
409		tok = au_to_arg32(2, "setsmask:as_failure",
410		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
411		kau_write(rec, tok);
412		break;
413
414	case A_OLDSETCOND:
415		if ((size_t)ar->ar_arg_len == sizeof(int64_t)) {
416			tok = au_to_arg64(2, "setcond",
417			    ar->ar_arg_auditon.au_cond64);
418			kau_write(rec, tok);
419			break;
420		}
421		/* FALLTHROUGH */
422
423	case A_SETCOND:
424		tok = au_to_arg32(2, "setcond", ar->ar_arg_auditon.au_cond);
425		kau_write(rec, tok);
426		break;
427
428	case A_SETCLASS:
429		tok = au_to_arg32(2, "setclass:ec_event",
430		    ar->ar_arg_auditon.au_evclass.ec_number);
431		kau_write(rec, tok);
432		tok = au_to_arg32(2, "setclass:ec_class",
433		    ar->ar_arg_auditon.au_evclass.ec_class);
434		kau_write(rec, tok);
435		break;
436
437	case A_SETPMASK:
438		tok = au_to_arg32(2, "setpmask:as_success",
439		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
440		kau_write(rec, tok);
441		tok = au_to_arg32(2, "setpmask:as_failure",
442		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
443		kau_write(rec, tok);
444		break;
445
446	case A_SETFSIZE:
447		tok = au_to_arg32(2, "setfsize:filesize",
448		    ar->ar_arg_auditon.au_fstat.af_filesz);
449		kau_write(rec, tok);
450		break;
451
452	default:
453		break;
454	}
455}
456
457/*
458 * Convert an internal kernel audit record to a BSM record and return a
459 * success/failure indicator. The BSM record is passed as an out parameter to
460 * this function.
461 *
462 * Return conditions:
463 *   BSM_SUCCESS: The BSM record is valid
464 *   BSM_FAILURE: Failure; the BSM record is NULL.
465 *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
466 */
467int
468kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
469{
470	struct au_token *tok, *subj_tok, *jail_tok;
471	struct au_record *rec;
472	au_tid_t tid;
473	struct audit_record *ar;
474	int ctr;
475
476	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
477
478	*pau = NULL;
479	ar = &kar->k_ar;
480	rec = kau_open();
481
482	/*
483	 * Create the subject token.  If this credential was jailed be sure to
484	 * generate a zonename token.
485	 */
486	if (ar->ar_jailname[0] != '\0')
487		jail_tok = au_to_zonename(ar->ar_jailname);
488	else
489		jail_tok = NULL;
490	switch (ar->ar_subj_term_addr.at_type) {
491	case AU_IPv4:
492		tid.port = ar->ar_subj_term_addr.at_port;
493		tid.machine = ar->ar_subj_term_addr.at_addr[0];
494		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
495		    ar->ar_subj_cred.cr_uid, /* eff uid */
496		    ar->ar_subj_egid,	/* eff group id */
497		    ar->ar_subj_ruid,	/* real uid */
498		    ar->ar_subj_rgid,	/* real group id */
499		    ar->ar_subj_pid,	/* process id */
500		    ar->ar_subj_asid,	/* session ID */
501		    &tid);
502		break;
503	case AU_IPv6:
504		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
505		    ar->ar_subj_cred.cr_uid,
506		    ar->ar_subj_egid,
507		    ar->ar_subj_ruid,
508		    ar->ar_subj_rgid,
509		    ar->ar_subj_pid,
510		    ar->ar_subj_asid,
511		    &ar->ar_subj_term_addr);
512		break;
513	default:
514		bzero(&tid, sizeof(tid));
515		subj_tok = au_to_subject32(ar->ar_subj_auid,
516		    ar->ar_subj_cred.cr_uid,
517		    ar->ar_subj_egid,
518		    ar->ar_subj_ruid,
519		    ar->ar_subj_rgid,
520		    ar->ar_subj_pid,
521		    ar->ar_subj_asid,
522		    &tid);
523	}
524
525	/*
526	 * The logic inside each case fills in the tokens required for the
527	 * event, except for the header, trailer, and return tokens.  The
528	 * header and trailer tokens are added by the kau_close() function.
529	 * The return token is added outside of the switch statement.
530	 */
531	switch(ar->ar_event) {
532	case AUE_ACCEPT:
533		if (ARG_IS_VALID(kar, ARG_FD)) {
534			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
535			kau_write(rec, tok);
536		}
537		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
538			tok = au_to_sock_inet((struct sockaddr_in *)
539			    &ar->ar_arg_sockaddr);
540			kau_write(rec, tok);
541		}
542		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
543			tok = au_to_sock_unix((struct sockaddr_un *)
544			    &ar->ar_arg_sockaddr);
545			kau_write(rec, tok);
546			UPATH1_TOKENS;
547		}
548		break;
549
550	case AUE_BIND:
551	case AUE_LISTEN:
552	case AUE_CONNECT:
553	case AUE_RECV:
554	case AUE_RECVFROM:
555	case AUE_RECVMSG:
556	case AUE_SEND:
557	case AUE_SENDMSG:
558	case AUE_SENDTO:
559		/*
560		 * Socket-related events.
561		 */
562		if (ARG_IS_VALID(kar, ARG_FD)) {
563			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
564			kau_write(rec, tok);
565		}
566		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
567			tok = au_to_sock_inet((struct sockaddr_in *)
568			    &ar->ar_arg_sockaddr);
569			kau_write(rec, tok);
570		}
571		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
572			tok = au_to_sock_unix((struct sockaddr_un *)
573			    &ar->ar_arg_sockaddr);
574			kau_write(rec, tok);
575			UPATH1_TOKENS;
576		}
577		/* XXX Need to handle ARG_SADDRINET6 */
578		break;
579
580	case AUE_BINDAT:
581	case AUE_CONNECTAT:
582		ATFD1_TOKENS(1);
583		if (ARG_IS_VALID(kar, ARG_FD)) {
584			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
585			kau_write(rec, tok);
586		}
587		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
588			tok = au_to_sock_unix((struct sockaddr_un *)
589			    &ar->ar_arg_sockaddr);
590			kau_write(rec, tok);
591			UPATH1_TOKENS;
592		}
593		break;
594
595	case AUE_SENDFILE:
596		FD_VNODE1_TOKENS;
597		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
598			tok = au_to_sock_inet((struct sockaddr_in *)
599			    &ar->ar_arg_sockaddr);
600			kau_write(rec, tok);
601		}
602		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
603			tok = au_to_sock_unix((struct sockaddr_un *)
604			    &ar->ar_arg_sockaddr);
605			kau_write(rec, tok);
606			UPATH1_TOKENS;
607		}
608		/* XXX Need to handle ARG_SADDRINET6 */
609		break;
610
611	case AUE_SOCKET:
612	case AUE_SOCKETPAIR:
613		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
614			tok = au_to_arg32(1, "domain",
615			    ar->ar_arg_sockinfo.so_domain);
616			kau_write(rec, tok);
617			tok = au_to_arg32(2, "type",
618			    ar->ar_arg_sockinfo.so_type);
619			kau_write(rec, tok);
620			tok = au_to_arg32(3, "protocol",
621			    ar->ar_arg_sockinfo.so_protocol);
622			kau_write(rec, tok);
623		}
624		break;
625
626	case AUE_SETSOCKOPT:
627	case AUE_SHUTDOWN:
628		if (ARG_IS_VALID(kar, ARG_FD)) {
629			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
630			kau_write(rec, tok);
631		}
632		break;
633
634	case AUE_ACCT:
635		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
636			UPATH1_VNODE1_TOKENS;
637		} else {
638			tok = au_to_arg32(1, "accounting off", 0);
639			kau_write(rec, tok);
640		}
641		break;
642
643	case AUE_SETAUID:
644		if (ARG_IS_VALID(kar, ARG_AUID)) {
645			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
646			kau_write(rec, tok);
647		}
648		break;
649
650	case AUE_SETAUDIT:
651		if (ARG_IS_VALID(kar, ARG_AUID) &&
652		    ARG_IS_VALID(kar, ARG_ASID) &&
653		    ARG_IS_VALID(kar, ARG_AMASK) &&
654		    ARG_IS_VALID(kar, ARG_TERMID)) {
655			tok = au_to_arg32(1, "setaudit:auid",
656			    ar->ar_arg_auid);
657			kau_write(rec, tok);
658			tok = au_to_arg32(1, "setaudit:port",
659			    ar->ar_arg_termid.port);
660			kau_write(rec, tok);
661			tok = au_to_arg32(1, "setaudit:machine",
662			    ar->ar_arg_termid.machine);
663			kau_write(rec, tok);
664			tok = au_to_arg32(1, "setaudit:as_success",
665			    ar->ar_arg_amask.am_success);
666			kau_write(rec, tok);
667			tok = au_to_arg32(1, "setaudit:as_failure",
668			    ar->ar_arg_amask.am_failure);
669			kau_write(rec, tok);
670			tok = au_to_arg32(1, "setaudit:asid",
671			    ar->ar_arg_asid);
672			kau_write(rec, tok);
673		}
674		break;
675
676	case AUE_SETAUDIT_ADDR:
677		if (ARG_IS_VALID(kar, ARG_AUID) &&
678		    ARG_IS_VALID(kar, ARG_ASID) &&
679		    ARG_IS_VALID(kar, ARG_AMASK) &&
680		    ARG_IS_VALID(kar, ARG_TERMID_ADDR)) {
681			tok = au_to_arg32(1, "setaudit_addr:auid",
682			    ar->ar_arg_auid);
683			kau_write(rec, tok);
684			tok = au_to_arg32(1, "setaudit_addr:as_success",
685			    ar->ar_arg_amask.am_success);
686			kau_write(rec, tok);
687			tok = au_to_arg32(1, "setaudit_addr:as_failure",
688			    ar->ar_arg_amask.am_failure);
689			kau_write(rec, tok);
690			tok = au_to_arg32(1, "setaudit_addr:asid",
691			    ar->ar_arg_asid);
692			kau_write(rec, tok);
693			tok = au_to_arg32(1, "setaudit_addr:type",
694			    ar->ar_arg_termid_addr.at_type);
695			kau_write(rec, tok);
696			tok = au_to_arg32(1, "setaudit_addr:port",
697			    ar->ar_arg_termid_addr.at_port);
698			kau_write(rec, tok);
699			if (ar->ar_arg_termid_addr.at_type == AU_IPv6)
700				tok = au_to_in_addr_ex((struct in6_addr *)
701				    &ar->ar_arg_termid_addr.at_addr[0]);
702			if (ar->ar_arg_termid_addr.at_type == AU_IPv4)
703				tok = au_to_in_addr((struct in_addr *)
704				    &ar->ar_arg_termid_addr.at_addr[0]);
705			kau_write(rec, tok);
706		}
707		break;
708
709	case AUE_AUDITON:
710		/*
711		 * For AUDITON commands without own event, audit the cmd.
712		 */
713		if (ARG_IS_VALID(kar, ARG_CMD)) {
714			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
715			kau_write(rec, tok);
716		}
717		/* FALLTHROUGH */
718
719	case AUE_AUDITON_GETCAR:
720	case AUE_AUDITON_GETCLASS:
721	case AUE_AUDITON_GETCOND:
722	case AUE_AUDITON_GETCWD:
723	case AUE_AUDITON_GETKMASK:
724	case AUE_AUDITON_GETSTAT:
725	case AUE_AUDITON_GPOLICY:
726	case AUE_AUDITON_GQCTRL:
727	case AUE_AUDITON_SETCLASS:
728	case AUE_AUDITON_SETCOND:
729	case AUE_AUDITON_SETKMASK:
730	case AUE_AUDITON_SETSMASK:
731	case AUE_AUDITON_SETSTAT:
732	case AUE_AUDITON_SETUMASK:
733	case AUE_AUDITON_SPOLICY:
734	case AUE_AUDITON_SQCTRL:
735		if (ARG_IS_VALID(kar, ARG_AUDITON))
736			audit_sys_auditon(ar, rec);
737		break;
738
739	case AUE_AUDITCTL:
740		UPATH1_VNODE1_TOKENS;
741		break;
742
743	case AUE_EXIT:
744		if (ARG_IS_VALID(kar, ARG_EXIT)) {
745			tok = au_to_exit(ar->ar_arg_exitretval,
746			    ar->ar_arg_exitstatus);
747			kau_write(rec, tok);
748		}
749		break;
750
751	case AUE_ADJTIME:
752	case AUE_CLOCK_SETTIME:
753	case AUE_AUDIT:
754	case AUE_DUP2:
755	case AUE_GETAUDIT:
756	case AUE_GETAUDIT_ADDR:
757	case AUE_GETAUID:
758	case AUE_GETCWD:
759	case AUE_GETFSSTAT:
760	case AUE_GETRESUID:
761	case AUE_GETRESGID:
762	case AUE_KQUEUE:
763	case AUE_MODLOAD:
764	case AUE_MODUNLOAD:
765	case AUE_MSGSYS:
766	case AUE_NTP_ADJTIME:
767	case AUE_PIPE:
768	case AUE_POSIX_OPENPT:
769	case AUE_PROFILE:
770	case AUE_RTPRIO:
771	case AUE_SEMSYS:
772	case AUE_SETFIB:
773	case AUE_SHMSYS:
774	case AUE_SETPGRP:
775	case AUE_SETRLIMIT:
776	case AUE_SETSID:
777	case AUE_SETTIMEOFDAY:
778	case AUE_SYSARCH:
779
780		/*
781		 * Header, subject, and return tokens added at end.
782		 */
783		break;
784
785	case AUE_ACL_DELETE_FD:
786	case AUE_ACL_DELETE_FILE:
787	case AUE_ACL_CHECK_FD:
788	case AUE_ACL_CHECK_FILE:
789	case AUE_ACL_CHECK_LINK:
790	case AUE_ACL_DELETE_LINK:
791	case AUE_ACL_GET_FD:
792	case AUE_ACL_GET_FILE:
793	case AUE_ACL_GET_LINK:
794	case AUE_ACL_SET_FD:
795	case AUE_ACL_SET_FILE:
796	case AUE_ACL_SET_LINK:
797		if (ARG_IS_VALID(kar, ARG_VALUE)) {
798			tok = au_to_arg32(1, "type", ar->ar_arg_value);
799			kau_write(rec, tok);
800		}
801		ATFD1_TOKENS(1);
802		UPATH1_VNODE1_TOKENS;
803		break;
804
805	/*
806	 * NB: We may want to verify that the appropriate
807	 * audit args are being processed here, but I think
808	 * a bit analysis is required.
809	 *
810	 * Process AUE_JAIL_SET in the next block so we can pickup any path
811	 * related tokens that might exist.
812	 */
813	case AUE_JAIL_GET:
814	case AUE_JAIL_ATTACH:
815	case AUE_JAIL_REMOVE:
816		break;
817
818	case AUE_JAIL_SET:
819	case AUE_CHDIR:
820	case AUE_CHROOT:
821	case AUE_FSTATAT:
822	case AUE_FUTIMESAT:
823	case AUE_GETATTRLIST:
824	case AUE_JAIL:
825	case AUE_LUTIMES:
826	case AUE_NFS_GETFH:
827	case AUE_LGETFH:
828	case AUE_LSTAT:
829	case AUE_LPATHCONF:
830	case AUE_PATHCONF:
831	case AUE_READLINK:
832	case AUE_READLINKAT:
833	case AUE_REVOKE:
834	case AUE_RMDIR:
835	case AUE_SEARCHFS:
836	case AUE_SETATTRLIST:
837	case AUE_STAT:
838	case AUE_STATFS:
839	case AUE_SWAPON:
840	case AUE_SWAPOFF:
841	case AUE_TRUNCATE:
842	case AUE_UNDELETE:
843	case AUE_UNLINK:
844	case AUE_UNLINKAT:
845	case AUE_UTIMES:
846	case AUE_REALPATHAT:
847		ATFD1_TOKENS(1);
848		UPATH1_VNODE1_TOKENS;
849		break;
850
851	case AUE_ACCESS:
852	case AUE_EACCESS:
853	case AUE_FACCESSAT:
854		ATFD1_TOKENS(1);
855		UPATH1_VNODE1_TOKENS;
856		if (ARG_IS_VALID(kar, ARG_VALUE)) {
857			tok = au_to_arg32(2, "mode", ar->ar_arg_value);
858			kau_write(rec, tok);
859		}
860		break;
861
862	case AUE_FHSTATFS:
863	case AUE_FHOPEN:
864	case AUE_FHSTAT:
865		/* XXXRW: Need to audit vnode argument. */
866		break;
867
868	case AUE_CHFLAGS:
869	case AUE_LCHFLAGS:
870	case AUE_CHFLAGSAT:
871		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
872			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
873			kau_write(rec, tok);
874		}
875		UPATH1_VNODE1_TOKENS;
876		break;
877
878	case AUE_CHMOD:
879	case AUE_LCHMOD:
880		if (ARG_IS_VALID(kar, ARG_MODE)) {
881			tok = au_to_arg32(2, "new file mode",
882			    ar->ar_arg_mode);
883			kau_write(rec, tok);
884		}
885		UPATH1_VNODE1_TOKENS;
886		break;
887
888	case AUE_FCHMODAT:
889		ATFD1_TOKENS(1);
890		if (ARG_IS_VALID(kar, ARG_MODE)) {
891			tok = au_to_arg32(3, "new file mode",
892			    ar->ar_arg_mode);
893			kau_write(rec, tok);
894		}
895		UPATH1_VNODE1_TOKENS;
896		break;
897
898	case AUE_CHOWN:
899	case AUE_LCHOWN:
900		if (ARG_IS_VALID(kar, ARG_UID)) {
901			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
902			kau_write(rec, tok);
903		}
904		if (ARG_IS_VALID(kar, ARG_GID)) {
905			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
906			kau_write(rec, tok);
907		}
908		UPATH1_VNODE1_TOKENS;
909		break;
910
911	case AUE_FCHOWNAT:
912		ATFD1_TOKENS(1);
913		if (ARG_IS_VALID(kar, ARG_UID)) {
914			tok = au_to_arg32(3, "new file uid", ar->ar_arg_uid);
915			kau_write(rec, tok);
916		}
917		if (ARG_IS_VALID(kar, ARG_GID)) {
918			tok = au_to_arg32(4, "new file gid", ar->ar_arg_gid);
919			kau_write(rec, tok);
920		}
921		UPATH1_VNODE1_TOKENS;
922		break;
923
924	case AUE_EXCHANGEDATA:
925		UPATH1_VNODE1_TOKENS;
926		UPATH2_TOKENS;
927		break;
928
929	case AUE_CLOSE:
930		if (ARG_IS_VALID(kar, ARG_FD)) {
931			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
932			kau_write(rec, tok);
933		}
934		UPATH1_VNODE1_TOKENS;
935		break;
936
937	case AUE_CLOSEFROM:
938		if (ARG_IS_VALID(kar, ARG_FD)) {
939			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
940			kau_write(rec, tok);
941		}
942		break;
943
944	case AUE_CLOSERANGE:
945		if (ARG_IS_VALID(kar, ARG_FD)) {
946			tok = au_to_arg32(1, "lowfd", ar->ar_arg_fd);
947			kau_write(rec, tok);
948		}
949		if (ARG_IS_VALID(kar, ARG_CMD)) {
950			tok = au_to_arg32(2, "highfd", ar->ar_arg_cmd);
951			kau_write(rec, tok);
952		}
953		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
954			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
955			kau_write(rec, tok);
956		}
957		break;
958
959	case AUE_CORE:
960		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
961			tok = au_to_arg32(1, "signal", ar->ar_arg_signum);
962			kau_write(rec, tok);
963		}
964		UPATH1_VNODE1_TOKENS;
965		break;
966
967	case AUE_EXTATTRCTL:
968		UPATH1_VNODE1_TOKENS;
969		if (ARG_IS_VALID(kar, ARG_CMD)) {
970			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
971			kau_write(rec, tok);
972		}
973		/* extattrctl(2) filename parameter is in upath2/vnode2 */
974		UPATH2_TOKENS;
975		VNODE2_TOKENS;
976		EXTATTR_TOKENS(4);
977		break;
978
979	case AUE_EXTATTR_GET_FILE:
980	case AUE_EXTATTR_SET_FILE:
981	case AUE_EXTATTR_LIST_FILE:
982	case AUE_EXTATTR_DELETE_FILE:
983	case AUE_EXTATTR_GET_LINK:
984	case AUE_EXTATTR_SET_LINK:
985	case AUE_EXTATTR_LIST_LINK:
986	case AUE_EXTATTR_DELETE_LINK:
987		UPATH1_VNODE1_TOKENS;
988		EXTATTR_TOKENS(2);
989		break;
990
991	case AUE_EXTATTR_GET_FD:
992	case AUE_EXTATTR_SET_FD:
993	case AUE_EXTATTR_LIST_FD:
994	case AUE_EXTATTR_DELETE_FD:
995		if (ARG_IS_VALID(kar, ARG_FD)) {
996			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
997			kau_write(rec, tok);
998		}
999		EXTATTR_TOKENS(2);
1000		break;
1001
1002	case AUE_FEXECVE:
1003		if (ARG_IS_VALID(kar, ARG_FD)) {
1004			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
1005			kau_write(rec, tok);
1006		}
1007		/* FALLTHROUGH */
1008
1009	case AUE_EXECVE:
1010	case AUE_MAC_EXECVE:
1011		if (ARG_IS_VALID(kar, ARG_ARGV)) {
1012			tok = au_to_exec_args(ar->ar_arg_argv,
1013			    ar->ar_arg_argc);
1014			kau_write(rec, tok);
1015		}
1016		if (ARG_IS_VALID(kar, ARG_ENVV)) {
1017			tok = au_to_exec_env(ar->ar_arg_envv,
1018			    ar->ar_arg_envc);
1019			kau_write(rec, tok);
1020		}
1021		UPATH1_VNODE1_TOKENS;
1022		break;
1023
1024	case AUE_FCHMOD:
1025		if (ARG_IS_VALID(kar, ARG_MODE)) {
1026			tok = au_to_arg32(2, "new file mode",
1027			    ar->ar_arg_mode);
1028			kau_write(rec, tok);
1029		}
1030		FD_VNODE1_TOKENS;
1031		break;
1032
1033	/*
1034	 * XXXRW: Some of these need to handle non-vnode cases as well.
1035	 */
1036	case AUE_FCHDIR:
1037	case AUE_FPATHCONF:
1038	case AUE_FSTAT:
1039	case AUE_FSTATFS:
1040	case AUE_FSYNC:
1041	case AUE_FTRUNCATE:
1042	case AUE_FUTIMES:
1043	case AUE_GETDIRENTRIES:
1044	case AUE_GETDIRENTRIESATTR:
1045	case AUE_LSEEK:
1046	case AUE_POLL:
1047	case AUE_POSIX_FALLOCATE:
1048	case AUE_PREAD:
1049	case AUE_PWRITE:
1050	case AUE_READ:
1051	case AUE_READV:
1052	case AUE_WRITE:
1053	case AUE_WRITEV:
1054		FD_VNODE1_TOKENS;
1055		break;
1056
1057	case AUE_FCHOWN:
1058		if (ARG_IS_VALID(kar, ARG_UID)) {
1059			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
1060			kau_write(rec, tok);
1061		}
1062		if (ARG_IS_VALID(kar, ARG_GID)) {
1063			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
1064			kau_write(rec, tok);
1065		}
1066		FD_VNODE1_TOKENS;
1067		break;
1068
1069	case AUE_FCNTL:
1070		if (ARG_IS_VALID(kar, ARG_CMD)) {
1071			tok = au_to_arg32(2, "cmd",
1072			    au_fcntl_cmd_to_bsm(ar->ar_arg_cmd));
1073			kau_write(rec, tok);
1074		}
1075		FD_VNODE1_TOKENS;
1076		break;
1077
1078	case AUE_FCHFLAGS:
1079		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1080			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1081			kau_write(rec, tok);
1082		}
1083		FD_VNODE1_TOKENS;
1084		break;
1085
1086	case AUE_FLOCK:
1087		if (ARG_IS_VALID(kar, ARG_CMD)) {
1088			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
1089			kau_write(rec, tok);
1090		}
1091		FD_VNODE1_TOKENS;
1092		break;
1093
1094	case AUE_RFORK:
1095		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1096			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
1097			kau_write(rec, tok);
1098		}
1099		/* FALLTHROUGH */
1100
1101	case AUE_FORK:
1102	case AUE_VFORK:
1103		if (ARG_IS_VALID(kar, ARG_PID)) {
1104			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
1105			kau_write(rec, tok);
1106		}
1107		break;
1108
1109	case AUE_IOCTL:
1110		if (ARG_IS_VALID(kar, ARG_CMD)) {
1111			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
1112			kau_write(rec, tok);
1113		}
1114		if (ARG_IS_VALID(kar, ARG_VNODE1))
1115			FD_VNODE1_TOKENS;
1116		else {
1117			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
1118				tok = kau_to_socket(&ar->ar_arg_sockinfo);
1119				kau_write(rec, tok);
1120			} else {
1121				if (ARG_IS_VALID(kar, ARG_FD)) {
1122					tok = au_to_arg32(1, "fd",
1123					    ar->ar_arg_fd);
1124					kau_write(rec, tok);
1125				}
1126			}
1127		}
1128		break;
1129
1130	case AUE_KILL:
1131	case AUE_KILLPG:
1132		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
1133			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
1134			kau_write(rec, tok);
1135		}
1136		PROCESS_PID_TOKENS(1);
1137		break;
1138
1139	case AUE_KTRACE:
1140		if (ARG_IS_VALID(kar, ARG_CMD)) {
1141			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
1142			kau_write(rec, tok);
1143		}
1144		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1145			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
1146			kau_write(rec, tok);
1147		}
1148		PROCESS_PID_TOKENS(4);
1149		UPATH1_VNODE1_TOKENS;
1150		break;
1151
1152	case AUE_LINK:
1153	case AUE_LINKAT:
1154	case AUE_RENAME:
1155	case AUE_RENAMEAT:
1156		ATFD1_TOKENS(1);
1157		UPATH1_VNODE1_TOKENS;
1158		ATFD2_TOKENS(3);
1159		UPATH2_TOKENS;
1160		break;
1161
1162	case AUE_LOADSHFILE:
1163		ADDR_TOKEN(4, "base addr");
1164		UPATH1_VNODE1_TOKENS;
1165		break;
1166
1167	case AUE_MKDIR:
1168	case AUE_MKDIRAT:
1169	case AUE_MKFIFO:
1170	case AUE_MKFIFOAT:
1171		ATFD1_TOKENS(1);
1172		if (ARG_IS_VALID(kar, ARG_MODE)) {
1173			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1174			kau_write(rec, tok);
1175		}
1176		UPATH1_VNODE1_TOKENS;
1177		break;
1178
1179	case AUE_MKNOD:
1180	case AUE_MKNODAT:
1181		ATFD1_TOKENS(1);
1182		if (ARG_IS_VALID(kar, ARG_MODE)) {
1183			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1184			kau_write(rec, tok);
1185		}
1186		if (ARG_IS_VALID(kar, ARG_DEV)) {
1187			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
1188			kau_write(rec, tok);
1189		}
1190		UPATH1_VNODE1_TOKENS;
1191		break;
1192
1193	case AUE_MMAP:
1194	case AUE_MUNMAP:
1195	case AUE_MPROTECT:
1196	case AUE_MLOCK:
1197	case AUE_MUNLOCK:
1198	case AUE_MINHERIT:
1199		ADDR_TOKEN(1, "addr");
1200		if (ARG_IS_VALID(kar, ARG_LEN)) {
1201			tok = au_to_arg32(2, "len", ar->ar_arg_len);
1202			kau_write(rec, tok);
1203		}
1204		if (ar->ar_event == AUE_MMAP)
1205			FD_VNODE1_TOKENS;
1206		if (ar->ar_event == AUE_MPROTECT) {
1207			if (ARG_IS_VALID(kar, ARG_VALUE)) {
1208				tok = au_to_arg32(3, "protection",
1209				    ar->ar_arg_value);
1210				kau_write(rec, tok);
1211			}
1212		}
1213		if (ar->ar_event == AUE_MINHERIT) {
1214			if (ARG_IS_VALID(kar, ARG_VALUE)) {
1215				tok = au_to_arg32(3, "inherit",
1216				    ar->ar_arg_value);
1217				kau_write(rec, tok);
1218			}
1219		}
1220		break;
1221
1222	case AUE_MOUNT:
1223	case AUE_NMOUNT:
1224		/* XXX Need to handle NFS mounts */
1225		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1226			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1227			kau_write(rec, tok);
1228		}
1229		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1230			tok = au_to_text(ar->ar_arg_text);
1231			kau_write(rec, tok);
1232		}
1233		/* FALLTHROUGH */
1234
1235	case AUE_NFS_SVC:
1236		if (ARG_IS_VALID(kar, ARG_CMD)) {
1237			tok = au_to_arg32(1, "flags", ar->ar_arg_cmd);
1238			kau_write(rec, tok);
1239		}
1240		break;
1241
1242	case AUE_UMOUNT:
1243		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1244			tok = au_to_arg32(2, "flags", ar->ar_arg_value);
1245			kau_write(rec, tok);
1246		}
1247		UPATH1_VNODE1_TOKENS;
1248		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1249			tok = au_to_text(ar->ar_arg_text);
1250			kau_write(rec, tok);
1251		}
1252		break;
1253
1254	case AUE_MSGCTL:
1255		ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd);
1256		/* Fall through */
1257
1258	case AUE_MSGRCV:
1259	case AUE_MSGSND:
1260		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
1261		kau_write(rec, tok);
1262		if (ar->ar_errno != EINVAL) {
1263			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
1264			kau_write(rec, tok);
1265		}
1266		break;
1267
1268	case AUE_MSGGET:
1269		if (ar->ar_errno == 0) {
1270			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1271				tok = au_to_ipc(AT_IPC_MSG,
1272				    ar->ar_arg_svipc_id);
1273				kau_write(rec, tok);
1274			}
1275		}
1276		break;
1277
1278	case AUE_RESETSHFILE:
1279		ADDR_TOKEN(1, "base addr");
1280		break;
1281
1282	case AUE_OPEN_RC:
1283	case AUE_OPEN_RTC:
1284	case AUE_OPEN_RWC:
1285	case AUE_OPEN_RWTC:
1286	case AUE_OPEN_WC:
1287	case AUE_OPEN_WTC:
1288	case AUE_CREAT:
1289		if (ARG_IS_VALID(kar, ARG_MODE)) {
1290			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1291			kau_write(rec, tok);
1292		}
1293		/* FALLTHROUGH */
1294
1295	case AUE_OPEN_R:
1296	case AUE_OPEN_RT:
1297	case AUE_OPEN_RW:
1298	case AUE_OPEN_RWT:
1299	case AUE_OPEN_W:
1300	case AUE_OPEN_WT:
1301		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1302			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1303			kau_write(rec, tok);
1304		}
1305		UPATH1_VNODE1_TOKENS;
1306		break;
1307
1308	case AUE_OPENAT_RC:
1309	case AUE_OPENAT_RTC:
1310	case AUE_OPENAT_RWC:
1311	case AUE_OPENAT_RWTC:
1312	case AUE_OPENAT_WC:
1313	case AUE_OPENAT_WTC:
1314		if (ARG_IS_VALID(kar, ARG_MODE)) {
1315			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1316			kau_write(rec, tok);
1317		}
1318		/* FALLTHROUGH */
1319
1320	case AUE_OPENAT_R:
1321	case AUE_OPENAT_RT:
1322	case AUE_OPENAT_RW:
1323	case AUE_OPENAT_RWT:
1324	case AUE_OPENAT_W:
1325	case AUE_OPENAT_WT:
1326		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1327			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1328			kau_write(rec, tok);
1329		}
1330		ATFD1_TOKENS(1);
1331		UPATH1_VNODE1_TOKENS;
1332		break;
1333
1334	case AUE_PDKILL:
1335		if (ARG_IS_VALID(kar, ARG_FD)) {
1336			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
1337			kau_write(rec, tok);
1338		}
1339		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
1340			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
1341			kau_write(rec, tok);
1342		}
1343		PROCESS_PID_TOKENS(1);
1344		break;
1345	case AUE_PDFORK:
1346		if (ARG_IS_VALID(kar, ARG_PID)) {
1347			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
1348			kau_write(rec, tok);
1349		}
1350		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1351			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1352			kau_write(rec, tok);
1353		}
1354		if (ARG_IS_VALID(kar, ARG_FD)) {
1355			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
1356			kau_write(rec, tok);
1357		}
1358		break;
1359	case AUE_PDGETPID:
1360		if (ARG_IS_VALID(kar, ARG_FD)) {
1361			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
1362			kau_write(rec, tok);
1363		}
1364		break;
1365
1366	case AUE_PROCCTL:
1367		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1368			tok = au_to_arg32(1, "idtype", ar->ar_arg_value);
1369			kau_write(rec, tok);
1370		}
1371		if (ARG_IS_VALID(kar, ARG_CMD)) {
1372			tok = au_to_arg32(2, "com", ar->ar_arg_cmd);
1373			kau_write(rec, tok);
1374		}
1375		PROCESS_PID_TOKENS(3);
1376		break;
1377
1378	case AUE_PTRACE:
1379		if (ARG_IS_VALID(kar, ARG_CMD)) {
1380			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1381			kau_write(rec, tok);
1382		}
1383		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1384			tok = au_to_arg32(4, "data", ar->ar_arg_value);
1385			kau_write(rec, tok);
1386		}
1387		PROCESS_PID_TOKENS(2);
1388		break;
1389
1390	case AUE_QUOTACTL:
1391		if (ARG_IS_VALID(kar, ARG_CMD)) {
1392			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1393			kau_write(rec, tok);
1394		}
1395		if (ARG_IS_VALID(kar, ARG_UID)) {
1396			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1397			kau_write(rec, tok);
1398		}
1399		if (ARG_IS_VALID(kar, ARG_GID)) {
1400			tok = au_to_arg32(3, "gid", ar->ar_arg_gid);
1401			kau_write(rec, tok);
1402		}
1403		UPATH1_VNODE1_TOKENS;
1404		break;
1405
1406	case AUE_REBOOT:
1407		if (ARG_IS_VALID(kar, ARG_CMD)) {
1408			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1409			kau_write(rec, tok);
1410		}
1411		break;
1412
1413	case AUE_SEMCTL:
1414		ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd);
1415		/* Fall through */
1416
1417	case AUE_SEMOP:
1418		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1419			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1420			kau_write(rec, tok);
1421			if (ar->ar_errno != EINVAL) {
1422				tok = au_to_ipc(AT_IPC_SEM,
1423				    ar->ar_arg_svipc_id);
1424				kau_write(rec, tok);
1425			}
1426		}
1427		break;
1428
1429	case AUE_SEMGET:
1430		if (ar->ar_errno == 0) {
1431			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1432				tok = au_to_ipc(AT_IPC_SEM,
1433				    ar->ar_arg_svipc_id);
1434				kau_write(rec, tok);
1435			}
1436		}
1437		break;
1438
1439	case AUE_SETEGID:
1440		if (ARG_IS_VALID(kar, ARG_EGID)) {
1441			tok = au_to_arg32(1, "egid", ar->ar_arg_egid);
1442			kau_write(rec, tok);
1443		}
1444		break;
1445
1446	case AUE_SETEUID:
1447		if (ARG_IS_VALID(kar, ARG_EUID)) {
1448			tok = au_to_arg32(1, "euid", ar->ar_arg_euid);
1449			kau_write(rec, tok);
1450		}
1451		break;
1452
1453	case AUE_SETREGID:
1454		if (ARG_IS_VALID(kar, ARG_RGID)) {
1455			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1456			kau_write(rec, tok);
1457		}
1458		if (ARG_IS_VALID(kar, ARG_EGID)) {
1459			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1460			kau_write(rec, tok);
1461		}
1462		break;
1463
1464	case AUE_SETREUID:
1465		if (ARG_IS_VALID(kar, ARG_RUID)) {
1466			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1467			kau_write(rec, tok);
1468		}
1469		if (ARG_IS_VALID(kar, ARG_EUID)) {
1470			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1471			kau_write(rec, tok);
1472		}
1473		break;
1474
1475	case AUE_SETRESGID:
1476		if (ARG_IS_VALID(kar, ARG_RGID)) {
1477			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1478			kau_write(rec, tok);
1479		}
1480		if (ARG_IS_VALID(kar, ARG_EGID)) {
1481			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1482			kau_write(rec, tok);
1483		}
1484		if (ARG_IS_VALID(kar, ARG_SGID)) {
1485			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
1486			kau_write(rec, tok);
1487		}
1488		break;
1489
1490	case AUE_SETRESUID:
1491		if (ARG_IS_VALID(kar, ARG_RUID)) {
1492			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1493			kau_write(rec, tok);
1494		}
1495		if (ARG_IS_VALID(kar, ARG_EUID)) {
1496			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1497			kau_write(rec, tok);
1498		}
1499		if (ARG_IS_VALID(kar, ARG_SUID)) {
1500			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
1501			kau_write(rec, tok);
1502		}
1503		break;
1504
1505	case AUE_SETGID:
1506		if (ARG_IS_VALID(kar, ARG_GID)) {
1507			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1508			kau_write(rec, tok);
1509		}
1510		break;
1511
1512	case AUE_SETUID:
1513		if (ARG_IS_VALID(kar, ARG_UID)) {
1514			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1515			kau_write(rec, tok);
1516		}
1517		break;
1518
1519	case AUE_SETGROUPS:
1520		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1521			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1522			{
1523				tok = au_to_arg32(1, "setgroups",
1524				    ar->ar_arg_groups.gidset[ctr]);
1525				kau_write(rec, tok);
1526			}
1527		}
1528		break;
1529
1530	case AUE_SETLOGIN:
1531		if (ARG_IS_VALID(kar, ARG_LOGIN)) {
1532			tok = au_to_text(ar->ar_arg_login);
1533			kau_write(rec, tok);
1534		}
1535		break;
1536
1537	case AUE_SETLOGINCLASS:
1538		break;
1539
1540	case AUE_SETPRIORITY:
1541		if (ARG_IS_VALID(kar, ARG_CMD)) {
1542			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1543			kau_write(rec, tok);
1544		}
1545		if (ARG_IS_VALID(kar, ARG_UID)) {
1546			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1547			kau_write(rec, tok);
1548		}
1549		PROCESS_PID_TOKENS(2);
1550		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1551			tok = au_to_arg32(3, "priority", ar->ar_arg_value);
1552			kau_write(rec, tok);
1553		}
1554		break;
1555
1556	case AUE_SETPRIVEXEC:
1557		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1558			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1559			kau_write(rec, tok);
1560		}
1561		break;
1562
1563	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1564	case AUE_SHMAT:
1565		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1566			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1567			kau_write(rec, tok);
1568			/* XXXAUDIT: Does having the ipc token make sense? */
1569			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1570			kau_write(rec, tok);
1571		}
1572		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1573			tok = au_to_arg32(2, "shmaddr",
1574			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1575			kau_write(rec, tok);
1576		}
1577		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1578			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1579			kau_write(rec, tok);
1580		}
1581		break;
1582
1583	case AUE_SHMCTL:
1584		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1585			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1586			kau_write(rec, tok);
1587			/* XXXAUDIT: Does having the ipc token make sense? */
1588			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1589			kau_write(rec, tok);
1590		}
1591		switch (ar->ar_arg_svipc_cmd) {
1592		case IPC_STAT:
1593			ar->ar_event = AUE_SHMCTL_STAT;
1594			break;
1595		case IPC_RMID:
1596			ar->ar_event = AUE_SHMCTL_RMID;
1597			break;
1598		case IPC_SET:
1599			ar->ar_event = AUE_SHMCTL_SET;
1600			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1601				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1602				kau_write(rec, tok);
1603			}
1604			break;
1605		default:
1606			break;	/* We will audit a bad command */
1607		}
1608		break;
1609
1610	case AUE_SHMDT:
1611		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1612			tok = au_to_arg32(1, "shmaddr",
1613			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1614			kau_write(rec, tok);
1615		}
1616		break;
1617
1618	case AUE_SHMGET:
1619		/* This is unusual; the return value is in an argument token */
1620		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1621			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1622			kau_write(rec, tok);
1623			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1624			kau_write(rec, tok);
1625		}
1626		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1627			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1628			kau_write(rec, tok);
1629		}
1630		break;
1631
1632	/* shm_rename is a non-Posix extension to the Posix shm implementation */
1633	case AUE_SHMRENAME:
1634		UPATH1_TOKENS;
1635		UPATH2_TOKENS;
1636		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1637			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1638			kau_write(rec, tok);
1639		}
1640		break;
1641
1642	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1643	 * and AUE_SEMUNLINK are Posix IPC */
1644	case AUE_SHMOPEN:
1645		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1646			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1647			kau_write(rec, tok);
1648		}
1649		if (ARG_IS_VALID(kar, ARG_MODE)) {
1650			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1651			kau_write(rec, tok);
1652		}
1653		/* FALLTHROUGH */
1654
1655	case AUE_SHMUNLINK:
1656		UPATH1_TOKENS;
1657		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1658			struct ipc_perm perm;
1659
1660			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1661			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1662			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1663			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1664			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1665			perm.seq = 0;
1666			perm.key = 0;
1667			tok = au_to_ipc_perm(&perm);
1668			kau_write(rec, tok);
1669		}
1670		break;
1671
1672	case AUE_SEMOPEN:
1673		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1674			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1675			kau_write(rec, tok);
1676		}
1677		if (ARG_IS_VALID(kar, ARG_MODE)) {
1678			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1679			kau_write(rec, tok);
1680		}
1681		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1682			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1683			kau_write(rec, tok);
1684		}
1685		/* FALLTHROUGH */
1686
1687	case AUE_SEMUNLINK:
1688		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1689			tok = au_to_text(ar->ar_arg_text);
1690			kau_write(rec, tok);
1691		}
1692		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1693			struct ipc_perm perm;
1694
1695			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1696			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1697			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1698			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1699			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1700			perm.seq = 0;
1701			perm.key = 0;
1702			tok = au_to_ipc_perm(&perm);
1703			kau_write(rec, tok);
1704		}
1705		break;
1706
1707	case AUE_SEMCLOSE:
1708		if (ARG_IS_VALID(kar, ARG_FD)) {
1709			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1710			kau_write(rec, tok);
1711		}
1712		break;
1713
1714	case AUE_SYMLINK:
1715	case AUE_SYMLINKAT:
1716		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1717			tok = au_to_text(ar->ar_arg_text);
1718			kau_write(rec, tok);
1719		}
1720		ATFD1_TOKENS(1);
1721		UPATH1_VNODE1_TOKENS;
1722		break;
1723
1724	case AUE_SYSCTL:
1725	case AUE_SYSCTL_NONADMIN:
1726		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1727			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1728				tok = au_to_arg32(1, "name",
1729				    ar->ar_arg_ctlname[ctr]);
1730				kau_write(rec, tok);
1731			}
1732		}
1733		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1734			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1735			kau_write(rec, tok);
1736		}
1737		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1738			tok = au_to_text(ar->ar_arg_text);
1739			kau_write(rec, tok);
1740		}
1741		break;
1742
1743	case AUE_UMASK:
1744		if (ARG_IS_VALID(kar, ARG_MASK)) {
1745			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1746			kau_write(rec, tok);
1747		}
1748		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1749		kau_write(rec, tok);
1750		break;
1751
1752	case AUE_WAIT4:
1753	case AUE_WAIT6:
1754		PROCESS_PID_TOKENS(1);
1755		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1756			tok = au_to_arg32(3, "options", ar->ar_arg_value);
1757			kau_write(rec, tok);
1758		}
1759		break;
1760
1761	case AUE_CAP_RIGHTS_LIMIT:
1762		/*
1763		 * XXXRW/XXXJA: Would be nice to audit socket/etc information.
1764		 */
1765		FD_VNODE1_TOKENS;
1766		if (ARG_IS_VALID(kar, ARG_RIGHTS)) {
1767			tok = au_to_rights(&ar->ar_arg_rights);
1768			kau_write(rec, tok);
1769		}
1770		break;
1771
1772	case AUE_CAP_FCNTLS_GET:
1773	case AUE_CAP_IOCTLS_GET:
1774	case AUE_CAP_IOCTLS_LIMIT:
1775	case AUE_CAP_RIGHTS_GET:
1776		if (ARG_IS_VALID(kar, ARG_FD)) {
1777			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
1778			kau_write(rec, tok);
1779		}
1780		break;
1781
1782	case AUE_CAP_FCNTLS_LIMIT:
1783		FD_VNODE1_TOKENS;
1784		if (ARG_IS_VALID(kar, ARG_FCNTL_RIGHTS)) {
1785			tok = au_to_arg32(2, "fcntlrights",
1786			    ar->ar_arg_fcntl_rights);
1787			kau_write(rec, tok);
1788		}
1789		break;
1790
1791	case AUE_CAP_ENTER:
1792	case AUE_CAP_GETMODE:
1793		break;
1794
1795	case AUE_THR_NEW:
1796	case AUE_THR_KILL:
1797	case AUE_THR_EXIT:
1798		break;
1799
1800	case AUE_NULL:
1801	default:
1802		printf("BSM conversion requested for unknown event %d\n",
1803		    ar->ar_event);
1804
1805		/*
1806		 * Write the subject token so it is properly freed here.
1807		 */
1808		if (jail_tok != NULL)
1809			kau_write(rec, jail_tok);
1810		kau_write(rec, subj_tok);
1811		kau_free(rec);
1812		return (BSM_NOAUDIT);
1813	}
1814
1815	if (jail_tok != NULL)
1816		kau_write(rec, jail_tok);
1817	kau_write(rec, subj_tok);
1818	tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval);
1819	kau_write(rec, tok);  /* Every record gets a return token */
1820
1821	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1822
1823	*pau = rec;
1824	return (BSM_SUCCESS);
1825}
1826
1827/*
1828 * Verify that a record is a valid BSM record. This verification is simple
1829 * now, but may be expanded on sometime in the future.  Return 1 if the
1830 * record is good, 0 otherwise.
1831 */
1832int
1833bsm_rec_verify(void *rec)
1834{
1835	char c = *(char *)rec;
1836
1837	/*
1838	 * Check the token ID of the first token; it has to be a header
1839	 * token.
1840	 *
1841	 * XXXAUDIT There needs to be a token structure to map a token.
1842	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1843	 */
1844	if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) &&
1845	    (c != AUT_HEADER64) && (c != AUT_HEADER64_EX))
1846		return (0);
1847	return (1);
1848}
1849