1155192Srwatson/*
2188311Srwatson * Copyright (c) 1999-2009 Apple Inc.
3155192Srwatson * All rights reserved.
4155192Srwatson *
5155192Srwatson * Redistribution and use in source and binary forms, with or without
6155192Srwatson * modification, are permitted provided that the following conditions
7155192Srwatson * are met:
8155192Srwatson * 1.  Redistributions of source code must retain the above copyright
9155192Srwatson *     notice, this list of conditions and the following disclaimer.
10155192Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
11155192Srwatson *     notice, this list of conditions and the following disclaimer in the
12155192Srwatson *     documentation and/or other materials provided with the distribution.
13180701Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
14155192Srwatson *     its contributors may be used to endorse or promote products derived
15155192Srwatson *     from this software without specific prior written permission.
16155192Srwatson *
17155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27155192Srwatson * POSSIBILITY OF SUCH DAMAGE.
28155192Srwatson */
29155192Srwatson
30178186Srwatson#include <sys/cdefs.h>
31178186Srwatson__FBSDID("$FreeBSD: stable/10/sys/security/audit/audit_bsm.c 337251 2018-08-03 14:22:16Z asomers $");
32178186Srwatson
33155192Srwatson#include <sys/param.h>
34155192Srwatson#include <sys/vnode.h>
35155192Srwatson#include <sys/ipc.h>
36155192Srwatson#include <sys/lock.h>
37155192Srwatson#include <sys/malloc.h>
38155192Srwatson#include <sys/mutex.h>
39155192Srwatson#include <sys/socket.h>
40160136Swsalamon#include <sys/extattr.h>
41155192Srwatson#include <sys/fcntl.h>
42155192Srwatson#include <sys/user.h>
43155192Srwatson#include <sys/systm.h>
44155192Srwatson
45155192Srwatson#include <bsm/audit.h>
46155192Srwatson#include <bsm/audit_internal.h>
47155192Srwatson#include <bsm/audit_record.h>
48155192Srwatson#include <bsm/audit_kevents.h>
49155192Srwatson
50155192Srwatson#include <security/audit/audit.h>
51155192Srwatson#include <security/audit/audit_private.h>
52155192Srwatson
53155192Srwatson#include <netinet/in_systm.h>
54155192Srwatson#include <netinet/in.h>
55155192Srwatson#include <netinet/ip.h>
56155192Srwatson
57155192SrwatsonMALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
58155192Srwatson
59155192Srwatsonstatic void	audit_sys_auditon(struct audit_record *ar,
60155192Srwatson		    struct au_record *rec);
61155192Srwatson
62155192Srwatson/*
63155192Srwatson * Initialize the BSM auditing subsystem.
64155192Srwatson */
65155192Srwatsonvoid
66155192Srwatsonkau_init(void)
67155192Srwatson{
68155192Srwatson
69155192Srwatson	au_evclassmap_init();
70155192Srwatson}
71155192Srwatson
72155192Srwatson/*
73156889Srwatson * This call reserves memory for the audit record.  Memory must be guaranteed
74156889Srwatson * before any auditable event can be generated.  The au_record structure
75156889Srwatson * maintains a reference to the memory allocated above and also the list of
76180706Srwatson * tokens associated with this record.
77156889Srwatson */
78156889Srwatsonstatic struct au_record *
79155192Srwatsonkau_open(void)
80156889Srwatson{
81155192Srwatson	struct au_record *rec;
82156889Srwatson
83155192Srwatson	rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK);
84162466Srwatson	rec->data = NULL;
85155192Srwatson	TAILQ_INIT(&rec->token_q);
86155192Srwatson	rec->len = 0;
87155192Srwatson	rec->used = 1;
88155192Srwatson
89155192Srwatson	return (rec);
90155192Srwatson}
91155192Srwatson
92155192Srwatson/*
93155192Srwatson * Store the token with the record descriptor.
94156889Srwatson */
95155192Srwatsonstatic void
96155192Srwatsonkau_write(struct au_record *rec, struct au_token *tok)
97155192Srwatson{
98155192Srwatson
99155192Srwatson	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
100155192Srwatson
101155192Srwatson	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
102155192Srwatson	rec->len += tok->len;
103155192Srwatson}
104155192Srwatson
105155192Srwatson/*
106155192Srwatson * Close out the audit record by adding the header token, identifying any
107155192Srwatson * missing tokens.  Write out the tokens to the record memory.
108155192Srwatson */
109155192Srwatsonstatic void
110155192Srwatsonkau_close(struct au_record *rec, struct timespec *ctime, short event)
111155192Srwatson{
112155192Srwatson	u_char *dptr;
113155192Srwatson	size_t tot_rec_size;
114155192Srwatson	token_t *cur, *hdr, *trail;
115155192Srwatson	struct timeval tm;
116184856Scsjp	size_t hdrsize;
117184856Scsjp	struct auditinfo_addr ak;
118184856Scsjp	struct in6_addr *ap;
119156889Srwatson
120184856Scsjp	audit_get_kinfo(&ak);
121184856Scsjp	hdrsize = 0;
122184856Scsjp	switch (ak.ai_termid.at_type) {
123184856Scsjp	case AU_IPv4:
124184856Scsjp		hdrsize = (ak.ai_termid.at_addr[0] == INADDR_ANY) ?
125184856Scsjp		    AUDIT_HEADER_SIZE : AUDIT_HEADER_EX_SIZE(&ak);
126184856Scsjp		break;
127184856Scsjp	case AU_IPv6:
128184856Scsjp		ap = (struct in6_addr *)&ak.ai_termid.at_addr[0];
129184856Scsjp		hdrsize = (IN6_IS_ADDR_UNSPECIFIED(ap)) ? AUDIT_HEADER_SIZE :
130184856Scsjp		    AUDIT_HEADER_EX_SIZE(&ak);
131184856Scsjp		break;
132184856Scsjp	default:
133184856Scsjp		panic("kau_close: invalid address family");
134184856Scsjp	}
135184856Scsjp	tot_rec_size = rec->len + hdrsize + AUDIT_TRAILER_SIZE;
136162466Srwatson	rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO);
137170196Srwatson
138162466Srwatson	tm.tv_usec = ctime->tv_nsec / 1000;
139162466Srwatson	tm.tv_sec = ctime->tv_sec;
140184856Scsjp	if (hdrsize != AUDIT_HEADER_SIZE)
141184856Scsjp		hdr = au_to_header32_ex_tm(tot_rec_size, event, 0, tm, &ak);
142184856Scsjp	else
143184856Scsjp		hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
144162466Srwatson	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
145155192Srwatson
146162466Srwatson	trail = au_to_trailer(tot_rec_size);
147162466Srwatson	TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
148155192Srwatson
149162466Srwatson	rec->len = tot_rec_size;
150162466Srwatson	dptr = rec->data;
151162466Srwatson	TAILQ_FOREACH(cur, &rec->token_q, tokens) {
152162466Srwatson		memcpy(dptr, cur->t_data, cur->len);
153162466Srwatson		dptr += cur->len;
154155192Srwatson	}
155155192Srwatson}
156155192Srwatson
157155192Srwatson/*
158156889Srwatson * Free a BSM audit record by releasing all the tokens and clearing the audit
159156889Srwatson * record information.
160155192Srwatson */
161155192Srwatsonvoid
162155192Srwatsonkau_free(struct au_record *rec)
163155192Srwatson{
164155192Srwatson	struct au_token *tok;
165155192Srwatson
166156889Srwatson	/* Free the token list. */
167155192Srwatson	while ((tok = TAILQ_FIRST(&rec->token_q))) {
168155192Srwatson		TAILQ_REMOVE(&rec->token_q, tok, tokens);
169155192Srwatson		free(tok->t_data, M_AUDITBSM);
170155192Srwatson		free(tok, M_AUDITBSM);
171156889Srwatson	}
172155192Srwatson
173155192Srwatson	rec->used = 0;
174156889Srwatson	rec->len = 0;
175155192Srwatson	free(rec->data, M_AUDITBSM);
176155192Srwatson	free(rec, M_AUDITBSM);
177155192Srwatson}
178155192Srwatson
179155192Srwatson/*
180170196Srwatson * XXX: May want turn some (or all) of these macros into functions in order
181180704Srwatson * to reduce the generated code size.
182155192Srwatson *
183155192Srwatson * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
184155192Srwatson * caller are OK with this.
185155192Srwatson */
186195925Srwatson#define	ATFD1_TOKENS(argnum) do {					\
187195925Srwatson	if (ARG_IS_VALID(kar, ARG_ATFD1)) {				\
188195925Srwatson		tok = au_to_arg32(argnum, "at fd 1", ar->ar_arg_atfd1);	\
189195925Srwatson		kau_write(rec, tok);					\
190195925Srwatson	}								\
191195925Srwatson} while (0)
192195925Srwatson
193195925Srwatson#define	ATFD2_TOKENS(argnum) do {					\
194195925Srwatson	if (ARG_IS_VALID(kar, ARG_ATFD2)) {				\
195195925Srwatson		tok = au_to_arg32(argnum, "at fd 2", ar->ar_arg_atfd2);	\
196195925Srwatson		kau_write(rec, tok);					\
197195925Srwatson	}								\
198195925Srwatson} while (0)
199195925Srwatson
200180708Srwatson#define	UPATH1_TOKENS do {						\
201155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
202155192Srwatson		tok = au_to_path(ar->ar_arg_upath1);			\
203155192Srwatson		kau_write(rec, tok);					\
204155192Srwatson	}								\
205155192Srwatson} while (0)
206155192Srwatson
207180708Srwatson#define	UPATH2_TOKENS do {						\
208155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
209155192Srwatson		tok = au_to_path(ar->ar_arg_upath2);			\
210155192Srwatson		kau_write(rec, tok);					\
211155192Srwatson	}								\
212155192Srwatson} while (0)
213155192Srwatson
214180708Srwatson#define	VNODE1_TOKENS do {						\
215195925Srwatson	if (ARG_IS_VALID(kar, ARG_ATFD)) {				\
216195925Srwatson		tok = au_to_arg32(1, "at fd", ar->ar_arg_atfd);		\
217195925Srwatson		kau_write(rec, tok);					\
218195925Srwatson	}								\
219180709Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
220155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
221155192Srwatson		kau_write(rec, tok);					\
222155192Srwatson	}								\
223155192Srwatson} while (0)
224155192Srwatson
225180708Srwatson#define	UPATH1_VNODE1_TOKENS do {					\
226246911Spjd	UPATH1_TOKENS;							\
227180709Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
228155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
229155192Srwatson		kau_write(rec, tok);					\
230155192Srwatson	}								\
231155192Srwatson} while (0)
232155192Srwatson
233180708Srwatson#define	VNODE2_TOKENS do {						\
234180709Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE2)) {				\
235155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
236155192Srwatson		kau_write(rec, tok);					\
237155192Srwatson	}								\
238155192Srwatson} while (0)
239155192Srwatson
240180711Srwatson#define	FD_VNODE1_TOKENS do {						\
241155192Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
242155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {			\
243155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
244155192Srwatson			kau_write(rec, tok);				\
245155192Srwatson		}							\
246155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
247155192Srwatson		kau_write(rec, tok);					\
248155192Srwatson	} else {							\
249155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {			\
250156889Srwatson			tok = au_to_arg32(1, "non-file: fd",		\
251156889Srwatson			    ar->ar_arg_fd);				\
252155192Srwatson			kau_write(rec, tok);				\
253155192Srwatson		}							\
254155192Srwatson	}								\
255155192Srwatson} while (0)
256155192Srwatson
257180708Srwatson#define	PROCESS_PID_TOKENS(argn) do {					\
258159277Srwatson	if ((ar->ar_arg_pid > 0) /* Reference a single process */	\
259159277Srwatson	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {			\
260172915Scsjp		tok = au_to_process32_ex(ar->ar_arg_auid,		\
261159277Srwatson		    ar->ar_arg_euid, ar->ar_arg_egid,			\
262159277Srwatson		    ar->ar_arg_ruid, ar->ar_arg_rgid,			\
263159277Srwatson		    ar->ar_arg_pid, ar->ar_arg_asid,			\
264172915Scsjp		    &ar->ar_arg_termid_addr);				\
265159277Srwatson		kau_write(rec, tok);					\
266159277Srwatson	} else if (ARG_IS_VALID(kar, ARG_PID)) {			\
267159277Srwatson		tok = au_to_arg32(argn, "process", ar->ar_arg_pid);	\
268159277Srwatson		kau_write(rec, tok);					\
269155192Srwatson	}								\
270180712Srwatson} while (0)
271155192Srwatson
272195280Srwatson#define	EXTATTR_TOKENS(namespace_argnum) do {				\
273160136Swsalamon	if (ARG_IS_VALID(kar, ARG_VALUE)) {				\
274160136Swsalamon		switch (ar->ar_arg_value) {				\
275160136Swsalamon		case EXTATTR_NAMESPACE_USER:				\
276160136Swsalamon			tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
277160136Swsalamon			break;						\
278160136Swsalamon		case EXTATTR_NAMESPACE_SYSTEM:				\
279160136Swsalamon			tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
280160136Swsalamon			break;						\
281160136Swsalamon		default:						\
282195280Srwatson			tok = au_to_arg32((namespace_argnum),		\
283195280Srwatson			    "attrnamespace", ar->ar_arg_value);		\
284160136Swsalamon			break;						\
285160136Swsalamon		}							\
286160136Swsalamon		kau_write(rec, tok);					\
287160136Swsalamon	}								\
288160136Swsalamon	/* attrname is in the text field */				\
289160136Swsalamon	if (ARG_IS_VALID(kar, ARG_TEXT)) {				\
290160136Swsalamon		tok = au_to_text(ar->ar_arg_text);			\
291160136Swsalamon		kau_write(rec, tok);					\
292160136Swsalamon	}								\
293160136Swsalamon} while (0)
294160136Swsalamon
295155192Srwatson/*
296195280Srwatson * Not all pointer arguments to system calls are of interest, but in some
297195282Srwatson * cases they reflect delegation of rights, such as mmap(2) followed by
298195280Srwatson * minherit(2) before execve(2), so do the best we can.
299195280Srwatson */
300195280Srwatson#define	ADDR_TOKEN(argnum, argname) do {				\
301195280Srwatson	if (ARG_IS_VALID(kar, ARG_ADDR)) {				\
302195280Srwatson		if (sizeof(void *) == sizeof(uint32_t))			\
303195280Srwatson			tok = au_to_arg32((argnum), (argname),		\
304195280Srwatson			    (uint32_t)(uintptr_t)ar->ar_arg_addr);	\
305195280Srwatson		else							\
306195280Srwatson			tok = au_to_arg64((argnum), (argname),		\
307195280Srwatson			    (uint64_t)(uintptr_t)ar->ar_arg_addr);	\
308195280Srwatson		kau_write(rec, tok);					\
309195280Srwatson	}								\
310195280Srwatson} while (0)
311195280Srwatson
312195280Srwatson
313195280Srwatson/*
314155192Srwatson * Implement auditing for the auditon() system call. The audit tokens that
315155192Srwatson * are generated depend on the command that was sent into the auditon()
316155192Srwatson * system call.
317155192Srwatson */
318155192Srwatsonstatic void
319155192Srwatsonaudit_sys_auditon(struct audit_record *ar, struct au_record *rec)
320155192Srwatson{
321155192Srwatson	struct au_token *tok;
322155192Srwatson
323195280Srwatson	tok = au_to_arg32(3, "length", ar->ar_arg_len);
324195280Srwatson	kau_write(rec, tok);
325155192Srwatson	switch (ar->ar_arg_cmd) {
326191270Srwatson	case A_OLDSETPOLICY:
327191270Srwatson		if ((size_t)ar->ar_arg_len == sizeof(int64_t)) {
328191270Srwatson			tok = au_to_arg64(2, "policy",
329191270Srwatson			    ar->ar_arg_auditon.au_policy64);
330191270Srwatson			kau_write(rec, tok);
331191270Srwatson			break;
332191270Srwatson		}
333191270Srwatson		/* FALLTHROUGH */
334195280Srwatson
335156889Srwatson	case A_SETPOLICY:
336195280Srwatson		tok = au_to_arg32(2, "policy", ar->ar_arg_auditon.au_policy);
337155192Srwatson		kau_write(rec, tok);
338155192Srwatson		break;
339155192Srwatson
340156889Srwatson	case A_SETKMASK:
341156889Srwatson		tok = au_to_arg32(2, "setkmask:as_success",
342156889Srwatson		    ar->ar_arg_auditon.au_mask.am_success);
343155192Srwatson		kau_write(rec, tok);
344156889Srwatson		tok = au_to_arg32(2, "setkmask:as_failure",
345156889Srwatson		    ar->ar_arg_auditon.au_mask.am_failure);
346155192Srwatson		kau_write(rec, tok);
347155192Srwatson		break;
348155192Srwatson
349191270Srwatson	case A_OLDSETQCTRL:
350191270Srwatson		if ((size_t)ar->ar_arg_len == sizeof(au_qctrl64_t)) {
351191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_hiwater",
352191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_hiwater);
353191270Srwatson			kau_write(rec, tok);
354191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_lowater",
355191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_lowater);
356191270Srwatson			kau_write(rec, tok);
357191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_bufsz",
358191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_bufsz);
359191270Srwatson			kau_write(rec, tok);
360191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_delay",
361191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_delay);
362191270Srwatson			kau_write(rec, tok);
363191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_minfree",
364191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_minfree);
365191270Srwatson			kau_write(rec, tok);
366191270Srwatson			break;
367191270Srwatson		}
368191270Srwatson		/* FALLTHROUGH */
369195280Srwatson
370156889Srwatson	case A_SETQCTRL:
371195280Srwatson		tok = au_to_arg32(2, "setqctrl:aq_hiwater",
372156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
373155192Srwatson		kau_write(rec, tok);
374191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_lowater",
375156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
376155192Srwatson		kau_write(rec, tok);
377191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_bufsz",
378156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
379155192Srwatson		kau_write(rec, tok);
380191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_delay",
381156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_delay);
382155192Srwatson		kau_write(rec, tok);
383191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_minfree",
384156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
385155192Srwatson		kau_write(rec, tok);
386155192Srwatson		break;
387155192Srwatson
388156889Srwatson	case A_SETUMASK:
389195280Srwatson		tok = au_to_arg32(2, "setumask:as_success",
390156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
391155192Srwatson		kau_write(rec, tok);
392195280Srwatson		tok = au_to_arg32(2, "setumask:as_failure",
393156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
394155192Srwatson		kau_write(rec, tok);
395155192Srwatson		break;
396155192Srwatson
397156889Srwatson	case A_SETSMASK:
398191270Srwatson		tok = au_to_arg32(2, "setsmask:as_success",
399156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
400155192Srwatson		kau_write(rec, tok);
401191270Srwatson		tok = au_to_arg32(2, "setsmask:as_failure",
402156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
403155192Srwatson		kau_write(rec, tok);
404155192Srwatson		break;
405155192Srwatson
406191270Srwatson	case A_OLDSETCOND:
407191270Srwatson		if ((size_t)ar->ar_arg_len == sizeof(int64_t)) {
408191270Srwatson			tok = au_to_arg64(2, "setcond",
409191270Srwatson			    ar->ar_arg_auditon.au_cond64);
410191270Srwatson			kau_write(rec, tok);
411191270Srwatson			break;
412191270Srwatson		}
413191270Srwatson		/* FALLTHROUGH */
414195280Srwatson
415156889Srwatson	case A_SETCOND:
416195280Srwatson		tok = au_to_arg32(2, "setcond", ar->ar_arg_auditon.au_cond);
417155192Srwatson		kau_write(rec, tok);
418155192Srwatson		break;
419155192Srwatson
420156889Srwatson	case A_SETCLASS:
421155192Srwatson		tok = au_to_arg32(2, "setclass:ec_event",
422156889Srwatson		    ar->ar_arg_auditon.au_evclass.ec_number);
423155192Srwatson		kau_write(rec, tok);
424191270Srwatson		tok = au_to_arg32(2, "setclass:ec_class",
425156889Srwatson		    ar->ar_arg_auditon.au_evclass.ec_class);
426155192Srwatson		kau_write(rec, tok);
427155192Srwatson		break;
428155192Srwatson
429156889Srwatson	case A_SETPMASK:
430156889Srwatson		tok = au_to_arg32(2, "setpmask:as_success",
431156889Srwatson		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
432155192Srwatson		kau_write(rec, tok);
433156889Srwatson		tok = au_to_arg32(2, "setpmask:as_failure",
434156889Srwatson		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
435155192Srwatson		kau_write(rec, tok);
436155192Srwatson		break;
437155192Srwatson
438156889Srwatson	case A_SETFSIZE:
439156889Srwatson		tok = au_to_arg32(2, "setfsize:filesize",
440156889Srwatson		    ar->ar_arg_auditon.au_fstat.af_filesz);
441155192Srwatson		kau_write(rec, tok);
442155192Srwatson		break;
443155192Srwatson
444155192Srwatson	default:
445155192Srwatson		break;
446155192Srwatson	}
447155192Srwatson}
448155192Srwatson
449155192Srwatson/*
450156889Srwatson * Convert an internal kernel audit record to a BSM record and return a
451156889Srwatson * success/failure indicator. The BSM record is passed as an out parameter to
452156889Srwatson * this function.
453156889Srwatson *
454155192Srwatson * Return conditions:
455155192Srwatson *   BSM_SUCCESS: The BSM record is valid
456155192Srwatson *   BSM_FAILURE: Failure; the BSM record is NULL.
457156889Srwatson *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
458155192Srwatson */
459155192Srwatsonint
460155192Srwatsonkaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
461155192Srwatson{
462245573Scsjp	struct au_token *tok, *subj_tok, *jail_tok;
463155192Srwatson	struct au_record *rec;
464155192Srwatson	au_tid_t tid;
465155192Srwatson	struct audit_record *ar;
466155192Srwatson	int ctr;
467155192Srwatson
468155192Srwatson	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
469155192Srwatson
470155192Srwatson	*pau = NULL;
471155192Srwatson	ar = &kar->k_ar;
472155192Srwatson	rec = kau_open();
473155192Srwatson
474180715Srwatson	/*
475245573Scsjp	 * Create the subject token.  If this credential was jailed be sure to
476245573Scsjp	 * generate a zonename token.
477180715Srwatson	 */
478245573Scsjp	if (ar->ar_jailname[0] != '\0')
479245573Scsjp		jail_tok = au_to_zonename(ar->ar_jailname);
480245573Scsjp	else
481245573Scsjp		jail_tok = NULL;
482168688Scsjp	switch (ar->ar_subj_term_addr.at_type) {
483168688Scsjp	case AU_IPv4:
484168688Scsjp		tid.port = ar->ar_subj_term_addr.at_port;
485168688Scsjp		tid.machine = ar->ar_subj_term_addr.at_addr[0];
486168688Scsjp		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
487168688Scsjp		    ar->ar_subj_cred.cr_uid, /* eff uid */
488168688Scsjp		    ar->ar_subj_egid,	/* eff group id */
489180709Srwatson		    ar->ar_subj_ruid,	/* real uid */
490180709Srwatson		    ar->ar_subj_rgid,	/* real group id */
491168688Scsjp		    ar->ar_subj_pid,	/* process id */
492168688Scsjp		    ar->ar_subj_asid,	/* session ID */
493168688Scsjp		    &tid);
494168688Scsjp		break;
495168688Scsjp	case AU_IPv6:
496168688Scsjp		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
497168688Scsjp		    ar->ar_subj_cred.cr_uid,
498168688Scsjp		    ar->ar_subj_egid,
499168688Scsjp		    ar->ar_subj_ruid,
500168688Scsjp		    ar->ar_subj_rgid,
501168688Scsjp		    ar->ar_subj_pid,
502168688Scsjp		    ar->ar_subj_asid,
503168688Scsjp		    &ar->ar_subj_term_addr);
504168688Scsjp		break;
505168688Scsjp	default:
506168688Scsjp		bzero(&tid, sizeof(tid));
507168688Scsjp		subj_tok = au_to_subject32(ar->ar_subj_auid,
508168688Scsjp		    ar->ar_subj_cred.cr_uid,
509168688Scsjp		    ar->ar_subj_egid,
510168688Scsjp		    ar->ar_subj_ruid,
511168688Scsjp		    ar->ar_subj_rgid,
512168688Scsjp		    ar->ar_subj_pid,
513168688Scsjp		    ar->ar_subj_asid,
514168688Scsjp		    &tid);
515168688Scsjp	}
516155192Srwatson
517156889Srwatson	/*
518156889Srwatson	 * The logic inside each case fills in the tokens required for the
519156889Srwatson	 * event, except for the header, trailer, and return tokens.  The
520155192Srwatson	 * header and trailer tokens are added by the kau_close() function.
521155192Srwatson	 * The return token is added outside of the switch statement.
522156889Srwatson	 */
523155192Srwatson	switch(ar->ar_event) {
524155192Srwatson	case AUE_ACCEPT:
525155192Srwatson	case AUE_BIND:
526175455Scsjp	case AUE_LISTEN:
527155192Srwatson	case AUE_CONNECT:
528162990Srwatson	case AUE_RECV:
529155192Srwatson	case AUE_RECVFROM:
530156889Srwatson	case AUE_RECVMSG:
531162990Srwatson	case AUE_SEND:
532162990Srwatson	case AUE_SENDFILE:
533155192Srwatson	case AUE_SENDMSG:
534155192Srwatson	case AUE_SENDTO:
535156889Srwatson		/*
536156889Srwatson		 * Socket-related events.
537156889Srwatson		 */
538155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
539155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
540155192Srwatson			kau_write(rec, tok);
541155192Srwatson		}
542155192Srwatson		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
543156889Srwatson			tok = au_to_sock_inet((struct sockaddr_in *)
544156889Srwatson			    &ar->ar_arg_sockaddr);
545155192Srwatson			kau_write(rec, tok);
546155192Srwatson		}
547155192Srwatson		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
548156889Srwatson			tok = au_to_sock_unix((struct sockaddr_un *)
549156889Srwatson			    &ar->ar_arg_sockaddr);
550155192Srwatson			kau_write(rec, tok);
551155192Srwatson			UPATH1_TOKENS;
552155192Srwatson		}
553155192Srwatson		/* XXX Need to handle ARG_SADDRINET6 */
554155192Srwatson		break;
555155192Srwatson
556247667Spjd	case AUE_BINDAT:
557247667Spjd	case AUE_CONNECTAT:
558247667Spjd		ATFD1_TOKENS(1);
559247667Spjd		if (ARG_IS_VALID(kar, ARG_FD)) {
560247667Spjd			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
561247667Spjd			kau_write(rec, tok);
562247667Spjd		}
563247667Spjd		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
564247667Spjd			tok = au_to_sock_unix((struct sockaddr_un *)
565247667Spjd			    &ar->ar_arg_sockaddr);
566247667Spjd			kau_write(rec, tok);
567247667Spjd			UPATH1_TOKENS;
568247667Spjd		}
569247667Spjd		break;
570247667Spjd
571155192Srwatson	case AUE_SOCKET:
572155192Srwatson	case AUE_SOCKETPAIR:
573155192Srwatson		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
574195280Srwatson			tok = au_to_arg32(1, "domain",
575155192Srwatson			    ar->ar_arg_sockinfo.so_domain);
576155192Srwatson			kau_write(rec, tok);
577195280Srwatson			tok = au_to_arg32(2, "type",
578155192Srwatson			    ar->ar_arg_sockinfo.so_type);
579155192Srwatson			kau_write(rec, tok);
580195280Srwatson			tok = au_to_arg32(3, "protocol",
581155192Srwatson			    ar->ar_arg_sockinfo.so_protocol);
582155192Srwatson			kau_write(rec, tok);
583155192Srwatson		}
584155192Srwatson		break;
585155192Srwatson
586155192Srwatson	case AUE_SETSOCKOPT:
587155192Srwatson	case AUE_SHUTDOWN:
588155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
589155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
590155192Srwatson			kau_write(rec, tok);
591155192Srwatson		}
592155192Srwatson		break;
593155192Srwatson
594155192Srwatson	case AUE_ACCT:
595155192Srwatson		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
596155192Srwatson			UPATH1_VNODE1_TOKENS;
597155192Srwatson		} else {
598155192Srwatson			tok = au_to_arg32(1, "accounting off", 0);
599155192Srwatson			kau_write(rec, tok);
600155192Srwatson		}
601155192Srwatson		break;
602155192Srwatson
603155192Srwatson	case AUE_SETAUID:
604155192Srwatson		if (ARG_IS_VALID(kar, ARG_AUID)) {
605155192Srwatson			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
606155192Srwatson			kau_write(rec, tok);
607155192Srwatson		}
608155192Srwatson		break;
609155192Srwatson
610155192Srwatson	case AUE_SETAUDIT:
611171066Scsjp		if (ARG_IS_VALID(kar, ARG_AUID) &&
612171066Scsjp		    ARG_IS_VALID(kar, ARG_ASID) &&
613171066Scsjp		    ARG_IS_VALID(kar, ARG_AMASK) &&
614171066Scsjp		    ARG_IS_VALID(kar, ARG_TERMID)) {
615156889Srwatson			tok = au_to_arg32(1, "setaudit:auid",
616156889Srwatson			    ar->ar_arg_auid);
617155192Srwatson			kau_write(rec, tok);
618156889Srwatson			tok = au_to_arg32(1, "setaudit:port",
619156889Srwatson			    ar->ar_arg_termid.port);
620155192Srwatson			kau_write(rec, tok);
621156889Srwatson			tok = au_to_arg32(1, "setaudit:machine",
622156889Srwatson			    ar->ar_arg_termid.machine);
623155192Srwatson			kau_write(rec, tok);
624156889Srwatson			tok = au_to_arg32(1, "setaudit:as_success",
625156889Srwatson			    ar->ar_arg_amask.am_success);
626155192Srwatson			kau_write(rec, tok);
627156889Srwatson			tok = au_to_arg32(1, "setaudit:as_failure",
628156889Srwatson			    ar->ar_arg_amask.am_failure);
629155192Srwatson			kau_write(rec, tok);
630156889Srwatson			tok = au_to_arg32(1, "setaudit:asid",
631156889Srwatson			    ar->ar_arg_asid);
632155192Srwatson			kau_write(rec, tok);
633155192Srwatson		}
634155192Srwatson		break;
635155192Srwatson
636155192Srwatson	case AUE_SETAUDIT_ADDR:
637171066Scsjp		if (ARG_IS_VALID(kar, ARG_AUID) &&
638171066Scsjp		    ARG_IS_VALID(kar, ARG_ASID) &&
639171066Scsjp		    ARG_IS_VALID(kar, ARG_AMASK) &&
640171066Scsjp		    ARG_IS_VALID(kar, ARG_TERMID_ADDR)) {
641171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:auid",
642171066Scsjp			    ar->ar_arg_auid);
643171066Scsjp			kau_write(rec, tok);
644171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:as_success",
645171066Scsjp			    ar->ar_arg_amask.am_success);
646171066Scsjp			kau_write(rec, tok);
647171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:as_failure",
648171066Scsjp			    ar->ar_arg_amask.am_failure);
649171066Scsjp			kau_write(rec, tok);
650171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:asid",
651171066Scsjp			    ar->ar_arg_asid);
652171066Scsjp			kau_write(rec, tok);
653171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:type",
654171066Scsjp			    ar->ar_arg_termid_addr.at_type);
655171066Scsjp			kau_write(rec, tok);
656171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:port",
657171066Scsjp			    ar->ar_arg_termid_addr.at_port);
658171066Scsjp			kau_write(rec, tok);
659171066Scsjp			if (ar->ar_arg_termid_addr.at_type == AU_IPv6)
660171066Scsjp				tok = au_to_in_addr_ex((struct in6_addr *)
661171066Scsjp				    &ar->ar_arg_termid_addr.at_addr[0]);
662171066Scsjp			if (ar->ar_arg_termid_addr.at_type == AU_IPv4)
663171066Scsjp				tok = au_to_in_addr((struct in_addr *)
664171066Scsjp				    &ar->ar_arg_termid_addr.at_addr[0]);
665171066Scsjp			kau_write(rec, tok);
666171066Scsjp		}
667171066Scsjp		break;
668155192Srwatson
669155192Srwatson	case AUE_AUDITON:
670156889Srwatson		/*
671156889Srwatson		 * For AUDITON commands without own event, audit the cmd.
672156889Srwatson		 */
673155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
674155192Srwatson			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
675155192Srwatson			kau_write(rec, tok);
676155192Srwatson		}
677185293Srwatson		/* FALLTHROUGH */
678155192Srwatson
679155192Srwatson	case AUE_AUDITON_GETCAR:
680155192Srwatson	case AUE_AUDITON_GETCLASS:
681155192Srwatson	case AUE_AUDITON_GETCOND:
682155192Srwatson	case AUE_AUDITON_GETCWD:
683155192Srwatson	case AUE_AUDITON_GETKMASK:
684155192Srwatson	case AUE_AUDITON_GETSTAT:
685155192Srwatson	case AUE_AUDITON_GPOLICY:
686155192Srwatson	case AUE_AUDITON_GQCTRL:
687155192Srwatson	case AUE_AUDITON_SETCLASS:
688155192Srwatson	case AUE_AUDITON_SETCOND:
689155192Srwatson	case AUE_AUDITON_SETKMASK:
690155192Srwatson	case AUE_AUDITON_SETSMASK:
691155192Srwatson	case AUE_AUDITON_SETSTAT:
692155192Srwatson	case AUE_AUDITON_SETUMASK:
693155192Srwatson	case AUE_AUDITON_SPOLICY:
694155192Srwatson	case AUE_AUDITON_SQCTRL:
695156889Srwatson		if (ARG_IS_VALID(kar, ARG_AUDITON))
696155192Srwatson			audit_sys_auditon(ar, rec);
697155192Srwatson		break;
698156889Srwatson
699155192Srwatson	case AUE_AUDITCTL:
700155192Srwatson		UPATH1_VNODE1_TOKENS;
701155192Srwatson		break;
702155192Srwatson
703155192Srwatson	case AUE_EXIT:
704155192Srwatson		if (ARG_IS_VALID(kar, ARG_EXIT)) {
705155192Srwatson			tok = au_to_exit(ar->ar_arg_exitretval,
706155192Srwatson			    ar->ar_arg_exitstatus);
707155192Srwatson			kau_write(rec, tok);
708155192Srwatson		}
709155192Srwatson		break;
710155192Srwatson
711155192Srwatson	case AUE_ADJTIME:
712162990Srwatson	case AUE_CLOCK_SETTIME:
713155192Srwatson	case AUE_AUDIT:
714162990Srwatson	case AUE_DUP2:
715155192Srwatson	case AUE_GETAUDIT:
716155192Srwatson	case AUE_GETAUDIT_ADDR:
717155192Srwatson	case AUE_GETAUID:
718162990Srwatson	case AUE_GETCWD:
719155192Srwatson	case AUE_GETFSSTAT:
720162990Srwatson	case AUE_GETRESUID:
721162990Srwatson	case AUE_GETRESGID:
722162990Srwatson	case AUE_KQUEUE:
723162990Srwatson	case AUE_MODLOAD:
724162990Srwatson	case AUE_MODUNLOAD:
725162990Srwatson	case AUE_MSGSYS:
726162990Srwatson	case AUE_NTP_ADJTIME:
727155192Srwatson	case AUE_PIPE:
728195291Srwatson	case AUE_POSIX_OPENPT:
729162990Srwatson	case AUE_PROFILE:
730162990Srwatson	case AUE_RTPRIO:
731162990Srwatson	case AUE_SEMSYS:
732162990Srwatson	case AUE_SHMSYS:
733155192Srwatson	case AUE_SETPGRP:
734155192Srwatson	case AUE_SETRLIMIT:
735155192Srwatson	case AUE_SETSID:
736155192Srwatson	case AUE_SETTIMEOFDAY:
737162990Srwatson	case AUE_SYSARCH:
738162990Srwatson
739156889Srwatson		/*
740156889Srwatson		 * Header, subject, and return tokens added at end.
741156889Srwatson		 */
742155192Srwatson		break;
743155192Srwatson
744155192Srwatson	case AUE_CHDIR:
745155192Srwatson	case AUE_CHROOT:
746195925Srwatson	case AUE_FSTATAT:
747195925Srwatson	case AUE_FUTIMESAT:
748155192Srwatson	case AUE_GETATTRLIST:
749162990Srwatson	case AUE_JAIL:
750162419Scsjp	case AUE_LUTIMES:
751155192Srwatson	case AUE_NFS_GETFH:
752155192Srwatson	case AUE_LSTAT:
753207615Scsjp	case AUE_LPATHCONF:
754155192Srwatson	case AUE_PATHCONF:
755155192Srwatson	case AUE_READLINK:
756243727Spjd	case AUE_READLINKAT:
757155192Srwatson	case AUE_REVOKE:
758155192Srwatson	case AUE_RMDIR:
759155192Srwatson	case AUE_SEARCHFS:
760155192Srwatson	case AUE_SETATTRLIST:
761155192Srwatson	case AUE_STAT:
762155192Srwatson	case AUE_STATFS:
763162990Srwatson	case AUE_SWAPON:
764162990Srwatson	case AUE_SWAPOFF:
765155192Srwatson	case AUE_TRUNCATE:
766155192Srwatson	case AUE_UNDELETE:
767155192Srwatson	case AUE_UNLINK:
768195925Srwatson	case AUE_UNLINKAT:
769155192Srwatson	case AUE_UTIMES:
770195925Srwatson		ATFD1_TOKENS(1);
771155192Srwatson		UPATH1_VNODE1_TOKENS;
772155192Srwatson		break;
773155192Srwatson
774195267Srwatson	case AUE_ACCESS:
775195267Srwatson	case AUE_EACCESS:
776243727Spjd	case AUE_FACCESSAT:
777243727Spjd		ATFD1_TOKENS(1);
778195267Srwatson		UPATH1_VNODE1_TOKENS;
779195267Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
780195280Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_value);
781195267Srwatson			kau_write(rec, tok);
782195267Srwatson		}
783195267Srwatson		break;
784195267Srwatson
785162990Srwatson	case AUE_FHSTATFS:
786162990Srwatson	case AUE_FHOPEN:
787162990Srwatson	case AUE_FHSTAT:
788162990Srwatson		/* XXXRW: Need to audit vnode argument. */
789162990Srwatson		break;
790162990Srwatson
791155192Srwatson	case AUE_CHFLAGS:
792155192Srwatson	case AUE_LCHFLAGS:
793155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
794155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
795155192Srwatson			kau_write(rec, tok);
796155192Srwatson		}
797155192Srwatson		UPATH1_VNODE1_TOKENS;
798155192Srwatson		break;
799156889Srwatson
800155192Srwatson	case AUE_CHMOD:
801155192Srwatson	case AUE_LCHMOD:
802155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
803156889Srwatson			tok = au_to_arg32(2, "new file mode",
804156889Srwatson			    ar->ar_arg_mode);
805155192Srwatson			kau_write(rec, tok);
806155192Srwatson		}
807155192Srwatson		UPATH1_VNODE1_TOKENS;
808155192Srwatson		break;
809156889Srwatson
810195925Srwatson	case AUE_FCHMODAT:
811195925Srwatson		ATFD1_TOKENS(1);
812195925Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
813195925Srwatson			tok = au_to_arg32(3, "new file mode",
814195925Srwatson			    ar->ar_arg_mode);
815195925Srwatson			kau_write(rec, tok);
816195925Srwatson		}
817195925Srwatson		UPATH1_VNODE1_TOKENS;
818195925Srwatson		break;
819195925Srwatson
820155192Srwatson	case AUE_CHOWN:
821155192Srwatson	case AUE_LCHOWN:
822155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
823155192Srwatson			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
824155192Srwatson			kau_write(rec, tok);
825155192Srwatson		}
826155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
827155192Srwatson			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
828155192Srwatson			kau_write(rec, tok);
829155192Srwatson		}
830155192Srwatson		UPATH1_VNODE1_TOKENS;
831155192Srwatson		break;
832156889Srwatson
833195925Srwatson	case AUE_FCHOWNAT:
834195925Srwatson		ATFD1_TOKENS(1);
835195925Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
836195925Srwatson			tok = au_to_arg32(3, "new file uid", ar->ar_arg_uid);
837195925Srwatson			kau_write(rec, tok);
838195925Srwatson		}
839195925Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
840195925Srwatson			tok = au_to_arg32(4, "new file gid", ar->ar_arg_gid);
841195925Srwatson			kau_write(rec, tok);
842195925Srwatson		}
843195925Srwatson		UPATH1_VNODE1_TOKENS;
844195925Srwatson		break;
845195925Srwatson
846155192Srwatson	case AUE_EXCHANGEDATA:
847155192Srwatson		UPATH1_VNODE1_TOKENS;
848155192Srwatson		UPATH2_TOKENS;
849155192Srwatson		break;
850155192Srwatson
851155192Srwatson	case AUE_CLOSE:
852155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
853195280Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
854155192Srwatson			kau_write(rec, tok);
855155192Srwatson		}
856155192Srwatson		UPATH1_VNODE1_TOKENS;
857155192Srwatson		break;
858155192Srwatson
859203328Scsjp	case AUE_CLOSEFROM:
860203328Scsjp		if (ARG_IS_VALID(kar, ARG_FD)) {
861203328Scsjp			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
862203328Scsjp			kau_write(rec, tok);
863203328Scsjp		}
864203328Scsjp		break;
865203328Scsjp
866172995Scsjp	case AUE_CORE:
867172995Scsjp		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
868195280Srwatson			tok = au_to_arg32(1, "signal", ar->ar_arg_signum);
869172995Scsjp			kau_write(rec, tok);
870172995Scsjp		}
871172995Scsjp		UPATH1_VNODE1_TOKENS;
872172995Scsjp		break;
873172995Scsjp
874160136Swsalamon	case AUE_EXTATTRCTL:
875160136Swsalamon		UPATH1_VNODE1_TOKENS;
876160136Swsalamon		if (ARG_IS_VALID(kar, ARG_CMD)) {
877160136Swsalamon			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
878160136Swsalamon			kau_write(rec, tok);
879160136Swsalamon		}
880160136Swsalamon		/* extattrctl(2) filename parameter is in upath2/vnode2 */
881160136Swsalamon		UPATH2_TOKENS;
882160136Swsalamon		VNODE2_TOKENS;
883195280Srwatson		EXTATTR_TOKENS(4);
884160136Swsalamon		break;
885160136Swsalamon
886160136Swsalamon	case AUE_EXTATTR_GET_FILE:
887160136Swsalamon	case AUE_EXTATTR_SET_FILE:
888160136Swsalamon	case AUE_EXTATTR_LIST_FILE:
889160136Swsalamon	case AUE_EXTATTR_DELETE_FILE:
890160136Swsalamon	case AUE_EXTATTR_GET_LINK:
891160136Swsalamon	case AUE_EXTATTR_SET_LINK:
892160136Swsalamon	case AUE_EXTATTR_LIST_LINK:
893160136Swsalamon	case AUE_EXTATTR_DELETE_LINK:
894160136Swsalamon		UPATH1_VNODE1_TOKENS;
895195280Srwatson		EXTATTR_TOKENS(2);
896160136Swsalamon		break;
897160136Swsalamon
898160136Swsalamon	case AUE_EXTATTR_GET_FD:
899160136Swsalamon	case AUE_EXTATTR_SET_FD:
900160136Swsalamon	case AUE_EXTATTR_LIST_FD:
901160136Swsalamon	case AUE_EXTATTR_DELETE_FD:
902160136Swsalamon		if (ARG_IS_VALID(kar, ARG_FD)) {
903160136Swsalamon			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
904160136Swsalamon			kau_write(rec, tok);
905160136Swsalamon		}
906195280Srwatson		EXTATTR_TOKENS(2);
907160136Swsalamon		break;
908160136Swsalamon
909182158Srwatson	case AUE_FEXECVE:
910182158Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
911182158Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
912182158Srwatson			kau_write(rec, tok);
913182158Srwatson		}
914182158Srwatson		/* FALLTHROUGH */
915182158Srwatson
916161813Swsalamon	case AUE_EXECVE:
917188312Srwatson	case AUE_MAC_EXECVE:
918161813Swsalamon		if (ARG_IS_VALID(kar, ARG_ARGV)) {
919161813Swsalamon			tok = au_to_exec_args(ar->ar_arg_argv,
920161813Swsalamon			    ar->ar_arg_argc);
921161813Swsalamon			kau_write(rec, tok);
922161813Swsalamon		}
923161813Swsalamon		if (ARG_IS_VALID(kar, ARG_ENVV)) {
924161813Swsalamon			tok = au_to_exec_env(ar->ar_arg_envv,
925161813Swsalamon			    ar->ar_arg_envc);
926161813Swsalamon			kau_write(rec, tok);
927161813Swsalamon		}
928161813Swsalamon		UPATH1_VNODE1_TOKENS;
929161813Swsalamon		break;
930161813Swsalamon
931155192Srwatson	case AUE_FCHMOD:
932155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
933156889Srwatson			tok = au_to_arg32(2, "new file mode",
934156889Srwatson			    ar->ar_arg_mode);
935155192Srwatson			kau_write(rec, tok);
936155192Srwatson		}
937155192Srwatson		FD_VNODE1_TOKENS;
938155192Srwatson		break;
939156889Srwatson
940162990Srwatson	/*
941162990Srwatson	 * XXXRW: Some of these need to handle non-vnode cases as well.
942162990Srwatson	 */
943155192Srwatson	case AUE_FCHDIR:
944155192Srwatson	case AUE_FPATHCONF:
945162990Srwatson	case AUE_FSTAT:
946155192Srwatson	case AUE_FSTATFS:
947155192Srwatson	case AUE_FSYNC:
948155192Srwatson	case AUE_FTRUNCATE:
949155192Srwatson	case AUE_FUTIMES:
950155192Srwatson	case AUE_GETDIRENTRIES:
951155192Srwatson	case AUE_GETDIRENTRIESATTR:
952195242Srwatson	case AUE_LSEEK:
953162990Srwatson	case AUE_POLL:
954162990Srwatson	case AUE_READ:
955162990Srwatson	case AUE_READV:
956162990Srwatson	case AUE_WRITE:
957162990Srwatson	case AUE_WRITEV:
958155192Srwatson		FD_VNODE1_TOKENS;
959155192Srwatson		break;
960156889Srwatson
961155192Srwatson	case AUE_FCHOWN:
962155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
963155192Srwatson			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
964155192Srwatson			kau_write(rec, tok);
965155192Srwatson		}
966155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
967155192Srwatson			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
968155192Srwatson			kau_write(rec, tok);
969155192Srwatson		}
970155192Srwatson		FD_VNODE1_TOKENS;
971155192Srwatson		break;
972156889Srwatson
973155192Srwatson	case AUE_FCNTL:
974191270Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
975191270Srwatson			tok = au_to_arg32(2, "cmd",
976191270Srwatson			    au_fcntl_cmd_to_bsm(ar->ar_arg_cmd));
977191270Srwatson			kau_write(rec, tok);
978191270Srwatson		}
979155192Srwatson		if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
980180715Srwatson		    ar->ar_arg_cmd == F_SETLKW) {
981155192Srwatson			FD_VNODE1_TOKENS;
982155192Srwatson		}
983155192Srwatson		break;
984156889Srwatson
985155192Srwatson	case AUE_FCHFLAGS:
986155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
987155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
988155192Srwatson			kau_write(rec, tok);
989155192Srwatson		}
990155192Srwatson		FD_VNODE1_TOKENS;
991155192Srwatson		break;
992156889Srwatson
993155192Srwatson	case AUE_FLOCK:
994155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
995155192Srwatson			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
996155192Srwatson			kau_write(rec, tok);
997155192Srwatson		}
998155192Srwatson		FD_VNODE1_TOKENS;
999155192Srwatson		break;
1000156889Srwatson
1001155192Srwatson	case AUE_RFORK:
1002155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1003155192Srwatson			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
1004155192Srwatson			kau_write(rec, tok);
1005155192Srwatson		}
1006185293Srwatson		/* FALLTHROUGH */
1007185293Srwatson
1008155192Srwatson	case AUE_FORK:
1009155192Srwatson	case AUE_VFORK:
1010155192Srwatson		if (ARG_IS_VALID(kar, ARG_PID)) {
1011155192Srwatson			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
1012155192Srwatson			kau_write(rec, tok);
1013155192Srwatson		}
1014155192Srwatson		break;
1015156889Srwatson
1016155192Srwatson	case AUE_IOCTL:
1017155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1018155192Srwatson			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
1019155192Srwatson			kau_write(rec, tok);
1020155192Srwatson		}
1021156889Srwatson		if (ARG_IS_VALID(kar, ARG_VNODE1))
1022155192Srwatson			FD_VNODE1_TOKENS;
1023156889Srwatson		else {
1024155192Srwatson			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
1025156889Srwatson				tok = kau_to_socket(&ar->ar_arg_sockinfo);
1026155192Srwatson				kau_write(rec, tok);
1027155192Srwatson			} else {
1028155192Srwatson				if (ARG_IS_VALID(kar, ARG_FD)) {
1029155192Srwatson					tok = au_to_arg32(1, "fd",
1030155192Srwatson					    ar->ar_arg_fd);
1031180709Srwatson					kau_write(rec, tok);
1032155192Srwatson				}
1033155192Srwatson			}
1034155192Srwatson		}
1035155192Srwatson		break;
1036155192Srwatson
1037155192Srwatson	case AUE_KILL:
1038162990Srwatson	case AUE_KILLPG:
1039155192Srwatson		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
1040155192Srwatson			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
1041155192Srwatson			kau_write(rec, tok);
1042155192Srwatson		}
1043155192Srwatson		PROCESS_PID_TOKENS(1);
1044155192Srwatson		break;
1045155192Srwatson
1046155192Srwatson	case AUE_KTRACE:
1047155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1048155192Srwatson			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
1049155192Srwatson			kau_write(rec, tok);
1050155192Srwatson		}
1051155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1052155192Srwatson			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
1053155192Srwatson			kau_write(rec, tok);
1054155192Srwatson		}
1055155192Srwatson		PROCESS_PID_TOKENS(4);
1056155192Srwatson		UPATH1_VNODE1_TOKENS;
1057155192Srwatson		break;
1058155192Srwatson
1059155192Srwatson	case AUE_LINK:
1060195925Srwatson	case AUE_LINKAT:
1061155192Srwatson	case AUE_RENAME:
1062195925Srwatson	case AUE_RENAMEAT:
1063195925Srwatson		ATFD1_TOKENS(1);
1064155192Srwatson		UPATH1_VNODE1_TOKENS;
1065195925Srwatson		ATFD2_TOKENS(3);
1066155192Srwatson		UPATH2_TOKENS;
1067155192Srwatson		break;
1068155192Srwatson
1069155192Srwatson	case AUE_LOADSHFILE:
1070195280Srwatson		ADDR_TOKEN(4, "base addr");
1071155192Srwatson		UPATH1_VNODE1_TOKENS;
1072155192Srwatson		break;
1073156889Srwatson
1074155192Srwatson	case AUE_MKDIR:
1075243727Spjd	case AUE_MKDIRAT:
1076243727Spjd	case AUE_MKFIFO:
1077243727Spjd	case AUE_MKFIFOAT:
1078243727Spjd		ATFD1_TOKENS(1);
1079155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1080155192Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1081155192Srwatson			kau_write(rec, tok);
1082155192Srwatson		}
1083155192Srwatson		UPATH1_VNODE1_TOKENS;
1084155192Srwatson		break;
1085155192Srwatson
1086155192Srwatson	case AUE_MKNOD:
1087243727Spjd	case AUE_MKNODAT:
1088243727Spjd		ATFD1_TOKENS(1);
1089155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1090155192Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1091155192Srwatson			kau_write(rec, tok);
1092155192Srwatson		}
1093155192Srwatson		if (ARG_IS_VALID(kar, ARG_DEV)) {
1094155192Srwatson			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
1095155192Srwatson			kau_write(rec, tok);
1096155192Srwatson		}
1097155192Srwatson		UPATH1_VNODE1_TOKENS;
1098155192Srwatson		break;
1099155192Srwatson
1100155192Srwatson	case AUE_MMAP:
1101155192Srwatson	case AUE_MUNMAP:
1102155192Srwatson	case AUE_MPROTECT:
1103155192Srwatson	case AUE_MLOCK:
1104155192Srwatson	case AUE_MUNLOCK:
1105155192Srwatson	case AUE_MINHERIT:
1106195280Srwatson		ADDR_TOKEN(1, "addr");
1107155192Srwatson		if (ARG_IS_VALID(kar, ARG_LEN)) {
1108155192Srwatson			tok = au_to_arg32(2, "len", ar->ar_arg_len);
1109155192Srwatson			kau_write(rec, tok);
1110155192Srwatson		}
1111155192Srwatson		if (ar->ar_event == AUE_MMAP)
1112155192Srwatson			FD_VNODE1_TOKENS;
1113155192Srwatson		if (ar->ar_event == AUE_MPROTECT) {
1114155192Srwatson			if (ARG_IS_VALID(kar, ARG_VALUE)) {
1115155192Srwatson				tok = au_to_arg32(3, "protection",
1116155192Srwatson				    ar->ar_arg_value);
1117155192Srwatson				kau_write(rec, tok);
1118155192Srwatson			}
1119155192Srwatson		}
1120155192Srwatson		if (ar->ar_event == AUE_MINHERIT) {
1121155192Srwatson			if (ARG_IS_VALID(kar, ARG_VALUE)) {
1122155192Srwatson				tok = au_to_arg32(3, "inherit",
1123155192Srwatson				    ar->ar_arg_value);
1124155192Srwatson				kau_write(rec, tok);
1125155192Srwatson			}
1126155192Srwatson		}
1127155192Srwatson		break;
1128155192Srwatson
1129155192Srwatson	case AUE_MOUNT:
1130162990Srwatson	case AUE_NMOUNT:
1131155192Srwatson		/* XXX Need to handle NFS mounts */
1132155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1133155192Srwatson			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1134155192Srwatson			kau_write(rec, tok);
1135155192Srwatson		}
1136155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1137155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1138155192Srwatson			kau_write(rec, tok);
1139155192Srwatson		}
1140185293Srwatson		/* FALLTHROUGH */
1141156889Srwatson
1142188311Srwatson	case AUE_NFS_SVC:
1143188311Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1144195280Srwatson			tok = au_to_arg32(1, "flags", ar->ar_arg_cmd);
1145188311Srwatson			kau_write(rec, tok);
1146188311Srwatson		}
1147188311Srwatson		break;
1148188311Srwatson
1149155192Srwatson	case AUE_UMOUNT:
1150195247Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1151195280Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_value);
1152195247Srwatson			kau_write(rec, tok);
1153195247Srwatson		}
1154155192Srwatson		UPATH1_VNODE1_TOKENS;
1155195247Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1156195247Srwatson			tok = au_to_text(ar->ar_arg_text);
1157195247Srwatson			kau_write(rec, tok);
1158195247Srwatson		}
1159155192Srwatson		break;
1160155192Srwatson
1161155192Srwatson	case AUE_MSGCTL:
1162176565Srwatson		ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd);
1163155192Srwatson		/* Fall through */
1164156889Srwatson
1165155192Srwatson	case AUE_MSGRCV:
1166155192Srwatson	case AUE_MSGSND:
1167155192Srwatson		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
1168155192Srwatson		kau_write(rec, tok);
1169155192Srwatson		if (ar->ar_errno != EINVAL) {
1170155192Srwatson			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
1171155192Srwatson			kau_write(rec, tok);
1172155192Srwatson		}
1173155192Srwatson		break;
1174155192Srwatson
1175155192Srwatson	case AUE_MSGGET:
1176155192Srwatson		if (ar->ar_errno == 0) {
1177155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1178155192Srwatson				tok = au_to_ipc(AT_IPC_MSG,
1179155192Srwatson				    ar->ar_arg_svipc_id);
1180155192Srwatson				kau_write(rec, tok);
1181155192Srwatson			}
1182155192Srwatson		}
1183155192Srwatson		break;
1184155192Srwatson
1185155192Srwatson	case AUE_RESETSHFILE:
1186195280Srwatson		ADDR_TOKEN(1, "base addr");
1187155192Srwatson		break;
1188156889Srwatson
1189155192Srwatson	case AUE_OPEN_RC:
1190155192Srwatson	case AUE_OPEN_RTC:
1191155192Srwatson	case AUE_OPEN_RWC:
1192155192Srwatson	case AUE_OPEN_RWTC:
1193155192Srwatson	case AUE_OPEN_WC:
1194155192Srwatson	case AUE_OPEN_WTC:
1195162990Srwatson	case AUE_CREAT:
1196155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1197155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1198155192Srwatson			kau_write(rec, tok);
1199155192Srwatson		}
1200185293Srwatson		/* FALLTHROUGH */
1201155192Srwatson
1202155192Srwatson	case AUE_OPEN_R:
1203155192Srwatson	case AUE_OPEN_RT:
1204155192Srwatson	case AUE_OPEN_RW:
1205155192Srwatson	case AUE_OPEN_RWT:
1206155192Srwatson	case AUE_OPEN_W:
1207155192Srwatson	case AUE_OPEN_WT:
1208155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1209155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1210155192Srwatson			kau_write(rec, tok);
1211155192Srwatson		}
1212155192Srwatson		UPATH1_VNODE1_TOKENS;
1213155192Srwatson		break;
1214155192Srwatson
1215195925Srwatson	case AUE_OPENAT_RC:
1216195925Srwatson	case AUE_OPENAT_RTC:
1217195925Srwatson	case AUE_OPENAT_RWC:
1218195925Srwatson	case AUE_OPENAT_RWTC:
1219195925Srwatson	case AUE_OPENAT_WC:
1220195925Srwatson	case AUE_OPENAT_WTC:
1221195925Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1222195925Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1223195925Srwatson			kau_write(rec, tok);
1224195925Srwatson		}
1225195925Srwatson		/* FALLTHROUGH */
1226195925Srwatson
1227195925Srwatson	case AUE_OPENAT_R:
1228195925Srwatson	case AUE_OPENAT_RT:
1229195925Srwatson	case AUE_OPENAT_RW:
1230195925Srwatson	case AUE_OPENAT_RWT:
1231195925Srwatson	case AUE_OPENAT_W:
1232195925Srwatson	case AUE_OPENAT_WT:
1233195925Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1234195925Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1235195925Srwatson			kau_write(rec, tok);
1236195925Srwatson		}
1237195925Srwatson		ATFD1_TOKENS(1);
1238195925Srwatson		UPATH1_VNODE1_TOKENS;
1239195925Srwatson		break;
1240195925Srwatson
1241155192Srwatson	case AUE_PTRACE:
1242155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1243155192Srwatson			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1244155192Srwatson			kau_write(rec, tok);
1245155192Srwatson		}
1246155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1247155192Srwatson			tok = au_to_arg32(4, "data", ar->ar_arg_value);
1248155192Srwatson			kau_write(rec, tok);
1249155192Srwatson		}
1250155192Srwatson		PROCESS_PID_TOKENS(2);
1251155192Srwatson		break;
1252155192Srwatson
1253155192Srwatson	case AUE_QUOTACTL:
1254155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1255155192Srwatson			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1256155192Srwatson			kau_write(rec, tok);
1257155192Srwatson		}
1258155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1259155192Srwatson			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1260155192Srwatson			kau_write(rec, tok);
1261155192Srwatson		}
1262195280Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
1263195280Srwatson			tok = au_to_arg32(3, "gid", ar->ar_arg_gid);
1264195280Srwatson			kau_write(rec, tok);
1265195280Srwatson		}
1266155192Srwatson		UPATH1_VNODE1_TOKENS;
1267155192Srwatson		break;
1268155192Srwatson
1269155192Srwatson	case AUE_REBOOT:
1270155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1271155192Srwatson			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1272155192Srwatson			kau_write(rec, tok);
1273155192Srwatson		}
1274155192Srwatson		break;
1275155192Srwatson
1276155192Srwatson	case AUE_SEMCTL:
1277176565Srwatson		ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd);
1278155192Srwatson		/* Fall through */
1279156889Srwatson
1280155192Srwatson	case AUE_SEMOP:
1281155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1282155192Srwatson			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1283155192Srwatson			kau_write(rec, tok);
1284155192Srwatson			if (ar->ar_errno != EINVAL) {
1285155192Srwatson				tok = au_to_ipc(AT_IPC_SEM,
1286155192Srwatson				    ar->ar_arg_svipc_id);
1287155192Srwatson				kau_write(rec, tok);
1288155192Srwatson			}
1289155192Srwatson		}
1290155192Srwatson		break;
1291156889Srwatson
1292155192Srwatson	case AUE_SEMGET:
1293155192Srwatson		if (ar->ar_errno == 0) {
1294155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1295155192Srwatson				tok = au_to_ipc(AT_IPC_SEM,
1296155192Srwatson				    ar->ar_arg_svipc_id);
1297155192Srwatson				kau_write(rec, tok);
1298155192Srwatson			}
1299155192Srwatson		}
1300155192Srwatson		break;
1301156889Srwatson
1302155192Srwatson	case AUE_SETEGID:
1303155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
1304195280Srwatson			tok = au_to_arg32(1, "egid", ar->ar_arg_egid);
1305155192Srwatson			kau_write(rec, tok);
1306155192Srwatson		}
1307155192Srwatson		break;
1308156889Srwatson
1309155192Srwatson	case AUE_SETEUID:
1310155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
1311195280Srwatson			tok = au_to_arg32(1, "euid", ar->ar_arg_euid);
1312155192Srwatson			kau_write(rec, tok);
1313155192Srwatson		}
1314155192Srwatson		break;
1315156889Srwatson
1316155192Srwatson	case AUE_SETREGID:
1317155192Srwatson		if (ARG_IS_VALID(kar, ARG_RGID)) {
1318155192Srwatson			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1319155192Srwatson			kau_write(rec, tok);
1320155192Srwatson		}
1321155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
1322155192Srwatson			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1323155192Srwatson			kau_write(rec, tok);
1324155192Srwatson		}
1325155192Srwatson		break;
1326156889Srwatson
1327155192Srwatson	case AUE_SETREUID:
1328155192Srwatson		if (ARG_IS_VALID(kar, ARG_RUID)) {
1329155192Srwatson			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1330155192Srwatson			kau_write(rec, tok);
1331155192Srwatson		}
1332155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
1333155192Srwatson			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1334155192Srwatson			kau_write(rec, tok);
1335155192Srwatson		}
1336155192Srwatson		break;
1337156889Srwatson
1338155192Srwatson	case AUE_SETRESGID:
1339155192Srwatson		if (ARG_IS_VALID(kar, ARG_RGID)) {
1340155192Srwatson			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1341155192Srwatson			kau_write(rec, tok);
1342155192Srwatson		}
1343155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
1344155192Srwatson			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1345155192Srwatson			kau_write(rec, tok);
1346155192Srwatson		}
1347155192Srwatson		if (ARG_IS_VALID(kar, ARG_SGID)) {
1348155192Srwatson			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
1349155192Srwatson			kau_write(rec, tok);
1350155192Srwatson		}
1351155192Srwatson		break;
1352156889Srwatson
1353155192Srwatson	case AUE_SETRESUID:
1354155192Srwatson		if (ARG_IS_VALID(kar, ARG_RUID)) {
1355155192Srwatson			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1356155192Srwatson			kau_write(rec, tok);
1357155192Srwatson		}
1358155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
1359155192Srwatson			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1360155192Srwatson			kau_write(rec, tok);
1361155192Srwatson		}
1362155192Srwatson		if (ARG_IS_VALID(kar, ARG_SUID)) {
1363155192Srwatson			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
1364155192Srwatson			kau_write(rec, tok);
1365155192Srwatson		}
1366155192Srwatson		break;
1367156889Srwatson
1368155192Srwatson	case AUE_SETGID:
1369155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
1370155192Srwatson			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1371155192Srwatson			kau_write(rec, tok);
1372155192Srwatson		}
1373155192Srwatson		break;
1374156889Srwatson
1375155192Srwatson	case AUE_SETUID:
1376155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1377155192Srwatson			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1378155192Srwatson			kau_write(rec, tok);
1379155192Srwatson		}
1380155192Srwatson		break;
1381156889Srwatson
1382155192Srwatson	case AUE_SETGROUPS:
1383155192Srwatson		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1384155192Srwatson			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1385155192Srwatson			{
1386175456Scsjp				tok = au_to_arg32(1, "setgroups",
1387175456Scsjp				    ar->ar_arg_groups.gidset[ctr]);
1388155192Srwatson				kau_write(rec, tok);
1389155192Srwatson			}
1390155192Srwatson		}
1391155192Srwatson		break;
1392155192Srwatson
1393155192Srwatson	case AUE_SETLOGIN:
1394155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1395155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1396155192Srwatson			kau_write(rec, tok);
1397155192Srwatson		}
1398155192Srwatson		break;
1399155192Srwatson
1400155192Srwatson	case AUE_SETPRIORITY:
1401155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1402155192Srwatson			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1403155192Srwatson			kau_write(rec, tok);
1404155192Srwatson		}
1405155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1406155192Srwatson			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1407155192Srwatson			kau_write(rec, tok);
1408155192Srwatson		}
1409195280Srwatson		PROCESS_PID_TOKENS(2);
1410155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1411195280Srwatson			tok = au_to_arg32(3, "priority", ar->ar_arg_value);
1412155192Srwatson			kau_write(rec, tok);
1413155192Srwatson		}
1414155192Srwatson		break;
1415155192Srwatson
1416155192Srwatson	case AUE_SETPRIVEXEC:
1417155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1418155192Srwatson			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1419155192Srwatson			kau_write(rec, tok);
1420155192Srwatson		}
1421155192Srwatson		break;
1422155192Srwatson
1423155192Srwatson	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1424155192Srwatson	case AUE_SHMAT:
1425155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1426155192Srwatson			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1427155192Srwatson			kau_write(rec, tok);
1428155192Srwatson			/* XXXAUDIT: Does having the ipc token make sense? */
1429155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1430155192Srwatson			kau_write(rec, tok);
1431155192Srwatson		}
1432155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1433155192Srwatson			tok = au_to_arg32(2, "shmaddr",
1434155271Srwatson			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1435155192Srwatson			kau_write(rec, tok);
1436155192Srwatson		}
1437155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1438155192Srwatson			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1439155192Srwatson			kau_write(rec, tok);
1440155192Srwatson		}
1441155192Srwatson		break;
1442155192Srwatson
1443155192Srwatson	case AUE_SHMCTL:
1444155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1445155192Srwatson			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1446155192Srwatson			kau_write(rec, tok);
1447155192Srwatson			/* XXXAUDIT: Does having the ipc token make sense? */
1448155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1449155192Srwatson			kau_write(rec, tok);
1450155192Srwatson		}
1451155192Srwatson		switch (ar->ar_arg_svipc_cmd) {
1452155192Srwatson		case IPC_STAT:
1453155192Srwatson			ar->ar_event = AUE_SHMCTL_STAT;
1454155192Srwatson			break;
1455155192Srwatson		case IPC_RMID:
1456155192Srwatson			ar->ar_event = AUE_SHMCTL_RMID;
1457155192Srwatson			break;
1458155192Srwatson		case IPC_SET:
1459155192Srwatson			ar->ar_event = AUE_SHMCTL_SET;
1460155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1461155192Srwatson				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1462155192Srwatson				kau_write(rec, tok);
1463155192Srwatson			}
1464155192Srwatson			break;
1465155192Srwatson		default:
1466155192Srwatson			break;	/* We will audit a bad command */
1467155192Srwatson		}
1468155192Srwatson		break;
1469155192Srwatson
1470155192Srwatson	case AUE_SHMDT:
1471155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1472155192Srwatson			tok = au_to_arg32(1, "shmaddr",
1473155271Srwatson			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1474155192Srwatson			kau_write(rec, tok);
1475155192Srwatson		}
1476155192Srwatson		break;
1477155192Srwatson
1478155192Srwatson	case AUE_SHMGET:
1479155192Srwatson		/* This is unusual; the return value is in an argument token */
1480155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1481155192Srwatson			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1482155192Srwatson			kau_write(rec, tok);
1483155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1484155192Srwatson			kau_write(rec, tok);
1485155192Srwatson		}
1486155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1487155192Srwatson			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1488155192Srwatson			kau_write(rec, tok);
1489155192Srwatson		}
1490155192Srwatson		break;
1491155192Srwatson
1492156889Srwatson	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1493155192Srwatson	 * and AUE_SEMUNLINK are Posix IPC */
1494155192Srwatson	case AUE_SHMOPEN:
1495155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1496155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1497155192Srwatson			kau_write(rec, tok);
1498155192Srwatson		}
1499155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1500155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1501155192Srwatson			kau_write(rec, tok);
1502155192Srwatson		}
1503185293Srwatson		/* FALLTHROUGH */
1504185293Srwatson
1505155192Srwatson	case AUE_SHMUNLINK:
1506155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1507155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1508155192Srwatson			kau_write(rec, tok);
1509155192Srwatson		}
1510155192Srwatson		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1511155192Srwatson			struct ipc_perm perm;
1512180715Srwatson
1513155192Srwatson			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1514155192Srwatson			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1515155192Srwatson			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1516155192Srwatson			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1517155192Srwatson			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1518155192Srwatson			perm.seq = 0;
1519155192Srwatson			perm.key = 0;
1520155192Srwatson			tok = au_to_ipc_perm(&perm);
1521155192Srwatson			kau_write(rec, tok);
1522155192Srwatson		}
1523155192Srwatson		break;
1524155192Srwatson
1525155192Srwatson	case AUE_SEMOPEN:
1526155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1527155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1528155192Srwatson			kau_write(rec, tok);
1529155192Srwatson		}
1530155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1531155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1532155192Srwatson			kau_write(rec, tok);
1533155192Srwatson		}
1534155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1535155192Srwatson			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1536155192Srwatson			kau_write(rec, tok);
1537155192Srwatson		}
1538185293Srwatson		/* FALLTHROUGH */
1539156889Srwatson
1540155192Srwatson	case AUE_SEMUNLINK:
1541155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1542155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1543155192Srwatson			kau_write(rec, tok);
1544155192Srwatson		}
1545155192Srwatson		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1546155192Srwatson			struct ipc_perm perm;
1547180715Srwatson
1548155192Srwatson			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1549155192Srwatson			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1550155192Srwatson			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1551155192Srwatson			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1552155192Srwatson			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1553155192Srwatson			perm.seq = 0;
1554155192Srwatson			perm.key = 0;
1555155192Srwatson			tok = au_to_ipc_perm(&perm);
1556155192Srwatson			kau_write(rec, tok);
1557155192Srwatson		}
1558155192Srwatson		break;
1559155192Srwatson
1560155192Srwatson	case AUE_SEMCLOSE:
1561155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
1562155192Srwatson			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1563155192Srwatson			kau_write(rec, tok);
1564155192Srwatson		}
1565155192Srwatson		break;
1566155192Srwatson
1567155192Srwatson	case AUE_SYMLINK:
1568243727Spjd	case AUE_SYMLINKAT:
1569155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1570155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1571155192Srwatson			kau_write(rec, tok);
1572155192Srwatson		}
1573243727Spjd		ATFD1_TOKENS(1);
1574155192Srwatson		UPATH1_VNODE1_TOKENS;
1575155192Srwatson		break;
1576155192Srwatson
1577155192Srwatson	case AUE_SYSCTL:
1578180716Srwatson	case AUE_SYSCTL_NONADMIN:
1579155192Srwatson		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1580155192Srwatson			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1581156889Srwatson				tok = au_to_arg32(1, "name",
1582156889Srwatson				    ar->ar_arg_ctlname[ctr]);
1583156889Srwatson				kau_write(rec, tok);
1584155192Srwatson			}
1585155192Srwatson		}
1586155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1587155192Srwatson			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1588155192Srwatson			kau_write(rec, tok);
1589155192Srwatson		}
1590155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1591155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1592155192Srwatson			kau_write(rec, tok);
1593155192Srwatson		}
1594155192Srwatson		break;
1595155192Srwatson
1596155192Srwatson	case AUE_UMASK:
1597155192Srwatson		if (ARG_IS_VALID(kar, ARG_MASK)) {
1598155192Srwatson			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1599155192Srwatson			kau_write(rec, tok);
1600155192Srwatson		}
1601155192Srwatson		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1602155192Srwatson		kau_write(rec, tok);
1603155192Srwatson		break;
1604155192Srwatson
1605155192Srwatson	case AUE_WAIT4:
1606195280Srwatson		PROCESS_PID_TOKENS(1);
1607195235Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1608195280Srwatson			tok = au_to_arg32(3, "options", ar->ar_arg_value);
1609195235Srwatson			kau_write(rec, tok);
1610195235Srwatson		}
1611155192Srwatson		break;
1612155192Srwatson
1613247602Spjd	case AUE_CAP_RIGHTS_LIMIT:
1614224181Sjonathan		/*
1615224181Sjonathan		 * XXXRW/XXXJA: Would be nice to audit socket/etc information.
1616224181Sjonathan		 */
1617224181Sjonathan		FD_VNODE1_TOKENS;
1618224181Sjonathan		if (ARG_IS_VALID(kar, ARG_RIGHTS)) {
1619255219Spjd			tok = au_to_rights(&ar->ar_arg_rights);
1620224181Sjonathan			kau_write(rec, tok);
1621224181Sjonathan		}
1622224181Sjonathan		break;
1623224181Sjonathan
1624247602Spjd	case AUE_CAP_FCNTLS_GET:
1625247602Spjd	case AUE_CAP_IOCTLS_GET:
1626247602Spjd	case AUE_CAP_IOCTLS_LIMIT:
1627247602Spjd	case AUE_CAP_RIGHTS_GET:
1628224181Sjonathan		if (ARG_IS_VALID(kar, ARG_FD)) {
1629224181Sjonathan			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
1630224181Sjonathan			kau_write(rec, tok);
1631224181Sjonathan		}
1632224181Sjonathan		break;
1633224181Sjonathan
1634247602Spjd	case AUE_CAP_FCNTLS_LIMIT:
1635247602Spjd		FD_VNODE1_TOKENS;
1636247602Spjd		if (ARG_IS_VALID(kar, ARG_FCNTL_RIGHTS)) {
1637247602Spjd			tok = au_to_arg32(2, "fcntlrights",
1638247602Spjd			    ar->ar_arg_fcntl_rights);
1639247602Spjd			kau_write(rec, tok);
1640247602Spjd		}
1641247602Spjd		break;
1642247602Spjd
1643224181Sjonathan	case AUE_CAP_ENTER:
1644224181Sjonathan	case AUE_CAP_GETMODE:
1645224181Sjonathan		break;
1646224181Sjonathan
1647162990Srwatson	case AUE_NULL:
1648156889Srwatson	default:
1649155192Srwatson		printf("BSM conversion requested for unknown event %d\n",
1650156889Srwatson		    ar->ar_event);
1651180715Srwatson
1652180715Srwatson		/*
1653180715Srwatson		 * Write the subject token so it is properly freed here.
1654180715Srwatson		 */
1655245573Scsjp		if (jail_tok != NULL)
1656245573Scsjp			kau_write(rec, jail_tok);
1657155192Srwatson		kau_write(rec, subj_tok);
1658155192Srwatson		kau_free(rec);
1659155192Srwatson		return (BSM_NOAUDIT);
1660155192Srwatson	}
1661155192Srwatson
1662245573Scsjp	if (jail_tok != NULL)
1663245573Scsjp		kau_write(rec, jail_tok);
1664156889Srwatson	kau_write(rec, subj_tok);
1665186649Srwatson	tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval);
1666155192Srwatson	kau_write(rec, tok);  /* Every record gets a return token */
1667155192Srwatson
1668155192Srwatson	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1669155192Srwatson
1670155192Srwatson	*pau = rec;
1671155192Srwatson	return (BSM_SUCCESS);
1672155192Srwatson}
1673155192Srwatson
1674155192Srwatson/*
1675156889Srwatson * Verify that a record is a valid BSM record. This verification is simple
1676156889Srwatson * now, but may be expanded on sometime in the future.  Return 1 if the
1677156889Srwatson * record is good, 0 otherwise.
1678155192Srwatson */
1679155192Srwatsonint
1680155192Srwatsonbsm_rec_verify(void *rec)
1681155192Srwatson{
1682155192Srwatson	char c = *(char *)rec;
1683156889Srwatson
1684156889Srwatson	/*
1685155192Srwatson	 * Check the token ID of the first token; it has to be a header
1686155192Srwatson	 * token.
1687156889Srwatson	 *
1688156889Srwatson	 * XXXAUDIT There needs to be a token structure to map a token.
1689155192Srwatson	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1690155192Srwatson	 */
1691156889Srwatson	if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) &&
1692156889Srwatson	    (c != AUT_HEADER64) && (c != AUT_HEADER64_EX))
1693155192Srwatson		return (0);
1694155192Srwatson	return (1);
1695155192Srwatson}
1696