audit_bsm.c revision 170585
1105513Sphk/*
2105513Sphk * Copyright (c) 1999-2005 Apple Computer, Inc.
3105513Sphk * All rights reserved.
4105513Sphk *
5105513Sphk * Redistribution and use in source and binary forms, with or without
6105513Sphk * modification, are permitted provided that the following conditions
7105513Sphk * are met:
8105513Sphk * 1.  Redistributions of source code must retain the above copyright
9105513Sphk *     notice, this list of conditions and the following disclaimer.
10105513Sphk * 2.  Redistributions in binary form must reproduce the above copyright
11105513Sphk *     notice, this list of conditions and the following disclaimer in the
12105513Sphk *     documentation and/or other materials provided with the distribution.
13105513Sphk * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14105513Sphk *     its contributors may be used to endorse or promote products derived
15105513Sphk *     from this software without specific prior written permission.
16105513Sphk *
17105513Sphk * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18105513Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19105513Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20105513Sphk * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21105513Sphk * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22105513Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23105513Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24105513Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25105513Sphk * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26105513Sphk * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27105513Sphk * POSSIBILITY OF SUCH DAMAGE.
28105513Sphk *
29105513Sphk * $FreeBSD: head/sys/security/audit/audit_bsm.c 170585 2007-06-11 22:10:54Z rwatson $
30105513Sphk */
31105513Sphk
32105513Sphk#include <sys/param.h>
33121073Sphk#include <sys/vnode.h>
34121073Sphk#include <sys/ipc.h>
35125387Sdes#include <sys/lock.h>
36121073Sphk#include <sys/malloc.h>
37121073Sphk#include <sys/mutex.h>
38121073Sphk#include <sys/socket.h>
39121073Sphk#include <sys/extattr.h>
40121073Sphk#include <sys/fcntl.h>
41121073Sphk#include <sys/user.h>
42121073Sphk#include <sys/systm.h>
43125387Sdes
44121073Sphk#include <bsm/audit.h>
45121073Sphk#include <bsm/audit_internal.h>
46121073Sphk#include <bsm/audit_record.h>
47121073Sphk#include <bsm/audit_kevents.h>
48121073Sphk
49121073Sphk#include <security/audit/audit.h>
50121073Sphk#include <security/audit/audit_private.h>
51121073Sphk
52121073Sphk#include <netinet/in_systm.h>
53121073Sphk#include <netinet/in.h>
54121073Sphk#include <netinet/ip.h>
55121073Sphk
56121073SphkMALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
57121073Sphk
58121073Sphkstatic void	audit_sys_auditon(struct audit_record *ar,
59121073Sphk		    struct au_record *rec);
60121073Sphk
61121073Sphk/*
62121073Sphk * Initialize the BSM auditing subsystem.
63121073Sphk */
64121073Sphkvoid
65105513Sphkkau_init(void)
66105513Sphk{
67105513Sphk
68105513Sphk	printf("BSM auditing present\n");
69105513Sphk	au_evclassmap_init();
70105513Sphk}
71105513Sphk
72105513Sphk/*
73105513Sphk * This call reserves memory for the audit record.  Memory must be guaranteed
74105513Sphk * before any auditable event can be generated.  The au_record structure
75105513Sphk * maintains a reference to the memory allocated above and also the list of
76107455Sphk * tokens associated with this record
77105513Sphk */
78105513Sphkstatic struct au_record *
79105513Sphkkau_open(void)
80105513Sphk{
81105513Sphk	struct au_record *rec;
82112877Sphk
83105513Sphk	rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK);
84105513Sphk	rec->data = NULL;
85106407Sphk	TAILQ_INIT(&rec->token_q);
86143431Sume	rec->len = 0;
87106407Sphk	rec->used = 1;
88120877Sphk
89120877Sphk	return (rec);
90105513Sphk}
91120877Sphk
92106407Sphk/*
93106407Sphk * Store the token with the record descriptor.
94105513Sphk */
95105513Sphkstatic void
96105513Sphkkau_write(struct au_record *rec, struct au_token *tok)
97105513Sphk{
98105513Sphk
99106407Sphk	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
100106407Sphk
101106407Sphk	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
102106407Sphk	rec->len += tok->len;
103106407Sphk}
104106407Sphk
105106407Sphk/*
106106407Sphk * Close out the audit record by adding the header token, identifying any
107106407Sphk * missing tokens.  Write out the tokens to the record memory.
108106407Sphk */
109106407Sphkstatic void
110106407Sphkkau_close(struct au_record *rec, struct timespec *ctime, short event)
111106407Sphk{
112106407Sphk	u_char *dptr;
113106407Sphk	size_t tot_rec_size;
114106407Sphk	token_t *cur, *hdr, *trail;
115106407Sphk	struct timeval tm;
116106407Sphk
117106407Sphk	tot_rec_size = rec->len + AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE;
118106407Sphk	rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO);
119106407Sphk
120106407Sphk	tm.tv_usec = ctime->tv_nsec / 1000;
121106407Sphk	tm.tv_sec = ctime->tv_sec;
122106407Sphk	hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
123106407Sphk	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
124106407Sphk
125106407Sphk	trail = au_to_trailer(tot_rec_size);
126106407Sphk	TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
127106407Sphk
128106407Sphk	rec->len = tot_rec_size;
129106407Sphk	dptr = rec->data;
130106407Sphk	TAILQ_FOREACH(cur, &rec->token_q, tokens) {
131106407Sphk		memcpy(dptr, cur->t_data, cur->len);
132105513Sphk		dptr += cur->len;
133141769Sru	}
134105513Sphk}
135105513Sphk
136141769Sru/*
137141769Sru * Free a BSM audit record by releasing all the tokens and clearing the audit
138141769Sru * record information.
139141769Sru */
140141769Sruvoid
141141769Srukau_free(struct au_record *rec)
142141769Sru{
143141769Sru	struct au_token *tok;
144141769Sru
145141769Sru	/* Free the token list. */
146105513Sphk	while ((tok = TAILQ_FIRST(&rec->token_q))) {
147105513Sphk		TAILQ_REMOVE(&rec->token_q, tok, tokens);
148105513Sphk		free(tok->t_data, M_AUDITBSM);
149105513Sphk		free(tok, M_AUDITBSM);
150105513Sphk	}
151105513Sphk
152105513Sphk	rec->used = 0;
153105513Sphk	rec->len = 0;
154105513Sphk	free(rec->data, M_AUDITBSM);
155105513Sphk	free(rec, M_AUDITBSM);
156105513Sphk}
157105513Sphk
158105513Sphk/*
159105513Sphk * XXX: May want turn some (or all) of these macros into functions in order
160105513Sphk * to reduce the generated code sized.
161105513Sphk *
162105513Sphk * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
163105513Sphk * caller are OK with this.
164105513Sphk */
165105513Sphk#define UPATH1_TOKENS do {						\
166105513Sphk	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
167105513Sphk		tok = au_to_path(ar->ar_arg_upath1);			\
168105513Sphk		kau_write(rec, tok);					\
169105513Sphk	}								\
170105513Sphk} while (0)
171105513Sphk
172105513Sphk#define UPATH2_TOKENS do {						\
173105513Sphk	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
174105513Sphk		tok = au_to_path(ar->ar_arg_upath2);			\
175105513Sphk		kau_write(rec, tok);					\
176105513Sphk	}								\
177105513Sphk} while (0)
178105513Sphk
179105513Sphk#define VNODE1_TOKENS do {						\
180105513Sphk	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
181125387Sdes		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
182105513Sphk		kau_write(rec, tok);					\
183105513Sphk	}								\
184105513Sphk} while (0)
185105513Sphk
186105513Sphk#define UPATH1_VNODE1_TOKENS do {					\
187105513Sphk	if (ARG_IS_VALID(kar, ARG_UPATH1)) {  				\
188106407Sphk		UPATH1_TOKENS;						\
189105513Sphk	}								\
190105513Sphk	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
191105513Sphk		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
192105513Sphk		kau_write(rec, tok);					\
193105513Sphk	}								\
194106407Sphk} while (0)
195105513Sphk
196105513Sphk#define VNODE2_TOKENS do {						\
197105513Sphk	if (ARG_IS_VALID(kar, ARG_VNODE2)) {  				\
198105513Sphk		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
199105513Sphk		kau_write(rec, tok);					\
200105513Sphk	}								\
201105513Sphk} while (0)
202105513Sphk
203106407Sphk#define FD_VNODE1_TOKENS	do {					\
204106407Sphk	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
205105513Sphk		if (ARG_IS_VALID(kar, ARG_FD)) {			\
206105513Sphk			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
207105513Sphk			kau_write(rec, tok);				\
208105513Sphk		}							\
209105513Sphk		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
210105513Sphk		kau_write(rec, tok);					\
211105513Sphk	} else {							\
212105513Sphk		if (ARG_IS_VALID(kar, ARG_FD)) {			\
213105513Sphk			tok = au_to_arg32(1, "non-file: fd",		\
214105513Sphk			    ar->ar_arg_fd);				\
215105513Sphk			kau_write(rec, tok);				\
216105513Sphk		}							\
217105513Sphk	}								\
218105513Sphk} while (0)
219105513Sphk
220105513Sphk#define PROCESS_PID_TOKENS(argn) do {					\
221105513Sphk	if ((ar->ar_arg_pid > 0) /* Reference a single process */	\
222105513Sphk	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {			\
223105513Sphk		tok = au_to_process(ar->ar_arg_auid,			\
224105513Sphk		    ar->ar_arg_euid, ar->ar_arg_egid,			\
225105513Sphk		    ar->ar_arg_ruid, ar->ar_arg_rgid,			\
226105513Sphk		    ar->ar_arg_pid, ar->ar_arg_asid,			\
227105513Sphk		    &ar->ar_arg_termid);				\
228105513Sphk		kau_write(rec, tok);					\
229105513Sphk	} else if (ARG_IS_VALID(kar, ARG_PID)) {			\
230105513Sphk		tok = au_to_arg32(argn, "process", ar->ar_arg_pid);	\
231105513Sphk		kau_write(rec, tok);					\
232105513Sphk	}								\
233106407Sphk} while (0)								\
234106407Sphk
235105513Sphk#define EXTATTR_TOKENS	do {						\
236105513Sphk	if (ARG_IS_VALID(kar, ARG_VALUE)) {				\
237105513Sphk		switch (ar->ar_arg_value) {				\
238106407Sphk		case EXTATTR_NAMESPACE_USER:				\
239105513Sphk			tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
240105513Sphk			break;						\
241105513Sphk		case EXTATTR_NAMESPACE_SYSTEM:				\
242105513Sphk			tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
243125387Sdes			break;						\
244105513Sphk		default:						\
245105513Sphk			tok = au_to_arg32(3, "attrnamespace",		\
246105513Sphk			    ar->ar_arg_value);				\
247106407Sphk			break;						\
248105513Sphk		}							\
249105513Sphk		kau_write(rec, tok);					\
250105513Sphk	}								\
251105513Sphk	/* attrname is in the text field */				\
252105513Sphk	if (ARG_IS_VALID(kar, ARG_TEXT)) {				\
253105513Sphk		tok = au_to_text(ar->ar_arg_text);			\
254105513Sphk		kau_write(rec, tok);					\
255105513Sphk	}								\
256105513Sphk} while (0)
257105513Sphk
258112877Sphk/*
259112877Sphk * Implement auditing for the auditon() system call. The audit tokens that
260112877Sphk * are generated depend on the command that was sent into the auditon()
261112877Sphk * system call.
262105513Sphk */
263115624Sphkstatic void
264115624Sphkaudit_sys_auditon(struct audit_record *ar, struct au_record *rec)
265112877Sphk{
266112877Sphk	struct au_token *tok;
267112877Sphk
268105513Sphk	switch (ar->ar_arg_cmd) {
269105513Sphk	case A_SETPOLICY:
270105513Sphk		if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
271111296Stjr			tok = au_to_arg64(1, "policy",
272112877Sphk			    ar->ar_arg_auditon.au_flags);
273112877Sphk		else
274105513Sphk			tok = au_to_arg32(1, "policy",
275105513Sphk			    ar->ar_arg_auditon.au_flags);
276112877Sphk		kau_write(rec, tok);
277112877Sphk		break;
278112877Sphk
279125386Sdes	case A_SETKMASK:
280105513Sphk		tok = au_to_arg32(2, "setkmask:as_success",
281105513Sphk		    ar->ar_arg_auditon.au_mask.am_success);
282105513Sphk		kau_write(rec, tok);
283105513Sphk		tok = au_to_arg32(2, "setkmask:as_failure",
284105513Sphk		    ar->ar_arg_auditon.au_mask.am_failure);
285105541Sphk		kau_write(rec, tok);
286105513Sphk		break;
287112877Sphk
288112877Sphk	case A_SETQCTRL:
289112877Sphk		tok = au_to_arg32(3, "setqctrl:aq_hiwater",
290105513Sphk		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
291115624Sphk		kau_write(rec, tok);
292115624Sphk		tok = au_to_arg32(3, "setqctrl:aq_lowater",
293112877Sphk		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
294112877Sphk		kau_write(rec, tok);
295112877Sphk		tok = au_to_arg32(3, "setqctrl:aq_bufsz",
296112877Sphk		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
297112877Sphk		kau_write(rec, tok);
298112877Sphk		tok = au_to_arg32(3, "setqctrl:aq_delay",
299125386Sdes		    ar->ar_arg_auditon.au_qctrl.aq_delay);
300105513Sphk		kau_write(rec, tok);
301105513Sphk		tok = au_to_arg32(3, "setqctrl:aq_minfree",
302105513Sphk		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
303105513Sphk		kau_write(rec, tok);
304106407Sphk		break;
305105513Sphk
306105513Sphk	case A_SETUMASK:
307105513Sphk		tok = au_to_arg32(3, "setumask:as_success",
308105513Sphk		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
309106407Sphk		kau_write(rec, tok);
310106407Sphk		tok = au_to_arg32(3, "setumask:as_failure",
311106407Sphk		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
312105513Sphk		kau_write(rec, tok);
313106407Sphk		break;
314106407Sphk
315106407Sphk	case A_SETSMASK:
316106407Sphk		tok = au_to_arg32(3, "setsmask:as_success",
317106407Sphk		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
318106407Sphk		kau_write(rec, tok);
319106407Sphk		tok = au_to_arg32(3, "setsmask:as_failure",
320106407Sphk		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
321106407Sphk		kau_write(rec, tok);
322106407Sphk		break;
323106407Sphk
324106407Sphk	case A_SETCOND:
325106407Sphk		if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
326105513Sphk			tok = au_to_arg64(3, "setcond",
327105513Sphk			    ar->ar_arg_auditon.au_cond);
328105513Sphk		else
329111296Stjr			tok = au_to_arg32(3, "setcond",
330105513Sphk			    ar->ar_arg_auditon.au_cond);
331105513Sphk		kau_write(rec, tok);
332105513Sphk		break;
333105513Sphk
334105513Sphk	case A_SETCLASS:
335105513Sphk		tok = au_to_arg32(2, "setclass:ec_event",
336106407Sphk		    ar->ar_arg_auditon.au_evclass.ec_number);
337106407Sphk		kau_write(rec, tok);
338105513Sphk		tok = au_to_arg32(3, "setclass:ec_class",
339105513Sphk		    ar->ar_arg_auditon.au_evclass.ec_class);
340105513Sphk		kau_write(rec, tok);
341105513Sphk		break;
342105513Sphk
343105513Sphk	case A_SETPMASK:
344105513Sphk		tok = au_to_arg32(2, "setpmask:as_success",
345105513Sphk		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
346105513Sphk		kau_write(rec, tok);
347105513Sphk		tok = au_to_arg32(2, "setpmask:as_failure",
348105513Sphk		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
349105513Sphk		kau_write(rec, tok);
350105513Sphk		break;
351105513Sphk
352105513Sphk	case A_SETFSIZE:
353105513Sphk		tok = au_to_arg32(2, "setfsize:filesize",
354105513Sphk		    ar->ar_arg_auditon.au_fstat.af_filesz);
355105513Sphk		kau_write(rec, tok);
356105513Sphk		break;
357105513Sphk
358105513Sphk	default:
359105513Sphk		break;
360105513Sphk	}
361105513Sphk}
362105513Sphk
363105513Sphk/*
364105513Sphk * Convert an internal kernel audit record to a BSM record and return a
365125473Spjd * success/failure indicator. The BSM record is passed as an out parameter to
366105513Sphk * this function.
367105513Sphk *
368105513Sphk * Return conditions:
369105513Sphk *   BSM_SUCCESS: The BSM record is valid
370105513Sphk *   BSM_FAILURE: Failure; the BSM record is NULL.
371105513Sphk *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
372105513Sphk */
373105513Sphkint
374105513Sphkkaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
375105513Sphk{
376105513Sphk	struct au_token *tok, *subj_tok;
377105513Sphk	struct au_record *rec;
378105513Sphk	au_tid_t tid;
379105513Sphk	struct audit_record *ar;
380105513Sphk	int ctr;
381105513Sphk
382105513Sphk	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
383105513Sphk
384105513Sphk	*pau = NULL;
385105513Sphk	ar = &kar->k_ar;
386105513Sphk	rec = kau_open();
387105513Sphk
388105513Sphk	/* Create the subject token */
389105513Sphk	switch (ar->ar_subj_term_addr.at_type) {
390105513Sphk	case AU_IPv4:
391105513Sphk		tid.port = ar->ar_subj_term_addr.at_port;
392105513Sphk		tid.machine = ar->ar_subj_term_addr.at_addr[0];
393105513Sphk		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
394105513Sphk		    ar->ar_subj_cred.cr_uid, /* eff uid */
395105513Sphk		    ar->ar_subj_egid,	/* eff group id */
396105513Sphk		    ar->ar_subj_ruid, 	/* real uid */
397105513Sphk		    ar->ar_subj_rgid, 	/* real group id */
398120876Sphk		    ar->ar_subj_pid,	/* process id */
399105513Sphk		    ar->ar_subj_asid,	/* session ID */
400105513Sphk		    &tid);
401105513Sphk		break;
402105513Sphk	case AU_IPv6:
403105513Sphk		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
404111296Stjr		    ar->ar_subj_cred.cr_uid,
405105513Sphk		    ar->ar_subj_egid,
406105513Sphk		    ar->ar_subj_ruid,
407120876Sphk		    ar->ar_subj_rgid,
408105513Sphk		    ar->ar_subj_pid,
409105513Sphk		    ar->ar_subj_asid,
410105513Sphk		    &ar->ar_subj_term_addr);
411105513Sphk		break;
412105513Sphk	default:
413105513Sphk		bzero(&tid, sizeof(tid));
414105513Sphk		subj_tok = au_to_subject32(ar->ar_subj_auid,
415105513Sphk		    ar->ar_subj_cred.cr_uid,
416105513Sphk		    ar->ar_subj_egid,
417105513Sphk		    ar->ar_subj_ruid,
418105513Sphk		    ar->ar_subj_rgid,
419105513Sphk		    ar->ar_subj_pid,
420105513Sphk		    ar->ar_subj_asid,
421105513Sphk		    &tid);
422105513Sphk	}
423105513Sphk
424105513Sphk	/*
425105513Sphk	 * The logic inside each case fills in the tokens required for the
426105513Sphk	 * event, except for the header, trailer, and return tokens.  The
427105513Sphk	 * header and trailer tokens are added by the kau_close() function.
428105513Sphk	 * The return token is added outside of the switch statement.
429105513Sphk	 */
430105513Sphk	switch(ar->ar_event) {
431105513Sphk	case AUE_ACCEPT:
432105513Sphk	case AUE_BIND:
433105513Sphk	case AUE_CONNECT:
434105513Sphk	case AUE_RECV:
435120876Sphk	case AUE_RECVFROM:
436106407Sphk	case AUE_RECVMSG:
437106407Sphk	case AUE_SEND:
438105513Sphk	case AUE_SENDFILE:
439106407Sphk	case AUE_SENDMSG:
440105513Sphk	case AUE_SENDTO:
441105513Sphk		/*
442105513Sphk		 * Socket-related events.
443105513Sphk		 */
444105513Sphk		if (ARG_IS_VALID(kar, ARG_FD)) {
445105513Sphk			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
446105513Sphk			kau_write(rec, tok);
447125473Spjd		}
448108052Sphk		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
449135035Sphk			tok = au_to_sock_inet((struct sockaddr_in *)
450108052Sphk			    &ar->ar_arg_sockaddr);
451108052Sphk			kau_write(rec, tok);
452108052Sphk		}
453108052Sphk		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
454108052Sphk			tok = au_to_sock_unix((struct sockaddr_un *)
455108052Sphk			    &ar->ar_arg_sockaddr);
456108052Sphk			kau_write(rec, tok);
457108052Sphk			UPATH1_TOKENS;
458108052Sphk		}
459105513Sphk		/* XXX Need to handle ARG_SADDRINET6 */
460105513Sphk		break;
461105513Sphk
462105513Sphk	case AUE_SOCKET:
463105513Sphk	case AUE_SOCKETPAIR:
464105513Sphk		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
465105513Sphk			tok = au_to_arg32(1,"domain",
466105513Sphk			    ar->ar_arg_sockinfo.so_domain);
467105513Sphk			kau_write(rec, tok);
468105513Sphk			tok = au_to_arg32(2,"type",
469105513Sphk			    ar->ar_arg_sockinfo.so_type);
470106227Sphk			kau_write(rec, tok);
471105513Sphk			tok = au_to_arg32(3,"protocol",
472105513Sphk			    ar->ar_arg_sockinfo.so_protocol);
473105513Sphk			kau_write(rec, tok);
474105513Sphk		}
475105513Sphk		break;
476108052Sphk
477108052Sphk	case AUE_SETSOCKOPT:
478108052Sphk	case AUE_SHUTDOWN:
479135035Sphk		if (ARG_IS_VALID(kar, ARG_FD)) {
480108052Sphk			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
481108052Sphk			kau_write(rec, tok);
482108052Sphk		}
483131101Ssobomax		break;
484131101Ssobomax
485131101Ssobomax	case AUE_ACCT:
486131101Ssobomax		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
487131101Ssobomax			UPATH1_VNODE1_TOKENS;
488108052Sphk		} else {
489108052Sphk			tok = au_to_arg32(1, "accounting off", 0);
490105513Sphk			kau_write(rec, tok);
491105513Sphk		}
492105513Sphk		break;
493105513Sphk
494105513Sphk	case AUE_SETAUID:
495105513Sphk		if (ARG_IS_VALID(kar, ARG_AUID)) {
496105513Sphk			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
497105513Sphk			kau_write(rec, tok);
498105513Sphk		}
499105513Sphk		break;
500105513Sphk
501105513Sphk	case AUE_SETAUDIT:
502105513Sphk		if (ARG_IS_VALID(kar, ARG_AUID)) {
503105513Sphk			tok = au_to_arg32(1, "setaudit:auid",
504105513Sphk			    ar->ar_arg_auid);
505105513Sphk			kau_write(rec, tok);
506105513Sphk			tok = au_to_arg32(1, "setaudit:port",
507105513Sphk			    ar->ar_arg_termid.port);
508105513Sphk			kau_write(rec, tok);
509105513Sphk			tok = au_to_arg32(1, "setaudit:machine",
510105513Sphk			    ar->ar_arg_termid.machine);
511111296Stjr			kau_write(rec, tok);
512105513Sphk			tok = au_to_arg32(1, "setaudit:as_success",
513105513Sphk			    ar->ar_arg_amask.am_success);
514125477Sdes			kau_write(rec, tok);
515105513Sphk			tok = au_to_arg32(1, "setaudit:as_failure",
516125477Sdes			    ar->ar_arg_amask.am_failure);
517125477Sdes			kau_write(rec, tok);
518125477Sdes			tok = au_to_arg32(1, "setaudit:asid",
519105513Sphk			    ar->ar_arg_asid);
520105513Sphk			kau_write(rec, tok);
521111296Stjr		}
522105513Sphk		break;
523105513Sphk
524125477Sdes	case AUE_SETAUDIT_ADDR:
525125477Sdes		break;		/* XXX need to add arguments */
526125477Sdes
527125477Sdes	case AUE_AUDITON:
528125477Sdes		/*
529125477Sdes		 * For AUDITON commands without own event, audit the cmd.
530125477Sdes		 */
531105513Sphk		if (ARG_IS_VALID(kar, ARG_CMD)) {
532125477Sdes			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
533105513Sphk			kau_write(rec, tok);
534105513Sphk		}
535111296Stjr		/* fall thru */
536105513Sphk
537105513Sphk	case AUE_AUDITON_GETCAR:
538105513Sphk	case AUE_AUDITON_GETCLASS:
539125473Spjd	case AUE_AUDITON_GETCOND:
540125477Sdes	case AUE_AUDITON_GETCWD:
541125477Sdes	case AUE_AUDITON_GETKMASK:
542125477Sdes	case AUE_AUDITON_GETSTAT:
543125477Sdes	case AUE_AUDITON_GPOLICY:
544125477Sdes	case AUE_AUDITON_GQCTRL:
545125477Sdes	case AUE_AUDITON_SETCLASS:
546125477Sdes	case AUE_AUDITON_SETCOND:
547105513Sphk	case AUE_AUDITON_SETKMASK:
548105513Sphk	case AUE_AUDITON_SETSMASK:
549105513Sphk	case AUE_AUDITON_SETSTAT:
550105513Sphk	case AUE_AUDITON_SETUMASK:
551105513Sphk	case AUE_AUDITON_SPOLICY:
552105513Sphk	case AUE_AUDITON_SQCTRL:
553105513Sphk		if (ARG_IS_VALID(kar, ARG_AUDITON))
554105513Sphk			audit_sys_auditon(ar, rec);
555105513Sphk		break;
556108020Sphk
557108020Sphk	case AUE_AUDITCTL:
558108020Sphk		UPATH1_VNODE1_TOKENS;
559108020Sphk		break;
560105513Sphk
561105513Sphk	case AUE_EXIT:
562105513Sphk		if (ARG_IS_VALID(kar, ARG_EXIT)) {
563105513Sphk			tok = au_to_exit(ar->ar_arg_exitretval,
564105513Sphk			    ar->ar_arg_exitstatus);
565105513Sphk			kau_write(rec, tok);
566105513Sphk		}
567105513Sphk		break;
568105513Sphk
569105513Sphk	case AUE_ADJTIME:
570105513Sphk	case AUE_CLOCK_SETTIME:
571105513Sphk	case AUE_AUDIT:
572105513Sphk	case AUE_DUP2:
573105513Sphk	case AUE_GETAUDIT:
574105513Sphk	case AUE_GETAUDIT_ADDR:
575105513Sphk	case AUE_GETAUID:
576105513Sphk	case AUE_GETCWD:
577105513Sphk	case AUE_GETFSSTAT:
578105513Sphk	case AUE_GETRESUID:
579105513Sphk	case AUE_GETRESGID:
580105513Sphk	case AUE_KQUEUE:
581105513Sphk	case AUE_LSEEK:
582105513Sphk	case AUE_MODLOAD:
583105513Sphk	case AUE_MODUNLOAD:
584105513Sphk	case AUE_MSGSYS:
585105513Sphk	case AUE_NFS_SVC:
586105513Sphk	case AUE_NTP_ADJTIME:
587105513Sphk	case AUE_PIPE:
588105513Sphk	case AUE_PROFILE:
589105513Sphk	case AUE_RTPRIO:
590105513Sphk	case AUE_SEMSYS:
591105513Sphk	case AUE_SHMSYS:
592105513Sphk	case AUE_SETPGRP:
593105513Sphk	case AUE_SETRLIMIT:
594105513Sphk	case AUE_SETSID:
595105513Sphk	case AUE_SETTIMEOFDAY:
596105513Sphk	case AUE_SYSARCH:
597105513Sphk
598105513Sphk		/*
599105513Sphk		 * Header, subject, and return tokens added at end.
600105513Sphk		 */
601105513Sphk		break;
602105513Sphk
603105513Sphk	case AUE_MKFIFO:
604105513Sphk		if (ARG_IS_VALID(kar, ARG_MODE)) {
605105513Sphk			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
606125387Sdes			kau_write(rec, tok);
607105513Sphk		}
608105513Sphk		/* fall through */
609105513Sphk	case AUE_ACCESS:
610105513Sphk	case AUE_CHDIR:
611105513Sphk	case AUE_CHROOT:
612105513Sphk	case AUE_EACCESS:
613105513Sphk	case AUE_GETATTRLIST:
614105513Sphk	case AUE_JAIL:
615120876Sphk	case AUE_LUTIMES:
616105513Sphk	case AUE_NFS_GETFH:
617108060Sphk	case AUE_LSTAT:
618105513Sphk	case AUE_PATHCONF:
619105513Sphk	case AUE_READLINK:
620105513Sphk	case AUE_REVOKE:
621105513Sphk	case AUE_RMDIR:
622105513Sphk	case AUE_SEARCHFS:
623105513Sphk	case AUE_SETATTRLIST:
624105513Sphk	case AUE_STAT:
625105513Sphk	case AUE_STATFS:
626105513Sphk	case AUE_SWAPON:
627105513Sphk	case AUE_SWAPOFF:
628105513Sphk	case AUE_TRUNCATE:
629105513Sphk	case AUE_UNDELETE:
630105513Sphk	case AUE_UNLINK:
631105513Sphk	case AUE_UTIMES:
632105513Sphk		UPATH1_VNODE1_TOKENS;
633105513Sphk		break;
634125477Sdes
635125477Sdes	case AUE_FHSTATFS:
636125477Sdes	case AUE_FHOPEN:
637125477Sdes	case AUE_FHSTAT:
638125477Sdes		/* XXXRW: Need to audit vnode argument. */
639125477Sdes		break;
640125477Sdes
641125477Sdes	case AUE_CHFLAGS:
642125477Sdes	case AUE_LCHFLAGS:
643105513Sphk		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
644105513Sphk			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
645105513Sphk			kau_write(rec, tok);
646105513Sphk		}
647105513Sphk		UPATH1_VNODE1_TOKENS;
648105513Sphk		break;
649105513Sphk
650105513Sphk	case AUE_CHMOD:
651105513Sphk	case AUE_LCHMOD:
652105513Sphk		if (ARG_IS_VALID(kar, ARG_MODE)) {
653105513Sphk			tok = au_to_arg32(2, "new file mode",
654105513Sphk			    ar->ar_arg_mode);
655105513Sphk			kau_write(rec, tok);
656105513Sphk		}
657105513Sphk		UPATH1_VNODE1_TOKENS;
658125387Sdes		break;
659105513Sphk
660125387Sdes	case AUE_CHOWN:
661105513Sphk	case AUE_LCHOWN:
662105513Sphk		if (ARG_IS_VALID(kar, ARG_UID)) {
663105513Sphk			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
664105513Sphk			kau_write(rec, tok);
665108052Sphk		}
666105513Sphk		if (ARG_IS_VALID(kar, ARG_GID)) {
667105513Sphk			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
668120876Sphk			kau_write(rec, tok);
669105513Sphk		}
670105513Sphk		UPATH1_VNODE1_TOKENS;
671105513Sphk		break;
672105513Sphk
673105513Sphk	case AUE_EXCHANGEDATA:
674105513Sphk		UPATH1_VNODE1_TOKENS;
675105513Sphk		UPATH2_TOKENS;
676105513Sphk		break;
677105513Sphk
678105513Sphk	case AUE_CLOSE:
679105513Sphk		if (ARG_IS_VALID(kar, ARG_FD)) {
680105513Sphk			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
681105513Sphk			kau_write(rec, tok);
682105513Sphk		}
683105513Sphk		UPATH1_VNODE1_TOKENS;
684105513Sphk		break;
685105513Sphk
686105513Sphk	case AUE_EXTATTRCTL:
687105513Sphk		UPATH1_VNODE1_TOKENS;
688105513Sphk		if (ARG_IS_VALID(kar, ARG_CMD)) {
689105513Sphk			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
690105513Sphk			kau_write(rec, tok);
691105513Sphk		}
692105513Sphk		/* extattrctl(2) filename parameter is in upath2/vnode2 */
693105513Sphk		UPATH2_TOKENS;
694105513Sphk		VNODE2_TOKENS;
695106227Sphk		EXTATTR_TOKENS;
696106227Sphk		break;
697125387Sdes
698105513Sphk	case AUE_EXTATTR_GET_FILE:
699105513Sphk	case AUE_EXTATTR_SET_FILE:
700105513Sphk	case AUE_EXTATTR_LIST_FILE:
701105513Sphk	case AUE_EXTATTR_DELETE_FILE:
702105513Sphk	case AUE_EXTATTR_GET_LINK:
703105541Sphk	case AUE_EXTATTR_SET_LINK:
704105513Sphk	case AUE_EXTATTR_LIST_LINK:
705105513Sphk	case AUE_EXTATTR_DELETE_LINK:
706105513Sphk		UPATH1_VNODE1_TOKENS;
707105513Sphk		EXTATTR_TOKENS;
708105513Sphk		break;
709105513Sphk
710105513Sphk	case AUE_EXTATTR_GET_FD:
711105513Sphk	case AUE_EXTATTR_SET_FD:
712105513Sphk	case AUE_EXTATTR_LIST_FD:
713105513Sphk	case AUE_EXTATTR_DELETE_FD:
714107455Sphk		if (ARG_IS_VALID(kar, ARG_FD)) {
715107455Sphk			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
716107455Sphk			kau_write(rec, tok);
717105513Sphk		}
718107455Sphk		EXTATTR_TOKENS;
719105513Sphk		break;
720105513Sphk
721105513Sphk	case AUE_EXECVE:
722105513Sphk		if (ARG_IS_VALID(kar, ARG_ARGV)) {
723141769Sru			tok = au_to_exec_args(ar->ar_arg_argv,
724105513Sphk			    ar->ar_arg_argc);
725141214Spjd			kau_write(rec, tok);
726141214Spjd		}
727141214Spjd		if (ARG_IS_VALID(kar, ARG_ENVV)) {
728141769Sru			tok = au_to_exec_env(ar->ar_arg_envv,
729141214Spjd			    ar->ar_arg_envc);
730105513Sphk			kau_write(rec, tok);
731105513Sphk		}
732105513Sphk		UPATH1_VNODE1_TOKENS;
733105513Sphk		break;
734105541Sphk
735105541Sphk	case AUE_FCHMOD:
736105513Sphk		if (ARG_IS_VALID(kar, ARG_MODE)) {
737105513Sphk			tok = au_to_arg32(2, "new file mode",
738105513Sphk			    ar->ar_arg_mode);
739105513Sphk			kau_write(rec, tok);
740105513Sphk		}
741105513Sphk		FD_VNODE1_TOKENS;
742105513Sphk		break;
743105513Sphk
744141216Spjd	/*
745105513Sphk	 * XXXRW: Some of these need to handle non-vnode cases as well.
746105513Sphk	 */
747105513Sphk	case AUE_FCHDIR:
748105513Sphk	case AUE_FPATHCONF:
749105513Sphk	case AUE_FSTAT:
750105513Sphk	case AUE_FSTATFS:
751105513Sphk	case AUE_FSYNC:
752141216Spjd	case AUE_FTRUNCATE:
753105513Sphk	case AUE_FUTIMES:
754141769Sru	case AUE_GETDIRENTRIES:
755105513Sphk	case AUE_GETDIRENTRIESATTR:
756105513Sphk	case AUE_POLL:
757105513Sphk	case AUE_READ:
758105513Sphk	case AUE_READV:
759107455Sphk	case AUE_WRITE:
760105513Sphk	case AUE_WRITEV:
761105513Sphk		FD_VNODE1_TOKENS;
762105513Sphk		break;
763105513Sphk
764105513Sphk	case AUE_FCHOWN:
765105513Sphk		if (ARG_IS_VALID(kar, ARG_UID)) {
766105513Sphk			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
767105513Sphk			kau_write(rec, tok);
768105513Sphk		}
769105513Sphk		if (ARG_IS_VALID(kar, ARG_GID)) {
770105513Sphk			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
771105513Sphk			kau_write(rec, tok);
772105513Sphk		}
773105513Sphk		FD_VNODE1_TOKENS;
774105513Sphk		break;
775105513Sphk
776105513Sphk	case AUE_FCNTL:
777105513Sphk		if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
778105513Sphk			ar->ar_arg_cmd == F_SETLKW) {
779105513Sphk			if (ARG_IS_VALID(kar, ARG_CMD)) {
780105513Sphk				tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
781105513Sphk				kau_write(rec, tok);
782105513Sphk			}
783105513Sphk			FD_VNODE1_TOKENS;
784141216Spjd		}
785141216Spjd		break;
786141216Spjd
787141769Sru	case AUE_FCHFLAGS:
788141216Spjd		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
789141769Sru			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
790141216Spjd			kau_write(rec, tok);
791105513Sphk		}
792105513Sphk		FD_VNODE1_TOKENS;
793105513Sphk		break;
794105513Sphk
795105513Sphk	case AUE_FLOCK:
796105513Sphk		if (ARG_IS_VALID(kar, ARG_CMD)) {
797105513Sphk			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
798141769Sru			kau_write(rec, tok);
799105513Sphk		}
800105513Sphk		FD_VNODE1_TOKENS;
801105513Sphk		break;
802141198Spjd
803141198Spjd	case AUE_RFORK:
804111298Stjr		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
805111298Stjr			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
806111298Stjr			kau_write(rec, tok);
807111298Stjr		}
808141198Spjd		/* fall through */
809107455Sphk	case AUE_FORK:
810105513Sphk	case AUE_VFORK:
811111296Stjr		if (ARG_IS_VALID(kar, ARG_PID)) {
812107455Sphk			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
813107455Sphk			kau_write(rec, tok);
814107455Sphk		}
815105513Sphk		break;
816105513Sphk
817105513Sphk	case AUE_IOCTL:
818107982Sphk		if (ARG_IS_VALID(kar, ARG_CMD)) {
819105513Sphk			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
820105513Sphk			kau_write(rec, tok);
821105513Sphk		}
822105513Sphk		if (ARG_IS_VALID(kar, ARG_ADDR)) {
823105513Sphk			tok = au_to_arg32(1, "arg",
824105513Sphk			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
825105541Sphk			kau_write(rec, tok);
826105541Sphk		}
827105513Sphk		if (ARG_IS_VALID(kar, ARG_VNODE1))
828105513Sphk			FD_VNODE1_TOKENS;
829105513Sphk		else {
830105513Sphk			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
831105513Sphk				tok = kau_to_socket(&ar->ar_arg_sockinfo);
832105513Sphk				kau_write(rec, tok);
833105513Sphk			} else {
834105513Sphk				if (ARG_IS_VALID(kar, ARG_FD)) {
835105513Sphk					tok = au_to_arg32(1, "fd",
836105513Sphk					    ar->ar_arg_fd);
837105513Sphk			    		kau_write(rec, tok);
838105513Sphk				}
839105513Sphk			}
840105513Sphk		}
841105513Sphk		break;
842105513Sphk
843105513Sphk	case AUE_KILL:
844105513Sphk	case AUE_KILLPG:
845105513Sphk		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
846105513Sphk			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
847105513Sphk			kau_write(rec, tok);
848105513Sphk		}
849105513Sphk		PROCESS_PID_TOKENS(1);
850105513Sphk		break;
851105513Sphk
852105513Sphk	case AUE_KTRACE:
853105513Sphk		if (ARG_IS_VALID(kar, ARG_CMD)) {
854105513Sphk			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
855105513Sphk			kau_write(rec, tok);
856105513Sphk		}
857105513Sphk		if (ARG_IS_VALID(kar, ARG_VALUE)) {
858105513Sphk			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
859105513Sphk			kau_write(rec, tok);
860105513Sphk		}
861141769Sru		PROCESS_PID_TOKENS(4);
862105513Sphk		UPATH1_VNODE1_TOKENS;
863105513Sphk		break;
864105513Sphk
865105513Sphk	case AUE_LINK:
866	case AUE_RENAME:
867		UPATH1_VNODE1_TOKENS;
868		UPATH2_TOKENS;
869		break;
870
871	case AUE_LOADSHFILE:
872		if (ARG_IS_VALID(kar, ARG_ADDR)) {
873			tok = au_to_arg32(4, "base addr",
874			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
875			kau_write(rec, tok);
876		}
877		UPATH1_VNODE1_TOKENS;
878		break;
879
880	case AUE_MKDIR:
881		if (ARG_IS_VALID(kar, ARG_MODE)) {
882			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
883			kau_write(rec, tok);
884		}
885		UPATH1_VNODE1_TOKENS;
886		break;
887
888	case AUE_MKNOD:
889		if (ARG_IS_VALID(kar, ARG_MODE)) {
890			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
891			kau_write(rec, tok);
892		}
893		if (ARG_IS_VALID(kar, ARG_DEV)) {
894			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
895			kau_write(rec, tok);
896		}
897		UPATH1_VNODE1_TOKENS;
898		break;
899
900	case AUE_MMAP:
901	case AUE_MUNMAP:
902	case AUE_MPROTECT:
903	case AUE_MLOCK:
904	case AUE_MUNLOCK:
905	case AUE_MINHERIT:
906		if (ARG_IS_VALID(kar, ARG_ADDR)) {
907			tok = au_to_arg32(1, "addr",
908			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
909			kau_write(rec, tok);
910		}
911		if (ARG_IS_VALID(kar, ARG_LEN)) {
912			tok = au_to_arg32(2, "len", ar->ar_arg_len);
913			kau_write(rec, tok);
914		}
915		if (ar->ar_event == AUE_MMAP)
916			FD_VNODE1_TOKENS;
917		if (ar->ar_event == AUE_MPROTECT) {
918			if (ARG_IS_VALID(kar, ARG_VALUE)) {
919				tok = au_to_arg32(3, "protection",
920				    ar->ar_arg_value);
921				kau_write(rec, tok);
922			}
923		}
924		if (ar->ar_event == AUE_MINHERIT) {
925			if (ARG_IS_VALID(kar, ARG_VALUE)) {
926				tok = au_to_arg32(3, "inherit",
927				    ar->ar_arg_value);
928				kau_write(rec, tok);
929			}
930		}
931		break;
932
933	case AUE_MOUNT:
934	case AUE_NMOUNT:
935		/* XXX Need to handle NFS mounts */
936		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
937			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
938			kau_write(rec, tok);
939		}
940		if (ARG_IS_VALID(kar, ARG_TEXT)) {
941			tok = au_to_text(ar->ar_arg_text);
942			kau_write(rec, tok);
943		}
944		/* fall through */
945
946	case AUE_UMOUNT:
947		UPATH1_VNODE1_TOKENS;
948		break;
949
950	case AUE_MSGCTL:
951		ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd);
952		/* Fall through */
953
954	case AUE_MSGRCV:
955	case AUE_MSGSND:
956		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
957		kau_write(rec, tok);
958		if (ar->ar_errno != EINVAL) {
959			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
960			kau_write(rec, tok);
961		}
962		break;
963
964	case AUE_MSGGET:
965		if (ar->ar_errno == 0) {
966			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
967				tok = au_to_ipc(AT_IPC_MSG,
968				    ar->ar_arg_svipc_id);
969				kau_write(rec, tok);
970			}
971		}
972		break;
973
974	case AUE_RESETSHFILE:
975		if (ARG_IS_VALID(kar, ARG_ADDR)) {
976			tok = au_to_arg32(1, "base addr",
977			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
978			kau_write(rec, tok);
979		}
980		break;
981
982	case AUE_OPEN_RC:
983	case AUE_OPEN_RTC:
984	case AUE_OPEN_RWC:
985	case AUE_OPEN_RWTC:
986	case AUE_OPEN_WC:
987	case AUE_OPEN_WTC:
988	case AUE_CREAT:
989		if (ARG_IS_VALID(kar, ARG_MODE)) {
990			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
991			kau_write(rec, tok);
992		}
993		/* fall through */
994
995	case AUE_OPEN_R:
996	case AUE_OPEN_RT:
997	case AUE_OPEN_RW:
998	case AUE_OPEN_RWT:
999	case AUE_OPEN_W:
1000	case AUE_OPEN_WT:
1001		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1002			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1003			kau_write(rec, tok);
1004		}
1005		UPATH1_VNODE1_TOKENS;
1006		break;
1007
1008	case AUE_PTRACE:
1009		if (ARG_IS_VALID(kar, ARG_CMD)) {
1010			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1011			kau_write(rec, tok);
1012		}
1013		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1014			tok = au_to_arg32(3, "addr",
1015			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1016			kau_write(rec, tok);
1017		}
1018		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1019			tok = au_to_arg32(4, "data", ar->ar_arg_value);
1020			kau_write(rec, tok);
1021		}
1022		PROCESS_PID_TOKENS(2);
1023		break;
1024
1025	case AUE_QUOTACTL:
1026		if (ARG_IS_VALID(kar, ARG_CMD)) {
1027			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1028			kau_write(rec, tok);
1029		}
1030		if (ARG_IS_VALID(kar, ARG_UID)) {
1031			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1032			kau_write(rec, tok);
1033		}
1034		UPATH1_VNODE1_TOKENS;
1035		break;
1036
1037	case AUE_REBOOT:
1038		if (ARG_IS_VALID(kar, ARG_CMD)) {
1039			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1040			kau_write(rec, tok);
1041		}
1042		break;
1043
1044	case AUE_SEMCTL:
1045		ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd);
1046		/* Fall through */
1047
1048	case AUE_SEMOP:
1049		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1050			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1051			kau_write(rec, tok);
1052			if (ar->ar_errno != EINVAL) {
1053				tok = au_to_ipc(AT_IPC_SEM,
1054				    ar->ar_arg_svipc_id);
1055				kau_write(rec, tok);
1056			}
1057		}
1058		break;
1059
1060	case AUE_SEMGET:
1061		if (ar->ar_errno == 0) {
1062			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1063				tok = au_to_ipc(AT_IPC_SEM,
1064				    ar->ar_arg_svipc_id);
1065				kau_write(rec, tok);
1066			}
1067		}
1068		break;
1069
1070	case AUE_SETEGID:
1071		if (ARG_IS_VALID(kar, ARG_EGID)) {
1072			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
1073			kau_write(rec, tok);
1074		}
1075		break;
1076
1077	case AUE_SETEUID:
1078		if (ARG_IS_VALID(kar, ARG_EUID)) {
1079			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
1080			kau_write(rec, tok);
1081		}
1082		break;
1083
1084	case AUE_SETREGID:
1085		if (ARG_IS_VALID(kar, ARG_RGID)) {
1086			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1087			kau_write(rec, tok);
1088		}
1089		if (ARG_IS_VALID(kar, ARG_EGID)) {
1090			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1091			kau_write(rec, tok);
1092		}
1093		break;
1094
1095	case AUE_SETREUID:
1096		if (ARG_IS_VALID(kar, ARG_RUID)) {
1097			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1098			kau_write(rec, tok);
1099		}
1100		if (ARG_IS_VALID(kar, ARG_EUID)) {
1101			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1102			kau_write(rec, tok);
1103		}
1104		break;
1105
1106	case AUE_SETRESGID:
1107		if (ARG_IS_VALID(kar, ARG_RGID)) {
1108			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1109			kau_write(rec, tok);
1110		}
1111		if (ARG_IS_VALID(kar, ARG_EGID)) {
1112			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1113			kau_write(rec, tok);
1114		}
1115		if (ARG_IS_VALID(kar, ARG_SGID)) {
1116			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
1117			kau_write(rec, tok);
1118		}
1119		break;
1120
1121	case AUE_SETRESUID:
1122		if (ARG_IS_VALID(kar, ARG_RUID)) {
1123			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1124			kau_write(rec, tok);
1125		}
1126		if (ARG_IS_VALID(kar, ARG_EUID)) {
1127			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1128			kau_write(rec, tok);
1129		}
1130		if (ARG_IS_VALID(kar, ARG_SUID)) {
1131			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
1132			kau_write(rec, tok);
1133		}
1134		break;
1135
1136	case AUE_SETGID:
1137		if (ARG_IS_VALID(kar, ARG_GID)) {
1138			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1139			kau_write(rec, tok);
1140		}
1141		break;
1142
1143	case AUE_SETUID:
1144		if (ARG_IS_VALID(kar, ARG_UID)) {
1145			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1146			kau_write(rec, tok);
1147		}
1148		break;
1149
1150	case AUE_SETGROUPS:
1151		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1152			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1153			{
1154				tok = au_to_arg32(1, "setgroups", 							ar->ar_arg_groups.gidset[ctr]);
1155				kau_write(rec, tok);
1156			}
1157		}
1158		break;
1159
1160	case AUE_SETLOGIN:
1161		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1162			tok = au_to_text(ar->ar_arg_text);
1163			kau_write(rec, tok);
1164		}
1165		break;
1166
1167	case AUE_SETPRIORITY:
1168		if (ARG_IS_VALID(kar, ARG_CMD)) {
1169			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1170			kau_write(rec, tok);
1171		}
1172		if (ARG_IS_VALID(kar, ARG_UID)) {
1173			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1174			kau_write(rec, tok);
1175		}
1176		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1177			tok = au_to_arg32(2, "priority", ar->ar_arg_value);
1178			kau_write(rec, tok);
1179		}
1180		break;
1181
1182	case AUE_SETPRIVEXEC:
1183		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1184			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1185			kau_write(rec, tok);
1186		}
1187		break;
1188
1189	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1190	case AUE_SHMAT:
1191		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1192			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1193			kau_write(rec, tok);
1194			/* XXXAUDIT: Does having the ipc token make sense? */
1195			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1196			kau_write(rec, tok);
1197		}
1198		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1199			tok = au_to_arg32(2, "shmaddr",
1200			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1201			kau_write(rec, tok);
1202		}
1203		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1204			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1205			kau_write(rec, tok);
1206		}
1207		break;
1208
1209	case AUE_SHMCTL:
1210		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1211			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1212			kau_write(rec, tok);
1213			/* XXXAUDIT: Does having the ipc token make sense? */
1214			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1215			kau_write(rec, tok);
1216		}
1217		switch (ar->ar_arg_svipc_cmd) {
1218		case IPC_STAT:
1219			ar->ar_event = AUE_SHMCTL_STAT;
1220			break;
1221		case IPC_RMID:
1222			ar->ar_event = AUE_SHMCTL_RMID;
1223			break;
1224		case IPC_SET:
1225			ar->ar_event = AUE_SHMCTL_SET;
1226			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1227				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1228				kau_write(rec, tok);
1229			}
1230			break;
1231		default:
1232			break;	/* We will audit a bad command */
1233		}
1234		break;
1235
1236	case AUE_SHMDT:
1237		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1238			tok = au_to_arg32(1, "shmaddr",
1239			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1240			kau_write(rec, tok);
1241		}
1242		break;
1243
1244	case AUE_SHMGET:
1245		/* This is unusual; the return value is in an argument token */
1246		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1247			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1248			kau_write(rec, tok);
1249			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1250			kau_write(rec, tok);
1251		}
1252		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1253			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1254			kau_write(rec, tok);
1255		}
1256		break;
1257
1258	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1259	 * and AUE_SEMUNLINK are Posix IPC */
1260	case AUE_SHMOPEN:
1261		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1262			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1263			kau_write(rec, tok);
1264		}
1265		if (ARG_IS_VALID(kar, ARG_MODE)) {
1266			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1267			kau_write(rec, tok);
1268		}
1269	case AUE_SHMUNLINK:
1270		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1271			tok = au_to_text(ar->ar_arg_text);
1272			kau_write(rec, tok);
1273		}
1274		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1275		/* Create an ipc_perm token */
1276			struct ipc_perm perm;
1277			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1278			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1279			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1280			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1281			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1282			perm.seq = 0;
1283			perm.key = 0;
1284			tok = au_to_ipc_perm(&perm);
1285			kau_write(rec, tok);
1286		}
1287		break;
1288
1289	case AUE_SEMOPEN:
1290		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1291			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1292			kau_write(rec, tok);
1293		}
1294		if (ARG_IS_VALID(kar, ARG_MODE)) {
1295			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1296			kau_write(rec, tok);
1297		}
1298		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1299			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1300			kau_write(rec, tok);
1301		}
1302		/* fall through */
1303
1304	case AUE_SEMUNLINK:
1305		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1306			tok = au_to_text(ar->ar_arg_text);
1307			kau_write(rec, tok);
1308		}
1309		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1310		/* Create an ipc_perm token */
1311			struct ipc_perm perm;
1312			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1313			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1314			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1315			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1316			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1317			perm.seq = 0;
1318			perm.key = 0;
1319			tok = au_to_ipc_perm(&perm);
1320			kau_write(rec, tok);
1321		}
1322		break;
1323
1324	case AUE_SEMCLOSE:
1325		if (ARG_IS_VALID(kar, ARG_FD)) {
1326			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1327			kau_write(rec, tok);
1328		}
1329		break;
1330
1331	case AUE_SYMLINK:
1332		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1333			tok = au_to_text(ar->ar_arg_text);
1334			kau_write(rec, tok);
1335		}
1336		UPATH1_VNODE1_TOKENS;
1337		break;
1338
1339	case AUE_SYSCTL:
1340		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1341			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1342				tok = au_to_arg32(1, "name",
1343				    ar->ar_arg_ctlname[ctr]);
1344				kau_write(rec, tok);
1345			}
1346		}
1347		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1348			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1349			kau_write(rec, tok);
1350		}
1351		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1352			tok = au_to_text(ar->ar_arg_text);
1353			kau_write(rec, tok);
1354		}
1355		break;
1356
1357	case AUE_UMASK:
1358		if (ARG_IS_VALID(kar, ARG_MASK)) {
1359			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1360			kau_write(rec, tok);
1361		}
1362		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1363		kau_write(rec, tok);
1364		break;
1365
1366	case AUE_WAIT4:
1367		if (ARG_IS_VALID(kar, ARG_PID)) {
1368			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1369			kau_write(rec, tok);
1370		}
1371		break;
1372
1373	case AUE_NULL:
1374	default:
1375		printf("BSM conversion requested for unknown event %d\n",
1376		    ar->ar_event);
1377		/* Write the subject token so it is properly freed here. */
1378		kau_write(rec, subj_tok);
1379		kau_free(rec);
1380		return (BSM_NOAUDIT);
1381	}
1382
1383	kau_write(rec, subj_tok);
1384	tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
1385	kau_write(rec, tok);  /* Every record gets a return token */
1386
1387	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1388
1389	*pau = rec;
1390	return (BSM_SUCCESS);
1391}
1392
1393/*
1394 * Verify that a record is a valid BSM record. This verification is simple
1395 * now, but may be expanded on sometime in the future.  Return 1 if the
1396 * record is good, 0 otherwise.
1397 */
1398int
1399bsm_rec_verify(void *rec)
1400{
1401	char c = *(char *)rec;
1402
1403	/*
1404	 * Check the token ID of the first token; it has to be a header
1405	 * token.
1406	 *
1407	 * XXXAUDIT There needs to be a token structure to map a token.
1408	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1409	 */
1410	if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) &&
1411	    (c != AUT_HEADER64) && (c != AUT_HEADER64_EX))
1412		return (0);
1413	return (1);
1414}
1415