audit_bsm.c revision 155192
1155192Srwatson/*
2155192Srwatson * Copyright (c) 1999-2005 Apple Computer, 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.
13155192Srwatson * 3.  Neither the name of Apple Computer, 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 * $FreeBSD: head/sys/security/audit/audit_bsm.c 155192 2006-02-01 20:01:18Z rwatson $
30155192Srwatson */
31155192Srwatson
32155192Srwatson#include <sys/param.h>
33155192Srwatson#include <sys/vnode.h>
34155192Srwatson#include <sys/ipc.h>
35155192Srwatson#include <sys/lock.h>
36155192Srwatson#include <sys/malloc.h>
37155192Srwatson#include <sys/mutex.h>
38155192Srwatson#include <sys/socket.h>
39155192Srwatson#include <sys/fcntl.h>
40155192Srwatson#include <sys/user.h>
41155192Srwatson#include <sys/systm.h>
42155192Srwatson
43155192Srwatson#include <bsm/audit.h>
44155192Srwatson#include <bsm/audit_internal.h>
45155192Srwatson#include <bsm/audit_record.h>
46155192Srwatson#include <bsm/audit_kevents.h>
47155192Srwatson
48155192Srwatson#include <security/audit/audit.h>
49155192Srwatson#include <security/audit/audit_private.h>
50155192Srwatson
51155192Srwatson#include <netinet/in_systm.h>
52155192Srwatson#include <netinet/in.h>
53155192Srwatson#include <netinet/ip.h>
54155192Srwatson
55155192SrwatsonMALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
56155192Srwatson
57155192Srwatson/*
58155192Srwatson * Forward declares.
59155192Srwatson */
60155192Srwatsonstatic void	audit_sys_auditon(struct audit_record *ar,
61155192Srwatson		    struct au_record *rec);
62155192Srwatson
63155192Srwatson/*
64155192Srwatson * Initialize the BSM auditing subsystem.
65155192Srwatson */
66155192Srwatsonvoid
67155192Srwatsonkau_init(void)
68155192Srwatson{
69155192Srwatson
70155192Srwatson	printf("BSM auditing present\n");
71155192Srwatson	au_evclassmap_init();
72155192Srwatson}
73155192Srwatson
74155192Srwatson/*
75155192Srwatson * This call reserves memory for the audit record.
76155192Srwatson * Memory must be guaranteed before any auditable event can be
77155192Srwatson * generated.
78155192Srwatson * The au_record structure maintains a reference to the
79155192Srwatson * memory allocated above and also the list of tokens associated
80155192Srwatson * with this record
81155192Srwatson */
82155192Srwatsonstatic struct au_record *
83155192Srwatsonkau_open(void)
84155192Srwatson{
85155192Srwatson	struct au_record *rec;
86155192Srwatson
87155192Srwatson	rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK);
88155192Srwatson	rec->data = malloc(MAX_AUDIT_RECORD_SIZE * sizeof(u_char),
89155192Srwatson	    M_AUDITBSM, M_WAITOK | M_ZERO);
90155192Srwatson	TAILQ_INIT(&rec->token_q);
91155192Srwatson	rec->len = 0;
92155192Srwatson	rec->used = 1;
93155192Srwatson
94155192Srwatson	return (rec);
95155192Srwatson}
96155192Srwatson
97155192Srwatson/*
98155192Srwatson * Store the token with the record descriptor.
99155192Srwatson */
100155192Srwatsonstatic void
101155192Srwatsonkau_write(struct au_record *rec, struct au_token *tok)
102155192Srwatson{
103155192Srwatson
104155192Srwatson	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
105155192Srwatson
106155192Srwatson	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
107155192Srwatson	rec->len += tok->len;
108155192Srwatson}
109155192Srwatson
110155192Srwatson/*
111155192Srwatson * Close out the audit record by adding the header token, identifying any
112155192Srwatson * missing tokens.  Write out the tokens to the record memory.
113155192Srwatson */
114155192Srwatsonstatic void
115155192Srwatsonkau_close(struct au_record *rec, struct timespec *ctime, short event)
116155192Srwatson{
117155192Srwatson	u_char *dptr;
118155192Srwatson	size_t tot_rec_size;
119155192Srwatson	token_t *cur, *hdr, *trail;
120155192Srwatson	struct timeval tm;
121155192Srwatson
122155192Srwatson	tot_rec_size = rec->len + BSM_HEADER_SIZE + BSM_TRAILER_SIZE;
123155192Srwatson	if (tot_rec_size <= MAX_AUDIT_RECORD_SIZE) {
124155192Srwatson		/* Create the header token */
125155192Srwatson		tm.tv_usec = ctime->tv_nsec / 1000;
126155192Srwatson		tm.tv_sec = ctime->tv_sec;
127155192Srwatson		hdr = au_to_header32(tot_rec_size, event, 0, tm);
128155192Srwatson		TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
129155192Srwatson
130155192Srwatson		trail = au_to_trailer(tot_rec_size);
131155192Srwatson		TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
132155192Srwatson
133155192Srwatson		/* Serialize token data to the record. */
134155192Srwatson
135155192Srwatson		rec->len = tot_rec_size;
136155192Srwatson		dptr = rec->data;
137155192Srwatson		TAILQ_FOREACH(cur, &rec->token_q, tokens) {
138155192Srwatson			memcpy(dptr, cur->t_data, cur->len);
139155192Srwatson			dptr += cur->len;
140155192Srwatson		}
141155192Srwatson	}
142155192Srwatson}
143155192Srwatson
144155192Srwatson/*
145155192Srwatson * Free a BSM audit record by releasing all the tokens and clearing the
146155192Srwatson * audit record information.
147155192Srwatson */
148155192Srwatsonvoid
149155192Srwatsonkau_free(struct au_record *rec)
150155192Srwatson{
151155192Srwatson	struct au_token *tok;
152155192Srwatson
153155192Srwatson	/* Free the token list */
154155192Srwatson	while ((tok = TAILQ_FIRST(&rec->token_q))) {
155155192Srwatson		TAILQ_REMOVE(&rec->token_q, tok, tokens);
156155192Srwatson		free(tok->t_data, M_AUDITBSM);
157155192Srwatson		free(tok, M_AUDITBSM);
158155192Srwatson	}
159155192Srwatson
160155192Srwatson	rec->used = 0;
161155192Srwatson	rec->len = 0;
162155192Srwatson	free(rec->data, M_AUDITBSM);
163155192Srwatson	free(rec, M_AUDITBSM);
164155192Srwatson}
165155192Srwatson
166155192Srwatson/*
167155192Srwatson * XXX May want turn some (or all) of these macros into functions in order
168155192Srwatson * to reduce the generated code sized.
169155192Srwatson *
170155192Srwatson * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
171155192Srwatson * caller are OK with this.
172155192Srwatson */
173155192Srwatson#define UPATH1_TOKENS do {						\
174155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
175155192Srwatson		tok = au_to_path(ar->ar_arg_upath1);			\
176155192Srwatson		kau_write(rec, tok);					\
177155192Srwatson	}								\
178155192Srwatson} while (0)
179155192Srwatson
180155192Srwatson#define UPATH2_TOKENS do {						\
181155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
182155192Srwatson		tok = au_to_path(ar->ar_arg_upath2);			\
183155192Srwatson		kau_write(rec, tok);					\
184155192Srwatson	}								\
185155192Srwatson} while (0)
186155192Srwatson
187155192Srwatson#define VNODE1_TOKENS do {						\
188155192Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
189155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
190155192Srwatson		kau_write(rec, tok);					\
191155192Srwatson	}								\
192155192Srwatson} while (0)
193155192Srwatson
194155192Srwatson#define UPATH1_VNODE1_TOKENS do {					\
195155192Srwatson	if (ARG_IS_VALID(kar, ARG_UPATH1)) {  				\
196155192Srwatson		UPATH1_TOKENS;						\
197155192Srwatson	}								\
198155192Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
199155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
200155192Srwatson		kau_write(rec, tok);					\
201155192Srwatson	}								\
202155192Srwatson} while (0)
203155192Srwatson
204155192Srwatson#define VNODE2_TOKENS do {						\
205155192Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE2)) {  				\
206155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
207155192Srwatson		kau_write(rec, tok);					\
208155192Srwatson	}								\
209155192Srwatson} while (0)
210155192Srwatson
211155192Srwatson#define FD_VNODE1_TOKENS	do {					\
212155192Srwatson	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
213155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {			\
214155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
215155192Srwatson			kau_write(rec, tok);				\
216155192Srwatson		}							\
217155192Srwatson		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
218155192Srwatson		kau_write(rec, tok);					\
219155192Srwatson	} else {							\
220155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {			\
221155192Srwatson			tok = au_to_arg32(1, "non-file: fd", ar->ar_arg_fd);\
222155192Srwatson			kau_write(rec, tok);				\
223155192Srwatson		}							\
224155192Srwatson	}								\
225155192Srwatson} while (0)
226155192Srwatson
227155192Srwatson#define PROCESS_PID_TOKENS(argn) do {					\
228155192Srwatson	if (ARG_IS_VALID(kar, ARG_PID)) {				\
229155192Srwatson		if ((ar->ar_arg_pid > 0) /* Kill a single process */	\
230155192Srwatson		    && (ARG_IS_VALID(kar, ARG_PROCESS))) {		\
231155192Srwatson			tok = au_to_process(ar->ar_arg_auid,		\
232155192Srwatson			    ar->ar_arg_euid, ar->ar_arg_egid,		\
233155192Srwatson			    ar->ar_arg_ruid, ar->ar_arg_rgid,		\
234155192Srwatson			    ar->ar_arg_pid, ar->ar_arg_asid,		\
235155192Srwatson			    &ar->ar_arg_termid);			\
236155192Srwatson			kau_write(rec, tok);				\
237155192Srwatson		} else {						\
238155192Srwatson			tok = au_to_arg32(argn, "process",		\
239155192Srwatson			    ar->ar_arg_pid);				\
240155192Srwatson			kau_write(rec, tok);				\
241155192Srwatson		}							\
242155192Srwatson	}								\
243155192Srwatson} while (0)								\
244155192Srwatson
245155192Srwatson/*
246155192Srwatson * Implement auditing for the auditon() system call. The audit tokens that
247155192Srwatson * are generated depend on the command that was sent into the auditon()
248155192Srwatson * system call.
249155192Srwatson */
250155192Srwatsonstatic void
251155192Srwatsonaudit_sys_auditon(struct audit_record *ar, struct au_record *rec)
252155192Srwatson{
253155192Srwatson	struct au_token *tok;
254155192Srwatson
255155192Srwatson	switch (ar->ar_arg_cmd) {
256155192Srwatson        case A_SETPOLICY:
257155192Srwatson		if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
258155192Srwatson			tok = au_to_arg64(1, "policy",
259155192Srwatson				ar->ar_arg_auditon.au_flags);
260155192Srwatson		else
261155192Srwatson			tok = au_to_arg32(1, "policy",
262155192Srwatson				ar->ar_arg_auditon.au_flags);
263155192Srwatson		kau_write(rec, tok);
264155192Srwatson		break;
265155192Srwatson
266155192Srwatson        case A_SETKMASK:
267155192Srwatson		tok = au_to_arg32(2, "setkmask:as_success",
268155192Srwatson			ar->ar_arg_auditon.au_mask.am_success);
269155192Srwatson		kau_write(rec, tok);
270155192Srwatson		tok = au_to_arg32(2, "setkmask:as_failure",
271155192Srwatson			ar->ar_arg_auditon.au_mask.am_failure);
272155192Srwatson		kau_write(rec, tok);
273155192Srwatson		break;
274155192Srwatson
275155192Srwatson        case A_SETQCTRL:
276155192Srwatson		tok = au_to_arg32(3, "setqctrl:aq_hiwater",
277155192Srwatson			ar->ar_arg_auditon.au_qctrl.aq_hiwater);
278155192Srwatson		kau_write(rec, tok);
279155192Srwatson		tok = au_to_arg32(3, "setqctrl:aq_lowater",
280155192Srwatson			ar->ar_arg_auditon.au_qctrl.aq_lowater);
281155192Srwatson		kau_write(rec, tok);
282155192Srwatson		tok = au_to_arg32(3, "setqctrl:aq_bufsz",
283155192Srwatson			ar->ar_arg_auditon.au_qctrl.aq_bufsz);
284155192Srwatson		kau_write(rec, tok);
285155192Srwatson		tok = au_to_arg32(3, "setqctrl:aq_delay",
286155192Srwatson			ar->ar_arg_auditon.au_qctrl.aq_delay);
287155192Srwatson		kau_write(rec, tok);
288155192Srwatson		tok = au_to_arg32(3, "setqctrl:aq_minfree",
289155192Srwatson			ar->ar_arg_auditon.au_qctrl.aq_minfree);
290155192Srwatson		kau_write(rec, tok);
291155192Srwatson		break;
292155192Srwatson
293155192Srwatson        case A_SETUMASK:
294155192Srwatson		tok = au_to_arg32(3, "setumask:as_success",
295155192Srwatson			ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
296155192Srwatson		kau_write(rec, tok);
297155192Srwatson		tok = au_to_arg32(3, "setumask:as_failure",
298155192Srwatson			ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
299155192Srwatson		kau_write(rec, tok);
300155192Srwatson		break;
301155192Srwatson
302155192Srwatson        case A_SETSMASK:
303155192Srwatson		tok = au_to_arg32(3, "setsmask:as_success",
304155192Srwatson			ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
305155192Srwatson		kau_write(rec, tok);
306155192Srwatson		tok = au_to_arg32(3, "setsmask:as_failure",
307155192Srwatson			ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
308155192Srwatson		kau_write(rec, tok);
309155192Srwatson		break;
310155192Srwatson
311155192Srwatson        case A_SETCOND:
312155192Srwatson		if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
313155192Srwatson			tok = au_to_arg64(3, "setcond",
314155192Srwatson				ar->ar_arg_auditon.au_cond);
315155192Srwatson		else
316155192Srwatson			tok = au_to_arg32(3, "setcond",
317155192Srwatson				ar->ar_arg_auditon.au_cond);
318155192Srwatson		kau_write(rec, tok);
319155192Srwatson		break;
320155192Srwatson
321155192Srwatson        case A_SETCLASS:
322155192Srwatson		tok = au_to_arg32(2, "setclass:ec_event",
323155192Srwatson			ar->ar_arg_auditon.au_evclass.ec_number);
324155192Srwatson		kau_write(rec, tok);
325155192Srwatson		tok = au_to_arg32(3, "setclass:ec_class",
326155192Srwatson			ar->ar_arg_auditon.au_evclass.ec_class);
327155192Srwatson		kau_write(rec, tok);
328155192Srwatson		break;
329155192Srwatson
330155192Srwatson        case A_SETPMASK:
331155192Srwatson		tok = au_to_arg32(2, "setpmask:as_success",
332155192Srwatson			ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
333155192Srwatson		kau_write(rec, tok);
334155192Srwatson		tok = au_to_arg32(2, "setpmask:as_failure",
335155192Srwatson			ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
336155192Srwatson		kau_write(rec, tok);
337155192Srwatson		break;
338155192Srwatson
339155192Srwatson        case A_SETFSIZE:
340155192Srwatson		tok = au_to_arg32(2, "setfsize:filesize",
341155192Srwatson			ar->ar_arg_auditon.au_fstat.af_filesz);
342155192Srwatson		kau_write(rec, tok);
343155192Srwatson		break;
344155192Srwatson
345155192Srwatson	default:
346155192Srwatson		break;
347155192Srwatson	}
348155192Srwatson}
349155192Srwatson
350155192Srwatson/*
351155192Srwatson * Convert an internal kernel audit record to a BSM record and return
352155192Srwatson * a success/failure indicator. The BSM record is passed as an out
353155192Srwatson * parameter to this function.
354155192Srwatson * Return conditions:
355155192Srwatson *   BSM_SUCCESS: The BSM record is valid
356155192Srwatson *   BSM_FAILURE: Failure; the BSM record is NULL.
357155192Srwatson *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
358155192Srwatson */
359155192Srwatsonint
360155192Srwatsonkaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
361155192Srwatson{
362155192Srwatson	struct au_token *tok, *subj_tok;
363155192Srwatson	struct au_record *rec;
364155192Srwatson	au_tid_t tid;
365155192Srwatson	struct audit_record *ar;
366155192Srwatson	int ctr;
367155192Srwatson
368155192Srwatson	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
369155192Srwatson
370155192Srwatson	*pau = NULL;
371155192Srwatson	ar = &kar->k_ar;
372155192Srwatson	rec = kau_open();
373155192Srwatson
374155192Srwatson	/* Create the subject token */
375155192Srwatson	tid.port = ar->ar_subj_term.port;
376155192Srwatson	tid.machine = ar->ar_subj_term.machine;
377155192Srwatson	subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
378155192Srwatson		ar->ar_subj_cred.cr_uid, /* eff uid */
379155192Srwatson		ar->ar_subj_egid,	/* eff group id */
380155192Srwatson		ar->ar_subj_ruid, 	/* real uid */
381155192Srwatson		ar->ar_subj_rgid, 	/* real group id */
382155192Srwatson		ar->ar_subj_pid,	/* process id */
383155192Srwatson		ar->ar_subj_asid,	/* session ID */
384155192Srwatson		&tid);
385155192Srwatson
386155192Srwatson	/* The logic inside each case fills in the tokens required for the
387155192Srwatson	 * event, except for the header, trailer, and return tokens. The
388155192Srwatson	 * header and trailer tokens are added by the kau_close() function.
389155192Srwatson	 * The return token is added outside of the switch statement.
390155192Srwatson	 */
391155192Srwatson	switch(ar->ar_event) {
392155192Srwatson
393155192Srwatson	/*
394155192Srwatson	 * Socket-related events.
395155192Srwatson	 */
396155192Srwatson	case AUE_ACCEPT:
397155192Srwatson	case AUE_BIND:
398155192Srwatson	case AUE_CONNECT:
399155192Srwatson	case AUE_RECVFROM:
400155192Srwatson	case AUE_RECVMSG:
401155192Srwatson	case AUE_SENDMSG:
402155192Srwatson	case AUE_SENDTO:
403155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
404155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
405155192Srwatson			kau_write(rec, tok);
406155192Srwatson		}
407155192Srwatson		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
408155192Srwatson			tok = au_to_sock_inet(
409155192Srwatson				(struct sockaddr_in *)&ar->ar_arg_sockaddr);
410155192Srwatson			kau_write(rec, tok);
411155192Srwatson		}
412155192Srwatson		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
413155192Srwatson			tok = au_to_sock_unix(
414155192Srwatson				(struct sockaddr_un *)&ar->ar_arg_sockaddr);
415155192Srwatson			kau_write(rec, tok);
416155192Srwatson			UPATH1_TOKENS;
417155192Srwatson		}
418155192Srwatson		/* XXX Need to handle ARG_SADDRINET6 */
419155192Srwatson		break;
420155192Srwatson
421155192Srwatson	case AUE_SOCKET:
422155192Srwatson	case AUE_SOCKETPAIR:
423155192Srwatson		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
424155192Srwatson			tok = au_to_arg32(1,"domain",
425155192Srwatson			    ar->ar_arg_sockinfo.so_domain);
426155192Srwatson			kau_write(rec, tok);
427155192Srwatson			tok = au_to_arg32(2,"type",
428155192Srwatson			    ar->ar_arg_sockinfo.so_type);
429155192Srwatson			kau_write(rec, tok);
430155192Srwatson			tok = au_to_arg32(3,"protocol",
431155192Srwatson			    ar->ar_arg_sockinfo.so_protocol);
432155192Srwatson			kau_write(rec, tok);
433155192Srwatson		}
434155192Srwatson		break;
435155192Srwatson
436155192Srwatson	case AUE_SETSOCKOPT:
437155192Srwatson	case AUE_SHUTDOWN:
438155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
439155192Srwatson			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
440155192Srwatson			kau_write(rec, tok);
441155192Srwatson		}
442155192Srwatson		break;
443155192Srwatson
444155192Srwatson	case AUE_ACCT:
445155192Srwatson		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
446155192Srwatson			UPATH1_VNODE1_TOKENS;
447155192Srwatson		} else {
448155192Srwatson			tok = au_to_arg32(1, "accounting off", 0);
449155192Srwatson			kau_write(rec, tok);
450155192Srwatson		}
451155192Srwatson		break;
452155192Srwatson
453155192Srwatson	case AUE_SETAUID:
454155192Srwatson		if (ARG_IS_VALID(kar, ARG_AUID)) {
455155192Srwatson			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
456155192Srwatson			kau_write(rec, tok);
457155192Srwatson		}
458155192Srwatson		break;
459155192Srwatson
460155192Srwatson	case AUE_SETAUDIT:
461155192Srwatson		if (ARG_IS_VALID(kar, ARG_AUID)) {
462155192Srwatson			tok = au_to_arg32(1, "setaudit:auid", ar->ar_arg_auid);
463155192Srwatson			kau_write(rec, tok);
464155192Srwatson			tok = au_to_arg32(1, "setaudit:port",
465155192Srwatson					ar->ar_arg_termid.port);
466155192Srwatson			kau_write(rec, tok);
467155192Srwatson			tok = au_to_arg32(1, "setaudit:machine",
468155192Srwatson					ar->ar_arg_termid.machine);
469155192Srwatson			kau_write(rec, tok);
470155192Srwatson			tok = au_to_arg32(1, "setaudit:as_success",
471155192Srwatson					ar->ar_arg_amask.am_success);
472155192Srwatson			kau_write(rec, tok);
473155192Srwatson			tok = au_to_arg32(1, "setaudit:as_failure",
474155192Srwatson					ar->ar_arg_amask.am_failure);
475155192Srwatson			kau_write(rec, tok);
476155192Srwatson			tok = au_to_arg32(1, "setaudit:asid", ar->ar_arg_asid);
477155192Srwatson			kau_write(rec, tok);
478155192Srwatson		}
479155192Srwatson		break;
480155192Srwatson
481155192Srwatson	case AUE_SETAUDIT_ADDR:
482155192Srwatson		break;		/* XXX need to add arguments */
483155192Srwatson
484155192Srwatson	case AUE_AUDITON:
485155192Srwatson		/* For AUDITON commands without own event, audit the cmd */
486155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
487155192Srwatson			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
488155192Srwatson			kau_write(rec, tok);
489155192Srwatson		}
490155192Srwatson		/* fall thru */
491155192Srwatson
492155192Srwatson	case AUE_AUDITON_GETCAR:
493155192Srwatson	case AUE_AUDITON_GETCLASS:
494155192Srwatson	case AUE_AUDITON_GETCOND:
495155192Srwatson	case AUE_AUDITON_GETCWD:
496155192Srwatson	case AUE_AUDITON_GETKMASK:
497155192Srwatson	case AUE_AUDITON_GETSTAT:
498155192Srwatson	case AUE_AUDITON_GPOLICY:
499155192Srwatson	case AUE_AUDITON_GQCTRL:
500155192Srwatson	case AUE_AUDITON_SETCLASS:
501155192Srwatson	case AUE_AUDITON_SETCOND:
502155192Srwatson	case AUE_AUDITON_SETKMASK:
503155192Srwatson	case AUE_AUDITON_SETSMASK:
504155192Srwatson	case AUE_AUDITON_SETSTAT:
505155192Srwatson	case AUE_AUDITON_SETUMASK:
506155192Srwatson	case AUE_AUDITON_SPOLICY:
507155192Srwatson	case AUE_AUDITON_SQCTRL:
508155192Srwatson		if (ARG_IS_VALID(kar, ARG_AUDITON)) {
509155192Srwatson			audit_sys_auditon(ar, rec);
510155192Srwatson		}
511155192Srwatson		break;
512155192Srwatson
513155192Srwatson	case AUE_AUDITCTL:
514155192Srwatson		UPATH1_VNODE1_TOKENS;
515155192Srwatson		break;
516155192Srwatson
517155192Srwatson	case AUE_EXIT:
518155192Srwatson		if (ARG_IS_VALID(kar, ARG_EXIT)) {
519155192Srwatson			tok = au_to_exit(ar->ar_arg_exitretval,
520155192Srwatson			    ar->ar_arg_exitstatus);
521155192Srwatson			kau_write(rec, tok);
522155192Srwatson		}
523155192Srwatson		break;
524155192Srwatson
525155192Srwatson	case AUE_ADJTIME:
526155192Srwatson	case AUE_AUDIT:
527155192Srwatson	case AUE_GETAUDIT:
528155192Srwatson	case AUE_GETAUDIT_ADDR:
529155192Srwatson	case AUE_GETAUID:
530155192Srwatson	case AUE_GETFSSTAT:
531155192Srwatson	case AUE_PIPE:
532155192Srwatson	case AUE_SETPGRP:
533155192Srwatson	case AUE_SETRLIMIT:
534155192Srwatson	case AUE_SETSID:
535155192Srwatson	case AUE_SETTIMEOFDAY:
536155192Srwatson	case AUE_NEWSYSTEMSHREG:
537155192Srwatson		/* Header, subject, and return tokens added at end */
538155192Srwatson		break;
539155192Srwatson
540155192Srwatson	case AUE_ACCESS:
541155192Srwatson	case AUE_CHDIR:
542155192Srwatson	case AUE_CHROOT:
543155192Srwatson	case AUE_EXECVE:
544155192Srwatson	case AUE_GETATTRLIST:
545155192Srwatson	case AUE_NFS_GETFH:
546155192Srwatson	case AUE_LSTAT:
547155192Srwatson	case AUE_MKFIFO:
548155192Srwatson	case AUE_PATHCONF:
549155192Srwatson	case AUE_READLINK:
550155192Srwatson	case AUE_REVOKE:
551155192Srwatson	case AUE_RMDIR:
552155192Srwatson	case AUE_SEARCHFS:
553155192Srwatson	case AUE_SETATTRLIST:
554155192Srwatson	case AUE_STAT:
555155192Srwatson	case AUE_STATFS:
556155192Srwatson	case AUE_TRUNCATE:
557155192Srwatson	case AUE_UNDELETE:
558155192Srwatson	case AUE_UNLINK:
559155192Srwatson	case AUE_UTIMES:
560155192Srwatson		UPATH1_VNODE1_TOKENS;
561155192Srwatson		break;
562155192Srwatson
563155192Srwatson	case AUE_CHFLAGS:
564155192Srwatson	case AUE_LCHFLAGS:
565155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
566155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
567155192Srwatson			kau_write(rec, tok);
568155192Srwatson		}
569155192Srwatson		UPATH1_VNODE1_TOKENS;
570155192Srwatson		break;
571155192Srwatson
572155192Srwatson	case AUE_CHMOD:
573155192Srwatson	case AUE_LCHMOD:
574155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
575155192Srwatson			tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
576155192Srwatson			kau_write(rec, tok);
577155192Srwatson		}
578155192Srwatson		UPATH1_VNODE1_TOKENS;
579155192Srwatson		break;
580155192Srwatson
581155192Srwatson	case AUE_CHOWN:
582155192Srwatson	case AUE_LCHOWN:
583155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
584155192Srwatson			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
585155192Srwatson			kau_write(rec, tok);
586155192Srwatson		}
587155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
588155192Srwatson			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
589155192Srwatson			kau_write(rec, tok);
590155192Srwatson		}
591155192Srwatson		UPATH1_VNODE1_TOKENS;
592155192Srwatson		break;
593155192Srwatson
594155192Srwatson	case AUE_EXCHANGEDATA:
595155192Srwatson		UPATH1_VNODE1_TOKENS;
596155192Srwatson		UPATH2_TOKENS;
597155192Srwatson		break;
598155192Srwatson
599155192Srwatson	case AUE_CLOSE:
600155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
601155192Srwatson			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
602155192Srwatson			kau_write(rec, tok);
603155192Srwatson		}
604155192Srwatson		UPATH1_VNODE1_TOKENS;
605155192Srwatson		break;
606155192Srwatson
607155192Srwatson	case AUE_FCHMOD:
608155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
609155192Srwatson			tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
610155192Srwatson			kau_write(rec, tok);
611155192Srwatson		}
612155192Srwatson		FD_VNODE1_TOKENS;
613155192Srwatson		break;
614155192Srwatson
615155192Srwatson	case AUE_FCHDIR:
616155192Srwatson	case AUE_FPATHCONF:
617155192Srwatson	case AUE_FSTAT:		/* XXX Need to handle sockets and shm */
618155192Srwatson	case AUE_FSTATFS:
619155192Srwatson	case AUE_FSYNC:
620155192Srwatson	case AUE_FTRUNCATE:
621155192Srwatson	case AUE_FUTIMES:
622155192Srwatson	case AUE_GETDIRENTRIES:
623155192Srwatson	case AUE_GETDIRENTRIESATTR:
624155192Srwatson		FD_VNODE1_TOKENS;
625155192Srwatson		break;
626155192Srwatson
627155192Srwatson	case AUE_FCHOWN:
628155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
629155192Srwatson			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
630155192Srwatson			kau_write(rec, tok);
631155192Srwatson		}
632155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
633155192Srwatson			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
634155192Srwatson			kau_write(rec, tok);
635155192Srwatson		}
636155192Srwatson		FD_VNODE1_TOKENS;
637155192Srwatson		break;
638155192Srwatson
639155192Srwatson	case AUE_FCNTL:
640155192Srwatson		if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
641155192Srwatson			ar->ar_arg_cmd == F_SETLKW) {
642155192Srwatson			if (ARG_IS_VALID(kar, ARG_CMD)) {
643155192Srwatson				tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
644155192Srwatson				kau_write(rec, tok);
645155192Srwatson			}
646155192Srwatson			FD_VNODE1_TOKENS;
647155192Srwatson		}
648155192Srwatson		break;
649155192Srwatson
650155192Srwatson	case AUE_FCHFLAGS:
651155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
652155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
653155192Srwatson			kau_write(rec, tok);
654155192Srwatson		}
655155192Srwatson		FD_VNODE1_TOKENS;
656155192Srwatson		break;
657155192Srwatson
658155192Srwatson	case AUE_FLOCK:
659155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
660155192Srwatson			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
661155192Srwatson			kau_write(rec, tok);
662155192Srwatson		}
663155192Srwatson		FD_VNODE1_TOKENS;
664155192Srwatson		break;
665155192Srwatson
666155192Srwatson	case AUE_RFORK:
667155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
668155192Srwatson			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
669155192Srwatson			kau_write(rec, tok);
670155192Srwatson		}
671155192Srwatson		/* fall through */
672155192Srwatson	case AUE_FORK:
673155192Srwatson	case AUE_VFORK:
674155192Srwatson		if (ARG_IS_VALID(kar, ARG_PID)) {
675155192Srwatson			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
676155192Srwatson			kau_write(rec, tok);
677155192Srwatson		}
678155192Srwatson		break;
679155192Srwatson
680155192Srwatson	case AUE_IOCTL:
681155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
682155192Srwatson			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
683155192Srwatson			kau_write(rec, tok);
684155192Srwatson		}
685155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
686155192Srwatson			tok = au_to_arg32(1, "arg", (u_int32_t)ar->ar_arg_addr);
687155192Srwatson			kau_write(rec, tok);
688155192Srwatson		}
689155192Srwatson		if (ARG_IS_VALID(kar, ARG_VNODE1)) {
690155192Srwatson			FD_VNODE1_TOKENS;
691155192Srwatson		} else {
692155192Srwatson			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
693155192Srwatson				tok = kau_to_socket(&ar->ar_arg_sockinfo);
694155192Srwatson				kau_write(rec, tok);
695155192Srwatson			} else {
696155192Srwatson				if (ARG_IS_VALID(kar, ARG_FD)) {
697155192Srwatson					tok = au_to_arg32(1, "fd",
698155192Srwatson					    ar->ar_arg_fd);
699155192Srwatson			    		kau_write(rec, tok);
700155192Srwatson				}
701155192Srwatson			}
702155192Srwatson		}
703155192Srwatson		break;
704155192Srwatson
705155192Srwatson	case AUE_KILL:
706155192Srwatson		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
707155192Srwatson			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
708155192Srwatson			kau_write(rec, tok);
709155192Srwatson		}
710155192Srwatson		PROCESS_PID_TOKENS(1);
711155192Srwatson		break;
712155192Srwatson
713155192Srwatson	case AUE_KTRACE:
714155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
715155192Srwatson			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
716155192Srwatson			kau_write(rec, tok);
717155192Srwatson		}
718155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
719155192Srwatson			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
720155192Srwatson			kau_write(rec, tok);
721155192Srwatson		}
722155192Srwatson		PROCESS_PID_TOKENS(4);
723155192Srwatson		UPATH1_VNODE1_TOKENS;
724155192Srwatson		break;
725155192Srwatson
726155192Srwatson	case AUE_LINK:
727155192Srwatson	case AUE_RENAME:
728155192Srwatson		UPATH1_VNODE1_TOKENS;
729155192Srwatson		UPATH2_TOKENS;
730155192Srwatson		break;
731155192Srwatson
732155192Srwatson	case AUE_LOADSHFILE:
733155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
734155192Srwatson			tok = au_to_arg32(4, "base addr",
735155192Srwatson			    (u_int32_t)ar->ar_arg_addr);
736155192Srwatson			kau_write(rec, tok);
737155192Srwatson		}
738155192Srwatson		UPATH1_VNODE1_TOKENS;
739155192Srwatson		break;
740155192Srwatson
741155192Srwatson	case AUE_MKDIR:
742155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
743155192Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
744155192Srwatson			kau_write(rec, tok);
745155192Srwatson		}
746155192Srwatson		UPATH1_VNODE1_TOKENS;
747155192Srwatson		break;
748155192Srwatson
749155192Srwatson	case AUE_MKNOD:
750155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
751155192Srwatson			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
752155192Srwatson			kau_write(rec, tok);
753155192Srwatson		}
754155192Srwatson		if (ARG_IS_VALID(kar, ARG_DEV)) {
755155192Srwatson			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
756155192Srwatson			kau_write(rec, tok);
757155192Srwatson		}
758155192Srwatson		UPATH1_VNODE1_TOKENS;
759155192Srwatson		break;
760155192Srwatson
761155192Srwatson	case AUE_MMAP:
762155192Srwatson	case AUE_MUNMAP:
763155192Srwatson	case AUE_MPROTECT:
764155192Srwatson	case AUE_MLOCK:
765155192Srwatson	case AUE_MUNLOCK:
766155192Srwatson	case AUE_MINHERIT:
767155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
768155192Srwatson			tok = au_to_arg32(1, "addr",
769155192Srwatson			    (u_int32_t)ar->ar_arg_addr);
770155192Srwatson			kau_write(rec, tok);
771155192Srwatson		}
772155192Srwatson		if (ARG_IS_VALID(kar, ARG_LEN)) {
773155192Srwatson			tok = au_to_arg32(2, "len", ar->ar_arg_len);
774155192Srwatson			kau_write(rec, tok);
775155192Srwatson		}
776155192Srwatson		if (ar->ar_event == AUE_MMAP)
777155192Srwatson			FD_VNODE1_TOKENS;
778155192Srwatson		if (ar->ar_event == AUE_MPROTECT) {
779155192Srwatson			if (ARG_IS_VALID(kar, ARG_VALUE)) {
780155192Srwatson				tok = au_to_arg32(3, "protection",
781155192Srwatson				    ar->ar_arg_value);
782155192Srwatson				kau_write(rec, tok);
783155192Srwatson			}
784155192Srwatson		}
785155192Srwatson		if (ar->ar_event == AUE_MINHERIT) {
786155192Srwatson			if (ARG_IS_VALID(kar, ARG_VALUE)) {
787155192Srwatson				tok = au_to_arg32(3, "inherit",
788155192Srwatson				    ar->ar_arg_value);
789155192Srwatson				kau_write(rec, tok);
790155192Srwatson			}
791155192Srwatson		}
792155192Srwatson		break;
793155192Srwatson
794155192Srwatson	case AUE_MOUNT:
795155192Srwatson		/* XXX Need to handle NFS mounts */
796155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
797155192Srwatson			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
798155192Srwatson			kau_write(rec, tok);
799155192Srwatson		}
800155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
801155192Srwatson			tok = au_to_text(ar->ar_arg_text);
802155192Srwatson			kau_write(rec, tok);
803155192Srwatson		}
804155192Srwatson		/* fall through */
805155192Srwatson	case AUE_UMOUNT:
806155192Srwatson		UPATH1_VNODE1_TOKENS;
807155192Srwatson		break;
808155192Srwatson
809155192Srwatson	case AUE_MSGCTL:
810155192Srwatson		ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd);
811155192Srwatson		/* Fall through */
812155192Srwatson	case AUE_MSGRCV:
813155192Srwatson	case AUE_MSGSND:
814155192Srwatson		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
815155192Srwatson		kau_write(rec, tok);
816155192Srwatson		if (ar->ar_errno != EINVAL) {
817155192Srwatson			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
818155192Srwatson			kau_write(rec, tok);
819155192Srwatson		}
820155192Srwatson		break;
821155192Srwatson
822155192Srwatson	case AUE_MSGGET:
823155192Srwatson		if (ar->ar_errno == 0) {
824155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
825155192Srwatson				tok = au_to_ipc(AT_IPC_MSG,
826155192Srwatson				    ar->ar_arg_svipc_id);
827155192Srwatson				kau_write(rec, tok);
828155192Srwatson			}
829155192Srwatson		}
830155192Srwatson		break;
831155192Srwatson
832155192Srwatson	case AUE_RESETSHFILE:
833155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
834155192Srwatson			tok = au_to_arg32(1, "base addr",
835155192Srwatson			    (u_int32_t)ar->ar_arg_addr);
836155192Srwatson			kau_write(rec, tok);
837155192Srwatson		}
838155192Srwatson		break;
839155192Srwatson
840155192Srwatson	case AUE_OPEN_RC:
841155192Srwatson	case AUE_OPEN_RTC:
842155192Srwatson	case AUE_OPEN_RWC:
843155192Srwatson	case AUE_OPEN_RWTC:
844155192Srwatson	case AUE_OPEN_WC:
845155192Srwatson	case AUE_OPEN_WTC:
846155192Srwatson	/* case AUE_O_CREAT: */		/* AUE_O_CREAT == AUE_OPEN_RWTC */
847155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
848155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
849155192Srwatson			kau_write(rec, tok);
850155192Srwatson		}
851155192Srwatson		/* fall through */
852155192Srwatson
853155192Srwatson	case AUE_OPEN_R:
854155192Srwatson	case AUE_OPEN_RT:
855155192Srwatson	case AUE_OPEN_RW:
856155192Srwatson	case AUE_OPEN_RWT:
857155192Srwatson	case AUE_OPEN_W:
858155192Srwatson	case AUE_OPEN_WT:
859155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
860155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
861155192Srwatson			kau_write(rec, tok);
862155192Srwatson		}
863155192Srwatson		UPATH1_VNODE1_TOKENS;
864155192Srwatson		break;
865155192Srwatson
866155192Srwatson	case AUE_PTRACE:
867155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
868155192Srwatson			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
869155192Srwatson			kau_write(rec, tok);
870155192Srwatson		}
871155192Srwatson		if (ARG_IS_VALID(kar, ARG_ADDR)) {
872155192Srwatson			tok = au_to_arg32(3, "addr",
873155192Srwatson			    (u_int32_t)ar->ar_arg_addr);
874155192Srwatson			kau_write(rec, tok);
875155192Srwatson		}
876155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
877155192Srwatson			tok = au_to_arg32(4, "data", ar->ar_arg_value);
878155192Srwatson			kau_write(rec, tok);
879155192Srwatson		}
880155192Srwatson		PROCESS_PID_TOKENS(2);
881155192Srwatson		break;
882155192Srwatson
883155192Srwatson	case AUE_QUOTACTL:
884155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
885155192Srwatson			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
886155192Srwatson			kau_write(rec, tok);
887155192Srwatson		}
888155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
889155192Srwatson			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
890155192Srwatson			kau_write(rec, tok);
891155192Srwatson		}
892155192Srwatson		UPATH1_VNODE1_TOKENS;
893155192Srwatson		break;
894155192Srwatson
895155192Srwatson	case AUE_REBOOT:
896155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
897155192Srwatson			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
898155192Srwatson			kau_write(rec, tok);
899155192Srwatson		}
900155192Srwatson		break;
901155192Srwatson
902155192Srwatson	case AUE_SEMCTL:
903155192Srwatson		ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd);
904155192Srwatson		/* Fall through */
905155192Srwatson	case AUE_SEMOP:
906155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
907155192Srwatson			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
908155192Srwatson			kau_write(rec, tok);
909155192Srwatson			if (ar->ar_errno != EINVAL) {
910155192Srwatson				tok = au_to_ipc(AT_IPC_SEM,
911155192Srwatson				    ar->ar_arg_svipc_id);
912155192Srwatson				kau_write(rec, tok);
913155192Srwatson			}
914155192Srwatson		}
915155192Srwatson		break;
916155192Srwatson	case AUE_SEMGET:
917155192Srwatson		if (ar->ar_errno == 0) {
918155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
919155192Srwatson				tok = au_to_ipc(AT_IPC_SEM,
920155192Srwatson				    ar->ar_arg_svipc_id);
921155192Srwatson				kau_write(rec, tok);
922155192Srwatson			}
923155192Srwatson		}
924155192Srwatson		break;
925155192Srwatson	case AUE_SETEGID:
926155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
927155192Srwatson			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
928155192Srwatson			kau_write(rec, tok);
929155192Srwatson		}
930155192Srwatson		break;
931155192Srwatson	case AUE_SETEUID:
932155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
933155192Srwatson			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
934155192Srwatson			kau_write(rec, tok);
935155192Srwatson		}
936155192Srwatson		break;
937155192Srwatson	case AUE_SETREGID:
938155192Srwatson		if (ARG_IS_VALID(kar, ARG_RGID)) {
939155192Srwatson			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
940155192Srwatson			kau_write(rec, tok);
941155192Srwatson		}
942155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
943155192Srwatson			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
944155192Srwatson			kau_write(rec, tok);
945155192Srwatson		}
946155192Srwatson		break;
947155192Srwatson	case AUE_SETREUID:
948155192Srwatson		if (ARG_IS_VALID(kar, ARG_RUID)) {
949155192Srwatson			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
950155192Srwatson			kau_write(rec, tok);
951155192Srwatson		}
952155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
953155192Srwatson			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
954155192Srwatson			kau_write(rec, tok);
955155192Srwatson		}
956155192Srwatson		break;
957155192Srwatson	case AUE_SETRESGID:
958155192Srwatson		if (ARG_IS_VALID(kar, ARG_RGID)) {
959155192Srwatson			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
960155192Srwatson			kau_write(rec, tok);
961155192Srwatson		}
962155192Srwatson		if (ARG_IS_VALID(kar, ARG_EGID)) {
963155192Srwatson			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
964155192Srwatson			kau_write(rec, tok);
965155192Srwatson		}
966155192Srwatson		if (ARG_IS_VALID(kar, ARG_SGID)) {
967155192Srwatson			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
968155192Srwatson			kau_write(rec, tok);
969155192Srwatson		}
970155192Srwatson		break;
971155192Srwatson	case AUE_SETRESUID:
972155192Srwatson		if (ARG_IS_VALID(kar, ARG_RUID)) {
973155192Srwatson			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
974155192Srwatson			kau_write(rec, tok);
975155192Srwatson		}
976155192Srwatson		if (ARG_IS_VALID(kar, ARG_EUID)) {
977155192Srwatson			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
978155192Srwatson			kau_write(rec, tok);
979155192Srwatson		}
980155192Srwatson		if (ARG_IS_VALID(kar, ARG_SUID)) {
981155192Srwatson			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
982155192Srwatson			kau_write(rec, tok);
983155192Srwatson		}
984155192Srwatson		break;
985155192Srwatson	case AUE_SETGID:
986155192Srwatson		if (ARG_IS_VALID(kar, ARG_GID)) {
987155192Srwatson			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
988155192Srwatson			kau_write(rec, tok);
989155192Srwatson		}
990155192Srwatson		break;
991155192Srwatson	case AUE_SETUID:
992155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
993155192Srwatson			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
994155192Srwatson			kau_write(rec, tok);
995155192Srwatson		}
996155192Srwatson		break;
997155192Srwatson	case AUE_SETGROUPS:
998155192Srwatson		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
999155192Srwatson			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1000155192Srwatson			{
1001155192Srwatson				tok = au_to_arg32(1, "setgroups", 							ar->ar_arg_groups.gidset[ctr]);
1002155192Srwatson				kau_write(rec, tok);
1003155192Srwatson			}
1004155192Srwatson		}
1005155192Srwatson		break;
1006155192Srwatson
1007155192Srwatson	case AUE_SETLOGIN:
1008155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1009155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1010155192Srwatson			kau_write(rec, tok);
1011155192Srwatson		}
1012155192Srwatson		break;
1013155192Srwatson
1014155192Srwatson	case AUE_SETPRIORITY:
1015155192Srwatson		if (ARG_IS_VALID(kar, ARG_CMD)) {
1016155192Srwatson			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1017155192Srwatson			kau_write(rec, tok);
1018155192Srwatson		}
1019155192Srwatson		if (ARG_IS_VALID(kar, ARG_UID)) {
1020155192Srwatson			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1021155192Srwatson			kau_write(rec, tok);
1022155192Srwatson		}
1023155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1024155192Srwatson			tok = au_to_arg32(2, "priority", ar->ar_arg_value);
1025155192Srwatson			kau_write(rec, tok);
1026155192Srwatson		}
1027155192Srwatson		break;
1028155192Srwatson
1029155192Srwatson	case AUE_SETPRIVEXEC:
1030155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1031155192Srwatson			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1032155192Srwatson			kau_write(rec, tok);
1033155192Srwatson		}
1034155192Srwatson		break;
1035155192Srwatson
1036155192Srwatson	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1037155192Srwatson	case AUE_SHMAT:
1038155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1039155192Srwatson			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1040155192Srwatson			kau_write(rec, tok);
1041155192Srwatson			/* XXXAUDIT: Does having the ipc token make sense? */
1042155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1043155192Srwatson			kau_write(rec, tok);
1044155192Srwatson		}
1045155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1046155192Srwatson			tok = au_to_arg32(2, "shmaddr",
1047155192Srwatson			    (int)ar->ar_arg_svipc_addr);
1048155192Srwatson			kau_write(rec, tok);
1049155192Srwatson		}
1050155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1051155192Srwatson			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1052155192Srwatson			kau_write(rec, tok);
1053155192Srwatson		}
1054155192Srwatson		break;
1055155192Srwatson
1056155192Srwatson	case AUE_SHMCTL:
1057155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1058155192Srwatson			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1059155192Srwatson			kau_write(rec, tok);
1060155192Srwatson			/* XXXAUDIT: Does having the ipc token make sense? */
1061155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1062155192Srwatson			kau_write(rec, tok);
1063155192Srwatson		}
1064155192Srwatson		switch (ar->ar_arg_svipc_cmd) {
1065155192Srwatson		case IPC_STAT:
1066155192Srwatson			ar->ar_event = AUE_SHMCTL_STAT;
1067155192Srwatson			break;
1068155192Srwatson		case IPC_RMID:
1069155192Srwatson			ar->ar_event = AUE_SHMCTL_RMID;
1070155192Srwatson			break;
1071155192Srwatson		case IPC_SET:
1072155192Srwatson			ar->ar_event = AUE_SHMCTL_SET;
1073155192Srwatson			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1074155192Srwatson				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1075155192Srwatson				kau_write(rec, tok);
1076155192Srwatson			}
1077155192Srwatson			break;
1078155192Srwatson		default:
1079155192Srwatson			break;	/* We will audit a bad command */
1080155192Srwatson		}
1081155192Srwatson		break;
1082155192Srwatson
1083155192Srwatson	case AUE_SHMDT:
1084155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1085155192Srwatson			tok = au_to_arg32(1, "shmaddr",
1086155192Srwatson			    (int)ar->ar_arg_svipc_addr);
1087155192Srwatson			kau_write(rec, tok);
1088155192Srwatson		}
1089155192Srwatson		break;
1090155192Srwatson
1091155192Srwatson	case AUE_SHMGET:
1092155192Srwatson		/* This is unusual; the return value is in an argument token */
1093155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1094155192Srwatson			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1095155192Srwatson			kau_write(rec, tok);
1096155192Srwatson			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1097155192Srwatson			kau_write(rec, tok);
1098155192Srwatson		}
1099155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1100155192Srwatson			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1101155192Srwatson			kau_write(rec, tok);
1102155192Srwatson		}
1103155192Srwatson		break;
1104155192Srwatson
1105155192Srwatson	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1106155192Srwatson	 * and AUE_SEMUNLINK are Posix IPC */
1107155192Srwatson	case AUE_SHMOPEN:
1108155192Srwatson		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1109155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1110155192Srwatson			kau_write(rec, tok);
1111155192Srwatson		}
1112155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1113155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1114155192Srwatson			kau_write(rec, tok);
1115155192Srwatson		}
1116155192Srwatson	case AUE_SHMUNLINK:
1117155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1118155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1119155192Srwatson			kau_write(rec, tok);
1120155192Srwatson		}
1121155192Srwatson		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1122155192Srwatson		/* Create an ipc_perm token */
1123155192Srwatson			struct ipc_perm perm;
1124155192Srwatson			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1125155192Srwatson			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1126155192Srwatson			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1127155192Srwatson			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1128155192Srwatson			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1129155192Srwatson			perm.seq = 0;
1130155192Srwatson			perm.key = 0;
1131155192Srwatson			tok = au_to_ipc_perm(&perm);
1132155192Srwatson			kau_write(rec, tok);
1133155192Srwatson		}
1134155192Srwatson		break;
1135155192Srwatson
1136155192Srwatson	case AUE_SEMOPEN:
1137155192Srwatson		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1138155192Srwatson			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1139155192Srwatson			kau_write(rec, tok);
1140155192Srwatson		}
1141155192Srwatson		if (ARG_IS_VALID(kar, ARG_MODE)) {
1142155192Srwatson			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1143155192Srwatson			kau_write(rec, tok);
1144155192Srwatson		}
1145155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1146155192Srwatson			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1147155192Srwatson			kau_write(rec, tok);
1148155192Srwatson		}
1149155192Srwatson		/* fall through */
1150155192Srwatson	case AUE_SEMUNLINK:
1151155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1152155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1153155192Srwatson			kau_write(rec, tok);
1154155192Srwatson		}
1155155192Srwatson		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1156155192Srwatson		/* Create an ipc_perm token */
1157155192Srwatson			struct ipc_perm perm;
1158155192Srwatson			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1159155192Srwatson			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1160155192Srwatson			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1161155192Srwatson			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1162155192Srwatson			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1163155192Srwatson			perm.seq = 0;
1164155192Srwatson			perm.key = 0;
1165155192Srwatson			tok = au_to_ipc_perm(&perm);
1166155192Srwatson			kau_write(rec, tok);
1167155192Srwatson		}
1168155192Srwatson		break;
1169155192Srwatson
1170155192Srwatson	case AUE_SEMCLOSE:
1171155192Srwatson		if (ARG_IS_VALID(kar, ARG_FD)) {
1172155192Srwatson			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1173155192Srwatson			kau_write(rec, tok);
1174155192Srwatson		}
1175155192Srwatson		break;
1176155192Srwatson
1177155192Srwatson	case AUE_SYMLINK:
1178155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1179155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1180155192Srwatson			kau_write(rec, tok);
1181155192Srwatson		}
1182155192Srwatson		UPATH1_VNODE1_TOKENS;
1183155192Srwatson		break;
1184155192Srwatson
1185155192Srwatson	case AUE_SYSCTL:
1186155192Srwatson		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1187155192Srwatson			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1188155192Srwatson			  tok = au_to_arg32(1, "name", ar->ar_arg_ctlname[ctr]);
1189155192Srwatson			  kau_write(rec, tok);
1190155192Srwatson			}
1191155192Srwatson		}
1192155192Srwatson		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1193155192Srwatson			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1194155192Srwatson			kau_write(rec, tok);
1195155192Srwatson		}
1196155192Srwatson		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1197155192Srwatson			tok = au_to_text(ar->ar_arg_text);
1198155192Srwatson			kau_write(rec, tok);
1199155192Srwatson		}
1200155192Srwatson		break;
1201155192Srwatson
1202155192Srwatson	case AUE_UMASK:
1203155192Srwatson		if (ARG_IS_VALID(kar, ARG_MASK)) {
1204155192Srwatson			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1205155192Srwatson			kau_write(rec, tok);
1206155192Srwatson		}
1207155192Srwatson		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1208155192Srwatson		kau_write(rec, tok);
1209155192Srwatson		break;
1210155192Srwatson
1211155192Srwatson	case AUE_WAIT4:
1212155192Srwatson		if (ARG_IS_VALID(kar, ARG_PID)) {
1213155192Srwatson			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1214155192Srwatson			kau_write(rec, tok);
1215155192Srwatson		}
1216155192Srwatson		break;
1217155192Srwatson
1218155192Srwatson	default: /* We shouldn't fall through to here. */
1219155192Srwatson		printf("BSM conversion requested for unknown event %d\n",
1220155192Srwatson			ar->ar_event);
1221155192Srwatson		/* Write the subject token so it is properly freed here. */
1222155192Srwatson		kau_write(rec, subj_tok);
1223155192Srwatson		kau_free(rec);
1224155192Srwatson		return (BSM_NOAUDIT);
1225155192Srwatson	}
1226155192Srwatson
1227155192Srwatson	kau_write(rec, subj_tok);
1228155192Srwatson	tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
1229155192Srwatson	kau_write(rec, tok);  /* Every record gets a return token */
1230155192Srwatson
1231155192Srwatson	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1232155192Srwatson
1233155192Srwatson	*pau = rec;
1234155192Srwatson	return (BSM_SUCCESS);
1235155192Srwatson}
1236155192Srwatson
1237155192Srwatson/*
1238155192Srwatson * Verify that a record is a valid BSM record. This verification is
1239155192Srwatson * simple now, but may be expanded on sometime in the future.
1240155192Srwatson * Return 1 if the record is good, 0 otherwise.
1241155192Srwatson *
1242155192Srwatson */
1243155192Srwatsonint
1244155192Srwatsonbsm_rec_verify(void *rec)
1245155192Srwatson{
1246155192Srwatson	char c = *(char *)rec;
1247155192Srwatson	/*
1248155192Srwatson	 * Check the token ID of the first token; it has to be a header
1249155192Srwatson	 * token.
1250155192Srwatson	 */
1251155192Srwatson	/* XXXAUDIT There needs to be a token structure to map a token.
1252155192Srwatson	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1253155192Srwatson	 */
1254155192Srwatson	if ( (c != AUT_HEADER32) &&
1255155192Srwatson		(c != AUT_HEADER32_EX) &&
1256155192Srwatson		(c != AUT_HEADER64) &&
1257155192Srwatson		(c != AUT_HEADER64_EX) ) {
1258155192Srwatson		return (0);
1259155192Srwatson	}
1260155192Srwatson	return (1);
1261155192Srwatson}
1262