audit_bsm.c revision 195235
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: head/sys/security/audit/audit_bsm.c 195235 2009-07-01 12:36:10Z rwatson $");
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 */
186180708Srwatson#define	UPATH1_TOKENS do {						\
187155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
188155192Srwatson		tok = au_to_path(ar->ar_arg_upath1);			\
189155192Srwatson		kau_write(rec, tok);					\
190155192Srwatson	}								\
191155192Srwatson} while (0)
192155192Srwatson
193180708Srwatson#define	UPATH2_TOKENS do {						\
194155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
195155192Srwatson		tok = au_to_path(ar->ar_arg_upath2);			\
196155192Srwatson		kau_write(rec, tok);					\
197155192Srwatson	}								\
198155192Srwatson} while (0)
199155192Srwatson
200180708Srwatson#define	VNODE1_TOKENS do {						\
201180709Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
202155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
203155192Srwatson		kau_write(rec, tok);					\
204155192Srwatson	}								\
205155192Srwatson} while (0)
206155192Srwatson
207180708Srwatson#define	UPATH1_VNODE1_TOKENS do {					\
208180709Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
209155192Srwatson		UPATH1_TOKENS;						\
210155192Srwatson	}								\
211180709Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
212155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
213155192Srwatson		kau_write(rec, tok);					\
214155192Srwatson	}								\
215155192Srwatson} while (0)
216155192Srwatson
217180708Srwatson#define	VNODE2_TOKENS do {						\
218180709Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE2)) {				\
219155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
220155192Srwatson		kau_write(rec, tok);					\
221155192Srwatson	}								\
222155192Srwatson} while (0)
223155192Srwatson
224180711Srwatson#define	FD_VNODE1_TOKENS do {						\
225155192Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
226155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {			\
227155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
228155192Srwatson			kau_write(rec, tok);				\
229155192Srwatson		}							\
230155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
231155192Srwatson		kau_write(rec, tok);					\
232155192Srwatson	} else {							\
233155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {			\
234156889Srwatson			tok = au_to_arg32(1, "non-file: fd",		\
235156889Srwatson			    ar->ar_arg_fd);				\
236155192Srwatson			kau_write(rec, tok);				\
237155192Srwatson		}							\
238155192Srwatson	}								\
239155192Srwatson} while (0)
240155192Srwatson
241180708Srwatson#define	PROCESS_PID_TOKENS(argn) do {					\
242159277Srwatson	if ((ar->ar_arg_pid > 0) /* Reference a single process */	\
243159277Srwatson	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {			\
244172915Scsjp		tok = au_to_process32_ex(ar->ar_arg_auid,		\
245159277Srwatson		    ar->ar_arg_euid, ar->ar_arg_egid,			\
246159277Srwatson		    ar->ar_arg_ruid, ar->ar_arg_rgid,			\
247159277Srwatson		    ar->ar_arg_pid, ar->ar_arg_asid,			\
248172915Scsjp		    &ar->ar_arg_termid_addr);				\
249159277Srwatson		kau_write(rec, tok);					\
250159277Srwatson	} else if (ARG_IS_VALID(kar, ARG_PID)) {			\
251159277Srwatson		tok = au_to_arg32(argn, "process", ar->ar_arg_pid);	\
252159277Srwatson		kau_write(rec, tok);					\
253155192Srwatson	}								\
254180712Srwatson} while (0)
255155192Srwatson
256180711Srwatson#define	EXTATTR_TOKENS do {						\
257160136Swsalamon	if (ARG_IS_VALID(kar, ARG_VALUE)) {				\
258160136Swsalamon		switch (ar->ar_arg_value) {				\
259160136Swsalamon		case EXTATTR_NAMESPACE_USER:				\
260160136Swsalamon			tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
261160136Swsalamon			break;						\
262160136Swsalamon		case EXTATTR_NAMESPACE_SYSTEM:				\
263160136Swsalamon			tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
264160136Swsalamon			break;						\
265160136Swsalamon		default:						\
266160136Swsalamon			tok = au_to_arg32(3, "attrnamespace",		\
267160136Swsalamon			    ar->ar_arg_value);				\
268160136Swsalamon			break;						\
269160136Swsalamon		}							\
270160136Swsalamon		kau_write(rec, tok);					\
271160136Swsalamon	}								\
272160136Swsalamon	/* attrname is in the text field */				\
273160136Swsalamon	if (ARG_IS_VALID(kar, ARG_TEXT)) {				\
274160136Swsalamon		tok = au_to_text(ar->ar_arg_text);			\
275160136Swsalamon		kau_write(rec, tok);					\
276160136Swsalamon	}								\
277160136Swsalamon} while (0)
278160136Swsalamon
279155192Srwatson/*
280155192Srwatson * Implement auditing for the auditon() system call. The audit tokens that
281155192Srwatson * are generated depend on the command that was sent into the auditon()
282155192Srwatson * system call.
283155192Srwatson */
284155192Srwatsonstatic void
285155192Srwatsonaudit_sys_auditon(struct audit_record *ar, struct au_record *rec)
286155192Srwatson{
287155192Srwatson	struct au_token *tok;
288155192Srwatson
289155192Srwatson	switch (ar->ar_arg_cmd) {
290191270Srwatson	case A_OLDSETPOLICY:
291191270Srwatson		if ((size_t)ar->ar_arg_len == sizeof(int64_t)) {
292191270Srwatson			tok = au_to_arg32(3, "length", ar->ar_arg_len);
293191270Srwatson			kau_write(rec, tok);
294191270Srwatson			tok = au_to_arg64(2, "policy",
295191270Srwatson			    ar->ar_arg_auditon.au_policy64);
296191270Srwatson			kau_write(rec, tok);
297191270Srwatson			break;
298191270Srwatson		}
299191270Srwatson		/* FALLTHROUGH */
300156889Srwatson	case A_SETPOLICY:
301191270Srwatson		tok = au_to_arg32(3, "length", ar->ar_arg_len);
302155192Srwatson		kau_write(rec, tok);
303191270Srwatson		tok = au_to_arg32(1, "policy", ar->ar_arg_auditon.au_policy);
304191270Srwatson		kau_write(rec, tok);
305155192Srwatson		break;
306155192Srwatson
307156889Srwatson	case A_SETKMASK:
308156889Srwatson		tok = au_to_arg32(2, "setkmask:as_success",
309156889Srwatson		    ar->ar_arg_auditon.au_mask.am_success);
310155192Srwatson		kau_write(rec, tok);
311156889Srwatson		tok = au_to_arg32(2, "setkmask:as_failure",
312156889Srwatson		    ar->ar_arg_auditon.au_mask.am_failure);
313155192Srwatson		kau_write(rec, tok);
314155192Srwatson		break;
315155192Srwatson
316191270Srwatson	case A_OLDSETQCTRL:
317191270Srwatson		if ((size_t)ar->ar_arg_len == sizeof(au_qctrl64_t)) {
318191270Srwatson			tok = au_to_arg32(3, "length", ar->ar_arg_len);
319191270Srwatson			kau_write(rec, tok);
320191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_hiwater",
321191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_hiwater);
322191270Srwatson			kau_write(rec, tok);
323191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_lowater",
324191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_lowater);
325191270Srwatson			kau_write(rec, tok);
326191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_bufsz",
327191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_bufsz);
328191270Srwatson			kau_write(rec, tok);
329191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_delay",
330191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_delay);
331191270Srwatson			kau_write(rec, tok);
332191270Srwatson			tok = au_to_arg64(2, "setqctrl:aq_minfree",
333191270Srwatson			    ar->ar_arg_auditon.au_qctrl64.aq64_minfree);
334191270Srwatson			kau_write(rec, tok);
335191270Srwatson			break;
336191270Srwatson		}
337191270Srwatson		/* FALLTHROUGH */
338156889Srwatson	case A_SETQCTRL:
339156889Srwatson		tok = au_to_arg32(3, "setqctrl:aq_hiwater",
340156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
341155192Srwatson		kau_write(rec, tok);
342191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_lowater",
343156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
344155192Srwatson		kau_write(rec, tok);
345191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_bufsz",
346156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
347155192Srwatson		kau_write(rec, tok);
348191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_delay",
349156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_delay);
350155192Srwatson		kau_write(rec, tok);
351191270Srwatson		tok = au_to_arg32(2, "setqctrl:aq_minfree",
352156889Srwatson		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
353155192Srwatson		kau_write(rec, tok);
354155192Srwatson		break;
355155192Srwatson
356156889Srwatson	case A_SETUMASK:
357156889Srwatson		tok = au_to_arg32(3, "setumask:as_success",
358156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
359155192Srwatson		kau_write(rec, tok);
360156889Srwatson		tok = au_to_arg32(3, "setumask:as_failure",
361156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
362155192Srwatson		kau_write(rec, tok);
363155192Srwatson		break;
364155192Srwatson
365156889Srwatson	case A_SETSMASK:
366191270Srwatson		tok = au_to_arg32(3, "length", ar->ar_arg_len);
367191270Srwatson		kau_write(rec, tok);
368191270Srwatson		tok = au_to_arg32(2, "setsmask:as_success",
369156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
370155192Srwatson		kau_write(rec, tok);
371191270Srwatson		tok = au_to_arg32(2, "setsmask:as_failure",
372156889Srwatson		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
373155192Srwatson		kau_write(rec, tok);
374155192Srwatson		break;
375155192Srwatson
376191270Srwatson	case A_OLDSETCOND:
377191270Srwatson		if ((size_t)ar->ar_arg_len == sizeof(int64_t)) {
378191270Srwatson			tok = au_to_arg32(3, "length", ar->ar_arg_len);
379191270Srwatson			kau_write(rec, tok);
380191270Srwatson			tok = au_to_arg64(2, "setcond",
381191270Srwatson			    ar->ar_arg_auditon.au_cond64);
382191270Srwatson			kau_write(rec, tok);
383191270Srwatson			break;
384191270Srwatson		}
385191270Srwatson		/* FALLTHROUGH */
386156889Srwatson	case A_SETCOND:
387191270Srwatson		tok = au_to_arg32(3, "length", ar->ar_arg_len);
388155192Srwatson		kau_write(rec, tok);
389191270Srwatson		tok = au_to_arg32(3, "setcond", ar->ar_arg_auditon.au_cond);
390191270Srwatson		kau_write(rec, tok);
391155192Srwatson		break;
392155192Srwatson
393156889Srwatson	case A_SETCLASS:
394191270Srwatson		tok = au_to_arg32(3, "length", ar->ar_arg_len);
395191270Srwatson		kau_write(rec, tok);
396155192Srwatson		tok = au_to_arg32(2, "setclass:ec_event",
397156889Srwatson		    ar->ar_arg_auditon.au_evclass.ec_number);
398155192Srwatson		kau_write(rec, tok);
399191270Srwatson		tok = au_to_arg32(2, "setclass:ec_class",
400156889Srwatson		    ar->ar_arg_auditon.au_evclass.ec_class);
401155192Srwatson		kau_write(rec, tok);
402155192Srwatson		break;
403155192Srwatson
404156889Srwatson	case A_SETPMASK:
405191270Srwatson		tok = au_to_arg32(3, "length", ar->ar_arg_len);
406191270Srwatson		kau_write(rec, tok);
407156889Srwatson		tok = au_to_arg32(2, "setpmask:as_success",
408156889Srwatson		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
409155192Srwatson		kau_write(rec, tok);
410156889Srwatson		tok = au_to_arg32(2, "setpmask:as_failure",
411156889Srwatson		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
412155192Srwatson		kau_write(rec, tok);
413155192Srwatson		break;
414155192Srwatson
415156889Srwatson	case A_SETFSIZE:
416191270Srwatson		tok = au_to_arg32(3, "length", ar->ar_arg_len);
417191270Srwatson		kau_write(rec, tok);
418156889Srwatson		tok = au_to_arg32(2, "setfsize:filesize",
419156889Srwatson		    ar->ar_arg_auditon.au_fstat.af_filesz);
420155192Srwatson		kau_write(rec, tok);
421155192Srwatson		break;
422155192Srwatson
423155192Srwatson	default:
424155192Srwatson		break;
425155192Srwatson	}
426155192Srwatson}
427155192Srwatson
428155192Srwatson/*
429156889Srwatson * Convert an internal kernel audit record to a BSM record and return a
430156889Srwatson * success/failure indicator. The BSM record is passed as an out parameter to
431156889Srwatson * this function.
432156889Srwatson *
433155192Srwatson * Return conditions:
434155192Srwatson *   BSM_SUCCESS: The BSM record is valid
435155192Srwatson *   BSM_FAILURE: Failure; the BSM record is NULL.
436156889Srwatson *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
437155192Srwatson */
438155192Srwatsonint
439155192Srwatsonkaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
440155192Srwatson{
441155192Srwatson	struct au_token *tok, *subj_tok;
442155192Srwatson	struct au_record *rec;
443155192Srwatson	au_tid_t tid;
444155192Srwatson	struct audit_record *ar;
445155192Srwatson	int ctr;
446155192Srwatson
447155192Srwatson	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
448155192Srwatson
449155192Srwatson	*pau = NULL;
450155192Srwatson	ar = &kar->k_ar;
451155192Srwatson	rec = kau_open();
452155192Srwatson
453180715Srwatson	/*
454180715Srwatson	 * Create the subject token.
455180715Srwatson	 */
456168688Scsjp	switch (ar->ar_subj_term_addr.at_type) {
457168688Scsjp	case AU_IPv4:
458168688Scsjp		tid.port = ar->ar_subj_term_addr.at_port;
459168688Scsjp		tid.machine = ar->ar_subj_term_addr.at_addr[0];
460168688Scsjp		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
461168688Scsjp		    ar->ar_subj_cred.cr_uid, /* eff uid */
462168688Scsjp		    ar->ar_subj_egid,	/* eff group id */
463180709Srwatson		    ar->ar_subj_ruid,	/* real uid */
464180709Srwatson		    ar->ar_subj_rgid,	/* real group id */
465168688Scsjp		    ar->ar_subj_pid,	/* process id */
466168688Scsjp		    ar->ar_subj_asid,	/* session ID */
467168688Scsjp		    &tid);
468168688Scsjp		break;
469168688Scsjp	case AU_IPv6:
470168688Scsjp		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
471168688Scsjp		    ar->ar_subj_cred.cr_uid,
472168688Scsjp		    ar->ar_subj_egid,
473168688Scsjp		    ar->ar_subj_ruid,
474168688Scsjp		    ar->ar_subj_rgid,
475168688Scsjp		    ar->ar_subj_pid,
476168688Scsjp		    ar->ar_subj_asid,
477168688Scsjp		    &ar->ar_subj_term_addr);
478168688Scsjp		break;
479168688Scsjp	default:
480168688Scsjp		bzero(&tid, sizeof(tid));
481168688Scsjp		subj_tok = au_to_subject32(ar->ar_subj_auid,
482168688Scsjp		    ar->ar_subj_cred.cr_uid,
483168688Scsjp		    ar->ar_subj_egid,
484168688Scsjp		    ar->ar_subj_ruid,
485168688Scsjp		    ar->ar_subj_rgid,
486168688Scsjp		    ar->ar_subj_pid,
487168688Scsjp		    ar->ar_subj_asid,
488168688Scsjp		    &tid);
489168688Scsjp	}
490155192Srwatson
491156889Srwatson	/*
492156889Srwatson	 * The logic inside each case fills in the tokens required for the
493156889Srwatson	 * event, except for the header, trailer, and return tokens.  The
494155192Srwatson	 * header and trailer tokens are added by the kau_close() function.
495155192Srwatson	 * The return token is added outside of the switch statement.
496156889Srwatson	 */
497155192Srwatson	switch(ar->ar_event) {
498155192Srwatson	case AUE_ACCEPT:
499155192Srwatson	case AUE_BIND:
500175455Scsjp	case AUE_LISTEN:
501155192Srwatson	case AUE_CONNECT:
502162990Srwatson	case AUE_RECV:
503155192Srwatson	case AUE_RECVFROM:
504156889Srwatson	case AUE_RECVMSG:
505162990Srwatson	case AUE_SEND:
506162990Srwatson	case AUE_SENDFILE:
507155192Srwatson	case AUE_SENDMSG:
508155192Srwatson	case AUE_SENDTO:
509156889Srwatson		/*
510156889Srwatson		 * Socket-related events.
511156889Srwatson		 */
512155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
513155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
514155192Srwatson			kau_write(rec, tok);
515155192Srwatson		}
516155192Srwatson		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
517156889Srwatson			tok = au_to_sock_inet((struct sockaddr_in *)
518156889Srwatson			    &ar->ar_arg_sockaddr);
519155192Srwatson			kau_write(rec, tok);
520155192Srwatson		}
521155192Srwatson		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
522156889Srwatson			tok = au_to_sock_unix((struct sockaddr_un *)
523156889Srwatson			    &ar->ar_arg_sockaddr);
524155192Srwatson			kau_write(rec, tok);
525155192Srwatson			UPATH1_TOKENS;
526155192Srwatson		}
527155192Srwatson		/* XXX Need to handle ARG_SADDRINET6 */
528155192Srwatson		break;
529155192Srwatson
530155192Srwatson	case AUE_SOCKET:
531155192Srwatson	case AUE_SOCKETPAIR:
532155192Srwatson		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
533155192Srwatson			tok = au_to_arg32(1,"domain",
534155192Srwatson			    ar->ar_arg_sockinfo.so_domain);
535155192Srwatson			kau_write(rec, tok);
536155192Srwatson			tok = au_to_arg32(2,"type",
537155192Srwatson			    ar->ar_arg_sockinfo.so_type);
538155192Srwatson			kau_write(rec, tok);
539155192Srwatson			tok = au_to_arg32(3,"protocol",
540155192Srwatson			    ar->ar_arg_sockinfo.so_protocol);
541155192Srwatson			kau_write(rec, tok);
542155192Srwatson		}
543155192Srwatson		break;
544155192Srwatson
545155192Srwatson	case AUE_SETSOCKOPT:
546155192Srwatson	case AUE_SHUTDOWN:
547155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
548155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
549155192Srwatson			kau_write(rec, tok);
550155192Srwatson		}
551155192Srwatson		break;
552155192Srwatson
553155192Srwatson	case AUE_ACCT:
554155192Srwatson		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
555155192Srwatson			UPATH1_VNODE1_TOKENS;
556155192Srwatson		} else {
557155192Srwatson			tok = au_to_arg32(1, "accounting off", 0);
558155192Srwatson			kau_write(rec, tok);
559155192Srwatson		}
560155192Srwatson		break;
561155192Srwatson
562155192Srwatson	case AUE_SETAUID:
563155192Srwatson		if (ARG_IS_VALID(kar, ARG_AUID)) {
564155192Srwatson			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
565155192Srwatson			kau_write(rec, tok);
566155192Srwatson		}
567155192Srwatson		break;
568155192Srwatson
569155192Srwatson	case AUE_SETAUDIT:
570171066Scsjp		if (ARG_IS_VALID(kar, ARG_AUID) &&
571171066Scsjp		    ARG_IS_VALID(kar, ARG_ASID) &&
572171066Scsjp		    ARG_IS_VALID(kar, ARG_AMASK) &&
573171066Scsjp		    ARG_IS_VALID(kar, ARG_TERMID)) {
574156889Srwatson			tok = au_to_arg32(1, "setaudit:auid",
575156889Srwatson			    ar->ar_arg_auid);
576155192Srwatson			kau_write(rec, tok);
577156889Srwatson			tok = au_to_arg32(1, "setaudit:port",
578156889Srwatson			    ar->ar_arg_termid.port);
579155192Srwatson			kau_write(rec, tok);
580156889Srwatson			tok = au_to_arg32(1, "setaudit:machine",
581156889Srwatson			    ar->ar_arg_termid.machine);
582155192Srwatson			kau_write(rec, tok);
583156889Srwatson			tok = au_to_arg32(1, "setaudit:as_success",
584156889Srwatson			    ar->ar_arg_amask.am_success);
585155192Srwatson			kau_write(rec, tok);
586156889Srwatson			tok = au_to_arg32(1, "setaudit:as_failure",
587156889Srwatson			    ar->ar_arg_amask.am_failure);
588155192Srwatson			kau_write(rec, tok);
589156889Srwatson			tok = au_to_arg32(1, "setaudit:asid",
590156889Srwatson			    ar->ar_arg_asid);
591155192Srwatson			kau_write(rec, tok);
592155192Srwatson		}
593155192Srwatson		break;
594155192Srwatson
595155192Srwatson	case AUE_SETAUDIT_ADDR:
596171066Scsjp		if (ARG_IS_VALID(kar, ARG_AUID) &&
597171066Scsjp		    ARG_IS_VALID(kar, ARG_ASID) &&
598171066Scsjp		    ARG_IS_VALID(kar, ARG_AMASK) &&
599171066Scsjp		    ARG_IS_VALID(kar, ARG_TERMID_ADDR)) {
600171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:auid",
601171066Scsjp			    ar->ar_arg_auid);
602171066Scsjp			kau_write(rec, tok);
603171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:as_success",
604171066Scsjp			    ar->ar_arg_amask.am_success);
605171066Scsjp			kau_write(rec, tok);
606171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:as_failure",
607171066Scsjp			    ar->ar_arg_amask.am_failure);
608171066Scsjp			kau_write(rec, tok);
609171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:asid",
610171066Scsjp			    ar->ar_arg_asid);
611171066Scsjp			kau_write(rec, tok);
612171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:type",
613171066Scsjp			    ar->ar_arg_termid_addr.at_type);
614171066Scsjp			kau_write(rec, tok);
615171066Scsjp			tok = au_to_arg32(1, "setaudit_addr:port",
616171066Scsjp			    ar->ar_arg_termid_addr.at_port);
617171066Scsjp			kau_write(rec, tok);
618171066Scsjp			if (ar->ar_arg_termid_addr.at_type == AU_IPv6)
619171066Scsjp				tok = au_to_in_addr_ex((struct in6_addr *)
620171066Scsjp				    &ar->ar_arg_termid_addr.at_addr[0]);
621171066Scsjp			if (ar->ar_arg_termid_addr.at_type == AU_IPv4)
622171066Scsjp				tok = au_to_in_addr((struct in_addr *)
623171066Scsjp				    &ar->ar_arg_termid_addr.at_addr[0]);
624171066Scsjp			kau_write(rec, tok);
625171066Scsjp		}
626171066Scsjp		break;
627155192Srwatson
628155192Srwatson	case AUE_AUDITON:
629156889Srwatson		/*
630156889Srwatson		 * For AUDITON commands without own event, audit the cmd.
631156889Srwatson		 */
632155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
633155192Srwatson			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
634155192Srwatson			kau_write(rec, tok);
635155192Srwatson		}
636185293Srwatson		/* FALLTHROUGH */
637155192Srwatson
638155192Srwatson	case AUE_AUDITON_GETCAR:
639155192Srwatson	case AUE_AUDITON_GETCLASS:
640155192Srwatson	case AUE_AUDITON_GETCOND:
641155192Srwatson	case AUE_AUDITON_GETCWD:
642155192Srwatson	case AUE_AUDITON_GETKMASK:
643155192Srwatson	case AUE_AUDITON_GETSTAT:
644155192Srwatson	case AUE_AUDITON_GPOLICY:
645155192Srwatson	case AUE_AUDITON_GQCTRL:
646155192Srwatson	case AUE_AUDITON_SETCLASS:
647155192Srwatson	case AUE_AUDITON_SETCOND:
648155192Srwatson	case AUE_AUDITON_SETKMASK:
649155192Srwatson	case AUE_AUDITON_SETSMASK:
650155192Srwatson	case AUE_AUDITON_SETSTAT:
651155192Srwatson	case AUE_AUDITON_SETUMASK:
652155192Srwatson	case AUE_AUDITON_SPOLICY:
653155192Srwatson	case AUE_AUDITON_SQCTRL:
654156889Srwatson		if (ARG_IS_VALID(kar, ARG_AUDITON))
655155192Srwatson			audit_sys_auditon(ar, rec);
656155192Srwatson		break;
657156889Srwatson
658155192Srwatson	case AUE_AUDITCTL:
659155192Srwatson		UPATH1_VNODE1_TOKENS;
660155192Srwatson		break;
661155192Srwatson
662155192Srwatson	case AUE_EXIT:
663155192Srwatson		if (ARG_IS_VALID(kar, ARG_EXIT)) {
664155192Srwatson			tok = au_to_exit(ar->ar_arg_exitretval,
665155192Srwatson			    ar->ar_arg_exitstatus);
666155192Srwatson			kau_write(rec, tok);
667155192Srwatson		}
668155192Srwatson		break;
669155192Srwatson
670155192Srwatson	case AUE_ADJTIME:
671162990Srwatson	case AUE_CLOCK_SETTIME:
672155192Srwatson	case AUE_AUDIT:
673162990Srwatson	case AUE_DUP2:
674155192Srwatson	case AUE_GETAUDIT:
675155192Srwatson	case AUE_GETAUDIT_ADDR:
676155192Srwatson	case AUE_GETAUID:
677162990Srwatson	case AUE_GETCWD:
678155192Srwatson	case AUE_GETFSSTAT:
679162990Srwatson	case AUE_GETRESUID:
680162990Srwatson	case AUE_GETRESGID:
681162990Srwatson	case AUE_KQUEUE:
682162990Srwatson	case AUE_LSEEK:
683162990Srwatson	case AUE_MODLOAD:
684162990Srwatson	case AUE_MODUNLOAD:
685162990Srwatson	case AUE_MSGSYS:
686162990Srwatson	case AUE_NTP_ADJTIME:
687155192Srwatson	case AUE_PIPE:
688162990Srwatson	case AUE_PROFILE:
689162990Srwatson	case AUE_RTPRIO:
690162990Srwatson	case AUE_SEMSYS:
691162990Srwatson	case AUE_SHMSYS:
692155192Srwatson	case AUE_SETPGRP:
693155192Srwatson	case AUE_SETRLIMIT:
694155192Srwatson	case AUE_SETSID:
695155192Srwatson	case AUE_SETTIMEOFDAY:
696162990Srwatson	case AUE_SYSARCH:
697162990Srwatson
698156889Srwatson		/*
699156889Srwatson		 * Header, subject, and return tokens added at end.
700156889Srwatson		 */
701155192Srwatson		break;
702155192Srwatson
703159278Srwatson	case AUE_MKFIFO:
704159278Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
705159278Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
706159278Srwatson			kau_write(rec, tok);
707159278Srwatson		}
708185293Srwatson		/* FALLTHROUGH */
709185293Srwatson
710155192Srwatson	case AUE_ACCESS:
711155192Srwatson	case AUE_CHDIR:
712155192Srwatson	case AUE_CHROOT:
713155559Srwatson	case AUE_EACCESS:
714155192Srwatson	case AUE_GETATTRLIST:
715162990Srwatson	case AUE_JAIL:
716162419Scsjp	case AUE_LUTIMES:
717155192Srwatson	case AUE_NFS_GETFH:
718155192Srwatson	case AUE_LSTAT:
719155192Srwatson	case AUE_PATHCONF:
720155192Srwatson	case AUE_READLINK:
721155192Srwatson	case AUE_REVOKE:
722155192Srwatson	case AUE_RMDIR:
723155192Srwatson	case AUE_SEARCHFS:
724155192Srwatson	case AUE_SETATTRLIST:
725155192Srwatson	case AUE_STAT:
726155192Srwatson	case AUE_STATFS:
727162990Srwatson	case AUE_SWAPON:
728162990Srwatson	case AUE_SWAPOFF:
729155192Srwatson	case AUE_TRUNCATE:
730155192Srwatson	case AUE_UNDELETE:
731155192Srwatson	case AUE_UNLINK:
732155192Srwatson	case AUE_UTIMES:
733155192Srwatson		UPATH1_VNODE1_TOKENS;
734155192Srwatson		break;
735155192Srwatson
736162990Srwatson	case AUE_FHSTATFS:
737162990Srwatson	case AUE_FHOPEN:
738162990Srwatson	case AUE_FHSTAT:
739162990Srwatson		/* XXXRW: Need to audit vnode argument. */
740162990Srwatson		break;
741162990Srwatson
742155192Srwatson	case AUE_CHFLAGS:
743155192Srwatson	case AUE_LCHFLAGS:
744155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
745155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
746155192Srwatson			kau_write(rec, tok);
747155192Srwatson		}
748155192Srwatson		UPATH1_VNODE1_TOKENS;
749155192Srwatson		break;
750156889Srwatson
751155192Srwatson	case AUE_CHMOD:
752155192Srwatson	case AUE_LCHMOD:
753155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
754156889Srwatson			tok = au_to_arg32(2, "new file mode",
755156889Srwatson			    ar->ar_arg_mode);
756155192Srwatson			kau_write(rec, tok);
757155192Srwatson		}
758155192Srwatson		UPATH1_VNODE1_TOKENS;
759155192Srwatson		break;
760156889Srwatson
761155192Srwatson	case AUE_CHOWN:
762155192Srwatson	case AUE_LCHOWN:
763155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
764155192Srwatson			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
765155192Srwatson			kau_write(rec, tok);
766155192Srwatson		}
767155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
768155192Srwatson			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
769155192Srwatson			kau_write(rec, tok);
770155192Srwatson		}
771155192Srwatson		UPATH1_VNODE1_TOKENS;
772155192Srwatson		break;
773156889Srwatson
774155192Srwatson	case AUE_EXCHANGEDATA:
775155192Srwatson		UPATH1_VNODE1_TOKENS;
776155192Srwatson		UPATH2_TOKENS;
777155192Srwatson		break;
778155192Srwatson
779155192Srwatson	case AUE_CLOSE:
780155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
781155192Srwatson			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
782155192Srwatson			kau_write(rec, tok);
783155192Srwatson		}
784155192Srwatson		UPATH1_VNODE1_TOKENS;
785155192Srwatson		break;
786155192Srwatson
787172995Scsjp	case AUE_CORE:
788172995Scsjp		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
789172995Scsjp			tok = au_to_arg32(0, "signal", ar->ar_arg_signum);
790172995Scsjp			kau_write(rec, tok);
791172995Scsjp		}
792172995Scsjp		UPATH1_VNODE1_TOKENS;
793172995Scsjp		break;
794172995Scsjp
795160136Swsalamon	case AUE_EXTATTRCTL:
796160136Swsalamon		UPATH1_VNODE1_TOKENS;
797160136Swsalamon		if (ARG_IS_VALID(kar, ARG_CMD)) {
798160136Swsalamon			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
799160136Swsalamon			kau_write(rec, tok);
800160136Swsalamon		}
801160136Swsalamon		/* extattrctl(2) filename parameter is in upath2/vnode2 */
802160136Swsalamon		UPATH2_TOKENS;
803160136Swsalamon		VNODE2_TOKENS;
804160136Swsalamon		EXTATTR_TOKENS;
805160136Swsalamon		break;
806160136Swsalamon
807160136Swsalamon	case AUE_EXTATTR_GET_FILE:
808160136Swsalamon	case AUE_EXTATTR_SET_FILE:
809160136Swsalamon	case AUE_EXTATTR_LIST_FILE:
810160136Swsalamon	case AUE_EXTATTR_DELETE_FILE:
811160136Swsalamon	case AUE_EXTATTR_GET_LINK:
812160136Swsalamon	case AUE_EXTATTR_SET_LINK:
813160136Swsalamon	case AUE_EXTATTR_LIST_LINK:
814160136Swsalamon	case AUE_EXTATTR_DELETE_LINK:
815160136Swsalamon		UPATH1_VNODE1_TOKENS;
816160136Swsalamon		EXTATTR_TOKENS;
817160136Swsalamon		break;
818160136Swsalamon
819160136Swsalamon	case AUE_EXTATTR_GET_FD:
820160136Swsalamon	case AUE_EXTATTR_SET_FD:
821160136Swsalamon	case AUE_EXTATTR_LIST_FD:
822160136Swsalamon	case AUE_EXTATTR_DELETE_FD:
823160136Swsalamon		if (ARG_IS_VALID(kar, ARG_FD)) {
824160136Swsalamon			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
825160136Swsalamon			kau_write(rec, tok);
826160136Swsalamon		}
827160136Swsalamon		EXTATTR_TOKENS;
828160136Swsalamon		break;
829160136Swsalamon
830182158Srwatson	case AUE_FEXECVE:
831182158Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
832182158Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
833182158Srwatson			kau_write(rec, tok);
834182158Srwatson		}
835182158Srwatson		/* FALLTHROUGH */
836182158Srwatson
837161813Swsalamon	case AUE_EXECVE:
838188312Srwatson	case AUE_MAC_EXECVE:
839161813Swsalamon		if (ARG_IS_VALID(kar, ARG_ARGV)) {
840161813Swsalamon			tok = au_to_exec_args(ar->ar_arg_argv,
841161813Swsalamon			    ar->ar_arg_argc);
842161813Swsalamon			kau_write(rec, tok);
843161813Swsalamon		}
844161813Swsalamon		if (ARG_IS_VALID(kar, ARG_ENVV)) {
845161813Swsalamon			tok = au_to_exec_env(ar->ar_arg_envv,
846161813Swsalamon			    ar->ar_arg_envc);
847161813Swsalamon			kau_write(rec, tok);
848161813Swsalamon		}
849161813Swsalamon		UPATH1_VNODE1_TOKENS;
850161813Swsalamon		break;
851161813Swsalamon
852155192Srwatson	case AUE_FCHMOD:
853155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
854156889Srwatson			tok = au_to_arg32(2, "new file mode",
855156889Srwatson			    ar->ar_arg_mode);
856155192Srwatson			kau_write(rec, tok);
857155192Srwatson		}
858155192Srwatson		FD_VNODE1_TOKENS;
859155192Srwatson		break;
860156889Srwatson
861162990Srwatson	/*
862162990Srwatson	 * XXXRW: Some of these need to handle non-vnode cases as well.
863162990Srwatson	 */
864155192Srwatson	case AUE_FCHDIR:
865155192Srwatson	case AUE_FPATHCONF:
866162990Srwatson	case AUE_FSTAT:
867155192Srwatson	case AUE_FSTATFS:
868155192Srwatson	case AUE_FSYNC:
869155192Srwatson	case AUE_FTRUNCATE:
870155192Srwatson	case AUE_FUTIMES:
871155192Srwatson	case AUE_GETDIRENTRIES:
872155192Srwatson	case AUE_GETDIRENTRIESATTR:
873162990Srwatson	case AUE_POLL:
874162990Srwatson	case AUE_READ:
875162990Srwatson	case AUE_READV:
876162990Srwatson	case AUE_WRITE:
877162990Srwatson	case AUE_WRITEV:
878155192Srwatson		FD_VNODE1_TOKENS;
879155192Srwatson		break;
880156889Srwatson
881155192Srwatson	case AUE_FCHOWN:
882155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
883155192Srwatson			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
884155192Srwatson			kau_write(rec, tok);
885155192Srwatson		}
886155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
887155192Srwatson			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
888155192Srwatson			kau_write(rec, tok);
889155192Srwatson		}
890155192Srwatson		FD_VNODE1_TOKENS;
891155192Srwatson		break;
892156889Srwatson
893155192Srwatson	case AUE_FCNTL:
894191270Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
895191270Srwatson			tok = au_to_arg32(2, "cmd",
896191270Srwatson			    au_fcntl_cmd_to_bsm(ar->ar_arg_cmd));
897191270Srwatson			kau_write(rec, tok);
898191270Srwatson		}
899155192Srwatson		if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
900180715Srwatson		    ar->ar_arg_cmd == F_SETLKW) {
901155192Srwatson			FD_VNODE1_TOKENS;
902155192Srwatson		}
903155192Srwatson		break;
904156889Srwatson
905155192Srwatson	case AUE_FCHFLAGS:
906155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
907155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
908155192Srwatson			kau_write(rec, tok);
909155192Srwatson		}
910155192Srwatson		FD_VNODE1_TOKENS;
911155192Srwatson		break;
912156889Srwatson
913155192Srwatson	case AUE_FLOCK:
914155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
915155192Srwatson			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
916155192Srwatson			kau_write(rec, tok);
917155192Srwatson		}
918155192Srwatson		FD_VNODE1_TOKENS;
919155192Srwatson		break;
920156889Srwatson
921155192Srwatson	case AUE_RFORK:
922155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
923155192Srwatson			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
924155192Srwatson			kau_write(rec, tok);
925155192Srwatson		}
926185293Srwatson		/* FALLTHROUGH */
927185293Srwatson
928155192Srwatson	case AUE_FORK:
929155192Srwatson	case AUE_VFORK:
930155192Srwatson		if (ARG_IS_VALID(kar, ARG_PID)) {
931155192Srwatson			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
932155192Srwatson			kau_write(rec, tok);
933155192Srwatson		}
934155192Srwatson		break;
935156889Srwatson
936155192Srwatson	case AUE_IOCTL:
937155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
938155192Srwatson			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
939155192Srwatson			kau_write(rec, tok);
940155192Srwatson		}
941155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
942155271Srwatson			tok = au_to_arg32(1, "arg",
943155271Srwatson			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
944155192Srwatson			kau_write(rec, tok);
945155192Srwatson		}
946156889Srwatson		if (ARG_IS_VALID(kar, ARG_VNODE1))
947155192Srwatson			FD_VNODE1_TOKENS;
948156889Srwatson		else {
949155192Srwatson			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
950156889Srwatson				tok = kau_to_socket(&ar->ar_arg_sockinfo);
951155192Srwatson				kau_write(rec, tok);
952155192Srwatson			} else {
953155192Srwatson				if (ARG_IS_VALID(kar, ARG_FD)) {
954155192Srwatson					tok = au_to_arg32(1, "fd",
955155192Srwatson					    ar->ar_arg_fd);
956180709Srwatson					kau_write(rec, tok);
957155192Srwatson				}
958155192Srwatson			}
959155192Srwatson		}
960155192Srwatson		break;
961155192Srwatson
962155192Srwatson	case AUE_KILL:
963162990Srwatson	case AUE_KILLPG:
964155192Srwatson		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
965155192Srwatson			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
966155192Srwatson			kau_write(rec, tok);
967155192Srwatson		}
968155192Srwatson		PROCESS_PID_TOKENS(1);
969155192Srwatson		break;
970155192Srwatson
971155192Srwatson	case AUE_KTRACE:
972155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
973155192Srwatson			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
974155192Srwatson			kau_write(rec, tok);
975155192Srwatson		}
976155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
977155192Srwatson			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
978155192Srwatson			kau_write(rec, tok);
979155192Srwatson		}
980155192Srwatson		PROCESS_PID_TOKENS(4);
981155192Srwatson		UPATH1_VNODE1_TOKENS;
982155192Srwatson		break;
983155192Srwatson
984155192Srwatson	case AUE_LINK:
985155192Srwatson	case AUE_RENAME:
986155192Srwatson		UPATH1_VNODE1_TOKENS;
987155192Srwatson		UPATH2_TOKENS;
988155192Srwatson		break;
989155192Srwatson
990155192Srwatson	case AUE_LOADSHFILE:
991155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
992155192Srwatson			tok = au_to_arg32(4, "base addr",
993155271Srwatson			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
994155192Srwatson			kau_write(rec, tok);
995155192Srwatson		}
996155192Srwatson		UPATH1_VNODE1_TOKENS;
997155192Srwatson		break;
998156889Srwatson
999155192Srwatson	case AUE_MKDIR:
1000155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1001155192Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1002155192Srwatson			kau_write(rec, tok);
1003155192Srwatson		}
1004155192Srwatson		UPATH1_VNODE1_TOKENS;
1005155192Srwatson		break;
1006155192Srwatson
1007155192Srwatson	case AUE_MKNOD:
1008155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1009155192Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
1010155192Srwatson			kau_write(rec, tok);
1011155192Srwatson		}
1012155192Srwatson		if (ARG_IS_VALID(kar, ARG_DEV)) {
1013155192Srwatson			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
1014155192Srwatson			kau_write(rec, tok);
1015155192Srwatson		}
1016155192Srwatson		UPATH1_VNODE1_TOKENS;
1017155192Srwatson		break;
1018155192Srwatson
1019155192Srwatson	case AUE_MMAP:
1020155192Srwatson	case AUE_MUNMAP:
1021155192Srwatson	case AUE_MPROTECT:
1022155192Srwatson	case AUE_MLOCK:
1023155192Srwatson	case AUE_MUNLOCK:
1024155192Srwatson	case AUE_MINHERIT:
1025155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1026155192Srwatson			tok = au_to_arg32(1, "addr",
1027155271Srwatson			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1028155192Srwatson			kau_write(rec, tok);
1029155192Srwatson		}
1030155192Srwatson		if (ARG_IS_VALID(kar, ARG_LEN)) {
1031155192Srwatson			tok = au_to_arg32(2, "len", ar->ar_arg_len);
1032155192Srwatson			kau_write(rec, tok);
1033155192Srwatson		}
1034155192Srwatson		if (ar->ar_event == AUE_MMAP)
1035155192Srwatson			FD_VNODE1_TOKENS;
1036155192Srwatson		if (ar->ar_event == AUE_MPROTECT) {
1037155192Srwatson			if (ARG_IS_VALID(kar, ARG_VALUE)) {
1038155192Srwatson				tok = au_to_arg32(3, "protection",
1039155192Srwatson				    ar->ar_arg_value);
1040155192Srwatson				kau_write(rec, tok);
1041155192Srwatson			}
1042155192Srwatson		}
1043155192Srwatson		if (ar->ar_event == AUE_MINHERIT) {
1044155192Srwatson			if (ARG_IS_VALID(kar, ARG_VALUE)) {
1045155192Srwatson				tok = au_to_arg32(3, "inherit",
1046155192Srwatson				    ar->ar_arg_value);
1047155192Srwatson				kau_write(rec, tok);
1048155192Srwatson			}
1049155192Srwatson		}
1050155192Srwatson		break;
1051155192Srwatson
1052155192Srwatson	case AUE_MOUNT:
1053162990Srwatson	case AUE_NMOUNT:
1054155192Srwatson		/* XXX Need to handle NFS mounts */
1055155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1056155192Srwatson			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
1057155192Srwatson			kau_write(rec, tok);
1058155192Srwatson		}
1059155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1060155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1061155192Srwatson			kau_write(rec, tok);
1062155192Srwatson		}
1063185293Srwatson		/* FALLTHROUGH */
1064156889Srwatson
1065188311Srwatson	case AUE_NFS_SVC:
1066188311Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1067188311Srwatson			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1068188311Srwatson			kau_write(rec, tok);
1069188311Srwatson		}
1070188311Srwatson		break;
1071188311Srwatson
1072155192Srwatson	case AUE_UMOUNT:
1073155192Srwatson		UPATH1_VNODE1_TOKENS;
1074155192Srwatson		break;
1075155192Srwatson
1076155192Srwatson	case AUE_MSGCTL:
1077176565Srwatson		ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd);
1078155192Srwatson		/* Fall through */
1079156889Srwatson
1080155192Srwatson	case AUE_MSGRCV:
1081155192Srwatson	case AUE_MSGSND:
1082155192Srwatson		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
1083155192Srwatson		kau_write(rec, tok);
1084155192Srwatson		if (ar->ar_errno != EINVAL) {
1085155192Srwatson			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
1086155192Srwatson			kau_write(rec, tok);
1087155192Srwatson		}
1088155192Srwatson		break;
1089155192Srwatson
1090155192Srwatson	case AUE_MSGGET:
1091155192Srwatson		if (ar->ar_errno == 0) {
1092155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1093155192Srwatson				tok = au_to_ipc(AT_IPC_MSG,
1094155192Srwatson				    ar->ar_arg_svipc_id);
1095155192Srwatson				kau_write(rec, tok);
1096155192Srwatson			}
1097155192Srwatson		}
1098155192Srwatson		break;
1099155192Srwatson
1100155192Srwatson	case AUE_RESETSHFILE:
1101155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1102155192Srwatson			tok = au_to_arg32(1, "base addr",
1103155271Srwatson			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1104155192Srwatson			kau_write(rec, tok);
1105155192Srwatson		}
1106155192Srwatson		break;
1107156889Srwatson
1108155192Srwatson	case AUE_OPEN_RC:
1109155192Srwatson	case AUE_OPEN_RTC:
1110155192Srwatson	case AUE_OPEN_RWC:
1111155192Srwatson	case AUE_OPEN_RWTC:
1112155192Srwatson	case AUE_OPEN_WC:
1113155192Srwatson	case AUE_OPEN_WTC:
1114162990Srwatson	case AUE_CREAT:
1115155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1116155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1117155192Srwatson			kau_write(rec, tok);
1118155192Srwatson		}
1119185293Srwatson		/* FALLTHROUGH */
1120155192Srwatson
1121155192Srwatson	case AUE_OPEN_R:
1122155192Srwatson	case AUE_OPEN_RT:
1123155192Srwatson	case AUE_OPEN_RW:
1124155192Srwatson	case AUE_OPEN_RWT:
1125155192Srwatson	case AUE_OPEN_W:
1126155192Srwatson	case AUE_OPEN_WT:
1127155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1128155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1129155192Srwatson			kau_write(rec, tok);
1130155192Srwatson		}
1131155192Srwatson		UPATH1_VNODE1_TOKENS;
1132155192Srwatson		break;
1133155192Srwatson
1134155192Srwatson	case AUE_PTRACE:
1135155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1136155192Srwatson			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1137155192Srwatson			kau_write(rec, tok);
1138155192Srwatson		}
1139155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1140155192Srwatson			tok = au_to_arg32(3, "addr",
1141155271Srwatson			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1142155192Srwatson			kau_write(rec, tok);
1143155192Srwatson		}
1144155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1145155192Srwatson			tok = au_to_arg32(4, "data", ar->ar_arg_value);
1146155192Srwatson			kau_write(rec, tok);
1147155192Srwatson		}
1148155192Srwatson		PROCESS_PID_TOKENS(2);
1149155192Srwatson		break;
1150155192Srwatson
1151155192Srwatson	case AUE_QUOTACTL:
1152155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1153155192Srwatson			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1154155192Srwatson			kau_write(rec, tok);
1155155192Srwatson		}
1156155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1157155192Srwatson			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1158155192Srwatson			kau_write(rec, tok);
1159155192Srwatson		}
1160155192Srwatson		UPATH1_VNODE1_TOKENS;
1161155192Srwatson		break;
1162155192Srwatson
1163155192Srwatson	case AUE_REBOOT:
1164155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1165155192Srwatson			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1166155192Srwatson			kau_write(rec, tok);
1167155192Srwatson		}
1168155192Srwatson		break;
1169155192Srwatson
1170155192Srwatson	case AUE_SEMCTL:
1171176565Srwatson		ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd);
1172155192Srwatson		/* Fall through */
1173156889Srwatson
1174155192Srwatson	case AUE_SEMOP:
1175155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1176155192Srwatson			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1177155192Srwatson			kau_write(rec, tok);
1178155192Srwatson			if (ar->ar_errno != EINVAL) {
1179155192Srwatson				tok = au_to_ipc(AT_IPC_SEM,
1180155192Srwatson				    ar->ar_arg_svipc_id);
1181155192Srwatson				kau_write(rec, tok);
1182155192Srwatson			}
1183155192Srwatson		}
1184155192Srwatson		break;
1185156889Srwatson
1186155192Srwatson	case AUE_SEMGET:
1187155192Srwatson		if (ar->ar_errno == 0) {
1188155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1189155192Srwatson				tok = au_to_ipc(AT_IPC_SEM,
1190155192Srwatson				    ar->ar_arg_svipc_id);
1191155192Srwatson				kau_write(rec, tok);
1192155192Srwatson			}
1193155192Srwatson		}
1194155192Srwatson		break;
1195156889Srwatson
1196155192Srwatson	case AUE_SETEGID:
1197155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
1198155192Srwatson			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
1199155192Srwatson			kau_write(rec, tok);
1200155192Srwatson		}
1201155192Srwatson		break;
1202156889Srwatson
1203155192Srwatson	case AUE_SETEUID:
1204155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
1205155192Srwatson			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
1206155192Srwatson			kau_write(rec, tok);
1207155192Srwatson		}
1208155192Srwatson		break;
1209156889Srwatson
1210155192Srwatson	case AUE_SETREGID:
1211155192Srwatson		if (ARG_IS_VALID(kar, ARG_RGID)) {
1212155192Srwatson			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1213155192Srwatson			kau_write(rec, tok);
1214155192Srwatson		}
1215155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
1216155192Srwatson			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1217155192Srwatson			kau_write(rec, tok);
1218155192Srwatson		}
1219155192Srwatson		break;
1220156889Srwatson
1221155192Srwatson	case AUE_SETREUID:
1222155192Srwatson		if (ARG_IS_VALID(kar, ARG_RUID)) {
1223155192Srwatson			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1224155192Srwatson			kau_write(rec, tok);
1225155192Srwatson		}
1226155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
1227155192Srwatson			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1228155192Srwatson			kau_write(rec, tok);
1229155192Srwatson		}
1230155192Srwatson		break;
1231156889Srwatson
1232155192Srwatson	case AUE_SETRESGID:
1233155192Srwatson		if (ARG_IS_VALID(kar, ARG_RGID)) {
1234155192Srwatson			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1235155192Srwatson			kau_write(rec, tok);
1236155192Srwatson		}
1237155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
1238155192Srwatson			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1239155192Srwatson			kau_write(rec, tok);
1240155192Srwatson		}
1241155192Srwatson		if (ARG_IS_VALID(kar, ARG_SGID)) {
1242155192Srwatson			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
1243155192Srwatson			kau_write(rec, tok);
1244155192Srwatson		}
1245155192Srwatson		break;
1246156889Srwatson
1247155192Srwatson	case AUE_SETRESUID:
1248155192Srwatson		if (ARG_IS_VALID(kar, ARG_RUID)) {
1249155192Srwatson			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1250155192Srwatson			kau_write(rec, tok);
1251155192Srwatson		}
1252155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
1253155192Srwatson			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1254155192Srwatson			kau_write(rec, tok);
1255155192Srwatson		}
1256155192Srwatson		if (ARG_IS_VALID(kar, ARG_SUID)) {
1257155192Srwatson			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
1258155192Srwatson			kau_write(rec, tok);
1259155192Srwatson		}
1260155192Srwatson		break;
1261156889Srwatson
1262155192Srwatson	case AUE_SETGID:
1263155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
1264155192Srwatson			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1265155192Srwatson			kau_write(rec, tok);
1266155192Srwatson		}
1267155192Srwatson		break;
1268156889Srwatson
1269155192Srwatson	case AUE_SETUID:
1270155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1271155192Srwatson			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1272155192Srwatson			kau_write(rec, tok);
1273155192Srwatson		}
1274155192Srwatson		break;
1275156889Srwatson
1276155192Srwatson	case AUE_SETGROUPS:
1277155192Srwatson		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1278155192Srwatson			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1279155192Srwatson			{
1280175456Scsjp				tok = au_to_arg32(1, "setgroups",
1281175456Scsjp				    ar->ar_arg_groups.gidset[ctr]);
1282155192Srwatson				kau_write(rec, tok);
1283155192Srwatson			}
1284155192Srwatson		}
1285155192Srwatson		break;
1286155192Srwatson
1287155192Srwatson	case AUE_SETLOGIN:
1288155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1289155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1290155192Srwatson			kau_write(rec, tok);
1291155192Srwatson		}
1292155192Srwatson		break;
1293155192Srwatson
1294155192Srwatson	case AUE_SETPRIORITY:
1295155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1296155192Srwatson			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1297155192Srwatson			kau_write(rec, tok);
1298155192Srwatson		}
1299155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1300155192Srwatson			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1301155192Srwatson			kau_write(rec, tok);
1302155192Srwatson		}
1303155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1304155192Srwatson			tok = au_to_arg32(2, "priority", ar->ar_arg_value);
1305155192Srwatson			kau_write(rec, tok);
1306155192Srwatson		}
1307155192Srwatson		break;
1308155192Srwatson
1309155192Srwatson	case AUE_SETPRIVEXEC:
1310155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1311155192Srwatson			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1312155192Srwatson			kau_write(rec, tok);
1313155192Srwatson		}
1314155192Srwatson		break;
1315155192Srwatson
1316155192Srwatson	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1317155192Srwatson	case AUE_SHMAT:
1318155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1319155192Srwatson			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1320155192Srwatson			kau_write(rec, tok);
1321155192Srwatson			/* XXXAUDIT: Does having the ipc token make sense? */
1322155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1323155192Srwatson			kau_write(rec, tok);
1324155192Srwatson		}
1325155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1326155192Srwatson			tok = au_to_arg32(2, "shmaddr",
1327155271Srwatson			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1328155192Srwatson			kau_write(rec, tok);
1329155192Srwatson		}
1330155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1331155192Srwatson			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1332155192Srwatson			kau_write(rec, tok);
1333155192Srwatson		}
1334155192Srwatson		break;
1335155192Srwatson
1336155192Srwatson	case AUE_SHMCTL:
1337155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1338155192Srwatson			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1339155192Srwatson			kau_write(rec, tok);
1340155192Srwatson			/* XXXAUDIT: Does having the ipc token make sense? */
1341155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1342155192Srwatson			kau_write(rec, tok);
1343155192Srwatson		}
1344155192Srwatson		switch (ar->ar_arg_svipc_cmd) {
1345155192Srwatson		case IPC_STAT:
1346155192Srwatson			ar->ar_event = AUE_SHMCTL_STAT;
1347155192Srwatson			break;
1348155192Srwatson		case IPC_RMID:
1349155192Srwatson			ar->ar_event = AUE_SHMCTL_RMID;
1350155192Srwatson			break;
1351155192Srwatson		case IPC_SET:
1352155192Srwatson			ar->ar_event = AUE_SHMCTL_SET;
1353155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1354155192Srwatson				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1355155192Srwatson				kau_write(rec, tok);
1356155192Srwatson			}
1357155192Srwatson			break;
1358155192Srwatson		default:
1359155192Srwatson			break;	/* We will audit a bad command */
1360155192Srwatson		}
1361155192Srwatson		break;
1362155192Srwatson
1363155192Srwatson	case AUE_SHMDT:
1364155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1365155192Srwatson			tok = au_to_arg32(1, "shmaddr",
1366155271Srwatson			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1367155192Srwatson			kau_write(rec, tok);
1368155192Srwatson		}
1369155192Srwatson		break;
1370155192Srwatson
1371155192Srwatson	case AUE_SHMGET:
1372155192Srwatson		/* This is unusual; the return value is in an argument token */
1373155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1374155192Srwatson			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1375155192Srwatson			kau_write(rec, tok);
1376155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1377155192Srwatson			kau_write(rec, tok);
1378155192Srwatson		}
1379155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1380155192Srwatson			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1381155192Srwatson			kau_write(rec, tok);
1382155192Srwatson		}
1383155192Srwatson		break;
1384155192Srwatson
1385156889Srwatson	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1386155192Srwatson	 * and AUE_SEMUNLINK are Posix IPC */
1387155192Srwatson	case AUE_SHMOPEN:
1388155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1389155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1390155192Srwatson			kau_write(rec, tok);
1391155192Srwatson		}
1392155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1393155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1394155192Srwatson			kau_write(rec, tok);
1395155192Srwatson		}
1396185293Srwatson		/* FALLTHROUGH */
1397185293Srwatson
1398155192Srwatson	case AUE_SHMUNLINK:
1399155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1400155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1401155192Srwatson			kau_write(rec, tok);
1402155192Srwatson		}
1403155192Srwatson		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1404155192Srwatson			struct ipc_perm perm;
1405180715Srwatson
1406155192Srwatson			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1407155192Srwatson			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1408155192Srwatson			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1409155192Srwatson			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1410155192Srwatson			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1411155192Srwatson			perm.seq = 0;
1412155192Srwatson			perm.key = 0;
1413155192Srwatson			tok = au_to_ipc_perm(&perm);
1414155192Srwatson			kau_write(rec, tok);
1415155192Srwatson		}
1416155192Srwatson		break;
1417155192Srwatson
1418155192Srwatson	case AUE_SEMOPEN:
1419155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1420155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1421155192Srwatson			kau_write(rec, tok);
1422155192Srwatson		}
1423155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1424155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1425155192Srwatson			kau_write(rec, tok);
1426155192Srwatson		}
1427155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1428155192Srwatson			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1429155192Srwatson			kau_write(rec, tok);
1430155192Srwatson		}
1431185293Srwatson		/* FALLTHROUGH */
1432156889Srwatson
1433155192Srwatson	case AUE_SEMUNLINK:
1434155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1435155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1436155192Srwatson			kau_write(rec, tok);
1437155192Srwatson		}
1438155192Srwatson		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1439155192Srwatson			struct ipc_perm perm;
1440180715Srwatson
1441155192Srwatson			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1442155192Srwatson			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1443155192Srwatson			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1444155192Srwatson			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1445155192Srwatson			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1446155192Srwatson			perm.seq = 0;
1447155192Srwatson			perm.key = 0;
1448155192Srwatson			tok = au_to_ipc_perm(&perm);
1449155192Srwatson			kau_write(rec, tok);
1450155192Srwatson		}
1451155192Srwatson		break;
1452155192Srwatson
1453155192Srwatson	case AUE_SEMCLOSE:
1454155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
1455155192Srwatson			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1456155192Srwatson			kau_write(rec, tok);
1457155192Srwatson		}
1458155192Srwatson		break;
1459155192Srwatson
1460155192Srwatson	case AUE_SYMLINK:
1461155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1462155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1463155192Srwatson			kau_write(rec, tok);
1464155192Srwatson		}
1465155192Srwatson		UPATH1_VNODE1_TOKENS;
1466155192Srwatson		break;
1467155192Srwatson
1468155192Srwatson	case AUE_SYSCTL:
1469180716Srwatson	case AUE_SYSCTL_NONADMIN:
1470155192Srwatson		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1471155192Srwatson			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1472156889Srwatson				tok = au_to_arg32(1, "name",
1473156889Srwatson				    ar->ar_arg_ctlname[ctr]);
1474156889Srwatson				kau_write(rec, tok);
1475155192Srwatson			}
1476155192Srwatson		}
1477155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1478155192Srwatson			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1479155192Srwatson			kau_write(rec, tok);
1480155192Srwatson		}
1481155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1482155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1483155192Srwatson			kau_write(rec, tok);
1484155192Srwatson		}
1485155192Srwatson		break;
1486155192Srwatson
1487155192Srwatson	case AUE_UMASK:
1488155192Srwatson		if (ARG_IS_VALID(kar, ARG_MASK)) {
1489155192Srwatson			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1490155192Srwatson			kau_write(rec, tok);
1491155192Srwatson		}
1492155192Srwatson		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1493155192Srwatson		kau_write(rec, tok);
1494155192Srwatson		break;
1495155192Srwatson
1496155192Srwatson	case AUE_WAIT4:
1497155192Srwatson		if (ARG_IS_VALID(kar, ARG_PID)) {
1498155192Srwatson			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1499155192Srwatson			kau_write(rec, tok);
1500155192Srwatson		}
1501195235Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1502195235Srwatson			tok = au_to_arg32(0, "options", ar->ar_arg_value);
1503195235Srwatson			kau_write(rec, tok);
1504195235Srwatson		}
1505155192Srwatson		break;
1506155192Srwatson
1507162990Srwatson	case AUE_NULL:
1508156889Srwatson	default:
1509155192Srwatson		printf("BSM conversion requested for unknown event %d\n",
1510156889Srwatson		    ar->ar_event);
1511180715Srwatson
1512180715Srwatson		/*
1513180715Srwatson		 * Write the subject token so it is properly freed here.
1514180715Srwatson		 */
1515155192Srwatson		kau_write(rec, subj_tok);
1516155192Srwatson		kau_free(rec);
1517155192Srwatson		return (BSM_NOAUDIT);
1518155192Srwatson	}
1519155192Srwatson
1520156889Srwatson	kau_write(rec, subj_tok);
1521186649Srwatson	tok = au_to_return32(au_errno_to_bsm(ar->ar_errno), ar->ar_retval);
1522155192Srwatson	kau_write(rec, tok);  /* Every record gets a return token */
1523155192Srwatson
1524155192Srwatson	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1525155192Srwatson
1526155192Srwatson	*pau = rec;
1527155192Srwatson	return (BSM_SUCCESS);
1528155192Srwatson}
1529155192Srwatson
1530155192Srwatson/*
1531156889Srwatson * Verify that a record is a valid BSM record. This verification is simple
1532156889Srwatson * now, but may be expanded on sometime in the future.  Return 1 if the
1533156889Srwatson * record is good, 0 otherwise.
1534155192Srwatson */
1535155192Srwatsonint
1536155192Srwatsonbsm_rec_verify(void *rec)
1537155192Srwatson{
1538155192Srwatson	char c = *(char *)rec;
1539156889Srwatson
1540156889Srwatson	/*
1541155192Srwatson	 * Check the token ID of the first token; it has to be a header
1542155192Srwatson	 * token.
1543156889Srwatson	 *
1544156889Srwatson	 * XXXAUDIT There needs to be a token structure to map a token.
1545155192Srwatson	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1546155192Srwatson	 */
1547156889Srwatson	if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) &&
1548156889Srwatson	    (c != AUT_HEADER64) && (c != AUT_HEADER64_EX))
1549155192Srwatson		return (0);
1550155192Srwatson	return (1);
1551155192Srwatson}
1552