audit_bsm.c revision 178186
1138568Ssam/*
2186904Ssam * Copyright (c) 1999-2005 Apple Computer, Inc.
3138568Ssam * All rights reserved.
4138568Ssam *
5138568Ssam * Redistribution and use in source and binary forms, with or without
6138568Ssam * modification, are permitted provided that the following conditions
7138568Ssam * are met:
8138568Ssam * 1.  Redistributions of source code must retain the above copyright
9138568Ssam *     notice, this list of conditions and the following disclaimer.
10138568Ssam * 2.  Redistributions in binary form must reproduce the above copyright
11138568Ssam *     notice, this list of conditions and the following disclaimer in the
12138568Ssam *     documentation and/or other materials provided with the distribution.
13138568Ssam * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14138568Ssam *     its contributors may be used to endorse or promote products derived
15138568Ssam *     from this software without specific prior written permission.
16138568Ssam *
17138568Ssam * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
18138568Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19138568Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20138568Ssam * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
21138568Ssam * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22138568Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23138568Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24138568Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25138568Ssam * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
26138568Ssam * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27138568Ssam * POSSIBILITY OF SUCH DAMAGE.
28138568Ssam */
29138568Ssam
30138568Ssam#include <sys/cdefs.h>
31138568Ssam__FBSDID("$FreeBSD: head/sys/security/audit/audit_bsm.c 178186 2008-04-13 22:06:56Z rwatson $");
32178354Ssam
33178354Ssam#include <sys/param.h>
34138568Ssam#include <sys/vnode.h>
35138568Ssam#include <sys/ipc.h>
36138568Ssam#include <sys/lock.h>
37138568Ssam#include <sys/malloc.h>
38138568Ssam#include <sys/mutex.h>
39138568Ssam#include <sys/socket.h>
40138568Ssam#include <sys/extattr.h>
41138568Ssam#include <sys/fcntl.h>
42138568Ssam#include <sys/user.h>
43138568Ssam#include <sys/systm.h>
44138568Ssam
45192468Ssam#include <bsm/audit.h>
46138568Ssam#include <bsm/audit_internal.h>
47190526Ssam#include <bsm/audit_record.h>
48178354Ssam#include <bsm/audit_kevents.h>
49138568Ssam
50178354Ssam#include <security/audit/audit.h>
51138568Ssam#include <security/audit/audit_private.h>
52138568Ssam
53196019Srwatson#include <netinet/in_systm.h>
54138568Ssam#include <netinet/in.h>
55138568Ssam#include <netinet/ip.h>
56195757Ssam
57138568SsamMALLOC_DEFINE(M_AUDITBSM, "audit_bsm", "Audit BSM data");
58138568Ssam
59138568Ssamstatic void	audit_sys_auditon(struct audit_record *ar,
60138568Ssam		    struct au_record *rec);
61138568Ssam
62138568Ssam/*
63138568Ssam * Initialize the BSM auditing subsystem.
64138568Ssam */
65138568Ssamvoid
66227293Sedkau_init(void)
67178354Ssam{
68178354Ssam
69178354Ssam	au_evclassmap_init();
70178354Ssam}
71178354Ssam
72178354Ssam/*
73178354Ssam * This call reserves memory for the audit record.  Memory must be guaranteed
74178354Ssam * before any auditable event can be generated.  The au_record structure
75178354Ssam * maintains a reference to the memory allocated above and also the list of
76178354Ssam * tokens associated with this record
77178354Ssam */
78178354Ssamstatic struct au_record *
79178354Ssamkau_open(void)
80178354Ssam{
81178354Ssam	struct au_record *rec;
82178354Ssam
83178354Ssam	rec = malloc(sizeof(*rec), M_AUDITBSM, M_WAITOK);
84178354Ssam	rec->data = NULL;
85178354Ssam	TAILQ_INIT(&rec->token_q);
86178354Ssam	rec->len = 0;
87178354Ssam	rec->used = 1;
88178354Ssam
89178354Ssam	return (rec);
90178354Ssam}
91138568Ssam
92178354Ssam/*
93173273Ssam * Store the token with the record descriptor.
94178354Ssam */
95178354Ssamstatic void
96178354Ssamkau_write(struct au_record *rec, struct au_token *tok)
97178354Ssam{
98173273Ssam
99173273Ssam	KASSERT(tok != NULL, ("kau_write: tok == NULL"));
100178354Ssam
101178354Ssam	TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
102178354Ssam	rec->len += tok->len;
103178354Ssam}
104178354Ssam
105178354Ssam/*
106178957Ssam * Close out the audit record by adding the header token, identifying any
107178354Ssam * missing tokens.  Write out the tokens to the record memory.
108178354Ssam */
109178957Ssamstatic void
110178957Ssamkau_close(struct au_record *rec, struct timespec *ctime, short event)
111178957Ssam{
112178957Ssam	u_char *dptr;
113178957Ssam	size_t tot_rec_size;
114178354Ssam	token_t *cur, *hdr, *trail;
115178354Ssam	struct timeval tm;
116178354Ssam
117178957Ssam	tot_rec_size = rec->len + AUDIT_HEADER_SIZE + AUDIT_TRAILER_SIZE;
118178957Ssam	rec->data = malloc(tot_rec_size, M_AUDITBSM, M_WAITOK | M_ZERO);
119178957Ssam
120178957Ssam	tm.tv_usec = ctime->tv_nsec / 1000;
121178957Ssam	tm.tv_sec = ctime->tv_sec;
122186904Ssam	hdr = au_to_header32_tm(tot_rec_size, event, 0, tm);
123186904Ssam	TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
124186904Ssam
125186904Ssam	trail = au_to_trailer(tot_rec_size);
126186904Ssam	TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
127186904Ssam
128186904Ssam	rec->len = tot_rec_size;
129186904Ssam	dptr = rec->data;
130186904Ssam	TAILQ_FOREACH(cur, &rec->token_q, tokens) {
131186904Ssam		memcpy(dptr, cur->t_data, cur->len);
132178354Ssam		dptr += cur->len;
133178354Ssam	}
134178354Ssam}
135190526Ssam
136178354Ssam/*
137178354Ssam * Free a BSM audit record by releasing all the tokens and clearing the audit
138178354Ssam * record information.
139178354Ssam */
140178354Ssamvoid
141178354Ssamkau_free(struct au_record *rec)
142178354Ssam{
143178354Ssam	struct au_token *tok;
144178354Ssam
145178354Ssam	/* Free the token list. */
146178354Ssam	while ((tok = TAILQ_FIRST(&rec->token_q))) {
147178354Ssam		TAILQ_REMOVE(&rec->token_q, tok, tokens);
148178354Ssam		free(tok->t_data, M_AUDITBSM);
149178354Ssam		free(tok, M_AUDITBSM);
150178354Ssam	}
151178354Ssam
152183210Sthompsa	rec->used = 0;
153178354Ssam	rec->len = 0;
154178354Ssam	free(rec->data, M_AUDITBSM);
155192473Ssam	free(rec, M_AUDITBSM);
156178354Ssam}
157178354Ssam
158178354Ssam/*
159178354Ssam * XXX: May want turn some (or all) of these macros into functions in order
160178354Ssam * to reduce the generated code sized.
161178354Ssam *
162173273Ssam * XXXAUDIT: These macros assume that 'kar', 'ar', 'rec', and 'tok' in the
163173273Ssam * caller are OK with this.
164178354Ssam */
165178354Ssam#define UPATH1_TOKENS do {						\
166173273Ssam	if (ARG_IS_VALID(kar, ARG_UPATH1)) {				\
167173273Ssam		tok = au_to_path(ar->ar_arg_upath1);			\
168178354Ssam		kau_write(rec, tok);					\
169173273Ssam	}								\
170138568Ssam} while (0)
171138568Ssam
172138568Ssam#define UPATH2_TOKENS do {						\
173138568Ssam	if (ARG_IS_VALID(kar, ARG_UPATH2)) {				\
174138568Ssam		tok = au_to_path(ar->ar_arg_upath2);			\
175138568Ssam		kau_write(rec, tok);					\
176138568Ssam	}								\
177138568Ssam} while (0)
178138568Ssam
179138568Ssam#define VNODE1_TOKENS do {						\
180138568Ssam	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
181138568Ssam		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
182138568Ssam		kau_write(rec, tok);					\
183138568Ssam	}								\
184138568Ssam} while (0)
185138568Ssam
186138568Ssam#define UPATH1_VNODE1_TOKENS do {					\
187138568Ssam	if (ARG_IS_VALID(kar, ARG_UPATH1)) {  				\
188138568Ssam		UPATH1_TOKENS;						\
189138568Ssam	}								\
190138568Ssam	if (ARG_IS_VALID(kar, ARG_VNODE1)) {  				\
191181194Ssam		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
192181194Ssam		kau_write(rec, tok);					\
193181194Ssam	}								\
194181194Ssam} while (0)
195181194Ssam
196181194Ssam#define VNODE2_TOKENS do {						\
197181194Ssam	if (ARG_IS_VALID(kar, ARG_VNODE2)) {  				\
198181194Ssam		tok = au_to_attr32(&ar->ar_arg_vnode2);			\
199181194Ssam		kau_write(rec, tok);					\
200181194Ssam	}								\
201181194Ssam} while (0)
202181194Ssam
203181194Ssam#define FD_VNODE1_TOKENS	do {					\
204181194Ssam	if (ARG_IS_VALID(kar, ARG_VNODE1)) {				\
205181194Ssam		if (ARG_IS_VALID(kar, ARG_FD)) {			\
206138568Ssam			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);	\
207138568Ssam			kau_write(rec, tok);				\
208138568Ssam		}							\
209178354Ssam		tok = au_to_attr32(&ar->ar_arg_vnode1);			\
210178354Ssam		kau_write(rec, tok);					\
211178354Ssam	} else {							\
212178354Ssam		if (ARG_IS_VALID(kar, ARG_FD)) {			\
213178354Ssam			tok = au_to_arg32(1, "non-file: fd",		\
214178354Ssam			    ar->ar_arg_fd);				\
215178354Ssam			kau_write(rec, tok);				\
216178354Ssam		}							\
217178354Ssam	}								\
218178354Ssam} while (0)
219178354Ssam
220138568Ssam#define PROCESS_PID_TOKENS(argn) do {					\
221138568Ssam	if ((ar->ar_arg_pid > 0) /* Reference a single process */	\
222138568Ssam	    && (ARG_IS_VALID(kar, ARG_PROCESS))) {			\
223138568Ssam		tok = au_to_process32_ex(ar->ar_arg_auid,		\
224186302Ssam		    ar->ar_arg_euid, ar->ar_arg_egid,			\
225138568Ssam		    ar->ar_arg_ruid, ar->ar_arg_rgid,			\
226138568Ssam		    ar->ar_arg_pid, ar->ar_arg_asid,			\
227178354Ssam		    &ar->ar_arg_termid_addr);				\
228138568Ssam		kau_write(rec, tok);					\
229138568Ssam	} else if (ARG_IS_VALID(kar, ARG_PID)) {			\
230138568Ssam		tok = au_to_arg32(argn, "process", ar->ar_arg_pid);	\
231138568Ssam		kau_write(rec, tok);					\
232178354Ssam	}								\
233138568Ssam} while (0)								\
234138568Ssam
235138568Ssam#define EXTATTR_TOKENS	do {						\
236217554Smdf	if (ARG_IS_VALID(kar, ARG_VALUE)) {				\
237178354Ssam		switch (ar->ar_arg_value) {				\
238217322Smdf		case EXTATTR_NAMESPACE_USER:				\
239178354Ssam			tok = au_to_text(EXTATTR_NAMESPACE_USER_STRING);\
240178354Ssam			break;						\
241138568Ssam		case EXTATTR_NAMESPACE_SYSTEM:				\
242178354Ssam			tok = au_to_text(EXTATTR_NAMESPACE_SYSTEM_STRING);\
243217322Smdf			break;						\
244178354Ssam		default:						\
245138568Ssam			tok = au_to_arg32(3, "attrnamespace",		\
246138568Ssam			    ar->ar_arg_value);				\
247178354Ssam			break;						\
248178354Ssam		}							\
249178354Ssam		kau_write(rec, tok);					\
250138568Ssam	}								\
251138568Ssam	/* attrname is in the text field */				\
252178354Ssam	if (ARG_IS_VALID(kar, ARG_TEXT)) {				\
253138568Ssam		tok = au_to_text(ar->ar_arg_text);			\
254138568Ssam		kau_write(rec, tok);					\
255138568Ssam	}								\
256178354Ssam} while (0)
257138568Ssam
258138568Ssam/*
259138568Ssam * Implement auditing for the auditon() system call. The audit tokens that
260178354Ssam * are generated depend on the command that was sent into the auditon()
261138568Ssam * system call.
262138568Ssam */
263138568Ssamstatic void
264178354Ssamaudit_sys_auditon(struct audit_record *ar, struct au_record *rec)
265138568Ssam{
266138568Ssam	struct au_token *tok;
267178354Ssam
268217322Smdf	switch (ar->ar_arg_cmd) {
269178354Ssam	case A_SETPOLICY:
270178354Ssam		if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
271178354Ssam			tok = au_to_arg64(1, "policy",
272217322Smdf			    ar->ar_arg_auditon.au_flags);
273178354Ssam		else
274178354Ssam			tok = au_to_arg32(1, "policy",
275178354Ssam			    ar->ar_arg_auditon.au_flags);
276217322Smdf		kau_write(rec, tok);
277178354Ssam		break;
278178354Ssam
279178354Ssam	case A_SETKMASK:
280217322Smdf		tok = au_to_arg32(2, "setkmask:as_success",
281178354Ssam		    ar->ar_arg_auditon.au_mask.am_success);
282178354Ssam		kau_write(rec, tok);
283178354Ssam		tok = au_to_arg32(2, "setkmask:as_failure",
284178354Ssam		    ar->ar_arg_auditon.au_mask.am_failure);
285181194Ssam		kau_write(rec, tok);
286181194Ssam		break;
287181194Ssam
288193115Ssam	case A_SETQCTRL:
289181194Ssam		tok = au_to_arg32(3, "setqctrl:aq_hiwater",
290178354Ssam		    ar->ar_arg_auditon.au_qctrl.aq_hiwater);
291178354Ssam		kau_write(rec, tok);
292138568Ssam		tok = au_to_arg32(3, "setqctrl:aq_lowater",
293138568Ssam		    ar->ar_arg_auditon.au_qctrl.aq_lowater);
294138568Ssam		kau_write(rec, tok);
295178354Ssam		tok = au_to_arg32(3, "setqctrl:aq_bufsz",
296138568Ssam		    ar->ar_arg_auditon.au_qctrl.aq_bufsz);
297138568Ssam		kau_write(rec, tok);
298178354Ssam		tok = au_to_arg32(3, "setqctrl:aq_delay",
299178354Ssam		    ar->ar_arg_auditon.au_qctrl.aq_delay);
300186302Ssam		kau_write(rec, tok);
301178354Ssam		tok = au_to_arg32(3, "setqctrl:aq_minfree",
302138568Ssam		    ar->ar_arg_auditon.au_qctrl.aq_minfree);
303138568Ssam		kau_write(rec, tok);
304138568Ssam		break;
305138568Ssam
306138568Ssam	case A_SETUMASK:
307138568Ssam		tok = au_to_arg32(3, "setumask:as_success",
308138568Ssam		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
309138568Ssam		kau_write(rec, tok);
310138568Ssam		tok = au_to_arg32(3, "setumask:as_failure",
311138568Ssam		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
312138568Ssam		kau_write(rec, tok);
313165894Ssam		break;
314165894Ssam
315165894Ssam	case A_SETSMASK:
316165894Ssam		tok = au_to_arg32(3, "setsmask:as_success",
317165894Ssam		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
318165894Ssam		kau_write(rec, tok);
319165894Ssam		tok = au_to_arg32(3, "setsmask:as_failure",
320165894Ssam		    ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
321165894Ssam		kau_write(rec, tok);
322165894Ssam		break;
323165894Ssam
324165894Ssam	case A_SETCOND:
325165894Ssam		if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
326165894Ssam			tok = au_to_arg64(3, "setcond",
327165894Ssam			    ar->ar_arg_auditon.au_cond);
328165894Ssam		else
329165894Ssam			tok = au_to_arg32(3, "setcond",
330165894Ssam			    ar->ar_arg_auditon.au_cond);
331165894Ssam		kau_write(rec, tok);
332165894Ssam		break;
333178354Ssam
334178354Ssam	case A_SETCLASS:
335178354Ssam		tok = au_to_arg32(2, "setclass:ec_event",
336178354Ssam		    ar->ar_arg_auditon.au_evclass.ec_number);
337178354Ssam		kau_write(rec, tok);
338178354Ssam		tok = au_to_arg32(3, "setclass:ec_class",
339178354Ssam		    ar->ar_arg_auditon.au_evclass.ec_class);
340178354Ssam		kau_write(rec, tok);
341178354Ssam		break;
342178354Ssam
343178354Ssam	case A_SETPMASK:
344178354Ssam		tok = au_to_arg32(2, "setpmask:as_success",
345178354Ssam		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
346178354Ssam		kau_write(rec, tok);
347178354Ssam		tok = au_to_arg32(2, "setpmask:as_failure",
348178354Ssam		    ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
349178354Ssam		kau_write(rec, tok);
350178354Ssam		break;
351178354Ssam
352178354Ssam	case A_SETFSIZE:
353178354Ssam		tok = au_to_arg32(2, "setfsize:filesize",
354178354Ssam		    ar->ar_arg_auditon.au_fstat.af_filesz);
355178354Ssam		kau_write(rec, tok);
356178354Ssam		break;
357178354Ssam
358178354Ssam	default:
359178354Ssam		break;
360138568Ssam	}
361170530Ssam}
362170530Ssam
363170530Ssam/*
364170530Ssam * Convert an internal kernel audit record to a BSM record and return a
365170530Ssam * success/failure indicator. The BSM record is passed as an out parameter to
366170530Ssam * this function.
367170530Ssam *
368170530Ssam * Return conditions:
369170530Ssam *   BSM_SUCCESS: The BSM record is valid
370138568Ssam *   BSM_FAILURE: Failure; the BSM record is NULL.
371138568Ssam *   BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
372138568Ssam */
373138568Ssamint
374138568Ssamkaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
375138568Ssam{
376138568Ssam	struct au_token *tok, *subj_tok;
377138568Ssam	struct au_record *rec;
378138568Ssam	au_tid_t tid;
379170530Ssam	struct audit_record *ar;
380138568Ssam	int ctr;
381138568Ssam
382138568Ssam	KASSERT(kar != NULL, ("kaudit_to_bsm: kar == NULL"));
383138568Ssam
384138568Ssam	*pau = NULL;
385138568Ssam	ar = &kar->k_ar;
386138568Ssam	rec = kau_open();
387138568Ssam
388170530Ssam	/* Create the subject token */
389138568Ssam	switch (ar->ar_subj_term_addr.at_type) {
390138568Ssam	case AU_IPv4:
391151967Sandre		tid.port = ar->ar_subj_term_addr.at_port;
392138568Ssam		tid.machine = ar->ar_subj_term_addr.at_addr[0];
393138568Ssam		subj_tok = au_to_subject32(ar->ar_subj_auid,  /* audit ID */
394138568Ssam		    ar->ar_subj_cred.cr_uid, /* eff uid */
395138568Ssam		    ar->ar_subj_egid,	/* eff group id */
396138568Ssam		    ar->ar_subj_ruid, 	/* real uid */
397138568Ssam		    ar->ar_subj_rgid, 	/* real group id */
398138568Ssam		    ar->ar_subj_pid,	/* process id */
399138568Ssam		    ar->ar_subj_asid,	/* session ID */
400170530Ssam		    &tid);
401151967Sandre		break;
402170530Ssam	case AU_IPv6:
403170530Ssam		subj_tok = au_to_subject32_ex(ar->ar_subj_auid,
404170530Ssam		    ar->ar_subj_cred.cr_uid,
405138568Ssam		    ar->ar_subj_egid,
406171984Ssephe		    ar->ar_subj_ruid,
407138568Ssam		    ar->ar_subj_rgid,
408138568Ssam		    ar->ar_subj_pid,
409138568Ssam		    ar->ar_subj_asid,
410138568Ssam		    &ar->ar_subj_term_addr);
411138568Ssam		break;
412195757Ssam	default:
413195757Ssam		bzero(&tid, sizeof(tid));
414195757Ssam		subj_tok = au_to_subject32(ar->ar_subj_auid,
415195757Ssam		    ar->ar_subj_cred.cr_uid,
416195757Ssam		    ar->ar_subj_egid,
417195757Ssam		    ar->ar_subj_ruid,
418195757Ssam		    ar->ar_subj_rgid,
419195757Ssam		    ar->ar_subj_pid,
420195757Ssam		    ar->ar_subj_asid,
421195757Ssam		    &tid);
422195757Ssam	}
423195757Ssam
424195757Ssam	/*
425195757Ssam	 * The logic inside each case fills in the tokens required for the
426195757Ssam	 * event, except for the header, trailer, and return tokens.  The
427195757Ssam	 * header and trailer tokens are added by the kau_close() function.
428195757Ssam	 * The return token is added outside of the switch statement.
429195757Ssam	 */
430195757Ssam	switch(ar->ar_event) {
431195757Ssam	case AUE_ACCEPT:
432195757Ssam	case AUE_BIND:
433195757Ssam	case AUE_LISTEN:
434195757Ssam	case AUE_CONNECT:
435195757Ssam	case AUE_RECV:
436195757Ssam	case AUE_RECVFROM:
437195757Ssam	case AUE_RECVMSG:
438195757Ssam	case AUE_SEND:
439195757Ssam	case AUE_SENDFILE:
440195757Ssam	case AUE_SENDMSG:
441195757Ssam	case AUE_SENDTO:
442195757Ssam		/*
443195757Ssam		 * Socket-related events.
444195757Ssam		 */
445195757Ssam		if (ARG_IS_VALID(kar, ARG_FD)) {
446195757Ssam			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
447195757Ssam			kau_write(rec, tok);
448195757Ssam		}
449170530Ssam		if (ARG_IS_VALID(kar, ARG_SADDRINET)) {
450170530Ssam			tok = au_to_sock_inet((struct sockaddr_in *)
451170530Ssam			    &ar->ar_arg_sockaddr);
452170530Ssam			kau_write(rec, tok);
453170530Ssam		}
454170530Ssam		if (ARG_IS_VALID(kar, ARG_SADDRUNIX)) {
455170530Ssam			tok = au_to_sock_unix((struct sockaddr_un *)
456170530Ssam			    &ar->ar_arg_sockaddr);
457170530Ssam			kau_write(rec, tok);
458170530Ssam			UPATH1_TOKENS;
459170530Ssam		}
460170530Ssam		/* XXX Need to handle ARG_SADDRINET6 */
461170530Ssam		break;
462170530Ssam
463170530Ssam	case AUE_SOCKET:
464170530Ssam	case AUE_SOCKETPAIR:
465170530Ssam		if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
466170530Ssam			tok = au_to_arg32(1,"domain",
467170530Ssam			    ar->ar_arg_sockinfo.so_domain);
468170530Ssam			kau_write(rec, tok);
469170530Ssam			tok = au_to_arg32(2,"type",
470170530Ssam			    ar->ar_arg_sockinfo.so_type);
471170530Ssam			kau_write(rec, tok);
472170530Ssam			tok = au_to_arg32(3,"protocol",
473170530Ssam			    ar->ar_arg_sockinfo.so_protocol);
474170530Ssam			kau_write(rec, tok);
475170530Ssam		}
476170530Ssam		break;
477170530Ssam
478170530Ssam	case AUE_SETSOCKOPT:
479170530Ssam	case AUE_SHUTDOWN:
480170530Ssam		if (ARG_IS_VALID(kar, ARG_FD)) {
481170530Ssam			tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
482138568Ssam			kau_write(rec, tok);
483138568Ssam		}
484138568Ssam		break;
485138568Ssam
486138568Ssam	case AUE_ACCT:
487170530Ssam		if (ARG_IS_VALID(kar, ARG_UPATH1)) {
488138568Ssam			UPATH1_VNODE1_TOKENS;
489138568Ssam		} else {
490170530Ssam			tok = au_to_arg32(1, "accounting off", 0);
491170530Ssam			kau_write(rec, tok);
492170530Ssam		}
493170530Ssam		break;
494138568Ssam
495138568Ssam	case AUE_SETAUID:
496138568Ssam		if (ARG_IS_VALID(kar, ARG_AUID)) {
497178354Ssam			tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
498178354Ssam			kau_write(rec, tok);
499178354Ssam		}
500178354Ssam		break;
501178354Ssam
502138568Ssam	case AUE_SETAUDIT:
503138568Ssam		if (ARG_IS_VALID(kar, ARG_AUID) &&
504138568Ssam		    ARG_IS_VALID(kar, ARG_ASID) &&
505191816Szec		    ARG_IS_VALID(kar, ARG_AMASK) &&
506144302Ssam		    ARG_IS_VALID(kar, ARG_TERMID)) {
507178354Ssam			tok = au_to_arg32(1, "setaudit:auid",
508178354Ssam			    ar->ar_arg_auid);
509191816Szec			kau_write(rec, tok);
510178354Ssam			tok = au_to_arg32(1, "setaudit:port",
511178354Ssam			    ar->ar_arg_termid.port);
512178354Ssam			kau_write(rec, tok);
513178354Ssam			tok = au_to_arg32(1, "setaudit:machine",
514178354Ssam			    ar->ar_arg_termid.machine);
515178354Ssam			kau_write(rec, tok);
516178354Ssam			tok = au_to_arg32(1, "setaudit:as_success",
517178354Ssam			    ar->ar_arg_amask.am_success);
518191816Szec			kau_write(rec, tok);
519178354Ssam			tok = au_to_arg32(1, "setaudit:as_failure",
520178354Ssam			    ar->ar_arg_amask.am_failure);
521178354Ssam			kau_write(rec, tok);
522178354Ssam			tok = au_to_arg32(1, "setaudit:asid",
523178354Ssam			    ar->ar_arg_asid);
524178354Ssam			kau_write(rec, tok);
525138568Ssam		}
526144302Ssam		break;
527178354Ssam
528178354Ssam	case AUE_SETAUDIT_ADDR:
529138568Ssam		if (ARG_IS_VALID(kar, ARG_AUID) &&
530191816Szec		    ARG_IS_VALID(kar, ARG_ASID) &&
531138568Ssam		    ARG_IS_VALID(kar, ARG_AMASK) &&
532138568Ssam		    ARG_IS_VALID(kar, ARG_TERMID_ADDR)) {
533138568Ssam			tok = au_to_arg32(1, "setaudit_addr:auid",
534178354Ssam			    ar->ar_arg_auid);
535138568Ssam			kau_write(rec, tok);
536178354Ssam			tok = au_to_arg32(1, "setaudit_addr:as_success",
537178354Ssam			    ar->ar_arg_amask.am_success);
538138568Ssam			kau_write(rec, tok);
539191816Szec			tok = au_to_arg32(1, "setaudit_addr:as_failure",
540178354Ssam			    ar->ar_arg_amask.am_failure);
541178354Ssam			kau_write(rec, tok);
542178354Ssam			tok = au_to_arg32(1, "setaudit_addr:asid",
543178354Ssam			    ar->ar_arg_asid);
544138568Ssam			kau_write(rec, tok);
545138568Ssam			tok = au_to_arg32(1, "setaudit_addr:type",
546138568Ssam			    ar->ar_arg_termid_addr.at_type);
547138568Ssam			kau_write(rec, tok);
548178354Ssam			tok = au_to_arg32(1, "setaudit_addr:port",
549138568Ssam			    ar->ar_arg_termid_addr.at_port);
550191816Szec			kau_write(rec, tok);
551138568Ssam			if (ar->ar_arg_termid_addr.at_type == AU_IPv6)
552138568Ssam				tok = au_to_in_addr_ex((struct in6_addr *)
553138568Ssam				    &ar->ar_arg_termid_addr.at_addr[0]);
554178354Ssam			if (ar->ar_arg_termid_addr.at_type == AU_IPv4)
555138568Ssam				tok = au_to_in_addr((struct in_addr *)
556178354Ssam				    &ar->ar_arg_termid_addr.at_addr[0]);
557138568Ssam			kau_write(rec, tok);
558178354Ssam		}
559138568Ssam		break;
560138568Ssam
561191816Szec	case AUE_AUDITON:
562138568Ssam		/*
563191816Szec		 * For AUDITON commands without own event, audit the cmd.
564138568Ssam		 */
565138568Ssam		if (ARG_IS_VALID(kar, ARG_CMD)) {
566138568Ssam			tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
567178354Ssam			kau_write(rec, tok);
568138568Ssam		}
569193541Ssam		/* fall thru */
570138568Ssam
571178354Ssam	case AUE_AUDITON_GETCAR:
572138568Ssam	case AUE_AUDITON_GETCLASS:
573178354Ssam	case AUE_AUDITON_GETCOND:
574226885Sadrian	case AUE_AUDITON_GETCWD:
575226885Sadrian	case AUE_AUDITON_GETKMASK:
576193541Ssam	case AUE_AUDITON_GETSTAT:
577148863Ssam	case AUE_AUDITON_GPOLICY:
578138568Ssam	case AUE_AUDITON_GQCTRL:
579138568Ssam	case AUE_AUDITON_SETCLASS:
580138568Ssam	case AUE_AUDITON_SETCOND:
581138568Ssam	case AUE_AUDITON_SETKMASK:
582138568Ssam	case AUE_AUDITON_SETSMASK:
583138568Ssam	case AUE_AUDITON_SETSTAT:
584138568Ssam	case AUE_AUDITON_SETUMASK:
585148863Ssam	case AUE_AUDITON_SPOLICY:
586148863Ssam	case AUE_AUDITON_SQCTRL:
587148863Ssam		if (ARG_IS_VALID(kar, ARG_AUDITON))
588148863Ssam			audit_sys_auditon(ar, rec);
589193541Ssam		break;
590138568Ssam
591191816Szec	case AUE_AUDITCTL:
592138568Ssam		UPATH1_VNODE1_TOKENS;
593191816Szec		break;
594138568Ssam
595138568Ssam	case AUE_EXIT:
596138568Ssam		if (ARG_IS_VALID(kar, ARG_EXIT)) {
597138568Ssam			tok = au_to_exit(ar->ar_arg_exitretval,
598178354Ssam			    ar->ar_arg_exitstatus);
599138568Ssam			kau_write(rec, tok);
600138568Ssam		}
601178354Ssam		break;
602138568Ssam
603178354Ssam	case AUE_ADJTIME:
604178354Ssam	case AUE_CLOCK_SETTIME:
605178354Ssam	case AUE_AUDIT:
606138568Ssam	case AUE_DUP2:
607138568Ssam	case AUE_GETAUDIT:
608138568Ssam	case AUE_GETAUDIT_ADDR:
609138568Ssam	case AUE_GETAUID:
610138568Ssam	case AUE_GETCWD:
611138568Ssam	case AUE_GETFSSTAT:
612138568Ssam	case AUE_GETRESUID:
613138568Ssam	case AUE_GETRESGID:
614191816Szec	case AUE_KQUEUE:
615138568Ssam	case AUE_LSEEK:
616191816Szec	case AUE_MODLOAD:
617138568Ssam	case AUE_MODUNLOAD:
618138568Ssam	case AUE_MSGSYS:
619138568Ssam	case AUE_NFS_SVC:
620138568Ssam	case AUE_NTP_ADJTIME:
621178354Ssam	case AUE_PIPE:
622178354Ssam	case AUE_PROFILE:
623178354Ssam	case AUE_RTPRIO:
624178354Ssam	case AUE_SEMSYS:
625178354Ssam	case AUE_SHMSYS:
626178354Ssam	case AUE_SETPGRP:
627178354Ssam	case AUE_SETRLIMIT:
628178354Ssam	case AUE_SETSID:
629178354Ssam	case AUE_SETTIMEOFDAY:
630178354Ssam	case AUE_SYSARCH:
631178354Ssam
632178354Ssam		/*
633178354Ssam		 * Header, subject, and return tokens added at end.
634178354Ssam		 */
635178354Ssam		break;
636178354Ssam
637178354Ssam	case AUE_MKFIFO:
638178354Ssam		if (ARG_IS_VALID(kar, ARG_MODE)) {
639178354Ssam			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
640178354Ssam			kau_write(rec, tok);
641178354Ssam		}
642178354Ssam		/* fall through */
643178354Ssam	case AUE_ACCESS:
644178354Ssam	case AUE_CHDIR:
645178354Ssam	case AUE_CHROOT:
646178354Ssam	case AUE_EACCESS:
647178354Ssam	case AUE_GETATTRLIST:
648178354Ssam	case AUE_JAIL:
649178354Ssam	case AUE_LUTIMES:
650178354Ssam	case AUE_NFS_GETFH:
651178354Ssam	case AUE_LSTAT:
652178354Ssam	case AUE_PATHCONF:
653178354Ssam	case AUE_READLINK:
654178354Ssam	case AUE_REVOKE:
655178354Ssam	case AUE_RMDIR:
656178354Ssam	case AUE_SEARCHFS:
657178354Ssam	case AUE_SETATTRLIST:
658178354Ssam	case AUE_STAT:
659178354Ssam	case AUE_STATFS:
660178354Ssam	case AUE_SWAPON:
661178354Ssam	case AUE_SWAPOFF:
662178354Ssam	case AUE_TRUNCATE:
663178354Ssam	case AUE_UNDELETE:
664178354Ssam	case AUE_UNLINK:
665178354Ssam	case AUE_UTIMES:
666178354Ssam		UPATH1_VNODE1_TOKENS;
667178354Ssam		break;
668178354Ssam
669178354Ssam	case AUE_FHSTATFS:
670178354Ssam	case AUE_FHOPEN:
671178354Ssam	case AUE_FHSTAT:
672178354Ssam		/* XXXRW: Need to audit vnode argument. */
673178354Ssam		break;
674178354Ssam
675178354Ssam	case AUE_CHFLAGS:
676178354Ssam	case AUE_LCHFLAGS:
677178354Ssam		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
678178354Ssam			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
679178354Ssam			kau_write(rec, tok);
680178354Ssam		}
681178354Ssam		UPATH1_VNODE1_TOKENS;
682178354Ssam		break;
683178354Ssam
684178354Ssam	case AUE_CHMOD:
685178354Ssam	case AUE_LCHMOD:
686178354Ssam		if (ARG_IS_VALID(kar, ARG_MODE)) {
687178354Ssam			tok = au_to_arg32(2, "new file mode",
688178354Ssam			    ar->ar_arg_mode);
689178354Ssam			kau_write(rec, tok);
690178354Ssam		}
691178354Ssam		UPATH1_VNODE1_TOKENS;
692178354Ssam		break;
693178354Ssam
694178354Ssam	case AUE_CHOWN:
695178354Ssam	case AUE_LCHOWN:
696178354Ssam		if (ARG_IS_VALID(kar, ARG_UID)) {
697178354Ssam			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
698178354Ssam			kau_write(rec, tok);
699178354Ssam		}
700178354Ssam		if (ARG_IS_VALID(kar, ARG_GID)) {
701178354Ssam			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
702178354Ssam			kau_write(rec, tok);
703178354Ssam		}
704178354Ssam		UPATH1_VNODE1_TOKENS;
705178354Ssam		break;
706178354Ssam
707178354Ssam	case AUE_EXCHANGEDATA:
708178354Ssam		UPATH1_VNODE1_TOKENS;
709178354Ssam		UPATH2_TOKENS;
710178354Ssam		break;
711178354Ssam
712178354Ssam	case AUE_CLOSE:
713178354Ssam		if (ARG_IS_VALID(kar, ARG_FD)) {
714178354Ssam			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
715178354Ssam			kau_write(rec, tok);
716178354Ssam		}
717178354Ssam		UPATH1_VNODE1_TOKENS;
718178354Ssam		break;
719178354Ssam
720178354Ssam	case AUE_CORE:
721178354Ssam		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
722138568Ssam			tok = au_to_arg32(0, "signal", ar->ar_arg_signum);
723138568Ssam			kau_write(rec, tok);
724159590Sjhb		}
725138777Ssam		UPATH1_VNODE1_TOKENS;
726159590Sjhb		break;
727138777Ssam
728138777Ssam	case AUE_EXTATTRCTL:
729138777Ssam		UPATH1_VNODE1_TOKENS;
730138568Ssam		if (ARG_IS_VALID(kar, ARG_CMD)) {
731138568Ssam			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
732192468Ssam			kau_write(rec, tok);
733202612Sthompsa		}
734192468Ssam		/* extattrctl(2) filename parameter is in upath2/vnode2 */
735192468Ssam		UPATH2_TOKENS;
736192764Ssam		VNODE2_TOKENS;
737192468Ssam		EXTATTR_TOKENS;
738192468Ssam		break;
739192764Ssam
740192468Ssam	case AUE_EXTATTR_GET_FILE:
741192468Ssam	case AUE_EXTATTR_SET_FILE:
742192468Ssam	case AUE_EXTATTR_LIST_FILE:
743192468Ssam	case AUE_EXTATTR_DELETE_FILE:
744192468Ssam	case AUE_EXTATTR_GET_LINK:
745192468Ssam	case AUE_EXTATTR_SET_LINK:
746192468Ssam	case AUE_EXTATTR_LIST_LINK:
747192468Ssam	case AUE_EXTATTR_DELETE_LINK:
748193292Ssam		UPATH1_VNODE1_TOKENS;
749192468Ssam		EXTATTR_TOKENS;
750193292Ssam		break;
751193292Ssam
752193312Ssam	case AUE_EXTATTR_GET_FD:
753192468Ssam	case AUE_EXTATTR_SET_FD:
754193292Ssam	case AUE_EXTATTR_LIST_FD:
755193292Ssam	case AUE_EXTATTR_DELETE_FD:
756193292Ssam		if (ARG_IS_VALID(kar, ARG_FD)) {
757192468Ssam			tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
758192468Ssam			kau_write(rec, tok);
759192468Ssam		}
760202612Sthompsa		EXTATTR_TOKENS;
761202612Sthompsa		break;
762202612Sthompsa
763202612Sthompsa	case AUE_EXECVE:
764202612Sthompsa		if (ARG_IS_VALID(kar, ARG_ARGV)) {
765202612Sthompsa			tok = au_to_exec_args(ar->ar_arg_argv,
766202612Sthompsa			    ar->ar_arg_argc);
767202612Sthompsa			kau_write(rec, tok);
768202612Sthompsa		}
769202612Sthompsa		if (ARG_IS_VALID(kar, ARG_ENVV)) {
770202612Sthompsa			tok = au_to_exec_env(ar->ar_arg_envv,
771202612Sthompsa			    ar->ar_arg_envc);
772202612Sthompsa			kau_write(rec, tok);
773202612Sthompsa		}
774202612Sthompsa		UPATH1_VNODE1_TOKENS;
775202612Sthompsa		break;
776202612Sthompsa
777202612Sthompsa	case AUE_FCHMOD:
778202612Sthompsa		if (ARG_IS_VALID(kar, ARG_MODE)) {
779202612Sthompsa			tok = au_to_arg32(2, "new file mode",
780202612Sthompsa			    ar->ar_arg_mode);
781202612Sthompsa			kau_write(rec, tok);
782202612Sthompsa		}
783202612Sthompsa		FD_VNODE1_TOKENS;
784202612Sthompsa		break;
785202612Sthompsa
786202612Sthompsa	/*
787138568Ssam	 * XXXRW: Some of these need to handle non-vnode cases as well.
788138568Ssam	 */
789138568Ssam	case AUE_FCHDIR:
790138568Ssam	case AUE_FPATHCONF:
791138568Ssam	case AUE_FSTAT:
792138568Ssam	case AUE_FSTATFS:
793138568Ssam	case AUE_FSYNC:
794138568Ssam	case AUE_FTRUNCATE:
795138568Ssam	case AUE_FUTIMES:
796138568Ssam	case AUE_GETDIRENTRIES:
797138568Ssam	case AUE_GETDIRENTRIESATTR:
798138568Ssam	case AUE_POLL:
799192468Ssam	case AUE_READ:
800192468Ssam	case AUE_READV:
801192468Ssam	case AUE_WRITE:
802192468Ssam	case AUE_WRITEV:
803202612Sthompsa		FD_VNODE1_TOKENS;
804202612Sthompsa		break;
805202612Sthompsa
806202612Sthompsa	case AUE_FCHOWN:
807202612Sthompsa		if (ARG_IS_VALID(kar, ARG_UID)) {
808202612Sthompsa			tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
809178354Ssam			kau_write(rec, tok);
810178354Ssam		}
811138568Ssam		if (ARG_IS_VALID(kar, ARG_GID)) {
812138568Ssam			tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
813178354Ssam			kau_write(rec, tok);
814178354Ssam		}
815192468Ssam		FD_VNODE1_TOKENS;
816202612Sthompsa		break;
817138568Ssam
818138568Ssam	case AUE_FCNTL:
819138568Ssam		if (ar->ar_arg_cmd == F_GETLK || ar->ar_arg_cmd == F_SETLK ||
820138568Ssam			ar->ar_arg_cmd == F_SETLKW) {
821138568Ssam			if (ARG_IS_VALID(kar, ARG_CMD)) {
822138568Ssam				tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
823138568Ssam				kau_write(rec, tok);
824138568Ssam			}
825138568Ssam			FD_VNODE1_TOKENS;
826138568Ssam		}
827138568Ssam		break;
828138568Ssam
829138568Ssam	case AUE_FCHFLAGS:
830		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
831			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
832			kau_write(rec, tok);
833		}
834		FD_VNODE1_TOKENS;
835		break;
836
837	case AUE_FLOCK:
838		if (ARG_IS_VALID(kar, ARG_CMD)) {
839			tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
840			kau_write(rec, tok);
841		}
842		FD_VNODE1_TOKENS;
843		break;
844
845	case AUE_RFORK:
846		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
847			tok = au_to_arg32(1, "flags", ar->ar_arg_fflags);
848			kau_write(rec, tok);
849		}
850		/* fall through */
851	case AUE_FORK:
852	case AUE_VFORK:
853		if (ARG_IS_VALID(kar, ARG_PID)) {
854			tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
855			kau_write(rec, tok);
856		}
857		break;
858
859	case AUE_IOCTL:
860		if (ARG_IS_VALID(kar, ARG_CMD)) {
861			tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
862			kau_write(rec, tok);
863		}
864		if (ARG_IS_VALID(kar, ARG_ADDR)) {
865			tok = au_to_arg32(1, "arg",
866			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
867			kau_write(rec, tok);
868		}
869		if (ARG_IS_VALID(kar, ARG_VNODE1))
870			FD_VNODE1_TOKENS;
871		else {
872			if (ARG_IS_VALID(kar, ARG_SOCKINFO)) {
873				tok = kau_to_socket(&ar->ar_arg_sockinfo);
874				kau_write(rec, tok);
875			} else {
876				if (ARG_IS_VALID(kar, ARG_FD)) {
877					tok = au_to_arg32(1, "fd",
878					    ar->ar_arg_fd);
879			    		kau_write(rec, tok);
880				}
881			}
882		}
883		break;
884
885	case AUE_KILL:
886	case AUE_KILLPG:
887		if (ARG_IS_VALID(kar, ARG_SIGNUM)) {
888			tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
889			kau_write(rec, tok);
890		}
891		PROCESS_PID_TOKENS(1);
892		break;
893
894	case AUE_KTRACE:
895		if (ARG_IS_VALID(kar, ARG_CMD)) {
896			tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
897			kau_write(rec, tok);
898		}
899		if (ARG_IS_VALID(kar, ARG_VALUE)) {
900			tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
901			kau_write(rec, tok);
902		}
903		PROCESS_PID_TOKENS(4);
904		UPATH1_VNODE1_TOKENS;
905		break;
906
907	case AUE_LINK:
908	case AUE_RENAME:
909		UPATH1_VNODE1_TOKENS;
910		UPATH2_TOKENS;
911		break;
912
913	case AUE_LOADSHFILE:
914		if (ARG_IS_VALID(kar, ARG_ADDR)) {
915			tok = au_to_arg32(4, "base addr",
916			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
917			kau_write(rec, tok);
918		}
919		UPATH1_VNODE1_TOKENS;
920		break;
921
922	case AUE_MKDIR:
923		if (ARG_IS_VALID(kar, ARG_MODE)) {
924			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
925			kau_write(rec, tok);
926		}
927		UPATH1_VNODE1_TOKENS;
928		break;
929
930	case AUE_MKNOD:
931		if (ARG_IS_VALID(kar, ARG_MODE)) {
932			tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
933			kau_write(rec, tok);
934		}
935		if (ARG_IS_VALID(kar, ARG_DEV)) {
936			tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
937			kau_write(rec, tok);
938		}
939		UPATH1_VNODE1_TOKENS;
940		break;
941
942	case AUE_MMAP:
943	case AUE_MUNMAP:
944	case AUE_MPROTECT:
945	case AUE_MLOCK:
946	case AUE_MUNLOCK:
947	case AUE_MINHERIT:
948		if (ARG_IS_VALID(kar, ARG_ADDR)) {
949			tok = au_to_arg32(1, "addr",
950			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
951			kau_write(rec, tok);
952		}
953		if (ARG_IS_VALID(kar, ARG_LEN)) {
954			tok = au_to_arg32(2, "len", ar->ar_arg_len);
955			kau_write(rec, tok);
956		}
957		if (ar->ar_event == AUE_MMAP)
958			FD_VNODE1_TOKENS;
959		if (ar->ar_event == AUE_MPROTECT) {
960			if (ARG_IS_VALID(kar, ARG_VALUE)) {
961				tok = au_to_arg32(3, "protection",
962				    ar->ar_arg_value);
963				kau_write(rec, tok);
964			}
965		}
966		if (ar->ar_event == AUE_MINHERIT) {
967			if (ARG_IS_VALID(kar, ARG_VALUE)) {
968				tok = au_to_arg32(3, "inherit",
969				    ar->ar_arg_value);
970				kau_write(rec, tok);
971			}
972		}
973		break;
974
975	case AUE_MOUNT:
976	case AUE_NMOUNT:
977		/* XXX Need to handle NFS mounts */
978		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
979			tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
980			kau_write(rec, tok);
981		}
982		if (ARG_IS_VALID(kar, ARG_TEXT)) {
983			tok = au_to_text(ar->ar_arg_text);
984			kau_write(rec, tok);
985		}
986		/* fall through */
987
988	case AUE_UMOUNT:
989		UPATH1_VNODE1_TOKENS;
990		break;
991
992	case AUE_MSGCTL:
993		ar->ar_event = audit_msgctl_to_event(ar->ar_arg_svipc_cmd);
994		/* Fall through */
995
996	case AUE_MSGRCV:
997	case AUE_MSGSND:
998		tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
999		kau_write(rec, tok);
1000		if (ar->ar_errno != EINVAL) {
1001			tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
1002			kau_write(rec, tok);
1003		}
1004		break;
1005
1006	case AUE_MSGGET:
1007		if (ar->ar_errno == 0) {
1008			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1009				tok = au_to_ipc(AT_IPC_MSG,
1010				    ar->ar_arg_svipc_id);
1011				kau_write(rec, tok);
1012			}
1013		}
1014		break;
1015
1016	case AUE_RESETSHFILE:
1017		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1018			tok = au_to_arg32(1, "base addr",
1019			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1020			kau_write(rec, tok);
1021		}
1022		break;
1023
1024	case AUE_OPEN_RC:
1025	case AUE_OPEN_RTC:
1026	case AUE_OPEN_RWC:
1027	case AUE_OPEN_RWTC:
1028	case AUE_OPEN_WC:
1029	case AUE_OPEN_WTC:
1030	case AUE_CREAT:
1031		if (ARG_IS_VALID(kar, ARG_MODE)) {
1032			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1033			kau_write(rec, tok);
1034		}
1035		/* fall through */
1036
1037	case AUE_OPEN_R:
1038	case AUE_OPEN_RT:
1039	case AUE_OPEN_RW:
1040	case AUE_OPEN_RWT:
1041	case AUE_OPEN_W:
1042	case AUE_OPEN_WT:
1043		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1044			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1045			kau_write(rec, tok);
1046		}
1047		UPATH1_VNODE1_TOKENS;
1048		break;
1049
1050	case AUE_PTRACE:
1051		if (ARG_IS_VALID(kar, ARG_CMD)) {
1052			tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
1053			kau_write(rec, tok);
1054		}
1055		if (ARG_IS_VALID(kar, ARG_ADDR)) {
1056			tok = au_to_arg32(3, "addr",
1057			    (u_int32_t)(uintptr_t)ar->ar_arg_addr);
1058			kau_write(rec, tok);
1059		}
1060		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1061			tok = au_to_arg32(4, "data", ar->ar_arg_value);
1062			kau_write(rec, tok);
1063		}
1064		PROCESS_PID_TOKENS(2);
1065		break;
1066
1067	case AUE_QUOTACTL:
1068		if (ARG_IS_VALID(kar, ARG_CMD)) {
1069			tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
1070			kau_write(rec, tok);
1071		}
1072		if (ARG_IS_VALID(kar, ARG_UID)) {
1073			tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
1074			kau_write(rec, tok);
1075		}
1076		UPATH1_VNODE1_TOKENS;
1077		break;
1078
1079	case AUE_REBOOT:
1080		if (ARG_IS_VALID(kar, ARG_CMD)) {
1081			tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
1082			kau_write(rec, tok);
1083		}
1084		break;
1085
1086	case AUE_SEMCTL:
1087		ar->ar_event = audit_semctl_to_event(ar->ar_arg_svipc_cmd);
1088		/* Fall through */
1089
1090	case AUE_SEMOP:
1091		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1092			tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
1093			kau_write(rec, tok);
1094			if (ar->ar_errno != EINVAL) {
1095				tok = au_to_ipc(AT_IPC_SEM,
1096				    ar->ar_arg_svipc_id);
1097				kau_write(rec, tok);
1098			}
1099		}
1100		break;
1101
1102	case AUE_SEMGET:
1103		if (ar->ar_errno == 0) {
1104			if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1105				tok = au_to_ipc(AT_IPC_SEM,
1106				    ar->ar_arg_svipc_id);
1107				kau_write(rec, tok);
1108			}
1109		}
1110		break;
1111
1112	case AUE_SETEGID:
1113		if (ARG_IS_VALID(kar, ARG_EGID)) {
1114			tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
1115			kau_write(rec, tok);
1116		}
1117		break;
1118
1119	case AUE_SETEUID:
1120		if (ARG_IS_VALID(kar, ARG_EUID)) {
1121			tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
1122			kau_write(rec, tok);
1123		}
1124		break;
1125
1126	case AUE_SETREGID:
1127		if (ARG_IS_VALID(kar, ARG_RGID)) {
1128			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1129			kau_write(rec, tok);
1130		}
1131		if (ARG_IS_VALID(kar, ARG_EGID)) {
1132			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1133			kau_write(rec, tok);
1134		}
1135		break;
1136
1137	case AUE_SETREUID:
1138		if (ARG_IS_VALID(kar, ARG_RUID)) {
1139			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1140			kau_write(rec, tok);
1141		}
1142		if (ARG_IS_VALID(kar, ARG_EUID)) {
1143			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1144			kau_write(rec, tok);
1145		}
1146		break;
1147
1148	case AUE_SETRESGID:
1149		if (ARG_IS_VALID(kar, ARG_RGID)) {
1150			tok = au_to_arg32(1, "rgid", ar->ar_arg_rgid);
1151			kau_write(rec, tok);
1152		}
1153		if (ARG_IS_VALID(kar, ARG_EGID)) {
1154			tok = au_to_arg32(2, "egid", ar->ar_arg_egid);
1155			kau_write(rec, tok);
1156		}
1157		if (ARG_IS_VALID(kar, ARG_SGID)) {
1158			tok = au_to_arg32(3, "sgid", ar->ar_arg_sgid);
1159			kau_write(rec, tok);
1160		}
1161		break;
1162
1163	case AUE_SETRESUID:
1164		if (ARG_IS_VALID(kar, ARG_RUID)) {
1165			tok = au_to_arg32(1, "ruid", ar->ar_arg_ruid);
1166			kau_write(rec, tok);
1167		}
1168		if (ARG_IS_VALID(kar, ARG_EUID)) {
1169			tok = au_to_arg32(2, "euid", ar->ar_arg_euid);
1170			kau_write(rec, tok);
1171		}
1172		if (ARG_IS_VALID(kar, ARG_SUID)) {
1173			tok = au_to_arg32(3, "suid", ar->ar_arg_suid);
1174			kau_write(rec, tok);
1175		}
1176		break;
1177
1178	case AUE_SETGID:
1179		if (ARG_IS_VALID(kar, ARG_GID)) {
1180			tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
1181			kau_write(rec, tok);
1182		}
1183		break;
1184
1185	case AUE_SETUID:
1186		if (ARG_IS_VALID(kar, ARG_UID)) {
1187			tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
1188			kau_write(rec, tok);
1189		}
1190		break;
1191
1192	case AUE_SETGROUPS:
1193		if (ARG_IS_VALID(kar, ARG_GROUPSET)) {
1194			for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
1195			{
1196				tok = au_to_arg32(1, "setgroups",
1197				    ar->ar_arg_groups.gidset[ctr]);
1198				kau_write(rec, tok);
1199			}
1200		}
1201		break;
1202
1203	case AUE_SETLOGIN:
1204		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1205			tok = au_to_text(ar->ar_arg_text);
1206			kau_write(rec, tok);
1207		}
1208		break;
1209
1210	case AUE_SETPRIORITY:
1211		if (ARG_IS_VALID(kar, ARG_CMD)) {
1212			tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
1213			kau_write(rec, tok);
1214		}
1215		if (ARG_IS_VALID(kar, ARG_UID)) {
1216			tok = au_to_arg32(2, "who", ar->ar_arg_uid);
1217			kau_write(rec, tok);
1218		}
1219		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1220			tok = au_to_arg32(2, "priority", ar->ar_arg_value);
1221			kau_write(rec, tok);
1222		}
1223		break;
1224
1225	case AUE_SETPRIVEXEC:
1226		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1227			tok = au_to_arg32(1, "flag", ar->ar_arg_value);
1228			kau_write(rec, tok);
1229		}
1230		break;
1231
1232	/* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
1233	case AUE_SHMAT:
1234		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1235			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1236			kau_write(rec, tok);
1237			/* XXXAUDIT: Does having the ipc token make sense? */
1238			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1239			kau_write(rec, tok);
1240		}
1241		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1242			tok = au_to_arg32(2, "shmaddr",
1243			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1244			kau_write(rec, tok);
1245		}
1246		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1247			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1248			kau_write(rec, tok);
1249		}
1250		break;
1251
1252	case AUE_SHMCTL:
1253		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1254			tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
1255			kau_write(rec, tok);
1256			/* XXXAUDIT: Does having the ipc token make sense? */
1257			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1258			kau_write(rec, tok);
1259		}
1260		switch (ar->ar_arg_svipc_cmd) {
1261		case IPC_STAT:
1262			ar->ar_event = AUE_SHMCTL_STAT;
1263			break;
1264		case IPC_RMID:
1265			ar->ar_event = AUE_SHMCTL_RMID;
1266			break;
1267		case IPC_SET:
1268			ar->ar_event = AUE_SHMCTL_SET;
1269			if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1270				tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1271				kau_write(rec, tok);
1272			}
1273			break;
1274		default:
1275			break;	/* We will audit a bad command */
1276		}
1277		break;
1278
1279	case AUE_SHMDT:
1280		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1281			tok = au_to_arg32(1, "shmaddr",
1282			    (int)(uintptr_t)ar->ar_arg_svipc_addr);
1283			kau_write(rec, tok);
1284		}
1285		break;
1286
1287	case AUE_SHMGET:
1288		/* This is unusual; the return value is in an argument token */
1289		if (ARG_IS_VALID(kar, ARG_SVIPC_ID)) {
1290			tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
1291			kau_write(rec, tok);
1292			tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
1293			kau_write(rec, tok);
1294		}
1295		if (ARG_IS_VALID(kar, ARG_SVIPC_PERM)) {
1296			tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
1297			kau_write(rec, tok);
1298		}
1299		break;
1300
1301	/* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
1302	 * and AUE_SEMUNLINK are Posix IPC */
1303	case AUE_SHMOPEN:
1304		if (ARG_IS_VALID(kar, ARG_SVIPC_ADDR)) {
1305			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1306			kau_write(rec, tok);
1307		}
1308		if (ARG_IS_VALID(kar, ARG_MODE)) {
1309			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1310			kau_write(rec, tok);
1311		}
1312	case AUE_SHMUNLINK:
1313		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1314			tok = au_to_text(ar->ar_arg_text);
1315			kau_write(rec, tok);
1316		}
1317		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1318		/* Create an ipc_perm token */
1319			struct ipc_perm perm;
1320			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1321			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1322			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1323			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1324			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1325			perm.seq = 0;
1326			perm.key = 0;
1327			tok = au_to_ipc_perm(&perm);
1328			kau_write(rec, tok);
1329		}
1330		break;
1331
1332	case AUE_SEMOPEN:
1333		if (ARG_IS_VALID(kar, ARG_FFLAGS)) {
1334			tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1335			kau_write(rec, tok);
1336		}
1337		if (ARG_IS_VALID(kar, ARG_MODE)) {
1338			tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1339			kau_write(rec, tok);
1340		}
1341		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1342			tok = au_to_arg32(4, "value", ar->ar_arg_value);
1343			kau_write(rec, tok);
1344		}
1345		/* fall through */
1346
1347	case AUE_SEMUNLINK:
1348		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1349			tok = au_to_text(ar->ar_arg_text);
1350			kau_write(rec, tok);
1351		}
1352		if (ARG_IS_VALID(kar, ARG_POSIX_IPC_PERM)) {
1353		/* Create an ipc_perm token */
1354			struct ipc_perm perm;
1355			perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1356			perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1357			perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1358			perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1359			perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1360			perm.seq = 0;
1361			perm.key = 0;
1362			tok = au_to_ipc_perm(&perm);
1363			kau_write(rec, tok);
1364		}
1365		break;
1366
1367	case AUE_SEMCLOSE:
1368		if (ARG_IS_VALID(kar, ARG_FD)) {
1369			tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1370			kau_write(rec, tok);
1371		}
1372		break;
1373
1374	case AUE_SYMLINK:
1375		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1376			tok = au_to_text(ar->ar_arg_text);
1377			kau_write(rec, tok);
1378		}
1379		UPATH1_VNODE1_TOKENS;
1380		break;
1381
1382	case AUE_SYSCTL:
1383		if (ARG_IS_VALID(kar, ARG_CTLNAME | ARG_LEN)) {
1384			for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1385				tok = au_to_arg32(1, "name",
1386				    ar->ar_arg_ctlname[ctr]);
1387				kau_write(rec, tok);
1388			}
1389		}
1390		if (ARG_IS_VALID(kar, ARG_VALUE)) {
1391			tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1392			kau_write(rec, tok);
1393		}
1394		if (ARG_IS_VALID(kar, ARG_TEXT)) {
1395			tok = au_to_text(ar->ar_arg_text);
1396			kau_write(rec, tok);
1397		}
1398		break;
1399
1400	case AUE_UMASK:
1401		if (ARG_IS_VALID(kar, ARG_MASK)) {
1402			tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1403			kau_write(rec, tok);
1404		}
1405		tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1406		kau_write(rec, tok);
1407		break;
1408
1409	case AUE_WAIT4:
1410		if (ARG_IS_VALID(kar, ARG_PID)) {
1411			tok = au_to_arg32(0, "pid", ar->ar_arg_pid);
1412			kau_write(rec, tok);
1413		}
1414		break;
1415
1416	case AUE_NULL:
1417	default:
1418		printf("BSM conversion requested for unknown event %d\n",
1419		    ar->ar_event);
1420		/* Write the subject token so it is properly freed here. */
1421		kau_write(rec, subj_tok);
1422		kau_free(rec);
1423		return (BSM_NOAUDIT);
1424	}
1425
1426	kau_write(rec, subj_tok);
1427	tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
1428	kau_write(rec, tok);  /* Every record gets a return token */
1429
1430	kau_close(rec, &ar->ar_endtime, ar->ar_event);
1431
1432	*pau = rec;
1433	return (BSM_SUCCESS);
1434}
1435
1436/*
1437 * Verify that a record is a valid BSM record. This verification is simple
1438 * now, but may be expanded on sometime in the future.  Return 1 if the
1439 * record is good, 0 otherwise.
1440 */
1441int
1442bsm_rec_verify(void *rec)
1443{
1444	char c = *(char *)rec;
1445
1446	/*
1447	 * Check the token ID of the first token; it has to be a header
1448	 * token.
1449	 *
1450	 * XXXAUDIT There needs to be a token structure to map a token.
1451	 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1452	 */
1453	if ((c != AUT_HEADER32) && (c != AUT_HEADER32_EX) &&
1454	    (c != AUT_HEADER64) && (c != AUT_HEADER64_EX))
1455		return (0);
1456	return (1);
1457}
1458