bsm_token.c revision 189279
1185573Srwatson/*-
2189279Srwatson * Copyright (c) 2004-2009 Apple Inc.
3155131Srwatson * Copyright (c) 2005 SPARTA, Inc.
4155131Srwatson * All rights reserved.
5155131Srwatson *
6155131Srwatson * This code was developed in part by Robert N. M. Watson, Senior Principal
7155131Srwatson * Scientist, SPARTA, Inc.
8155131Srwatson *
9155131Srwatson * Redistribution and use in source and binary forms, with or without
10155131Srwatson * modification, are permitted provided that the following conditions
11155131Srwatson * are met:
12155131Srwatson * 1.  Redistributions of source code must retain the above copyright
13155131Srwatson *     notice, this list of conditions and the following disclaimer.
14155131Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
15155131Srwatson *     notice, this list of conditions and the following disclaimer in the
16155131Srwatson *     documentation and/or other materials provided with the distribution.
17185573Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
18155131Srwatson *     its contributors may be used to endorse or promote products derived
19155131Srwatson *     from this software without specific prior written permission.
20155131Srwatson *
21155131Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22155131Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23155131Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24155131Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25155131Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26155131Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27155131Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28155131Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29155131Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30155131Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31155131Srwatson * POSSIBILITY OF SUCH DAMAGE.
32155131Srwatson *
33189279Srwatson * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#90 $
34155131Srwatson */
35155131Srwatson
36155131Srwatson#include <sys/types.h>
37156283Srwatson
38156283Srwatson#include <config/config.h>
39186647Srwatson#if defined(HAVE_SYS_ENDIAN_H) && defined(HAVE_BE32ENC)
40156283Srwatson#include <sys/endian.h>
41186647Srwatson#else /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */
42156283Srwatson#ifdef HAVE_MACHINE_ENDIAN_H
43156283Srwatson#include <machine/endian.h>
44156283Srwatson#else /* !HAVE_MACHINE_ENDIAN_H */
45156283Srwatson#ifdef HAVE_ENDIAN_H
46156283Srwatson#include <endian.h>
47156283Srwatson#else /* !HAVE_ENDIAN_H */
48156283Srwatson#error "No supported endian.h"
49156283Srwatson#endif /* !HAVE_ENDIAN_H */
50156283Srwatson#endif /* !HAVE_MACHINE_ENDIAN_H */
51155131Srwatson#include <compat/endian.h>
52186647Srwatson#endif /* !HAVE_SYS_ENDIAN_H || !HAVE_BE32ENC */
53156283Srwatson#ifdef HAVE_FULL_QUEUE_H
54156283Srwatson#include <sys/queue.h>
55156283Srwatson#else /* !HAVE_FULL_QUEUE_H */
56156283Srwatson#include <compat/queue.h>
57156283Srwatson#endif /* !HAVE_FULL_QUEUE_H */
58156283Srwatson
59155131Srwatson#include <sys/socket.h>
60155131Srwatson#include <sys/time.h>
61155131Srwatson#include <sys/un.h>
62155131Srwatson
63155131Srwatson#include <sys/ipc.h>
64155131Srwatson
65155131Srwatson#include <netinet/in.h>
66155131Srwatson#include <netinet/in_systm.h>
67155131Srwatson#include <netinet/ip.h>
68155131Srwatson
69155131Srwatson#include <assert.h>
70155131Srwatson#include <errno.h>
71155131Srwatson#include <string.h>
72155131Srwatson#include <stdlib.h>
73155131Srwatson#include <unistd.h>
74155131Srwatson
75155131Srwatson#include <bsm/audit_internal.h>
76155131Srwatson#include <bsm/libbsm.h>
77155131Srwatson
78155131Srwatson#define	GET_TOKEN_AREA(t, dptr, length) do {				\
79155131Srwatson	(t) = malloc(sizeof(token_t));					\
80155131Srwatson	if ((t) != NULL) {						\
81155131Srwatson		(t)->len = (length);					\
82155131Srwatson		(dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \
83155131Srwatson		if ((dptr) == NULL) {					\
84155131Srwatson			free(t);					\
85155131Srwatson			(t) = NULL;					\
86155131Srwatson		} else							\
87155131Srwatson			memset((dptr), 0, (length));			\
88155131Srwatson	} else								\
89155131Srwatson		(dptr) = NULL;						\
90185573Srwatson	assert((t) == NULL || (dptr) != NULL);				\
91155131Srwatson} while (0)
92155131Srwatson
93155131Srwatson/*
94155131Srwatson * token ID                1 byte
95155131Srwatson * argument #              1 byte
96155131Srwatson * argument value          4 bytes/8 bytes (32-bit/64-bit value)
97155131Srwatson * text length             2 bytes
98155131Srwatson * text                    N bytes + 1 terminating NULL byte
99155131Srwatson */
100155131Srwatsontoken_t *
101185573Srwatsonau_to_arg32(char n, const char *text, u_int32_t v)
102155131Srwatson{
103155131Srwatson	token_t *t;
104155131Srwatson	u_char *dptr = NULL;
105155131Srwatson	u_int16_t textlen;
106155131Srwatson
107155131Srwatson	textlen = strlen(text);
108155131Srwatson	textlen += 1;
109155131Srwatson
110155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
111155131Srwatson	    sizeof(u_int16_t) + textlen);
112155131Srwatson	if (t == NULL)
113155131Srwatson		return (NULL);
114155131Srwatson
115155131Srwatson	ADD_U_CHAR(dptr, AUT_ARG32);
116155131Srwatson	ADD_U_CHAR(dptr, n);
117155131Srwatson	ADD_U_INT32(dptr, v);
118155131Srwatson	ADD_U_INT16(dptr, textlen);
119155131Srwatson	ADD_STRING(dptr, text, textlen);
120155131Srwatson
121155131Srwatson	return (t);
122155131Srwatson}
123155131Srwatson
124155131Srwatsontoken_t *
125185573Srwatsonau_to_arg64(char n, const char *text, u_int64_t v)
126155131Srwatson{
127155131Srwatson	token_t *t;
128155131Srwatson	u_char *dptr = NULL;
129155131Srwatson	u_int16_t textlen;
130155131Srwatson
131155131Srwatson	textlen = strlen(text);
132155131Srwatson	textlen += 1;
133155131Srwatson
134155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
135155131Srwatson	    sizeof(u_int16_t) + textlen);
136155131Srwatson	if (t == NULL)
137155131Srwatson		return (NULL);
138155131Srwatson
139155131Srwatson	ADD_U_CHAR(dptr, AUT_ARG64);
140155131Srwatson	ADD_U_CHAR(dptr, n);
141155131Srwatson	ADD_U_INT64(dptr, v);
142155131Srwatson	ADD_U_INT16(dptr, textlen);
143155131Srwatson	ADD_STRING(dptr, text, textlen);
144155131Srwatson
145155131Srwatson	return (t);
146155131Srwatson}
147155131Srwatson
148155131Srwatsontoken_t *
149185573Srwatsonau_to_arg(char n, const char *text, u_int32_t v)
150155131Srwatson{
151155131Srwatson
152155131Srwatson	return (au_to_arg32(n, text, v));
153155131Srwatson}
154155131Srwatson
155155131Srwatson#if defined(_KERNEL) || defined(KERNEL)
156155131Srwatson/*
157155131Srwatson * token ID                1 byte
158155131Srwatson * file access mode        4 bytes
159155131Srwatson * owner user ID           4 bytes
160155131Srwatson * owner group ID          4 bytes
161155131Srwatson * file system ID          4 bytes
162155131Srwatson * node ID                 8 bytes
163155131Srwatson * device                  4 bytes/8 bytes (32-bit/64-bit)
164155131Srwatson */
165155131Srwatsontoken_t *
166155131Srwatsonau_to_attr32(struct vnode_au_info *vni)
167155131Srwatson{
168155131Srwatson	token_t *t;
169155131Srwatson	u_char *dptr = NULL;
170155131Srwatson	u_int16_t pad0_16 = 0;
171189279Srwatson	u_int32_t pad0_32 = 0;
172155131Srwatson
173155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
174155131Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
175155131Srwatson	if (t == NULL)
176155131Srwatson		return (NULL);
177155131Srwatson
178155131Srwatson	ADD_U_CHAR(dptr, AUT_ATTR32);
179155131Srwatson
180155131Srwatson	/*
181186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
182186647Srwatson	 * so pad with 0.
183186647Srwatson	 *
184186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
185186647Srwatson	 *
186186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
187155131Srwatson	 */
188155131Srwatson	ADD_U_INT16(dptr, pad0_16);
189155131Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
190155131Srwatson
191155131Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
192155131Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
193155131Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
194155131Srwatson
195155131Srwatson	/*
196185573Srwatson	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
197155131Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
198155131Srwatson	 * could pick this out at compile-time, it would be better, so as to
199155131Srwatson	 * avoid the else case below.
200155131Srwatson	 */
201155131Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
202155131Srwatson		ADD_U_INT32(dptr, pad0_32);
203155131Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
204155131Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
205155131Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
206155131Srwatson	else
207155131Srwatson		ADD_U_INT64(dptr, 0LL);
208155131Srwatson
209155131Srwatson	ADD_U_INT32(dptr, vni->vn_dev);
210155131Srwatson
211155131Srwatson	return (t);
212155131Srwatson}
213155131Srwatson
214155131Srwatsontoken_t *
215155131Srwatsonau_to_attr64(struct vnode_au_info *vni)
216155131Srwatson{
217168777Srwatson	token_t *t;
218168777Srwatson	u_char *dptr = NULL;
219168777Srwatson	u_int16_t pad0_16 = 0;
220189279Srwatson	u_int32_t pad0_32 = 0;
221155131Srwatson
222168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
223168777Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
224168777Srwatson	if (t == NULL)
225168777Srwatson		return (NULL);
226168777Srwatson
227168777Srwatson	ADD_U_CHAR(dptr, AUT_ATTR64);
228168777Srwatson
229168777Srwatson	/*
230186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
231186647Srwatson	 * so pad with 0.
232186647Srwatson	 *
233186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
234186647Srwatson	 *
235186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
236168777Srwatson	 */
237168777Srwatson	ADD_U_INT16(dptr, pad0_16);
238168777Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
239168777Srwatson
240168777Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
241168777Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
242168777Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
243168777Srwatson
244168777Srwatson	/*
245168777Srwatson	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
246168777Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
247168777Srwatson	 * could pick this out at compile-time, it would be better, so as to
248168777Srwatson	 * avoid the else case below.
249168777Srwatson	 */
250168777Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
251168777Srwatson		ADD_U_INT32(dptr, pad0_32);
252168777Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
253168777Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
254168777Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
255168777Srwatson	else
256168777Srwatson		ADD_U_INT64(dptr, 0LL);
257168777Srwatson
258168777Srwatson	ADD_U_INT64(dptr, vni->vn_dev);
259168777Srwatson
260168777Srwatson	return (t);
261155131Srwatson}
262155131Srwatson
263155131Srwatsontoken_t *
264155131Srwatsonau_to_attr(struct vnode_au_info *vni)
265155131Srwatson{
266155131Srwatson
267155131Srwatson	return (au_to_attr32(vni));
268155131Srwatson}
269155131Srwatson#endif /* !(defined(_KERNEL) || defined(KERNEL) */
270155131Srwatson
271155131Srwatson/*
272155131Srwatson * token ID                1 byte
273155131Srwatson * how to print            1 byte
274155131Srwatson * basic unit              1 byte
275155131Srwatson * unit count              1 byte
276155131Srwatson * data items              (depends on basic unit)
277155131Srwatson */
278155131Srwatsontoken_t *
279185573Srwatsonau_to_data(char unit_print, char unit_type, char unit_count, const char *p)
280155131Srwatson{
281155131Srwatson	token_t *t;
282155131Srwatson	u_char *dptr = NULL;
283155131Srwatson	size_t datasize, totdata;
284155131Srwatson
285155131Srwatson	/* Determine the size of the basic unit. */
286155131Srwatson	switch (unit_type) {
287155131Srwatson	case AUR_BYTE:
288159248Srwatson	/* case AUR_CHAR: */
289155131Srwatson		datasize = AUR_BYTE_SIZE;
290155131Srwatson		break;
291155131Srwatson
292155131Srwatson	case AUR_SHORT:
293155131Srwatson		datasize = AUR_SHORT_SIZE;
294155131Srwatson		break;
295155131Srwatson
296159248Srwatson	case AUR_INT32:
297159248Srwatson	/* case AUR_INT: */
298159248Srwatson		datasize = AUR_INT32_SIZE;
299155131Srwatson		break;
300155131Srwatson
301159248Srwatson	case AUR_INT64:
302159248Srwatson		datasize = AUR_INT64_SIZE;
303159248Srwatson		break;
304159248Srwatson
305155131Srwatson	default:
306155131Srwatson		errno = EINVAL;
307185573Srwatson		return (NULL);
308155131Srwatson	}
309155131Srwatson
310155131Srwatson	totdata = datasize * unit_count;
311155131Srwatson
312159248Srwatson	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
313155131Srwatson	if (t == NULL)
314155131Srwatson		return (NULL);
315155131Srwatson
316186647Srwatson	/*
317186647Srwatson	 * XXXRW: We should be byte-swapping each data item for multi-byte
318186647Srwatson	 * types.
319186647Srwatson	 */
320155131Srwatson	ADD_U_CHAR(dptr, AUT_DATA);
321155131Srwatson	ADD_U_CHAR(dptr, unit_print);
322155131Srwatson	ADD_U_CHAR(dptr, unit_type);
323155131Srwatson	ADD_U_CHAR(dptr, unit_count);
324155131Srwatson	ADD_MEM(dptr, p, totdata);
325155131Srwatson
326155131Srwatson	return (t);
327155131Srwatson}
328155131Srwatson
329155131Srwatson
330155131Srwatson/*
331155131Srwatson * token ID                1 byte
332155131Srwatson * status		   4 bytes
333155131Srwatson * return value            4 bytes
334155131Srwatson */
335155131Srwatsontoken_t *
336155131Srwatsonau_to_exit(int retval, int err)
337155131Srwatson{
338155131Srwatson	token_t *t;
339155131Srwatson	u_char *dptr = NULL;
340155131Srwatson
341155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
342155131Srwatson	if (t == NULL)
343155131Srwatson		return (NULL);
344155131Srwatson
345155131Srwatson	ADD_U_CHAR(dptr, AUT_EXIT);
346155131Srwatson	ADD_U_INT32(dptr, err);
347155131Srwatson	ADD_U_INT32(dptr, retval);
348155131Srwatson
349155131Srwatson	return (t);
350155131Srwatson}
351155131Srwatson
352155131Srwatson/*
353155131Srwatson */
354155131Srwatsontoken_t *
355155131Srwatsonau_to_groups(int *groups)
356155131Srwatson{
357155131Srwatson
358185573Srwatson	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
359155131Srwatson}
360155131Srwatson
361155131Srwatson/*
362155131Srwatson * token ID                1 byte
363155131Srwatson * number groups           2 bytes
364155131Srwatson * group list              count * 4 bytes
365155131Srwatson */
366155131Srwatsontoken_t *
367155131Srwatsonau_to_newgroups(u_int16_t n, gid_t *groups)
368155131Srwatson{
369155131Srwatson	token_t *t;
370155131Srwatson	u_char *dptr = NULL;
371155131Srwatson	int i;
372155131Srwatson
373155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
374155131Srwatson	    n * sizeof(u_int32_t));
375155131Srwatson	if (t == NULL)
376155131Srwatson		return (NULL);
377155131Srwatson
378155131Srwatson	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
379155131Srwatson	ADD_U_INT16(dptr, n);
380155131Srwatson	for (i = 0; i < n; i++)
381155131Srwatson		ADD_U_INT32(dptr, groups[i]);
382155131Srwatson
383155131Srwatson	return (t);
384155131Srwatson}
385155131Srwatson
386155131Srwatson/*
387155131Srwatson * token ID                1 byte
388155131Srwatson * internet address        4 bytes
389155131Srwatson */
390155131Srwatsontoken_t *
391155131Srwatsonau_to_in_addr(struct in_addr *internet_addr)
392155131Srwatson{
393155131Srwatson	token_t *t;
394155131Srwatson	u_char *dptr = NULL;
395155131Srwatson
396159248Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
397155131Srwatson	if (t == NULL)
398155131Srwatson		return (NULL);
399155131Srwatson
400155131Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR);
401159248Srwatson	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
402155131Srwatson
403155131Srwatson	return (t);
404155131Srwatson}
405155131Srwatson
406155131Srwatson/*
407155131Srwatson * token ID                1 byte
408155131Srwatson * address type/length     4 bytes
409185573Srwatson * address                16 bytes
410155131Srwatson */
411155131Srwatsontoken_t *
412155131Srwatsonau_to_in_addr_ex(struct in6_addr *internet_addr)
413155131Srwatson{
414155131Srwatson	token_t *t;
415155131Srwatson	u_char *dptr = NULL;
416186647Srwatson	u_int32_t type = AU_IPv6;
417155131Srwatson
418159248Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
419155131Srwatson	if (t == NULL)
420155131Srwatson		return (NULL);
421155131Srwatson
422155131Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
423155131Srwatson	ADD_U_INT32(dptr, type);
424171537Srwatson	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
425155131Srwatson
426155131Srwatson	return (t);
427155131Srwatson}
428155131Srwatson
429155131Srwatson/*
430155131Srwatson * token ID                1 byte
431155131Srwatson * ip header		   20 bytes
432168777Srwatson *
433168777Srwatson * The IP header should be submitted in network byte order.
434155131Srwatson */
435155131Srwatsontoken_t *
436155131Srwatsonau_to_ip(struct ip *ip)
437155131Srwatson{
438155131Srwatson	token_t *t;
439155131Srwatson	u_char *dptr = NULL;
440155131Srwatson
441155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
442155131Srwatson	if (t == NULL)
443155131Srwatson		return (NULL);
444155131Srwatson
445155131Srwatson	ADD_U_CHAR(dptr, AUT_IP);
446155131Srwatson	ADD_MEM(dptr, ip, sizeof(struct ip));
447155131Srwatson
448155131Srwatson	return (t);
449155131Srwatson}
450155131Srwatson
451155131Srwatson/*
452155131Srwatson * token ID                1 byte
453155131Srwatson * object ID type          1 byte
454155131Srwatson * object ID               4 bytes
455155131Srwatson */
456155131Srwatsontoken_t *
457155131Srwatsonau_to_ipc(char type, int id)
458155131Srwatson{
459155131Srwatson	token_t *t;
460155131Srwatson	u_char *dptr = NULL;
461155131Srwatson
462155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
463155131Srwatson	if (t == NULL)
464155131Srwatson		return (NULL);
465155131Srwatson
466155131Srwatson	ADD_U_CHAR(dptr, AUT_IPC);
467155131Srwatson	ADD_U_CHAR(dptr, type);
468155131Srwatson	ADD_U_INT32(dptr, id);
469155131Srwatson
470155131Srwatson	return (t);
471155131Srwatson}
472155131Srwatson
473155131Srwatson/*
474155131Srwatson * token ID                1 byte
475155131Srwatson * owner user ID           4 bytes
476155131Srwatson * owner group ID          4 bytes
477155131Srwatson * creator user ID         4 bytes
478155131Srwatson * creator group ID        4 bytes
479155131Srwatson * access mode             4 bytes
480155131Srwatson * slot sequence #         4 bytes
481155131Srwatson * key                     4 bytes
482155131Srwatson */
483155131Srwatsontoken_t *
484155131Srwatsonau_to_ipc_perm(struct ipc_perm *perm)
485155131Srwatson{
486155131Srwatson	token_t *t;
487155131Srwatson	u_char *dptr = NULL;
488155131Srwatson	u_int16_t pad0 = 0;
489155131Srwatson
490189279Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
491189279Srwatson	    sizeof(u_int32_t));
492155131Srwatson	if (t == NULL)
493155131Srwatson		return (NULL);
494155131Srwatson
495155131Srwatson	ADD_U_CHAR(dptr, AUT_IPC_PERM);
496155131Srwatson
497155131Srwatson	/*
498186647Srwatson	 * Systems vary significantly in what types they use in struct
499186647Srwatson	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
500186647Srwatson	 * allow for that, as BSM define 32-bit values here.
501186647Srwatson	 * Some systems define the sizes for ipc_perm members as 2 bytes;
502186647Srwatson	 * BSM defines 4 so pad with 0.
503186647Srwatson	 *
504186647Srwatson	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
505186647Srwatson	 * need to be handled.
506155131Srwatson	 */
507186647Srwatson	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
508186647Srwatson		ADD_U_INT16(dptr, pad0);
509186647Srwatson		ADD_U_INT16(dptr, perm->uid);
510186647Srwatson		ADD_U_INT16(dptr, pad0);
511186647Srwatson		ADD_U_INT16(dptr, perm->gid);
512186647Srwatson		ADD_U_INT16(dptr, pad0);
513186647Srwatson		ADD_U_INT16(dptr, perm->cuid);
514186647Srwatson		ADD_U_INT16(dptr, pad0);
515186647Srwatson		ADD_U_INT16(dptr, perm->cgid);
516186647Srwatson	} else {
517186647Srwatson		ADD_U_INT32(dptr, perm->uid);
518186647Srwatson		ADD_U_INT32(dptr, perm->gid);
519186647Srwatson		ADD_U_INT32(dptr, perm->cuid);
520186647Srwatson		ADD_U_INT32(dptr, perm->cgid);
521186647Srwatson	}
522155131Srwatson
523155131Srwatson	ADD_U_INT16(dptr, pad0);
524155131Srwatson	ADD_U_INT16(dptr, perm->mode);
525155131Srwatson
526155131Srwatson	ADD_U_INT16(dptr, pad0);
527156283Srwatson
528156283Srwatson#ifdef HAVE_IPC_PERM___SEQ
529156283Srwatson	ADD_U_INT16(dptr, perm->__seq);
530185573Srwatson#else	/* HAVE_IPC_PERM___SEQ */
531185573Srwatson#ifdef  HAVE_IPC_PERM__SEQ
532185573Srwatson	ADD_U_INT16(dptr, perm->_seq);
533185573Srwatson#else	/* HAVE_IPC_PERM__SEQ */
534155131Srwatson	ADD_U_INT16(dptr, perm->seq);
535185573Srwatson#endif	/* HAVE_IPC_PERM__SEQ */
536185573Srwatson#endif	/* HAVE_IPC_PERM___SEQ */
537155131Srwatson
538156283Srwatson#ifdef HAVE_IPC_PERM___KEY
539156283Srwatson	ADD_U_INT32(dptr, perm->__key);
540185573Srwatson#else	/* HAVE_IPC_PERM___KEY */
541185573Srwatson#ifdef  HAVE_IPC_PERM__KEY
542185573Srwatson	ADD_U_INT32(dptr, perm->_key);
543185573Srwatson#else	/* HAVE_IPC_PERM__KEY */
544155131Srwatson	ADD_U_INT32(dptr, perm->key);
545185573Srwatson#endif	/* HAVE_IPC_PERM__KEY */
546185573Srwatson#endif	/* HAVE_IPC_PERM___KEY */
547155131Srwatson
548155131Srwatson	return (t);
549155131Srwatson}
550155131Srwatson
551155131Srwatson/*
552155131Srwatson * token ID                1 byte
553155131Srwatson * port IP address         2 bytes
554155131Srwatson */
555155131Srwatsontoken_t *
556155131Srwatsonau_to_iport(u_int16_t iport)
557155131Srwatson{
558155131Srwatson	token_t *t;
559155131Srwatson	u_char *dptr = NULL;
560155131Srwatson
561155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
562155131Srwatson	if (t == NULL)
563155131Srwatson		return (NULL);
564155131Srwatson
565155131Srwatson	ADD_U_CHAR(dptr, AUT_IPORT);
566155131Srwatson	ADD_U_INT16(dptr, iport);
567155131Srwatson
568155131Srwatson	return (t);
569155131Srwatson}
570155131Srwatson
571155131Srwatson/*
572155131Srwatson * token ID                1 byte
573155131Srwatson * size                    2 bytes
574155131Srwatson * data                    size bytes
575155131Srwatson */
576155131Srwatsontoken_t *
577185573Srwatsonau_to_opaque(const char *data, u_int16_t bytes)
578155131Srwatson{
579155131Srwatson	token_t *t;
580155131Srwatson	u_char *dptr = NULL;
581155131Srwatson
582155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
583155131Srwatson	if (t == NULL)
584155131Srwatson		return (NULL);
585155131Srwatson
586155131Srwatson	ADD_U_CHAR(dptr, AUT_OPAQUE);
587155131Srwatson	ADD_U_INT16(dptr, bytes);
588155131Srwatson	ADD_MEM(dptr, data, bytes);
589155131Srwatson
590155131Srwatson	return (t);
591155131Srwatson}
592155131Srwatson
593155131Srwatson/*
594155131Srwatson * token ID                1 byte
595155131Srwatson * seconds of time         4 bytes
596155131Srwatson * milliseconds of time    4 bytes
597155131Srwatson * file name len           2 bytes
598155131Srwatson * file pathname           N bytes + 1 terminating NULL byte
599155131Srwatson */
600155131Srwatsontoken_t *
601185573Srwatsonau_to_file(const char *file, struct timeval tm)
602155131Srwatson{
603155131Srwatson	token_t *t;
604155131Srwatson	u_char *dptr = NULL;
605155131Srwatson	u_int16_t filelen;
606155131Srwatson	u_int32_t timems;
607155131Srwatson
608155131Srwatson	filelen = strlen(file);
609155131Srwatson	filelen += 1;
610155131Srwatson
611155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
612155131Srwatson	    sizeof(u_int16_t) + filelen);
613155131Srwatson	if (t == NULL)
614155131Srwatson		return (NULL);
615155131Srwatson
616155131Srwatson	timems = tm.tv_usec/1000;
617155131Srwatson
618155131Srwatson	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
619155131Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
620155131Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
621155131Srwatson	ADD_U_INT16(dptr, filelen);
622155131Srwatson	ADD_STRING(dptr, file, filelen);
623155131Srwatson
624155131Srwatson	return (t);
625155131Srwatson}
626155131Srwatson
627155131Srwatson/*
628155131Srwatson * token ID                1 byte
629155131Srwatson * text length             2 bytes
630155131Srwatson * text                    N bytes + 1 terminating NULL byte
631155131Srwatson */
632155131Srwatsontoken_t *
633185573Srwatsonau_to_text(const char *text)
634155131Srwatson{
635155131Srwatson	token_t *t;
636155131Srwatson	u_char *dptr = NULL;
637155131Srwatson	u_int16_t textlen;
638155131Srwatson
639155131Srwatson	textlen = strlen(text);
640155131Srwatson	textlen += 1;
641155131Srwatson
642186647Srwatson	/* XXXRW: Should validate length against token size limit. */
643186647Srwatson
644155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
645155131Srwatson	if (t == NULL)
646155131Srwatson		return (NULL);
647155131Srwatson
648155131Srwatson	ADD_U_CHAR(dptr, AUT_TEXT);
649155131Srwatson	ADD_U_INT16(dptr, textlen);
650155131Srwatson	ADD_STRING(dptr, text, textlen);
651155131Srwatson
652155131Srwatson	return (t);
653155131Srwatson}
654155131Srwatson
655155131Srwatson/*
656155131Srwatson * token ID                1 byte
657155131Srwatson * path length             2 bytes
658155131Srwatson * path                    N bytes + 1 terminating NULL byte
659155131Srwatson */
660155131Srwatsontoken_t *
661185573Srwatsonau_to_path(const char *text)
662155131Srwatson{
663155131Srwatson	token_t *t;
664155131Srwatson	u_char *dptr = NULL;
665155131Srwatson	u_int16_t textlen;
666155131Srwatson
667155131Srwatson	textlen = strlen(text);
668155131Srwatson	textlen += 1;
669155131Srwatson
670155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
671155131Srwatson	if (t == NULL)
672155131Srwatson		return (NULL);
673155131Srwatson
674155131Srwatson	ADD_U_CHAR(dptr, AUT_PATH);
675155131Srwatson	ADD_U_INT16(dptr, textlen);
676155131Srwatson	ADD_STRING(dptr, text, textlen);
677155131Srwatson
678155131Srwatson	return (t);
679155131Srwatson}
680155131Srwatson
681155131Srwatson/*
682155131Srwatson * token ID                1 byte
683155131Srwatson * audit ID                4 bytes
684155131Srwatson * effective user ID       4 bytes
685155131Srwatson * effective group ID      4 bytes
686155131Srwatson * real user ID            4 bytes
687155131Srwatson * real group ID           4 bytes
688155131Srwatson * process ID              4 bytes
689155131Srwatson * session ID              4 bytes
690155131Srwatson * terminal ID
691155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
692155131Srwatson *   machine address       4 bytes
693155131Srwatson */
694155131Srwatsontoken_t *
695155131Srwatsonau_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
696155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
697155131Srwatson{
698155131Srwatson	token_t *t;
699155131Srwatson	u_char *dptr = NULL;
700155131Srwatson
701155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
702155131Srwatson	if (t == NULL)
703155131Srwatson		return (NULL);
704155131Srwatson
705155131Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32);
706155131Srwatson	ADD_U_INT32(dptr, auid);
707155131Srwatson	ADD_U_INT32(dptr, euid);
708155131Srwatson	ADD_U_INT32(dptr, egid);
709155131Srwatson	ADD_U_INT32(dptr, ruid);
710155131Srwatson	ADD_U_INT32(dptr, rgid);
711155131Srwatson	ADD_U_INT32(dptr, pid);
712155131Srwatson	ADD_U_INT32(dptr, sid);
713155131Srwatson	ADD_U_INT32(dptr, tid->port);
714186647Srwatson
715186647Srwatson	/*
716186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
717186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
718186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
719186647Srwatson	 * addresses for process32 tokens.
720186647Srwatson	 */
721159248Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
722155131Srwatson
723155131Srwatson	return (t);
724155131Srwatson}
725155131Srwatson
726155131Srwatsontoken_t *
727168777Srwatsonau_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
728168777Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
729155131Srwatson{
730168777Srwatson	token_t *t;
731168777Srwatson	u_char *dptr = NULL;
732155131Srwatson
733168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
734168777Srwatson	    sizeof(u_int64_t));
735168777Srwatson	if (t == NULL)
736168777Srwatson		return (NULL);
737168777Srwatson
738168777Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64);
739168777Srwatson	ADD_U_INT32(dptr, auid);
740168777Srwatson	ADD_U_INT32(dptr, euid);
741168777Srwatson	ADD_U_INT32(dptr, egid);
742168777Srwatson	ADD_U_INT32(dptr, ruid);
743168777Srwatson	ADD_U_INT32(dptr, rgid);
744168777Srwatson	ADD_U_INT32(dptr, pid);
745168777Srwatson	ADD_U_INT32(dptr, sid);
746168777Srwatson	ADD_U_INT64(dptr, tid->port);
747186647Srwatson
748186647Srwatson	/*
749186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
750186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
751186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
752186647Srwatson	 * addresses for process64 tokens.
753186647Srwatson	 */
754168777Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
755168777Srwatson
756168777Srwatson	return (t);
757155131Srwatson}
758155131Srwatson
759155131Srwatsontoken_t *
760168777Srwatsonau_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
761168777Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
762155131Srwatson{
763155131Srwatson
764155131Srwatson	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
765155131Srwatson	    tid));
766155131Srwatson}
767155131Srwatson
768155131Srwatson/*
769155131Srwatson * token ID                1 byte
770155131Srwatson * audit ID                4 bytes
771155131Srwatson * effective user ID       4 bytes
772155131Srwatson * effective group ID      4 bytes
773155131Srwatson * real user ID            4 bytes
774155131Srwatson * real group ID           4 bytes
775155131Srwatson * process ID              4 bytes
776155131Srwatson * session ID              4 bytes
777155131Srwatson * terminal ID
778155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
779155131Srwatson *   address type-len      4 bytes
780155131Srwatson *   machine address      16 bytes
781155131Srwatson */
782155131Srwatsontoken_t *
783155131Srwatsonau_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
784155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
785155131Srwatson{
786155131Srwatson	token_t *t;
787155131Srwatson	u_char *dptr = NULL;
788155131Srwatson
789159985Srwatson	if (tid->at_type == AU_IPv4)
790159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
791159985Srwatson		    10 * sizeof(u_int32_t));
792159985Srwatson	else if (tid->at_type == AU_IPv6)
793159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
794159985Srwatson		    13 * sizeof(u_int32_t));
795159985Srwatson	else {
796159985Srwatson		errno = EINVAL;
797159985Srwatson		return (NULL);
798159985Srwatson	}
799155131Srwatson	if (t == NULL)
800155131Srwatson		return (NULL);
801155131Srwatson
802155131Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
803155131Srwatson	ADD_U_INT32(dptr, auid);
804155131Srwatson	ADD_U_INT32(dptr, euid);
805155131Srwatson	ADD_U_INT32(dptr, egid);
806155131Srwatson	ADD_U_INT32(dptr, ruid);
807155131Srwatson	ADD_U_INT32(dptr, rgid);
808155131Srwatson	ADD_U_INT32(dptr, pid);
809155131Srwatson	ADD_U_INT32(dptr, sid);
810155131Srwatson	ADD_U_INT32(dptr, tid->at_port);
811155131Srwatson	ADD_U_INT32(dptr, tid->at_type);
812168777Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
813159985Srwatson	if (tid->at_type == AU_IPv6) {
814168777Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
815168777Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
816168777Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
817159985Srwatson	}
818155131Srwatson
819155131Srwatson	return (t);
820155131Srwatson}
821155131Srwatson
822155131Srwatsontoken_t *
823155131Srwatsonau_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
824155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
825155131Srwatson{
826168777Srwatson	token_t *t;
827168777Srwatson	u_char *dptr = NULL;
828155131Srwatson
829168777Srwatson	if (tid->at_type == AU_IPv4)
830168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
831168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
832168777Srwatson		    2 * sizeof(u_int32_t));
833168777Srwatson	else if (tid->at_type == AU_IPv6)
834168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
835168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
836168777Srwatson		    5 * sizeof(u_int32_t));
837168777Srwatson	else {
838168777Srwatson		errno = EINVAL;
839168777Srwatson		return (NULL);
840168777Srwatson	}
841168777Srwatson	if (t == NULL)
842168777Srwatson		return (NULL);
843168777Srwatson
844168777Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
845168777Srwatson	ADD_U_INT32(dptr, auid);
846168777Srwatson	ADD_U_INT32(dptr, euid);
847168777Srwatson	ADD_U_INT32(dptr, egid);
848168777Srwatson	ADD_U_INT32(dptr, ruid);
849168777Srwatson	ADD_U_INT32(dptr, rgid);
850168777Srwatson	ADD_U_INT32(dptr, pid);
851168777Srwatson	ADD_U_INT32(dptr, sid);
852168777Srwatson	ADD_U_INT64(dptr, tid->at_port);
853168777Srwatson	ADD_U_INT32(dptr, tid->at_type);
854168777Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
855168777Srwatson	if (tid->at_type == AU_IPv6) {
856168777Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
857168777Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
858168777Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
859168777Srwatson	}
860168777Srwatson
861168777Srwatson	return (t);
862155131Srwatson}
863155131Srwatson
864155131Srwatsontoken_t *
865155131Srwatsonau_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
866155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
867155131Srwatson{
868155131Srwatson
869155131Srwatson	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
870155131Srwatson	    tid));
871155131Srwatson}
872155131Srwatson
873155131Srwatson/*
874155131Srwatson * token ID                1 byte
875155131Srwatson * error status            1 byte
876155131Srwatson * return value            4 bytes/8 bytes (32-bit/64-bit value)
877155131Srwatson */
878155131Srwatsontoken_t *
879155131Srwatsonau_to_return32(char status, u_int32_t ret)
880155131Srwatson{
881155131Srwatson	token_t *t;
882155131Srwatson	u_char *dptr = NULL;
883155131Srwatson
884155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
885155131Srwatson	if (t == NULL)
886155131Srwatson		return (NULL);
887155131Srwatson
888155131Srwatson	ADD_U_CHAR(dptr, AUT_RETURN32);
889155131Srwatson	ADD_U_CHAR(dptr, status);
890155131Srwatson	ADD_U_INT32(dptr, ret);
891155131Srwatson
892155131Srwatson	return (t);
893155131Srwatson}
894155131Srwatson
895155131Srwatsontoken_t *
896155131Srwatsonau_to_return64(char status, u_int64_t ret)
897155131Srwatson{
898155131Srwatson	token_t *t;
899155131Srwatson	u_char *dptr = NULL;
900155131Srwatson
901155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
902155131Srwatson	if (t == NULL)
903155131Srwatson		return (NULL);
904155131Srwatson
905155131Srwatson	ADD_U_CHAR(dptr, AUT_RETURN64);
906155131Srwatson	ADD_U_CHAR(dptr, status);
907155131Srwatson	ADD_U_INT64(dptr, ret);
908155131Srwatson
909155131Srwatson	return (t);
910155131Srwatson}
911155131Srwatson
912155131Srwatsontoken_t *
913155131Srwatsonau_to_return(char status, u_int32_t ret)
914155131Srwatson{
915155131Srwatson
916155131Srwatson	return (au_to_return32(status, ret));
917155131Srwatson}
918155131Srwatson
919155131Srwatson/*
920155131Srwatson * token ID                1 byte
921155131Srwatson * sequence number         4 bytes
922155131Srwatson */
923155131Srwatsontoken_t *
924155131Srwatsonau_to_seq(long audit_count)
925155131Srwatson{
926155131Srwatson	token_t *t;
927155131Srwatson	u_char *dptr = NULL;
928155131Srwatson
929155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
930155131Srwatson	if (t == NULL)
931155131Srwatson		return (NULL);
932155131Srwatson
933155131Srwatson	ADD_U_CHAR(dptr, AUT_SEQ);
934155131Srwatson	ADD_U_INT32(dptr, audit_count);
935155131Srwatson
936155131Srwatson	return (t);
937155131Srwatson}
938155131Srwatson
939155131Srwatson/*
940155131Srwatson * token ID                1 byte
941186647Srwatson * socket domain           2 bytes
942186647Srwatson * socket type             2 bytes
943186647Srwatson * address type            2 byte
944186647Srwatson * local port              2 bytes
945186647Srwatson * local address           4 bytes/16 bytes (IPv4/IPv6 address)
946186647Srwatson * remote port             2 bytes
947186647Srwatson * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
948187214Srwatson *
949187214Srwatson * Domain and type arguments to this routine are assumed to already have been
950187214Srwatson * converted to the BSM constant space, so we don't do that here.
951186647Srwatson */
952186647Srwatsontoken_t *
953186647Srwatsonau_to_socket_ex(u_short so_domain, u_short so_type,
954186647Srwatson    struct sockaddr *sa_local, struct sockaddr *sa_remote)
955186647Srwatson{
956186647Srwatson	token_t *t;
957186647Srwatson	u_char *dptr = NULL;
958186647Srwatson	struct sockaddr_in *sin;
959186647Srwatson	struct sockaddr_in6 *sin6;
960186647Srwatson
961186647Srwatson	if (so_domain == AF_INET)
962186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
963186647Srwatson		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
964186647Srwatson	else if (so_domain == AF_INET6)
965186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
966189279Srwatson		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
967186647Srwatson	else {
968186647Srwatson		errno = EINVAL;
969186647Srwatson		return (NULL);
970186647Srwatson	}
971186647Srwatson
972186647Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
973189279Srwatson	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
974189279Srwatson	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
975186647Srwatson	if (so_domain == AF_INET) {
976186647Srwatson		ADD_U_INT16(dptr, AU_IPv4);
977186647Srwatson		sin = (struct sockaddr_in *)sa_local;
978186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
979186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
980186647Srwatson		sin = (struct sockaddr_in *)sa_remote;
981186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
982186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
983186647Srwatson	} else {
984186647Srwatson		ADD_U_INT16(dptr, AU_IPv6);
985186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_local;
986186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
987186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
988186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_remote;
989186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
990186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
991186647Srwatson	}
992186647Srwatson
993186647Srwatson	return (t);
994186647Srwatson}
995186647Srwatson
996186647Srwatson/*
997186647Srwatson * token ID                1 byte
998155131Srwatson * socket family           2 bytes
999155131Srwatson * path                    104 bytes
1000155131Srwatson */
1001155131Srwatsontoken_t *
1002155131Srwatsonau_to_sock_unix(struct sockaddr_un *so)
1003155131Srwatson{
1004155131Srwatson	token_t *t;
1005155131Srwatson	u_char *dptr;
1006155131Srwatson
1007155131Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1008155131Srwatson	if (t == NULL)
1009155131Srwatson		return (NULL);
1010155131Srwatson
1011185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1012155131Srwatson	/* BSM token has two bytes for family */
1013155131Srwatson	ADD_U_CHAR(dptr, 0);
1014155131Srwatson	ADD_U_CHAR(dptr, so->sun_family);
1015155131Srwatson	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1016155131Srwatson
1017155131Srwatson	return (t);
1018155131Srwatson}
1019155131Srwatson
1020155131Srwatson/*
1021155131Srwatson * token ID                1 byte
1022155131Srwatson * socket family           2 bytes
1023155131Srwatson * local port              2 bytes
1024155131Srwatson * socket address          4 bytes
1025155131Srwatson */
1026155131Srwatsontoken_t *
1027155131Srwatsonau_to_sock_inet32(struct sockaddr_in *so)
1028155131Srwatson{
1029155131Srwatson	token_t *t;
1030155131Srwatson	u_char *dptr = NULL;
1031159248Srwatson	uint16_t family;
1032155131Srwatson
1033159248Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1034159248Srwatson	    sizeof(uint32_t));
1035155131Srwatson	if (t == NULL)
1036155131Srwatson		return (NULL);
1037155131Srwatson
1038155131Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1039155131Srwatson	/*
1040159248Srwatson	 * BSM defines the family field as 16 bits, but many operating
1041159248Srwatson	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1042159248Srwatson	 * writing into the token.  Assume that both the port and the address
1043159248Srwatson	 * in the sockaddr_in are already in network byte order, but family
1044159248Srwatson	 * is in local byte order.
1045159248Srwatson	 *
1046159248Srwatson	 * XXXRW: Should a name space conversion be taking place on the value
1047159248Srwatson	 * of sin_family?
1048185573Srwatson	 */
1049159248Srwatson	family = so->sin_family;
1050159248Srwatson	ADD_U_INT16(dptr, family);
1051159248Srwatson	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1052159248Srwatson	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1053155131Srwatson
1054155131Srwatson	return (t);
1055155131Srwatson}
1056155131Srwatson
1057155131Srwatsontoken_t *
1058155131Srwatsonau_to_sock_inet128(struct sockaddr_in6 *so)
1059155131Srwatson{
1060155131Srwatson	token_t *t;
1061155131Srwatson	u_char *dptr = NULL;
1062155131Srwatson
1063155131Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1064155131Srwatson	    4 * sizeof(u_int32_t));
1065155131Srwatson	if (t == NULL)
1066155131Srwatson		return (NULL);
1067155131Srwatson
1068155131Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1069155131Srwatson	/*
1070186647Srwatson	 * In BSD, sin6_family is one octet, but BSM defines the token to
1071186647Srwatson	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1072186647Srwatson	 * conditionally compiled.
1073185573Srwatson	 */
1074155131Srwatson	ADD_U_CHAR(dptr, 0);
1075155131Srwatson	ADD_U_CHAR(dptr, so->sin6_family);
1076155131Srwatson
1077155131Srwatson	ADD_U_INT16(dptr, so->sin6_port);
1078159248Srwatson	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1079155131Srwatson
1080155131Srwatson	return (t);
1081155131Srwatson}
1082155131Srwatson
1083155131Srwatsontoken_t *
1084155131Srwatsonau_to_sock_inet(struct sockaddr_in *so)
1085155131Srwatson{
1086155131Srwatson
1087155131Srwatson	return (au_to_sock_inet32(so));
1088155131Srwatson}
1089155131Srwatson
1090155131Srwatson/*
1091155131Srwatson * token ID                1 byte
1092155131Srwatson * audit ID                4 bytes
1093155131Srwatson * effective user ID       4 bytes
1094155131Srwatson * effective group ID      4 bytes
1095155131Srwatson * real user ID            4 bytes
1096155131Srwatson * real group ID           4 bytes
1097155131Srwatson * process ID              4 bytes
1098155131Srwatson * session ID              4 bytes
1099155131Srwatson * terminal ID
1100155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1101155131Srwatson *   machine address       4 bytes
1102155131Srwatson */
1103155131Srwatsontoken_t *
1104155131Srwatsonau_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1105155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1106155131Srwatson{
1107155131Srwatson	token_t *t;
1108155131Srwatson	u_char *dptr = NULL;
1109155131Srwatson
1110155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1111155131Srwatson	if (t == NULL)
1112155131Srwatson		return (NULL);
1113155131Srwatson
1114155131Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1115155131Srwatson	ADD_U_INT32(dptr, auid);
1116155131Srwatson	ADD_U_INT32(dptr, euid);
1117155131Srwatson	ADD_U_INT32(dptr, egid);
1118155131Srwatson	ADD_U_INT32(dptr, ruid);
1119155131Srwatson	ADD_U_INT32(dptr, rgid);
1120155131Srwatson	ADD_U_INT32(dptr, pid);
1121155131Srwatson	ADD_U_INT32(dptr, sid);
1122155131Srwatson	ADD_U_INT32(dptr, tid->port);
1123159248Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1124155131Srwatson
1125155131Srwatson	return (t);
1126155131Srwatson}
1127155131Srwatson
1128155131Srwatsontoken_t *
1129155131Srwatsonau_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1130155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1131155131Srwatson{
1132168777Srwatson	token_t *t;
1133168777Srwatson	u_char *dptr = NULL;
1134155131Srwatson
1135168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1136168777Srwatson	    sizeof(u_int64_t) + sizeof(u_int32_t));
1137168777Srwatson	if (t == NULL)
1138168777Srwatson		return (NULL);
1139168777Srwatson
1140168777Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1141168777Srwatson	ADD_U_INT32(dptr, auid);
1142168777Srwatson	ADD_U_INT32(dptr, euid);
1143168777Srwatson	ADD_U_INT32(dptr, egid);
1144168777Srwatson	ADD_U_INT32(dptr, ruid);
1145168777Srwatson	ADD_U_INT32(dptr, rgid);
1146168777Srwatson	ADD_U_INT32(dptr, pid);
1147168777Srwatson	ADD_U_INT32(dptr, sid);
1148168777Srwatson	ADD_U_INT64(dptr, tid->port);
1149168777Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1150168777Srwatson
1151168777Srwatson	return (t);
1152155131Srwatson}
1153155131Srwatson
1154155131Srwatsontoken_t *
1155155131Srwatsonau_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1156155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1157155131Srwatson{
1158155131Srwatson
1159155131Srwatson	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1160155131Srwatson	    tid));
1161155131Srwatson}
1162155131Srwatson
1163155131Srwatson/*
1164155131Srwatson * token ID                1 byte
1165155131Srwatson * audit ID                4 bytes
1166155131Srwatson * effective user ID       4 bytes
1167155131Srwatson * effective group ID      4 bytes
1168155131Srwatson * real user ID            4 bytes
1169155131Srwatson * real group ID           4 bytes
1170155131Srwatson * process ID              4 bytes
1171155131Srwatson * session ID              4 bytes
1172155131Srwatson * terminal ID
1173155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1174155131Srwatson *   address type/length   4 bytes
1175155131Srwatson *   machine address      16 bytes
1176155131Srwatson */
1177155131Srwatsontoken_t *
1178155131Srwatsonau_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1179155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1180155131Srwatson{
1181155131Srwatson	token_t *t;
1182155131Srwatson	u_char *dptr = NULL;
1183155131Srwatson
1184159985Srwatson	if (tid->at_type == AU_IPv4)
1185159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1186159985Srwatson		    sizeof(u_int32_t));
1187159985Srwatson	else if (tid->at_type == AU_IPv6)
1188159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1189159985Srwatson		    sizeof(u_int32_t));
1190159985Srwatson	else {
1191159985Srwatson		errno = EINVAL;
1192159985Srwatson		return (NULL);
1193159985Srwatson	}
1194155131Srwatson	if (t == NULL)
1195155131Srwatson		return (NULL);
1196155131Srwatson
1197155131Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1198155131Srwatson	ADD_U_INT32(dptr, auid);
1199155131Srwatson	ADD_U_INT32(dptr, euid);
1200155131Srwatson	ADD_U_INT32(dptr, egid);
1201155131Srwatson	ADD_U_INT32(dptr, ruid);
1202155131Srwatson	ADD_U_INT32(dptr, rgid);
1203155131Srwatson	ADD_U_INT32(dptr, pid);
1204155131Srwatson	ADD_U_INT32(dptr, sid);
1205155131Srwatson	ADD_U_INT32(dptr, tid->at_port);
1206155131Srwatson	ADD_U_INT32(dptr, tid->at_type);
1207168777Srwatson	if (tid->at_type == AU_IPv6)
1208168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1209168777Srwatson	else
1210168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1211155131Srwatson
1212155131Srwatson	return (t);
1213155131Srwatson}
1214155131Srwatson
1215155131Srwatsontoken_t *
1216155131Srwatsonau_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1217155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1218155131Srwatson{
1219168777Srwatson	token_t *t;
1220168777Srwatson	u_char *dptr = NULL;
1221155131Srwatson
1222168777Srwatson	if (tid->at_type == AU_IPv4)
1223168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1224168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1225168777Srwatson		    2 * sizeof(u_int32_t));
1226168777Srwatson	else if (tid->at_type == AU_IPv6)
1227168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1228168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1229168777Srwatson		    5 * sizeof(u_int32_t));
1230168777Srwatson	else {
1231168777Srwatson		errno = EINVAL;
1232168777Srwatson		return (NULL);
1233168777Srwatson	}
1234168777Srwatson	if (t == NULL)
1235168777Srwatson		return (NULL);
1236168777Srwatson
1237168777Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1238168777Srwatson	ADD_U_INT32(dptr, auid);
1239168777Srwatson	ADD_U_INT32(dptr, euid);
1240168777Srwatson	ADD_U_INT32(dptr, egid);
1241168777Srwatson	ADD_U_INT32(dptr, ruid);
1242168777Srwatson	ADD_U_INT32(dptr, rgid);
1243168777Srwatson	ADD_U_INT32(dptr, pid);
1244168777Srwatson	ADD_U_INT32(dptr, sid);
1245168777Srwatson	ADD_U_INT64(dptr, tid->at_port);
1246168777Srwatson	ADD_U_INT32(dptr, tid->at_type);
1247168777Srwatson	if (tid->at_type == AU_IPv6)
1248168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1249168777Srwatson	else
1250168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1251168777Srwatson
1252168777Srwatson	return (t);
1253155131Srwatson}
1254155131Srwatson
1255155131Srwatsontoken_t *
1256155131Srwatsonau_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1257155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1258155131Srwatson{
1259155131Srwatson
1260155131Srwatson	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1261155131Srwatson	    tid));
1262155131Srwatson}
1263155131Srwatson
1264156283Srwatson#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1265155131Srwatson/*
1266185573Srwatson * Collects audit information for the current process and creates a subject
1267185573Srwatson * token from it.
1268155131Srwatson */
1269155131Srwatsontoken_t *
1270155131Srwatsonau_to_me(void)
1271155131Srwatson{
1272155131Srwatson	auditinfo_t auinfo;
1273155131Srwatson
1274155131Srwatson	if (getaudit(&auinfo) != 0)
1275155131Srwatson		return (NULL);
1276155131Srwatson
1277155131Srwatson	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1278155131Srwatson	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1279155131Srwatson}
1280155131Srwatson#endif
1281155131Srwatson
1282155131Srwatson/*
1283155131Srwatson * token ID				1 byte
1284155131Srwatson * count				4 bytes
1285155131Srwatson * text					count null-terminated strings
1286155131Srwatson */
1287155131Srwatsontoken_t *
1288161818Srwatsonau_to_exec_args(char **argv)
1289155131Srwatson{
1290155131Srwatson	token_t *t;
1291155131Srwatson	u_char *dptr = NULL;
1292155131Srwatson	const char *nextarg;
1293155131Srwatson	int i, count = 0;
1294155131Srwatson	size_t totlen = 0;
1295155131Srwatson
1296161630Srwatson	nextarg = *argv;
1297155131Srwatson
1298155131Srwatson	while (nextarg != NULL) {
1299155131Srwatson		int nextlen;
1300155131Srwatson
1301155131Srwatson		nextlen = strlen(nextarg);
1302155131Srwatson		totlen += nextlen + 1;
1303155131Srwatson		count++;
1304161630Srwatson		nextarg = *(argv + count);
1305155131Srwatson	}
1306155131Srwatson
1307155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1308155131Srwatson	if (t == NULL)
1309155131Srwatson		return (NULL);
1310155131Srwatson
1311155131Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1312155131Srwatson	ADD_U_INT32(dptr, count);
1313155131Srwatson
1314155131Srwatson	for (i = 0; i < count; i++) {
1315161630Srwatson		nextarg = *(argv + i);
1316155131Srwatson		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1317155131Srwatson	}
1318155131Srwatson
1319155131Srwatson	return (t);
1320155131Srwatson}
1321155131Srwatson
1322155131Srwatson/*
1323155131Srwatson * token ID				1 byte
1324155131Srwatson * count				4 bytes
1325155131Srwatson * text					count null-terminated strings
1326155131Srwatson */
1327155131Srwatsontoken_t *
1328161818Srwatsonau_to_exec_env(char **envp)
1329155131Srwatson{
1330155131Srwatson	token_t *t;
1331155131Srwatson	u_char *dptr = NULL;
1332155131Srwatson	int i, count = 0;
1333155131Srwatson	size_t totlen = 0;
1334155131Srwatson	const char *nextenv;
1335155131Srwatson
1336161630Srwatson	nextenv = *envp;
1337155131Srwatson
1338155131Srwatson	while (nextenv != NULL) {
1339155131Srwatson		int nextlen;
1340155131Srwatson
1341155131Srwatson		nextlen = strlen(nextenv);
1342155131Srwatson		totlen += nextlen + 1;
1343155131Srwatson		count++;
1344161630Srwatson		nextenv = *(envp + count);
1345155131Srwatson	}
1346155131Srwatson
1347155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1348155131Srwatson	if (t == NULL)
1349155131Srwatson		return (NULL);
1350155131Srwatson
1351155131Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1352155131Srwatson	ADD_U_INT32(dptr, count);
1353155131Srwatson
1354155131Srwatson	for (i = 0; i < count; i++) {
1355161630Srwatson		nextenv = *(envp + i);
1356155131Srwatson		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1357155131Srwatson	}
1358155131Srwatson
1359155131Srwatson	return (t);
1360155131Srwatson}
1361155131Srwatson
1362155131Srwatson/*
1363155131Srwatson * token ID                1 byte
1364186647Srwatson * zonename length         2 bytes
1365186647Srwatson * zonename                N bytes + 1 terminating NULL byte
1366186647Srwatson */
1367186647Srwatsontoken_t *
1368186647Srwatsonau_to_zonename(const char *zonename)
1369186647Srwatson{
1370186647Srwatson	u_char *dptr = NULL;
1371186647Srwatson	u_int16_t textlen;
1372186647Srwatson	token_t *t;
1373186647Srwatson
1374186647Srwatson	textlen = strlen(zonename) + 1;
1375186647Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1376186647Srwatson	if (t == NULL)
1377186647Srwatson		return (NULL);
1378186647Srwatson
1379186647Srwatson	ADD_U_CHAR(dptr, AUT_ZONENAME);
1380186647Srwatson	ADD_U_INT16(dptr, textlen);
1381186647Srwatson	ADD_STRING(dptr, zonename, textlen);
1382186647Srwatson	return (t);
1383186647Srwatson}
1384186647Srwatson
1385186647Srwatson/*
1386186647Srwatson * token ID                1 byte
1387155131Srwatson * record byte count       4 bytes
1388155131Srwatson * version #               1 byte    [2]
1389155131Srwatson * event type              2 bytes
1390155131Srwatson * event modifier          2 bytes
1391155131Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1392155131Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1393155131Srwatson */
1394155131Srwatsontoken_t *
1395159248Srwatsonau_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1396155131Srwatson    struct timeval tm)
1397155131Srwatson{
1398155131Srwatson	token_t *t;
1399155131Srwatson	u_char *dptr = NULL;
1400155131Srwatson	u_int32_t timems;
1401155131Srwatson
1402155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1403155131Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1404155131Srwatson	if (t == NULL)
1405155131Srwatson		return (NULL);
1406155131Srwatson
1407155131Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32);
1408155131Srwatson	ADD_U_INT32(dptr, rec_size);
1409161630Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1410155131Srwatson	ADD_U_INT16(dptr, e_type);
1411155131Srwatson	ADD_U_INT16(dptr, e_mod);
1412155131Srwatson
1413155131Srwatson	timems = tm.tv_usec/1000;
1414155131Srwatson	/* Add the timestamp */
1415155131Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1416155131Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1417155131Srwatson
1418155131Srwatson	return (t);
1419155131Srwatson}
1420155131Srwatson
1421185573Srwatson/*
1422185573Srwatson * token ID                1 byte
1423185573Srwatson * record byte count       4 bytes
1424185573Srwatson * version #               1 byte    [2]
1425185573Srwatson * event type              2 bytes
1426185573Srwatson * event modifier          2 bytes
1427185573Srwatson * address type/length     4 bytes
1428185573Srwatson * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1429185573Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1430185573Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1431185573Srwatson */
1432168777Srwatsontoken_t *
1433185573Srwatsonau_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1434185573Srwatson    struct timeval tm, struct auditinfo_addr *aia)
1435185573Srwatson{
1436185573Srwatson	token_t *t;
1437185573Srwatson	u_char *dptr = NULL;
1438186647Srwatson	u_int32_t timems;
1439186647Srwatson	au_tid_addr_t *tid;
1440185573Srwatson
1441186647Srwatson	tid = &aia->ai_termid;
1442185573Srwatson	if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6)
1443185573Srwatson		return (NULL);
1444185573Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1445185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1446185573Srwatson	    sizeof(u_int32_t) + tid->at_type);
1447185573Srwatson	if (t == NULL)
1448185573Srwatson		return (NULL);
1449185573Srwatson
1450185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1451185573Srwatson	ADD_U_INT32(dptr, rec_size);
1452185573Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1453185573Srwatson	ADD_U_INT16(dptr, e_type);
1454185573Srwatson	ADD_U_INT16(dptr, e_mod);
1455185573Srwatson
1456185573Srwatson	ADD_U_INT32(dptr, tid->at_type);
1457185573Srwatson	if (tid->at_type == AU_IPv6)
1458185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1459185573Srwatson	else
1460185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1461185573Srwatson	timems = tm.tv_usec/1000;
1462185573Srwatson	/* Add the timestamp */
1463185573Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1464185573Srwatson	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1465185573Srwatson
1466185573Srwatson	return (t);
1467185573Srwatson}
1468185573Srwatson
1469185573Srwatsontoken_t *
1470168777Srwatsonau_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1471168777Srwatson    struct timeval tm)
1472168777Srwatson{
1473168777Srwatson	token_t *t;
1474168777Srwatson	u_char *dptr = NULL;
1475168777Srwatson	u_int32_t timems;
1476168777Srwatson
1477168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1478168777Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1479168777Srwatson	if (t == NULL)
1480168777Srwatson		return (NULL);
1481168777Srwatson
1482168777Srwatson	ADD_U_CHAR(dptr, AUT_HEADER64);
1483168777Srwatson	ADD_U_INT32(dptr, rec_size);
1484168777Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1485168777Srwatson	ADD_U_INT16(dptr, e_type);
1486168777Srwatson	ADD_U_INT16(dptr, e_mod);
1487168777Srwatson
1488168777Srwatson	timems = tm.tv_usec/1000;
1489168777Srwatson	/* Add the timestamp */
1490168777Srwatson	ADD_U_INT64(dptr, tm.tv_sec);
1491168777Srwatson	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1492168777Srwatson
1493168777Srwatson	return (t);
1494168777Srwatson}
1495168777Srwatson
1496159248Srwatson#if !defined(KERNEL) && !defined(_KERNEL)
1497185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1498155131Srwatsontoken_t *
1499185573Srwatsonau_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1500185573Srwatson{
1501185573Srwatson	struct timeval tm;
1502185573Srwatson	struct auditinfo_addr aia;
1503185573Srwatson
1504185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1505185573Srwatson		return (NULL);
1506185573Srwatson	if (auditon(A_GETKAUDIT, &aia, sizeof(aia)) < 0) {
1507185573Srwatson		if (errno != ENOSYS)
1508185573Srwatson			return (NULL);
1509185573Srwatson		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1510185573Srwatson	}
1511185573Srwatson	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1512185573Srwatson}
1513185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1514185573Srwatson
1515185573Srwatsontoken_t *
1516159248Srwatsonau_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1517159248Srwatson{
1518159248Srwatson	struct timeval tm;
1519159248Srwatson
1520159248Srwatson	if (gettimeofday(&tm, NULL) == -1)
1521159248Srwatson		return (NULL);
1522159248Srwatson	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1523159248Srwatson}
1524159248Srwatson
1525159248Srwatsontoken_t *
1526155131Srwatsonau_to_header64(__unused int rec_size, __unused au_event_t e_type,
1527155131Srwatson    __unused au_emod_t e_mod)
1528155131Srwatson{
1529168777Srwatson	struct timeval tm;
1530155131Srwatson
1531168777Srwatson	if (gettimeofday(&tm, NULL) == -1)
1532168777Srwatson		return (NULL);
1533168777Srwatson	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1534155131Srwatson}
1535155131Srwatson
1536155131Srwatsontoken_t *
1537155131Srwatsonau_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1538155131Srwatson{
1539155131Srwatson
1540155131Srwatson	return (au_to_header32(rec_size, e_type, e_mod));
1541155131Srwatson}
1542155131Srwatson
1543185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1544185573Srwatsontoken_t *
1545185573Srwatsonau_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1546185573Srwatson{
1547185573Srwatson
1548185573Srwatson	return (au_to_header32_ex(rec_size, e_type, e_mod));
1549185573Srwatson}
1550185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1551185573Srwatson#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1552185573Srwatson
1553155131Srwatson/*
1554155131Srwatson * token ID                1 byte
1555155131Srwatson * trailer magic number    2 bytes
1556155131Srwatson * record byte count       4 bytes
1557155131Srwatson */
1558155131Srwatsontoken_t *
1559155131Srwatsonau_to_trailer(int rec_size)
1560155131Srwatson{
1561155131Srwatson	token_t *t;
1562155131Srwatson	u_char *dptr = NULL;
1563186647Srwatson	u_int16_t magic = AUT_TRAILER_MAGIC;
1564155131Srwatson
1565155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1566155131Srwatson	    sizeof(u_int32_t));
1567155131Srwatson	if (t == NULL)
1568155131Srwatson		return (NULL);
1569155131Srwatson
1570155131Srwatson	ADD_U_CHAR(dptr, AUT_TRAILER);
1571155131Srwatson	ADD_U_INT16(dptr, magic);
1572155131Srwatson	ADD_U_INT32(dptr, rec_size);
1573155131Srwatson
1574155131Srwatson	return (t);
1575155131Srwatson}
1576