bsm_token.c revision 191270
1181053Srwatson/*-
2187215Srwatson * Copyright (c) 2004-2009 Apple Inc.
3155192Srwatson * Copyright (c) 2005 SPARTA, Inc.
4155192Srwatson * All rights reserved.
5155192Srwatson *
6155192Srwatson * This code was developed in part by Robert N. M. Watson, Senior Principal
7155192Srwatson * Scientist, SPARTA, Inc.
8155192Srwatson *
9155192Srwatson * Redistribution and use in source and binary forms, with or without
10155192Srwatson * modification, are permitted provided that the following conditions
11155192Srwatson * are met:
12155192Srwatson * 1.  Redistributions of source code must retain the above copyright
13155192Srwatson *     notice, this list of conditions and the following disclaimer.
14155192Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
15155192Srwatson *     notice, this list of conditions and the following disclaimer in the
16155192Srwatson *     documentation and/or other materials provided with the distribution.
17180701Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
18155192Srwatson *     its contributors may be used to endorse or promote products derived
19155192Srwatson *     from this software without specific prior written permission.
20155192Srwatson *
21155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31155192Srwatson * POSSIBILITY OF SUCH DAMAGE.
32185573Srwatson *
33191270Srwatson * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#91
34155192Srwatson */
35155192Srwatson
36178186Srwatson#include <sys/cdefs.h>
37178186Srwatson__FBSDID("$FreeBSD: head/sys/security/audit/audit_bsm_token.c 191270 2009-04-19 14:53:17Z rwatson $");
38178186Srwatson
39155192Srwatson#include <sys/types.h>
40155192Srwatson#include <sys/endian.h>
41159259Srwatson#include <sys/queue.h>
42155192Srwatson#include <sys/socket.h>
43155192Srwatson#include <sys/time.h>
44155192Srwatson
45155192Srwatson#include <sys/ipc.h>
46155192Srwatson#include <sys/libkern.h>
47155192Srwatson#include <sys/malloc.h>
48155192Srwatson#include <sys/un.h>
49155192Srwatson
50155192Srwatson#include <netinet/in.h>
51155192Srwatson#include <netinet/in_systm.h>
52155192Srwatson#include <netinet/ip.h>
53155192Srwatson
54155192Srwatson
55155192Srwatson#include <bsm/audit.h>
56155192Srwatson#include <bsm/audit_internal.h>
57155192Srwatson#include <bsm/audit_record.h>
58155192Srwatson#include <security/audit/audit.h>
59155192Srwatson#include <security/audit/audit_private.h>
60155192Srwatson
61155192Srwatson#define	GET_TOKEN_AREA(t, dptr, length) do {				\
62155192Srwatson	t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);		\
63155192Srwatson	t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);	\
64155192Srwatson	t->len = length;						\
65155192Srwatson	dptr = t->t_data;						\
66155192Srwatson} while (0)
67155192Srwatson
68155192Srwatson/*
69155192Srwatson * token ID                1 byte
70155192Srwatson * argument #              1 byte
71155192Srwatson * argument value          4 bytes/8 bytes (32-bit/64-bit value)
72155192Srwatson * text length             2 bytes
73155192Srwatson * text                    N bytes + 1 terminating NULL byte
74155192Srwatson */
75155192Srwatsontoken_t *
76185573Srwatsonau_to_arg32(char n, const char *text, u_int32_t v)
77155192Srwatson{
78155192Srwatson	token_t *t;
79155192Srwatson	u_char *dptr = NULL;
80155192Srwatson	u_int16_t textlen;
81155192Srwatson
82155192Srwatson	textlen = strlen(text);
83155192Srwatson	textlen += 1;
84155192Srwatson
85155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
86155192Srwatson	    sizeof(u_int16_t) + textlen);
87155192Srwatson
88155192Srwatson	ADD_U_CHAR(dptr, AUT_ARG32);
89155192Srwatson	ADD_U_CHAR(dptr, n);
90155192Srwatson	ADD_U_INT32(dptr, v);
91155192Srwatson	ADD_U_INT16(dptr, textlen);
92155192Srwatson	ADD_STRING(dptr, text, textlen);
93155192Srwatson
94155192Srwatson	return (t);
95155192Srwatson}
96155192Srwatson
97155192Srwatsontoken_t *
98185573Srwatsonau_to_arg64(char n, const char *text, u_int64_t v)
99155192Srwatson{
100155192Srwatson	token_t *t;
101155192Srwatson	u_char *dptr = NULL;
102155192Srwatson	u_int16_t textlen;
103155192Srwatson
104155192Srwatson	textlen = strlen(text);
105155192Srwatson	textlen += 1;
106155192Srwatson
107155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
108155192Srwatson	    sizeof(u_int16_t) + textlen);
109155192Srwatson
110155192Srwatson	ADD_U_CHAR(dptr, AUT_ARG64);
111155192Srwatson	ADD_U_CHAR(dptr, n);
112155192Srwatson	ADD_U_INT64(dptr, v);
113155192Srwatson	ADD_U_INT16(dptr, textlen);
114155192Srwatson	ADD_STRING(dptr, text, textlen);
115155192Srwatson
116155192Srwatson	return (t);
117155192Srwatson}
118155192Srwatson
119155192Srwatsontoken_t *
120185573Srwatsonau_to_arg(char n, const char *text, u_int32_t v)
121155192Srwatson{
122155192Srwatson
123155192Srwatson	return (au_to_arg32(n, text, v));
124155192Srwatson}
125155192Srwatson
126155192Srwatson#if defined(_KERNEL) || defined(KERNEL)
127155192Srwatson/*
128155192Srwatson * token ID                1 byte
129155192Srwatson * file access mode        4 bytes
130155192Srwatson * owner user ID           4 bytes
131155192Srwatson * owner group ID          4 bytes
132155192Srwatson * file system ID          4 bytes
133155192Srwatson * node ID                 8 bytes
134155192Srwatson * device                  4 bytes/8 bytes (32-bit/64-bit)
135155192Srwatson */
136155192Srwatsontoken_t *
137155192Srwatsonau_to_attr32(struct vnode_au_info *vni)
138155192Srwatson{
139155192Srwatson	token_t *t;
140155192Srwatson	u_char *dptr = NULL;
141155192Srwatson	u_int16_t pad0_16 = 0;
142189279Srwatson	u_int32_t pad0_32 = 0;
143155192Srwatson
144155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
145155192Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
146155192Srwatson
147155192Srwatson	ADD_U_CHAR(dptr, AUT_ATTR32);
148155192Srwatson
149155192Srwatson	/*
150186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
151186647Srwatson	 * so pad with 0.
152186647Srwatson	 *
153186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
154186647Srwatson	 *
155186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
156155192Srwatson	 */
157155192Srwatson	ADD_U_INT16(dptr, pad0_16);
158155192Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
159155192Srwatson
160155192Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
161155192Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
162155192Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
163155192Srwatson
164155192Srwatson	/*
165181053Srwatson	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
166155192Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
167155192Srwatson	 * could pick this out at compile-time, it would be better, so as to
168155192Srwatson	 * avoid the else case below.
169155192Srwatson	 */
170155192Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
171155192Srwatson		ADD_U_INT32(dptr, pad0_32);
172155192Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
173155192Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
174155192Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
175155192Srwatson	else
176155192Srwatson		ADD_U_INT64(dptr, 0LL);
177155192Srwatson
178155192Srwatson	ADD_U_INT32(dptr, vni->vn_dev);
179155192Srwatson
180155192Srwatson	return (t);
181155192Srwatson}
182155192Srwatson
183155192Srwatsontoken_t *
184155192Srwatsonau_to_attr64(struct vnode_au_info *vni)
185155192Srwatson{
186168783Srwatson	token_t *t;
187168783Srwatson	u_char *dptr = NULL;
188168783Srwatson	u_int16_t pad0_16 = 0;
189189279Srwatson	u_int32_t pad0_32 = 0;
190155192Srwatson
191168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
192168783Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
193168783Srwatson
194168783Srwatson	ADD_U_CHAR(dptr, AUT_ATTR64);
195168783Srwatson
196168783Srwatson	/*
197186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
198186647Srwatson	 * so pad with 0.
199186647Srwatson	 *
200186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
201186647Srwatson	 *
202186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
203168783Srwatson	 */
204168783Srwatson	ADD_U_INT16(dptr, pad0_16);
205168783Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
206168783Srwatson
207168783Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
208168783Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
209168783Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
210168783Srwatson
211168783Srwatson	/*
212168783Srwatson	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
213168783Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
214168783Srwatson	 * could pick this out at compile-time, it would be better, so as to
215168783Srwatson	 * avoid the else case below.
216168783Srwatson	 */
217168783Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
218168783Srwatson		ADD_U_INT32(dptr, pad0_32);
219168783Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
220168783Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
221168783Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
222168783Srwatson	else
223168783Srwatson		ADD_U_INT64(dptr, 0LL);
224168783Srwatson
225168783Srwatson	ADD_U_INT64(dptr, vni->vn_dev);
226168783Srwatson
227168783Srwatson	return (t);
228155192Srwatson}
229155192Srwatson
230155192Srwatsontoken_t *
231155192Srwatsonau_to_attr(struct vnode_au_info *vni)
232155192Srwatson{
233155192Srwatson
234155192Srwatson	return (au_to_attr32(vni));
235155192Srwatson}
236155192Srwatson#endif /* !(defined(_KERNEL) || defined(KERNEL) */
237155192Srwatson
238155192Srwatson/*
239155192Srwatson * token ID                1 byte
240155192Srwatson * how to print            1 byte
241155192Srwatson * basic unit              1 byte
242155192Srwatson * unit count              1 byte
243155192Srwatson * data items              (depends on basic unit)
244155192Srwatson */
245155192Srwatsontoken_t *
246185573Srwatsonau_to_data(char unit_print, char unit_type, char unit_count, const char *p)
247155192Srwatson{
248155192Srwatson	token_t *t;
249155192Srwatson	u_char *dptr = NULL;
250155192Srwatson	size_t datasize, totdata;
251155192Srwatson
252155192Srwatson	/* Determine the size of the basic unit. */
253155192Srwatson	switch (unit_type) {
254155192Srwatson	case AUR_BYTE:
255159259Srwatson	/* case AUR_CHAR: */
256155192Srwatson		datasize = AUR_BYTE_SIZE;
257155192Srwatson		break;
258155192Srwatson
259155192Srwatson	case AUR_SHORT:
260155192Srwatson		datasize = AUR_SHORT_SIZE;
261155192Srwatson		break;
262155192Srwatson
263159259Srwatson	case AUR_INT32:
264159259Srwatson	/* case AUR_INT: */
265159259Srwatson		datasize = AUR_INT32_SIZE;
266155192Srwatson		break;
267155192Srwatson
268159259Srwatson	case AUR_INT64:
269159259Srwatson		datasize = AUR_INT64_SIZE;
270159259Srwatson		break;
271159259Srwatson
272155192Srwatson	default:
273180709Srwatson		return (NULL);
274155192Srwatson	}
275155192Srwatson
276155192Srwatson	totdata = datasize * unit_count;
277155192Srwatson
278159259Srwatson	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
279155192Srwatson
280186647Srwatson	/*
281186647Srwatson	 * XXXRW: We should be byte-swapping each data item for multi-byte
282186647Srwatson	 * types.
283186647Srwatson	 */
284155192Srwatson	ADD_U_CHAR(dptr, AUT_DATA);
285155192Srwatson	ADD_U_CHAR(dptr, unit_print);
286155192Srwatson	ADD_U_CHAR(dptr, unit_type);
287155192Srwatson	ADD_U_CHAR(dptr, unit_count);
288155192Srwatson	ADD_MEM(dptr, p, totdata);
289155192Srwatson
290155192Srwatson	return (t);
291155192Srwatson}
292155192Srwatson
293155192Srwatson
294155192Srwatson/*
295155192Srwatson * token ID                1 byte
296155192Srwatson * status		   4 bytes
297155192Srwatson * return value            4 bytes
298155192Srwatson */
299155192Srwatsontoken_t *
300155192Srwatsonau_to_exit(int retval, int err)
301155192Srwatson{
302155192Srwatson	token_t *t;
303155192Srwatson	u_char *dptr = NULL;
304155192Srwatson
305155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
306155192Srwatson
307155192Srwatson	ADD_U_CHAR(dptr, AUT_EXIT);
308155192Srwatson	ADD_U_INT32(dptr, err);
309155192Srwatson	ADD_U_INT32(dptr, retval);
310155192Srwatson
311155192Srwatson	return (t);
312155192Srwatson}
313155192Srwatson
314155192Srwatson/*
315155192Srwatson */
316155192Srwatsontoken_t *
317155192Srwatsonau_to_groups(int *groups)
318155192Srwatson{
319155192Srwatson
320185573Srwatson	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
321155192Srwatson}
322155192Srwatson
323155192Srwatson/*
324155192Srwatson * token ID                1 byte
325155192Srwatson * number groups           2 bytes
326155192Srwatson * group list              count * 4 bytes
327155192Srwatson */
328155192Srwatsontoken_t *
329155192Srwatsonau_to_newgroups(u_int16_t n, gid_t *groups)
330155192Srwatson{
331155192Srwatson	token_t *t;
332155192Srwatson	u_char *dptr = NULL;
333155192Srwatson	int i;
334155192Srwatson
335155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
336155192Srwatson	    n * sizeof(u_int32_t));
337155192Srwatson
338155192Srwatson	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
339155192Srwatson	ADD_U_INT16(dptr, n);
340155192Srwatson	for (i = 0; i < n; i++)
341155192Srwatson		ADD_U_INT32(dptr, groups[i]);
342155192Srwatson
343155192Srwatson	return (t);
344155192Srwatson}
345155192Srwatson
346155192Srwatson/*
347155192Srwatson * token ID                1 byte
348155192Srwatson * internet address        4 bytes
349155192Srwatson */
350155192Srwatsontoken_t *
351155192Srwatsonau_to_in_addr(struct in_addr *internet_addr)
352155192Srwatson{
353155192Srwatson	token_t *t;
354155192Srwatson	u_char *dptr = NULL;
355155192Srwatson
356159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
357155192Srwatson
358155192Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR);
359159259Srwatson	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
360155192Srwatson
361155192Srwatson	return (t);
362155192Srwatson}
363155192Srwatson
364155192Srwatson/*
365155192Srwatson * token ID                1 byte
366155192Srwatson * address type/length     4 bytes
367185573Srwatson * address                16 bytes
368155192Srwatson */
369155192Srwatsontoken_t *
370155192Srwatsonau_to_in_addr_ex(struct in6_addr *internet_addr)
371155192Srwatson{
372155192Srwatson	token_t *t;
373155192Srwatson	u_char *dptr = NULL;
374171066Scsjp	u_int32_t type = AU_IPv6;
375155192Srwatson
376159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
377155192Srwatson
378155192Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
379155192Srwatson	ADD_U_INT32(dptr, type);
380171066Scsjp	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
381155192Srwatson
382155192Srwatson	return (t);
383155192Srwatson}
384155192Srwatson
385155192Srwatson/*
386155192Srwatson * token ID                1 byte
387155192Srwatson * ip header		   20 bytes
388165604Srwatson *
389165604Srwatson * The IP header should be submitted in network byte order.
390155192Srwatson */
391155192Srwatsontoken_t *
392155192Srwatsonau_to_ip(struct ip *ip)
393155192Srwatson{
394155192Srwatson	token_t *t;
395155192Srwatson	u_char *dptr = NULL;
396155192Srwatson
397155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
398155192Srwatson
399155192Srwatson	ADD_U_CHAR(dptr, AUT_IP);
400155192Srwatson	ADD_MEM(dptr, ip, sizeof(struct ip));
401155192Srwatson
402155192Srwatson	return (t);
403155192Srwatson}
404155192Srwatson
405155192Srwatson/*
406155192Srwatson * token ID                1 byte
407155192Srwatson * object ID type          1 byte
408155192Srwatson * object ID               4 bytes
409155192Srwatson */
410155192Srwatsontoken_t *
411155192Srwatsonau_to_ipc(char type, int id)
412155192Srwatson{
413155192Srwatson	token_t *t;
414155192Srwatson	u_char *dptr = NULL;
415155192Srwatson
416155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
417155192Srwatson
418155192Srwatson	ADD_U_CHAR(dptr, AUT_IPC);
419155192Srwatson	ADD_U_CHAR(dptr, type);
420155192Srwatson	ADD_U_INT32(dptr, id);
421155192Srwatson
422155192Srwatson	return (t);
423155192Srwatson}
424155192Srwatson
425155192Srwatson/*
426155192Srwatson * token ID                1 byte
427155192Srwatson * owner user ID           4 bytes
428155192Srwatson * owner group ID          4 bytes
429155192Srwatson * creator user ID         4 bytes
430155192Srwatson * creator group ID        4 bytes
431155192Srwatson * access mode             4 bytes
432155192Srwatson * slot sequence #         4 bytes
433155192Srwatson * key                     4 bytes
434155192Srwatson */
435155192Srwatsontoken_t *
436155192Srwatsonau_to_ipc_perm(struct ipc_perm *perm)
437155192Srwatson{
438155192Srwatson	token_t *t;
439155192Srwatson	u_char *dptr = NULL;
440155192Srwatson	u_int16_t pad0 = 0;
441155192Srwatson
442189279Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
443189279Srwatson	    sizeof(u_int32_t));
444155192Srwatson
445155192Srwatson	ADD_U_CHAR(dptr, AUT_IPC_PERM);
446155192Srwatson
447155192Srwatson	/*
448186647Srwatson	 * Systems vary significantly in what types they use in struct
449186647Srwatson	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
450186647Srwatson	 * allow for that, as BSM define 32-bit values here.
451186647Srwatson	 * Some systems define the sizes for ipc_perm members as 2 bytes;
452186647Srwatson	 * BSM defines 4 so pad with 0.
453186647Srwatson	 *
454186647Srwatson	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
455186647Srwatson	 * need to be handled.
456155192Srwatson	 */
457186647Srwatson	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
458186647Srwatson		ADD_U_INT16(dptr, pad0);
459186647Srwatson		ADD_U_INT16(dptr, perm->uid);
460186647Srwatson		ADD_U_INT16(dptr, pad0);
461186647Srwatson		ADD_U_INT16(dptr, perm->gid);
462186647Srwatson		ADD_U_INT16(dptr, pad0);
463186647Srwatson		ADD_U_INT16(dptr, perm->cuid);
464186647Srwatson		ADD_U_INT16(dptr, pad0);
465186647Srwatson		ADD_U_INT16(dptr, perm->cgid);
466186647Srwatson	} else {
467186647Srwatson		ADD_U_INT32(dptr, perm->uid);
468186647Srwatson		ADD_U_INT32(dptr, perm->gid);
469186647Srwatson		ADD_U_INT32(dptr, perm->cuid);
470186647Srwatson		ADD_U_INT32(dptr, perm->cgid);
471186647Srwatson	}
472155192Srwatson
473155192Srwatson	ADD_U_INT16(dptr, pad0);
474186647Srwatson	ADD_U_INT16(dptr, perm->mode);
475155192Srwatson
476155192Srwatson	ADD_U_INT16(dptr, pad0);
477155192Srwatson
478155192Srwatson	ADD_U_INT16(dptr, perm->seq);
479155192Srwatson
480155192Srwatson	ADD_U_INT32(dptr, perm->key);
481155192Srwatson
482155192Srwatson	return (t);
483155192Srwatson}
484155192Srwatson
485155192Srwatson/*
486155192Srwatson * token ID                1 byte
487155192Srwatson * port IP address         2 bytes
488155192Srwatson */
489155192Srwatsontoken_t *
490155192Srwatsonau_to_iport(u_int16_t iport)
491155192Srwatson{
492155192Srwatson	token_t *t;
493155192Srwatson	u_char *dptr = NULL;
494155192Srwatson
495155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
496155192Srwatson
497155192Srwatson	ADD_U_CHAR(dptr, AUT_IPORT);
498155192Srwatson	ADD_U_INT16(dptr, iport);
499155192Srwatson
500155192Srwatson	return (t);
501155192Srwatson}
502155192Srwatson
503155192Srwatson/*
504155192Srwatson * token ID                1 byte
505155192Srwatson * size                    2 bytes
506155192Srwatson * data                    size bytes
507155192Srwatson */
508155192Srwatsontoken_t *
509185573Srwatsonau_to_opaque(const char *data, u_int16_t bytes)
510155192Srwatson{
511155192Srwatson	token_t *t;
512155192Srwatson	u_char *dptr = NULL;
513155192Srwatson
514155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
515155192Srwatson
516155192Srwatson	ADD_U_CHAR(dptr, AUT_OPAQUE);
517155192Srwatson	ADD_U_INT16(dptr, bytes);
518155192Srwatson	ADD_MEM(dptr, data, bytes);
519155192Srwatson
520155192Srwatson	return (t);
521155192Srwatson}
522155192Srwatson
523155192Srwatson/*
524155192Srwatson * token ID                1 byte
525155192Srwatson * seconds of time         4 bytes
526155192Srwatson * milliseconds of time    4 bytes
527155192Srwatson * file name len           2 bytes
528155192Srwatson * file pathname           N bytes + 1 terminating NULL byte
529155192Srwatson */
530155192Srwatsontoken_t *
531185573Srwatsonau_to_file(const char *file, struct timeval tm)
532155192Srwatson{
533155192Srwatson	token_t *t;
534155192Srwatson	u_char *dptr = NULL;
535155192Srwatson	u_int16_t filelen;
536155192Srwatson	u_int32_t timems;
537155192Srwatson
538155192Srwatson	filelen = strlen(file);
539155192Srwatson	filelen += 1;
540155192Srwatson
541155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
542155192Srwatson	    sizeof(u_int16_t) + filelen);
543155192Srwatson
544155192Srwatson	timems = tm.tv_usec/1000;
545155192Srwatson
546155192Srwatson	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
547155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
548155192Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
549155192Srwatson	ADD_U_INT16(dptr, filelen);
550155192Srwatson	ADD_STRING(dptr, file, filelen);
551155192Srwatson
552155192Srwatson	return (t);
553155192Srwatson}
554155192Srwatson
555155192Srwatson/*
556155192Srwatson * token ID                1 byte
557155192Srwatson * text length             2 bytes
558155192Srwatson * text                    N bytes + 1 terminating NULL byte
559155192Srwatson */
560155192Srwatsontoken_t *
561185573Srwatsonau_to_text(const char *text)
562155192Srwatson{
563155192Srwatson	token_t *t;
564155192Srwatson	u_char *dptr = NULL;
565155192Srwatson	u_int16_t textlen;
566155192Srwatson
567155192Srwatson	textlen = strlen(text);
568155192Srwatson	textlen += 1;
569155192Srwatson
570186647Srwatson	/* XXXRW: Should validate length against token size limit. */
571186647Srwatson
572155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
573155192Srwatson
574155192Srwatson	ADD_U_CHAR(dptr, AUT_TEXT);
575155192Srwatson	ADD_U_INT16(dptr, textlen);
576155192Srwatson	ADD_STRING(dptr, text, textlen);
577155192Srwatson
578155192Srwatson	return (t);
579155192Srwatson}
580155192Srwatson
581155192Srwatson/*
582155192Srwatson * token ID                1 byte
583155192Srwatson * path length             2 bytes
584155192Srwatson * path                    N bytes + 1 terminating NULL byte
585155192Srwatson */
586155192Srwatsontoken_t *
587185573Srwatsonau_to_path(const char *text)
588155192Srwatson{
589155192Srwatson	token_t *t;
590155192Srwatson	u_char *dptr = NULL;
591155192Srwatson	u_int16_t textlen;
592155192Srwatson
593155192Srwatson	textlen = strlen(text);
594155192Srwatson	textlen += 1;
595155192Srwatson
596155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
597155192Srwatson
598155192Srwatson	ADD_U_CHAR(dptr, AUT_PATH);
599155192Srwatson	ADD_U_INT16(dptr, textlen);
600155192Srwatson	ADD_STRING(dptr, text, textlen);
601155192Srwatson
602155192Srwatson	return (t);
603155192Srwatson}
604155192Srwatson
605155192Srwatson/*
606155192Srwatson * token ID                1 byte
607155192Srwatson * audit ID                4 bytes
608155192Srwatson * effective user ID       4 bytes
609155192Srwatson * effective group ID      4 bytes
610155192Srwatson * real user ID            4 bytes
611155192Srwatson * real group ID           4 bytes
612155192Srwatson * process ID              4 bytes
613155192Srwatson * session ID              4 bytes
614155192Srwatson * terminal ID
615155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
616155192Srwatson *   machine address       4 bytes
617155192Srwatson */
618155192Srwatsontoken_t *
619155192Srwatsonau_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
620155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
621155192Srwatson{
622155192Srwatson	token_t *t;
623155192Srwatson	u_char *dptr = NULL;
624155192Srwatson
625155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
626155192Srwatson
627155192Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32);
628155192Srwatson	ADD_U_INT32(dptr, auid);
629155192Srwatson	ADD_U_INT32(dptr, euid);
630155192Srwatson	ADD_U_INT32(dptr, egid);
631155192Srwatson	ADD_U_INT32(dptr, ruid);
632155192Srwatson	ADD_U_INT32(dptr, rgid);
633155192Srwatson	ADD_U_INT32(dptr, pid);
634155192Srwatson	ADD_U_INT32(dptr, sid);
635155192Srwatson	ADD_U_INT32(dptr, tid->port);
636186647Srwatson
637186647Srwatson	/*
638186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
639186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
640186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
641186647Srwatson	 * addresses for process32 tokens.
642186647Srwatson	 */
643159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
644155192Srwatson
645155192Srwatson	return (t);
646155192Srwatson}
647155192Srwatson
648155192Srwatsontoken_t *
649168783Srwatsonau_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
650168783Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
651155192Srwatson{
652168783Srwatson	token_t *t;
653168783Srwatson	u_char *dptr = NULL;
654155192Srwatson
655168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
656168783Srwatson	    sizeof(u_int64_t));
657168783Srwatson
658168783Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64);
659168783Srwatson	ADD_U_INT32(dptr, auid);
660168783Srwatson	ADD_U_INT32(dptr, euid);
661168783Srwatson	ADD_U_INT32(dptr, egid);
662168783Srwatson	ADD_U_INT32(dptr, ruid);
663168783Srwatson	ADD_U_INT32(dptr, rgid);
664168783Srwatson	ADD_U_INT32(dptr, pid);
665168783Srwatson	ADD_U_INT32(dptr, sid);
666168783Srwatson	ADD_U_INT64(dptr, tid->port);
667186647Srwatson
668186647Srwatson	/*
669186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
670186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
671186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
672186647Srwatson	 * addresses for process64 tokens.
673186647Srwatson	 */
674168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
675168783Srwatson
676168783Srwatson	return (t);
677155192Srwatson}
678155192Srwatson
679155192Srwatsontoken_t *
680168783Srwatsonau_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
681168783Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
682155192Srwatson{
683155192Srwatson
684155192Srwatson	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
685155192Srwatson	    tid));
686155192Srwatson}
687155192Srwatson
688155192Srwatson/*
689155192Srwatson * token ID                1 byte
690155192Srwatson * audit ID                4 bytes
691155192Srwatson * effective user ID       4 bytes
692155192Srwatson * effective group ID      4 bytes
693155192Srwatson * real user ID            4 bytes
694155192Srwatson * real group ID           4 bytes
695155192Srwatson * process ID              4 bytes
696155192Srwatson * session ID              4 bytes
697155192Srwatson * terminal ID
698155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
699155192Srwatson *   address type-len      4 bytes
700185573Srwatson *   machine address      16 bytes
701155192Srwatson */
702155192Srwatsontoken_t *
703155192Srwatsonau_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
704155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
705155192Srwatson{
706155192Srwatson	token_t *t;
707155192Srwatson	u_char *dptr = NULL;
708155192Srwatson
709168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
710168688Scsjp	    ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
711185573Srwatson	if (tid->at_type == AU_IPv4)
712185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
713185573Srwatson		    10 * sizeof(u_int32_t));
714159686Swsalamon	else
715185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
716185573Srwatson		    13 * sizeof(u_int32_t));
717155192Srwatson
718155192Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
719155192Srwatson	ADD_U_INT32(dptr, auid);
720155192Srwatson	ADD_U_INT32(dptr, euid);
721155192Srwatson	ADD_U_INT32(dptr, egid);
722155192Srwatson	ADD_U_INT32(dptr, ruid);
723155192Srwatson	ADD_U_INT32(dptr, rgid);
724155192Srwatson	ADD_U_INT32(dptr, pid);
725155192Srwatson	ADD_U_INT32(dptr, sid);
726155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
727155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
728185573Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
729185573Srwatson	if (tid->at_type == AU_IPv6) {
730185573Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
731185573Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
732185573Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
733185573Srwatson	}
734170131Srwatson
735155192Srwatson	return (t);
736155192Srwatson}
737155192Srwatson
738155192Srwatsontoken_t *
739155192Srwatsonau_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
740155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
741155192Srwatson{
742168783Srwatson	token_t *t;
743168783Srwatson	u_char *dptr = NULL;
744155192Srwatson
745168783Srwatson	if (tid->at_type == AU_IPv4)
746168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
747168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
748168783Srwatson		    2 * sizeof(u_int32_t));
749168783Srwatson	else if (tid->at_type == AU_IPv6)
750168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
751168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
752168783Srwatson		    5 * sizeof(u_int32_t));
753168783Srwatson	else
754168783Srwatson		panic("au_to_process64_ex: invalidate at_type (%d)",
755168783Srwatson		    tid->at_type);
756168783Srwatson
757168783Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
758168783Srwatson	ADD_U_INT32(dptr, auid);
759168783Srwatson	ADD_U_INT32(dptr, euid);
760168783Srwatson	ADD_U_INT32(dptr, egid);
761168783Srwatson	ADD_U_INT32(dptr, ruid);
762168783Srwatson	ADD_U_INT32(dptr, rgid);
763168783Srwatson	ADD_U_INT32(dptr, pid);
764168783Srwatson	ADD_U_INT32(dptr, sid);
765168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
766168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
767168783Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
768168783Srwatson	if (tid->at_type == AU_IPv6) {
769168783Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
770168783Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
771168783Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
772168783Srwatson	}
773168783Srwatson
774168783Srwatson	return (t);
775155192Srwatson}
776155192Srwatson
777155192Srwatsontoken_t *
778155192Srwatsonau_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
779155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
780155192Srwatson{
781155192Srwatson
782155192Srwatson	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
783155192Srwatson	    tid));
784155192Srwatson}
785155192Srwatson
786155192Srwatson/*
787155192Srwatson * token ID                1 byte
788155192Srwatson * error status            1 byte
789155192Srwatson * return value            4 bytes/8 bytes (32-bit/64-bit value)
790155192Srwatson */
791155192Srwatsontoken_t *
792155192Srwatsonau_to_return32(char status, u_int32_t ret)
793155192Srwatson{
794155192Srwatson	token_t *t;
795155192Srwatson	u_char *dptr = NULL;
796155192Srwatson
797155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
798155192Srwatson
799155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN32);
800155192Srwatson	ADD_U_CHAR(dptr, status);
801155192Srwatson	ADD_U_INT32(dptr, ret);
802155192Srwatson
803155192Srwatson	return (t);
804155192Srwatson}
805155192Srwatson
806155192Srwatsontoken_t *
807155192Srwatsonau_to_return64(char status, u_int64_t ret)
808155192Srwatson{
809155192Srwatson	token_t *t;
810155192Srwatson	u_char *dptr = NULL;
811155192Srwatson
812155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
813155192Srwatson
814155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN64);
815155192Srwatson	ADD_U_CHAR(dptr, status);
816155192Srwatson	ADD_U_INT64(dptr, ret);
817155192Srwatson
818155192Srwatson	return (t);
819155192Srwatson}
820155192Srwatson
821155192Srwatsontoken_t *
822155192Srwatsonau_to_return(char status, u_int32_t ret)
823155192Srwatson{
824155192Srwatson
825155192Srwatson	return (au_to_return32(status, ret));
826155192Srwatson}
827155192Srwatson
828155192Srwatson/*
829155192Srwatson * token ID                1 byte
830155192Srwatson * sequence number         4 bytes
831155192Srwatson */
832155192Srwatsontoken_t *
833155192Srwatsonau_to_seq(long audit_count)
834155192Srwatson{
835155192Srwatson	token_t *t;
836155192Srwatson	u_char *dptr = NULL;
837155192Srwatson
838155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
839155192Srwatson
840155192Srwatson	ADD_U_CHAR(dptr, AUT_SEQ);
841155192Srwatson	ADD_U_INT32(dptr, audit_count);
842155192Srwatson
843155192Srwatson	return (t);
844155192Srwatson}
845155192Srwatson
846155192Srwatson/*
847155192Srwatson * token ID                1 byte
848186647Srwatson * socket domain           2 bytes
849155192Srwatson * socket type             2 bytes
850186647Srwatson * address type            2 byte
851155192Srwatson * local port              2 bytes
852186647Srwatson * local address           4 bytes/16 bytes (IPv4/IPv6 address)
853155192Srwatson * remote port             2 bytes
854186647Srwatson * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
855187214Srwatson *
856187214Srwatson * Domain and type arguments to this routine are assumed to already have been
857187214Srwatson * converted to the BSM constant space, so we don't do that here.
858155192Srwatson */
859155192Srwatsontoken_t *
860186647Srwatsonau_to_socket_ex(u_short so_domain, u_short so_type,
861186647Srwatson    struct sockaddr *sa_local, struct sockaddr *sa_remote)
862155192Srwatson{
863186647Srwatson	token_t *t;
864186647Srwatson	u_char *dptr = NULL;
865186647Srwatson	struct sockaddr_in *sin;
866186647Srwatson	struct sockaddr_in6 *sin6;
867155192Srwatson
868186647Srwatson	if (so_domain == AF_INET)
869186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
870186647Srwatson		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
871186647Srwatson	else if (so_domain == AF_INET6)
872186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
873189279Srwatson		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
874186647Srwatson	else
875186647Srwatson		return (NULL);
876186647Srwatson
877186647Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
878189279Srwatson	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
879189279Srwatson	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
880186647Srwatson	if (so_domain == AF_INET) {
881186647Srwatson		ADD_U_INT16(dptr, AU_IPv4);
882186647Srwatson		sin = (struct sockaddr_in *)sa_local;
883186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
884186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
885186647Srwatson		sin = (struct sockaddr_in *)sa_remote;
886186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
887186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
888186647Srwatson	} else {
889186647Srwatson		ADD_U_INT16(dptr, AU_IPv6);
890186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_local;
891186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
892186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
893186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_remote;
894186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
895186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
896186647Srwatson	}
897186647Srwatson
898186647Srwatson	return (t);
899155192Srwatson}
900155192Srwatson
901155192Srwatson/*
902155192Srwatson * Kernel-specific version of the above function.
903186647Srwatson *
904186647Srwatson * XXXRW: Should now use au_to_socket_ex() here.
905155192Srwatson */
906155192Srwatson#ifdef _KERNEL
907155192Srwatsontoken_t *
908155192Srwatsonkau_to_socket(struct socket_au_info *soi)
909155192Srwatson{
910155192Srwatson	token_t *t;
911155192Srwatson	u_char *dptr;
912155192Srwatson	u_int16_t so_type;
913155192Srwatson
914155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
915155192Srwatson	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
916186647Srwatson
917185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET);
918155192Srwatson	/* Coerce the socket type into a short value */
919155192Srwatson	so_type = soi->so_type;
920155192Srwatson	ADD_U_INT16(dptr, so_type);
921155192Srwatson	ADD_U_INT16(dptr, soi->so_lport);
922155192Srwatson	ADD_U_INT32(dptr, soi->so_laddr);
923155192Srwatson	ADD_U_INT16(dptr, soi->so_rport);
924155192Srwatson	ADD_U_INT32(dptr, soi->so_raddr);
925155192Srwatson
926155192Srwatson	return (t);
927155192Srwatson}
928155192Srwatson#endif
929155192Srwatson
930155192Srwatson/*
931155192Srwatson * token ID                1 byte
932155192Srwatson * socket family           2 bytes
933155192Srwatson * path                    104 bytes
934155192Srwatson */
935155192Srwatsontoken_t *
936155192Srwatsonau_to_sock_unix(struct sockaddr_un *so)
937155192Srwatson{
938155192Srwatson	token_t *t;
939155192Srwatson	u_char *dptr;
940155192Srwatson
941155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
942155192Srwatson
943185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
944155192Srwatson	/* BSM token has two bytes for family */
945155192Srwatson	ADD_U_CHAR(dptr, 0);
946155192Srwatson	ADD_U_CHAR(dptr, so->sun_family);
947155192Srwatson	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
948155192Srwatson
949155192Srwatson	return (t);
950155192Srwatson}
951155192Srwatson
952155192Srwatson/*
953155192Srwatson * token ID                1 byte
954155192Srwatson * socket family           2 bytes
955155192Srwatson * local port              2 bytes
956155192Srwatson * socket address          4 bytes
957155192Srwatson */
958155192Srwatsontoken_t *
959155192Srwatsonau_to_sock_inet32(struct sockaddr_in *so)
960155192Srwatson{
961155192Srwatson	token_t *t;
962155192Srwatson	u_char *dptr = NULL;
963159259Srwatson	uint16_t family;
964155192Srwatson
965159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
966159259Srwatson	    sizeof(uint32_t));
967155192Srwatson
968155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET32);
969155192Srwatson	/*
970159259Srwatson	 * BSM defines the family field as 16 bits, but many operating
971159259Srwatson	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
972159259Srwatson	 * writing into the token.  Assume that both the port and the address
973159259Srwatson	 * in the sockaddr_in are already in network byte order, but family
974159259Srwatson	 * is in local byte order.
975159259Srwatson	 *
976159259Srwatson	 * XXXRW: Should a name space conversion be taking place on the value
977159259Srwatson	 * of sin_family?
978180709Srwatson	 */
979159259Srwatson	family = so->sin_family;
980159259Srwatson	ADD_U_INT16(dptr, family);
981159259Srwatson	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
982159259Srwatson	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
983155192Srwatson
984155192Srwatson	return (t);
985155192Srwatson}
986155192Srwatson
987155192Srwatsontoken_t *
988155192Srwatsonau_to_sock_inet128(struct sockaddr_in6 *so)
989155192Srwatson{
990155192Srwatson	token_t *t;
991155192Srwatson	u_char *dptr = NULL;
992155192Srwatson
993155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
994155192Srwatson	    4 * sizeof(u_int32_t));
995155192Srwatson
996155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET128);
997155192Srwatson	/*
998186647Srwatson	 * In BSD, sin6_family is one octet, but BSM defines the token to
999186647Srwatson	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1000186647Srwatson	 * conditionally compiled.
1001180709Srwatson	 */
1002155192Srwatson	ADD_U_CHAR(dptr, 0);
1003155192Srwatson	ADD_U_CHAR(dptr, so->sin6_family);
1004155192Srwatson
1005155192Srwatson	ADD_U_INT16(dptr, so->sin6_port);
1006159259Srwatson	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1007155192Srwatson
1008155192Srwatson	return (t);
1009155192Srwatson}
1010155192Srwatson
1011155192Srwatsontoken_t *
1012155192Srwatsonau_to_sock_inet(struct sockaddr_in *so)
1013155192Srwatson{
1014155192Srwatson
1015155192Srwatson	return (au_to_sock_inet32(so));
1016155192Srwatson}
1017155192Srwatson
1018155192Srwatson/*
1019155192Srwatson * token ID                1 byte
1020155192Srwatson * audit ID                4 bytes
1021155192Srwatson * effective user ID       4 bytes
1022155192Srwatson * effective group ID      4 bytes
1023155192Srwatson * real user ID            4 bytes
1024155192Srwatson * real group ID           4 bytes
1025155192Srwatson * process ID              4 bytes
1026155192Srwatson * session ID              4 bytes
1027155192Srwatson * terminal ID
1028155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1029155192Srwatson *   machine address       4 bytes
1030155192Srwatson */
1031155192Srwatsontoken_t *
1032155192Srwatsonau_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1033155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1034155192Srwatson{
1035155192Srwatson	token_t *t;
1036155192Srwatson	u_char *dptr = NULL;
1037155192Srwatson
1038155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1039155192Srwatson
1040155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1041155192Srwatson	ADD_U_INT32(dptr, auid);
1042155192Srwatson	ADD_U_INT32(dptr, euid);
1043155192Srwatson	ADD_U_INT32(dptr, egid);
1044155192Srwatson	ADD_U_INT32(dptr, ruid);
1045155192Srwatson	ADD_U_INT32(dptr, rgid);
1046155192Srwatson	ADD_U_INT32(dptr, pid);
1047155192Srwatson	ADD_U_INT32(dptr, sid);
1048155192Srwatson	ADD_U_INT32(dptr, tid->port);
1049159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1050155192Srwatson
1051155192Srwatson	return (t);
1052155192Srwatson}
1053155192Srwatson
1054155192Srwatsontoken_t *
1055155192Srwatsonau_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1056155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1057155192Srwatson{
1058168783Srwatson	token_t *t;
1059168783Srwatson	u_char *dptr = NULL;
1060155192Srwatson
1061168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1062168783Srwatson	    sizeof(u_int64_t) + sizeof(u_int32_t));
1063168783Srwatson
1064168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1065168783Srwatson	ADD_U_INT32(dptr, auid);
1066168783Srwatson	ADD_U_INT32(dptr, euid);
1067168783Srwatson	ADD_U_INT32(dptr, egid);
1068168783Srwatson	ADD_U_INT32(dptr, ruid);
1069168783Srwatson	ADD_U_INT32(dptr, rgid);
1070168783Srwatson	ADD_U_INT32(dptr, pid);
1071168783Srwatson	ADD_U_INT32(dptr, sid);
1072168783Srwatson	ADD_U_INT64(dptr, tid->port);
1073168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1074168783Srwatson
1075168783Srwatson	return (t);
1076155192Srwatson}
1077155192Srwatson
1078155192Srwatsontoken_t *
1079155192Srwatsonau_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1080155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1081155192Srwatson{
1082155192Srwatson
1083155192Srwatson	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1084155192Srwatson	    tid));
1085155192Srwatson}
1086155192Srwatson
1087155192Srwatson/*
1088155192Srwatson * token ID                1 byte
1089155192Srwatson * audit ID                4 bytes
1090155192Srwatson * effective user ID       4 bytes
1091155192Srwatson * effective group ID      4 bytes
1092155192Srwatson * real user ID            4 bytes
1093155192Srwatson * real group ID           4 bytes
1094155192Srwatson * process ID              4 bytes
1095155192Srwatson * session ID              4 bytes
1096155192Srwatson * terminal ID
1097155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1098155192Srwatson *   address type/length   4 bytes
1099185573Srwatson *   machine address      16 bytes
1100155192Srwatson */
1101155192Srwatsontoken_t *
1102155192Srwatsonau_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1103155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1104155192Srwatson{
1105155192Srwatson	token_t *t;
1106155192Srwatson	u_char *dptr = NULL;
1107155192Srwatson
1108168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1109168688Scsjp	    ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1110185573Srwatson
1111185573Srwatson	if (tid->at_type == AU_IPv4)
1112185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1113159686Swsalamon		    sizeof(u_int32_t));
1114159686Swsalamon	else
1115185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1116159686Swsalamon		    sizeof(u_int32_t));
1117155192Srwatson
1118155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1119155192Srwatson	ADD_U_INT32(dptr, auid);
1120155192Srwatson	ADD_U_INT32(dptr, euid);
1121155192Srwatson	ADD_U_INT32(dptr, egid);
1122155192Srwatson	ADD_U_INT32(dptr, ruid);
1123155192Srwatson	ADD_U_INT32(dptr, rgid);
1124155192Srwatson	ADD_U_INT32(dptr, pid);
1125155192Srwatson	ADD_U_INT32(dptr, sid);
1126155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
1127155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
1128185573Srwatson	if (tid->at_type == AU_IPv6)
1129168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1130185573Srwatson	else
1131168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1132170131Srwatson
1133155192Srwatson	return (t);
1134155192Srwatson}
1135155192Srwatson
1136155192Srwatsontoken_t *
1137155192Srwatsonau_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1138155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1139155192Srwatson{
1140168783Srwatson	token_t *t;
1141168783Srwatson	u_char *dptr = NULL;
1142155192Srwatson
1143185573Srwatson	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1144185573Srwatson	    ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1145185573Srwatson
1146168783Srwatson	if (tid->at_type == AU_IPv4)
1147168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1148168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1149168783Srwatson		    2 * sizeof(u_int32_t));
1150185573Srwatson	else
1151168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1152168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1153168783Srwatson		    5 * sizeof(u_int32_t));
1154168783Srwatson
1155168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1156168783Srwatson	ADD_U_INT32(dptr, auid);
1157168783Srwatson	ADD_U_INT32(dptr, euid);
1158168783Srwatson	ADD_U_INT32(dptr, egid);
1159168783Srwatson	ADD_U_INT32(dptr, ruid);
1160168783Srwatson	ADD_U_INT32(dptr, rgid);
1161168783Srwatson	ADD_U_INT32(dptr, pid);
1162168783Srwatson	ADD_U_INT32(dptr, sid);
1163168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
1164168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
1165168783Srwatson	if (tid->at_type == AU_IPv6)
1166168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1167168783Srwatson	else
1168168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1169168783Srwatson
1170168783Srwatson	return (t);
1171155192Srwatson}
1172155192Srwatson
1173155192Srwatsontoken_t *
1174155192Srwatsonau_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1175155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1176155192Srwatson{
1177155192Srwatson
1178155192Srwatson	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1179155192Srwatson	    tid));
1180155192Srwatson}
1181155192Srwatson
1182156291Srwatson#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1183155192Srwatson/*
1184185573Srwatson * Collects audit information for the current process and creates a subject
1185185573Srwatson * token from it.
1186155192Srwatson */
1187155192Srwatsontoken_t *
1188155192Srwatsonau_to_me(void)
1189155192Srwatson{
1190155192Srwatson	auditinfo_t auinfo;
1191155192Srwatson
1192155192Srwatson	if (getaudit(&auinfo) != 0)
1193155192Srwatson		return (NULL);
1194155192Srwatson
1195155192Srwatson	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1196155192Srwatson	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1197155192Srwatson}
1198155192Srwatson#endif
1199155192Srwatson
1200161813Swsalamon#if defined(_KERNEL) || defined(KERNEL)
1201161813Swsalamonstatic token_t *
1202161813Swsalamonau_to_exec_strings(char *strs, int count, u_char type)
1203161813Swsalamon{
1204161813Swsalamon	token_t *t;
1205161813Swsalamon	u_char *dptr = NULL;
1206161813Swsalamon	u_int32_t totlen;
1207161813Swsalamon	int ctr;
1208161813Swsalamon	char *p;
1209161813Swsalamon
1210161813Swsalamon	totlen = 0;
1211161813Swsalamon	ctr = count;
1212161813Swsalamon	p = strs;
1213161813Swsalamon	while (ctr-- > 0) {
1214161813Swsalamon		totlen += strlen(p) + 1;
1215161813Swsalamon		p = strs + totlen;
1216161813Swsalamon	}
1217161813Swsalamon	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1218161813Swsalamon	ADD_U_CHAR(dptr, type);
1219161813Swsalamon	ADD_U_INT32(dptr, count);
1220161813Swsalamon	ADD_STRING(dptr, strs, totlen);
1221161813Swsalamon
1222161813Swsalamon	return (t);
1223161813Swsalamon}
1224161813Swsalamon
1225155192Srwatson/*
1226155192Srwatson * token ID				1 byte
1227155192Srwatson * count				4 bytes
1228155192Srwatson * text					count null-terminated strings
1229155192Srwatson */
1230155192Srwatsontoken_t *
1231161813Swsalamonau_to_exec_args(char *args, int argc)
1232155192Srwatson{
1233162465Srwatson
1234161813Swsalamon	return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1235161813Swsalamon}
1236161813Swsalamon
1237161813Swsalamon/*
1238161813Swsalamon * token ID				1 byte
1239161813Swsalamon * count				4 bytes
1240161813Swsalamon * text					count null-terminated strings
1241161813Swsalamon */
1242161813Swsalamontoken_t *
1243161813Swsalamonau_to_exec_env(char *envs, int envc)
1244161813Swsalamon{
1245162465Srwatson
1246161813Swsalamon	return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1247161813Swsalamon}
1248161813Swsalamon#else
1249161813Swsalamon/*
1250161813Swsalamon * token ID				1 byte
1251161813Swsalamon * count				4 bytes
1252161813Swsalamon * text					count null-terminated strings
1253161813Swsalamon */
1254161813Swsalamontoken_t *
1255161813Swsalamonau_to_exec_args(char **argv)
1256161813Swsalamon{
1257155192Srwatson	token_t *t;
1258155192Srwatson	u_char *dptr = NULL;
1259155192Srwatson	const char *nextarg;
1260155192Srwatson	int i, count = 0;
1261155192Srwatson	size_t totlen = 0;
1262155192Srwatson
1263161813Swsalamon	nextarg = *argv;
1264155192Srwatson
1265155192Srwatson	while (nextarg != NULL) {
1266155192Srwatson		int nextlen;
1267155192Srwatson
1268155192Srwatson		nextlen = strlen(nextarg);
1269155192Srwatson		totlen += nextlen + 1;
1270155192Srwatson		count++;
1271161813Swsalamon		nextarg = *(argv + count);
1272155192Srwatson	}
1273155192Srwatson
1274155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1275155192Srwatson
1276155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1277155192Srwatson	ADD_U_INT32(dptr, count);
1278155192Srwatson
1279155192Srwatson	for (i = 0; i < count; i++) {
1280161813Swsalamon		nextarg = *(argv + i);
1281155192Srwatson		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1282155192Srwatson	}
1283155192Srwatson
1284155192Srwatson	return (t);
1285155192Srwatson}
1286155192Srwatson
1287155192Srwatson/*
1288155192Srwatson * token ID				1 byte
1289155192Srwatson * count				4 bytes
1290155192Srwatson * text					count null-terminated strings
1291155192Srwatson */
1292155192Srwatsontoken_t *
1293161813Swsalamonau_to_exec_env(char **envp)
1294155192Srwatson{
1295155192Srwatson	token_t *t;
1296155192Srwatson	u_char *dptr = NULL;
1297155192Srwatson	int i, count = 0;
1298155192Srwatson	size_t totlen = 0;
1299155192Srwatson	const char *nextenv;
1300155192Srwatson
1301161813Swsalamon	nextenv = *envp;
1302155192Srwatson
1303155192Srwatson	while (nextenv != NULL) {
1304155192Srwatson		int nextlen;
1305155192Srwatson
1306155192Srwatson		nextlen = strlen(nextenv);
1307155192Srwatson		totlen += nextlen + 1;
1308155192Srwatson		count++;
1309161813Swsalamon		nextenv = *(envp + count);
1310155192Srwatson	}
1311155192Srwatson
1312155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1313155192Srwatson
1314155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1315155192Srwatson	ADD_U_INT32(dptr, count);
1316155192Srwatson
1317155192Srwatson	for (i = 0; i < count; i++) {
1318161813Swsalamon		nextenv = *(envp + i);
1319155192Srwatson		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1320155192Srwatson	}
1321155192Srwatson
1322155192Srwatson	return (t);
1323155192Srwatson}
1324161813Swsalamon#endif
1325155192Srwatson
1326155192Srwatson/*
1327155192Srwatson * token ID                1 byte
1328186647Srwatson * zonename length         2 bytes
1329186647Srwatson * zonename                N bytes + 1 terminating NULL byte
1330186647Srwatson */
1331186647Srwatsontoken_t *
1332186647Srwatsonau_to_zonename(const char *zonename)
1333186647Srwatson{
1334186647Srwatson	u_char *dptr = NULL;
1335186647Srwatson	u_int16_t textlen;
1336186647Srwatson	token_t *t;
1337186647Srwatson
1338186647Srwatson	textlen = strlen(zonename) + 1;
1339186647Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1340186647Srwatson
1341186647Srwatson	ADD_U_CHAR(dptr, AUT_ZONENAME);
1342186647Srwatson	ADD_U_INT16(dptr, textlen);
1343186647Srwatson	ADD_STRING(dptr, zonename, textlen);
1344186647Srwatson	return (t);
1345186647Srwatson}
1346186647Srwatson
1347186647Srwatson/*
1348186647Srwatson * token ID                1 byte
1349155192Srwatson * record byte count       4 bytes
1350185573Srwatson * version #               1 byte    [2]
1351184856Scsjp * event type              2 bytes
1352184856Scsjp * event modifier          2 bytes
1353185573Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1354185573Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1355184856Scsjp */
1356184856Scsjptoken_t *
1357185573Srwatsonau_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1358185573Srwatson    struct timeval tm)
1359184856Scsjp{
1360185573Srwatson	token_t *t;
1361184856Scsjp	u_char *dptr = NULL;
1362184856Scsjp	u_int32_t timems;
1363184856Scsjp
1364184856Scsjp	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1365185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1366184856Scsjp
1367185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32);
1368184856Scsjp	ADD_U_INT32(dptr, rec_size);
1369184856Scsjp	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1370184856Scsjp	ADD_U_INT16(dptr, e_type);
1371184856Scsjp	ADD_U_INT16(dptr, e_mod);
1372185573Srwatson
1373185573Srwatson	timems = tm.tv_usec/1000;
1374184856Scsjp	/* Add the timestamp */
1375184856Scsjp	ADD_U_INT32(dptr, tm.tv_sec);
1376185573Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1377185573Srwatson
1378184856Scsjp	return (t);
1379184856Scsjp}
1380184856Scsjp
1381184856Scsjp/*
1382184856Scsjp * token ID                1 byte
1383184856Scsjp * record byte count       4 bytes
1384155192Srwatson * version #               1 byte    [2]
1385155192Srwatson * event type              2 bytes
1386155192Srwatson * event modifier          2 bytes
1387185573Srwatson * address type/length     4 bytes
1388185573Srwatson * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1389155192Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1390155192Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1391155192Srwatson */
1392155192Srwatsontoken_t *
1393185573Srwatsonau_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1394185573Srwatson    struct timeval tm, struct auditinfo_addr *aia)
1395155192Srwatson{
1396155192Srwatson	token_t *t;
1397155192Srwatson	u_char *dptr = NULL;
1398155192Srwatson	u_int32_t timems;
1399185573Srwatson	au_tid_addr_t *tid;
1400155192Srwatson
1401185573Srwatson	tid = &aia->ai_termid;
1402185573Srwatson	KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1403185573Srwatson	    ("au_to_header32_ex_tm: invalid address family"));
1404185573Srwatson
1405155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1406185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1407185573Srwatson	    sizeof(u_int32_t) + tid->at_type);
1408155192Srwatson
1409185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1410155192Srwatson	ADD_U_INT32(dptr, rec_size);
1411161635Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1412155192Srwatson	ADD_U_INT16(dptr, e_type);
1413155192Srwatson	ADD_U_INT16(dptr, e_mod);
1414155192Srwatson
1415185573Srwatson	ADD_U_INT32(dptr, tid->at_type);
1416185573Srwatson	if (tid->at_type == AU_IPv6)
1417185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1418185573Srwatson	else
1419185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1420155192Srwatson	timems = tm.tv_usec/1000;
1421155192Srwatson	/* Add the timestamp */
1422155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1423185573Srwatson	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1424155192Srwatson
1425185573Srwatson	return (t);
1426155192Srwatson}
1427155192Srwatson
1428168783Srwatsontoken_t *
1429168783Srwatsonau_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1430168783Srwatson    struct timeval tm)
1431168783Srwatson{
1432168783Srwatson	token_t *t;
1433168783Srwatson	u_char *dptr = NULL;
1434168783Srwatson	u_int32_t timems;
1435168783Srwatson
1436168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1437168783Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1438168783Srwatson
1439168783Srwatson	ADD_U_CHAR(dptr, AUT_HEADER64);
1440168783Srwatson	ADD_U_INT32(dptr, rec_size);
1441168783Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1442168783Srwatson	ADD_U_INT16(dptr, e_type);
1443168783Srwatson	ADD_U_INT16(dptr, e_mod);
1444168783Srwatson
1445168783Srwatson	timems = tm.tv_usec/1000;
1446168783Srwatson	/* Add the timestamp */
1447168783Srwatson	ADD_U_INT64(dptr, tm.tv_sec);
1448168783Srwatson	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1449168783Srwatson
1450168783Srwatson	return (t);
1451168783Srwatson}
1452168783Srwatson
1453185573Srwatson#if !defined(KERNEL) && !defined(_KERNEL)
1454185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1455185573Srwatsontoken_t *
1456185573Srwatsonau_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1457185573Srwatson{
1458185573Srwatson	struct timeval tm;
1459185573Srwatson	struct auditinfo_addr aia;
1460185573Srwatson
1461185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1462185573Srwatson		return (NULL);
1463191270Srwatson	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1464185573Srwatson		if (errno != ENOSYS)
1465185573Srwatson			return (NULL);
1466185573Srwatson		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1467185573Srwatson	}
1468185573Srwatson	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1469185573Srwatson}
1470185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1471185573Srwatson
1472185573Srwatsontoken_t *
1473185573Srwatsonau_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1474185573Srwatson{
1475185573Srwatson	struct timeval tm;
1476185573Srwatson
1477185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1478185573Srwatson		return (NULL);
1479185573Srwatson	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1480185573Srwatson}
1481185573Srwatson
1482185573Srwatsontoken_t *
1483185573Srwatsonau_to_header64(__unused int rec_size, __unused au_event_t e_type,
1484185573Srwatson    __unused au_emod_t e_mod)
1485185573Srwatson{
1486185573Srwatson	struct timeval tm;
1487185573Srwatson
1488185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1489185573Srwatson		return (NULL);
1490185573Srwatson	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1491185573Srwatson}
1492185573Srwatson
1493185573Srwatsontoken_t *
1494185573Srwatsonau_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1495185573Srwatson{
1496185573Srwatson
1497185573Srwatson	return (au_to_header32(rec_size, e_type, e_mod));
1498185573Srwatson}
1499185573Srwatson
1500185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1501185573Srwatsontoken_t *
1502185573Srwatsonau_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1503185573Srwatson{
1504185573Srwatson
1505185573Srwatson	return (au_to_header32_ex(rec_size, e_type, e_mod));
1506185573Srwatson}
1507185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1508185573Srwatson#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1509185573Srwatson
1510155192Srwatson/*
1511155192Srwatson * token ID                1 byte
1512155192Srwatson * trailer magic number    2 bytes
1513155192Srwatson * record byte count       4 bytes
1514155192Srwatson */
1515155192Srwatsontoken_t *
1516155192Srwatsonau_to_trailer(int rec_size)
1517155192Srwatson{
1518155192Srwatson	token_t *t;
1519155192Srwatson	u_char *dptr = NULL;
1520186647Srwatson	u_int16_t magic = AUT_TRAILER_MAGIC;
1521155192Srwatson
1522155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1523155192Srwatson	    sizeof(u_int32_t));
1524155192Srwatson
1525155192Srwatson	ADD_U_CHAR(dptr, AUT_TRAILER);
1526155192Srwatson	ADD_U_INT16(dptr, magic);
1527155192Srwatson	ADD_U_INT32(dptr, rec_size);
1528155192Srwatson
1529155192Srwatson	return (t);
1530155192Srwatson}
1531