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 */
33155131Srwatson
34155131Srwatson#include <sys/types.h>
35156283Srwatson
36156283Srwatson#include <config/config.h>
37243750Srwatson
38243750Srwatson#ifdef USE_ENDIAN_H
39243750Srwatson#include <endian.h>
40243750Srwatson#endif
41243750Srwatson#ifdef USE_SYS_ENDIAN_H
42156283Srwatson#include <sys/endian.h>
43243750Srwatson#endif
44243750Srwatson#ifdef USE_MACHINE_ENDIAN_H
45156283Srwatson#include <machine/endian.h>
46243750Srwatson#endif
47243750Srwatson#ifdef USE_COMPAT_ENDIAN_H
48155131Srwatson#include <compat/endian.h>
49243750Srwatson#endif
50243750Srwatson#ifdef USE_COMPAT_ENDIAN_ENC_H
51243750Srwatson#include <compat/endian_enc.h>
52243750Srwatson#endif
53243750Srwatson
54156283Srwatson#ifdef HAVE_FULL_QUEUE_H
55156283Srwatson#include <sys/queue.h>
56156283Srwatson#else /* !HAVE_FULL_QUEUE_H */
57156283Srwatson#include <compat/queue.h>
58156283Srwatson#endif /* !HAVE_FULL_QUEUE_H */
59156283Srwatson
60155131Srwatson#include <sys/socket.h>
61155131Srwatson#include <sys/time.h>
62155131Srwatson#include <sys/un.h>
63155131Srwatson
64155131Srwatson#include <sys/ipc.h>
65155131Srwatson
66155131Srwatson#include <netinet/in.h>
67155131Srwatson#include <netinet/in_systm.h>
68155131Srwatson#include <netinet/ip.h>
69155131Srwatson
70155131Srwatson#include <assert.h>
71155131Srwatson#include <errno.h>
72155131Srwatson#include <string.h>
73155131Srwatson#include <stdlib.h>
74155131Srwatson#include <unistd.h>
75155131Srwatson
76155131Srwatson#include <bsm/audit_internal.h>
77155131Srwatson#include <bsm/libbsm.h>
78155131Srwatson
79155131Srwatson#define	GET_TOKEN_AREA(t, dptr, length) do {				\
80155131Srwatson	(t) = malloc(sizeof(token_t));					\
81155131Srwatson	if ((t) != NULL) {						\
82155131Srwatson		(t)->len = (length);					\
83243750Srwatson		(dptr) = (t->t_data) = calloc((length), sizeof(u_char)); \
84155131Srwatson		if ((dptr) == NULL) {					\
85155131Srwatson			free(t);					\
86155131Srwatson			(t) = NULL;					\
87243750Srwatson		}							\
88155131Srwatson	} else								\
89155131Srwatson		(dptr) = NULL;						\
90185573Srwatson	assert((t) == NULL || (dptr) != NULL);				\
91155131Srwatson} while (0)
92155131Srwatson
93155131Srwatson/*
94155131Srwatson * token ID                1 byte
95243750Srwatson * success/failure         1 byte
96243750Srwatson * privstrlen              2 bytes
97243750Srwatson * privstr                 N bytes + 1 (\0 byte)
98243750Srwatson */
99243750Srwatsontoken_t *
100243750Srwatsonau_to_upriv(char sorf, char *priv)
101243750Srwatson{
102243750Srwatson	u_int16_t textlen;
103243750Srwatson	u_char *dptr;
104243750Srwatson	token_t *t;
105243750Srwatson
106243750Srwatson	textlen = strlen(priv) + 1;
107243750Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
108243750Srwatson	    sizeof(u_int16_t) + textlen);
109243750Srwatson	if (t == NULL)
110243750Srwatson		return (NULL);
111243750Srwatson	ADD_U_CHAR(dptr, AUT_UPRIV);
112243750Srwatson	ADD_U_CHAR(dptr, sorf);
113243750Srwatson	ADD_U_INT16(dptr, textlen);
114243750Srwatson	ADD_STRING(dptr, priv, textlen);
115243750Srwatson	return (t);
116243750Srwatson}
117243750Srwatson
118243750Srwatson/*
119243750Srwatson * token ID		1 byte
120243750Srwatson * privtstrlen		2 bytes
121243750Srwatson * privtstr		N bytes + 1
122243750Srwatson * privstrlen		2 bytes
123243750Srwatson * privstr		N bytes + 1
124243750Srwatson */
125243750Srwatsontoken_t *
126243750Srwatsonau_to_privset(char *privtypestr, char *privstr)
127243750Srwatson{
128243750Srwatson	u_int16_t	 type_len, priv_len;
129243750Srwatson	u_char		*dptr;
130243750Srwatson	token_t		*t;
131243750Srwatson
132243750Srwatson	type_len = strlen(privtypestr) + 1;
133243750Srwatson	priv_len = strlen(privstr) + 1;
134243750Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
135243750Srwatson	    sizeof(u_int16_t) + type_len + priv_len);
136243750Srwatson	if (t == NULL)
137243750Srwatson		return (NULL);
138243750Srwatson	ADD_U_CHAR(dptr, AUT_PRIV);
139243750Srwatson	ADD_U_INT16(dptr, type_len);
140243750Srwatson	ADD_STRING(dptr, privtypestr, type_len);
141243750Srwatson	ADD_U_INT16(dptr, priv_len);
142243750Srwatson	ADD_STRING(dptr, privstr, priv_len);
143243750Srwatson	return (t);
144243750Srwatson}
145243750Srwatson
146243750Srwatson/*
147243750Srwatson * token ID                1 byte
148155131Srwatson * argument #              1 byte
149155131Srwatson * argument value          4 bytes/8 bytes (32-bit/64-bit value)
150155131Srwatson * text length             2 bytes
151155131Srwatson * text                    N bytes + 1 terminating NULL byte
152155131Srwatson */
153155131Srwatsontoken_t *
154185573Srwatsonau_to_arg32(char n, const char *text, u_int32_t v)
155155131Srwatson{
156155131Srwatson	token_t *t;
157155131Srwatson	u_char *dptr = NULL;
158155131Srwatson	u_int16_t textlen;
159155131Srwatson
160155131Srwatson	textlen = strlen(text);
161155131Srwatson	textlen += 1;
162155131Srwatson
163155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
164155131Srwatson	    sizeof(u_int16_t) + textlen);
165155131Srwatson	if (t == NULL)
166155131Srwatson		return (NULL);
167155131Srwatson
168155131Srwatson	ADD_U_CHAR(dptr, AUT_ARG32);
169155131Srwatson	ADD_U_CHAR(dptr, n);
170155131Srwatson	ADD_U_INT32(dptr, v);
171155131Srwatson	ADD_U_INT16(dptr, textlen);
172155131Srwatson	ADD_STRING(dptr, text, textlen);
173155131Srwatson
174155131Srwatson	return (t);
175155131Srwatson}
176155131Srwatson
177155131Srwatsontoken_t *
178185573Srwatsonau_to_arg64(char n, const char *text, u_int64_t v)
179155131Srwatson{
180155131Srwatson	token_t *t;
181155131Srwatson	u_char *dptr = NULL;
182155131Srwatson	u_int16_t textlen;
183155131Srwatson
184155131Srwatson	textlen = strlen(text);
185155131Srwatson	textlen += 1;
186155131Srwatson
187155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
188155131Srwatson	    sizeof(u_int16_t) + textlen);
189155131Srwatson	if (t == NULL)
190155131Srwatson		return (NULL);
191155131Srwatson
192155131Srwatson	ADD_U_CHAR(dptr, AUT_ARG64);
193155131Srwatson	ADD_U_CHAR(dptr, n);
194155131Srwatson	ADD_U_INT64(dptr, v);
195155131Srwatson	ADD_U_INT16(dptr, textlen);
196155131Srwatson	ADD_STRING(dptr, text, textlen);
197155131Srwatson
198155131Srwatson	return (t);
199155131Srwatson}
200155131Srwatson
201155131Srwatsontoken_t *
202185573Srwatsonau_to_arg(char n, const char *text, u_int32_t v)
203155131Srwatson{
204155131Srwatson
205155131Srwatson	return (au_to_arg32(n, text, v));
206155131Srwatson}
207155131Srwatson
208155131Srwatson#if defined(_KERNEL) || defined(KERNEL)
209155131Srwatson/*
210155131Srwatson * token ID                1 byte
211155131Srwatson * file access mode        4 bytes
212155131Srwatson * owner user ID           4 bytes
213155131Srwatson * owner group ID          4 bytes
214155131Srwatson * file system ID          4 bytes
215155131Srwatson * node ID                 8 bytes
216155131Srwatson * device                  4 bytes/8 bytes (32-bit/64-bit)
217155131Srwatson */
218155131Srwatsontoken_t *
219155131Srwatsonau_to_attr32(struct vnode_au_info *vni)
220155131Srwatson{
221155131Srwatson	token_t *t;
222155131Srwatson	u_char *dptr = NULL;
223155131Srwatson	u_int16_t pad0_16 = 0;
224189279Srwatson	u_int32_t pad0_32 = 0;
225155131Srwatson
226155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
227155131Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
228155131Srwatson	if (t == NULL)
229155131Srwatson		return (NULL);
230155131Srwatson
231155131Srwatson	ADD_U_CHAR(dptr, AUT_ATTR32);
232155131Srwatson
233155131Srwatson	/*
234186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
235186647Srwatson	 * so pad with 0.
236186647Srwatson	 *
237186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
238186647Srwatson	 *
239186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
240155131Srwatson	 */
241155131Srwatson	ADD_U_INT16(dptr, pad0_16);
242155131Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
243155131Srwatson
244155131Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
245155131Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
246155131Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
247155131Srwatson
248155131Srwatson	/*
249185573Srwatson	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
250155131Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
251155131Srwatson	 * could pick this out at compile-time, it would be better, so as to
252155131Srwatson	 * avoid the else case below.
253155131Srwatson	 */
254155131Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
255155131Srwatson		ADD_U_INT32(dptr, pad0_32);
256155131Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
257155131Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
258155131Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
259155131Srwatson	else
260155131Srwatson		ADD_U_INT64(dptr, 0LL);
261155131Srwatson
262155131Srwatson	ADD_U_INT32(dptr, vni->vn_dev);
263155131Srwatson
264155131Srwatson	return (t);
265155131Srwatson}
266155131Srwatson
267155131Srwatsontoken_t *
268155131Srwatsonau_to_attr64(struct vnode_au_info *vni)
269155131Srwatson{
270168777Srwatson	token_t *t;
271168777Srwatson	u_char *dptr = NULL;
272168777Srwatson	u_int16_t pad0_16 = 0;
273189279Srwatson	u_int32_t pad0_32 = 0;
274155131Srwatson
275168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
276168777Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
277168777Srwatson	if (t == NULL)
278168777Srwatson		return (NULL);
279168777Srwatson
280168777Srwatson	ADD_U_CHAR(dptr, AUT_ATTR64);
281168777Srwatson
282168777Srwatson	/*
283186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
284186647Srwatson	 * so pad with 0.
285186647Srwatson	 *
286186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
287186647Srwatson	 *
288186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
289168777Srwatson	 */
290168777Srwatson	ADD_U_INT16(dptr, pad0_16);
291168777Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
292168777Srwatson
293168777Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
294168777Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
295168777Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
296168777Srwatson
297168777Srwatson	/*
298168777Srwatson	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
299168777Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
300168777Srwatson	 * could pick this out at compile-time, it would be better, so as to
301168777Srwatson	 * avoid the else case below.
302168777Srwatson	 */
303168777Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
304168777Srwatson		ADD_U_INT32(dptr, pad0_32);
305168777Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
306168777Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
307168777Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
308168777Srwatson	else
309168777Srwatson		ADD_U_INT64(dptr, 0LL);
310168777Srwatson
311168777Srwatson	ADD_U_INT64(dptr, vni->vn_dev);
312168777Srwatson
313168777Srwatson	return (t);
314155131Srwatson}
315155131Srwatson
316155131Srwatsontoken_t *
317155131Srwatsonau_to_attr(struct vnode_au_info *vni)
318155131Srwatson{
319155131Srwatson
320155131Srwatson	return (au_to_attr32(vni));
321155131Srwatson}
322155131Srwatson#endif /* !(defined(_KERNEL) || defined(KERNEL) */
323155131Srwatson
324155131Srwatson/*
325155131Srwatson * token ID                1 byte
326155131Srwatson * how to print            1 byte
327155131Srwatson * basic unit              1 byte
328155131Srwatson * unit count              1 byte
329155131Srwatson * data items              (depends on basic unit)
330155131Srwatson */
331155131Srwatsontoken_t *
332185573Srwatsonau_to_data(char unit_print, char unit_type, char unit_count, const char *p)
333155131Srwatson{
334155131Srwatson	token_t *t;
335155131Srwatson	u_char *dptr = NULL;
336155131Srwatson	size_t datasize, totdata;
337155131Srwatson
338155131Srwatson	/* Determine the size of the basic unit. */
339155131Srwatson	switch (unit_type) {
340155131Srwatson	case AUR_BYTE:
341159248Srwatson	/* case AUR_CHAR: */
342155131Srwatson		datasize = AUR_BYTE_SIZE;
343155131Srwatson		break;
344155131Srwatson
345155131Srwatson	case AUR_SHORT:
346155131Srwatson		datasize = AUR_SHORT_SIZE;
347155131Srwatson		break;
348155131Srwatson
349159248Srwatson	case AUR_INT32:
350159248Srwatson	/* case AUR_INT: */
351159248Srwatson		datasize = AUR_INT32_SIZE;
352155131Srwatson		break;
353155131Srwatson
354159248Srwatson	case AUR_INT64:
355159248Srwatson		datasize = AUR_INT64_SIZE;
356159248Srwatson		break;
357159248Srwatson
358155131Srwatson	default:
359155131Srwatson		errno = EINVAL;
360185573Srwatson		return (NULL);
361155131Srwatson	}
362155131Srwatson
363155131Srwatson	totdata = datasize * unit_count;
364155131Srwatson
365159248Srwatson	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
366155131Srwatson	if (t == NULL)
367155131Srwatson		return (NULL);
368155131Srwatson
369186647Srwatson	/*
370186647Srwatson	 * XXXRW: We should be byte-swapping each data item for multi-byte
371186647Srwatson	 * types.
372186647Srwatson	 */
373155131Srwatson	ADD_U_CHAR(dptr, AUT_DATA);
374155131Srwatson	ADD_U_CHAR(dptr, unit_print);
375155131Srwatson	ADD_U_CHAR(dptr, unit_type);
376155131Srwatson	ADD_U_CHAR(dptr, unit_count);
377155131Srwatson	ADD_MEM(dptr, p, totdata);
378155131Srwatson
379155131Srwatson	return (t);
380155131Srwatson}
381155131Srwatson
382155131Srwatson
383155131Srwatson/*
384155131Srwatson * token ID                1 byte
385155131Srwatson * status		   4 bytes
386155131Srwatson * return value            4 bytes
387155131Srwatson */
388155131Srwatsontoken_t *
389155131Srwatsonau_to_exit(int retval, int err)
390155131Srwatson{
391155131Srwatson	token_t *t;
392155131Srwatson	u_char *dptr = NULL;
393155131Srwatson
394155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
395155131Srwatson	if (t == NULL)
396155131Srwatson		return (NULL);
397155131Srwatson
398155131Srwatson	ADD_U_CHAR(dptr, AUT_EXIT);
399155131Srwatson	ADD_U_INT32(dptr, err);
400155131Srwatson	ADD_U_INT32(dptr, retval);
401155131Srwatson
402155131Srwatson	return (t);
403155131Srwatson}
404155131Srwatson
405155131Srwatson/*
406155131Srwatson */
407155131Srwatsontoken_t *
408155131Srwatsonau_to_groups(int *groups)
409155131Srwatson{
410155131Srwatson
411185573Srwatson	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
412155131Srwatson}
413155131Srwatson
414155131Srwatson/*
415155131Srwatson * token ID                1 byte
416155131Srwatson * number groups           2 bytes
417155131Srwatson * group list              count * 4 bytes
418155131Srwatson */
419155131Srwatsontoken_t *
420155131Srwatsonau_to_newgroups(u_int16_t n, gid_t *groups)
421155131Srwatson{
422155131Srwatson	token_t *t;
423155131Srwatson	u_char *dptr = NULL;
424155131Srwatson	int i;
425155131Srwatson
426155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
427155131Srwatson	    n * sizeof(u_int32_t));
428155131Srwatson	if (t == NULL)
429155131Srwatson		return (NULL);
430155131Srwatson
431155131Srwatson	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
432155131Srwatson	ADD_U_INT16(dptr, n);
433155131Srwatson	for (i = 0; i < n; i++)
434155131Srwatson		ADD_U_INT32(dptr, groups[i]);
435155131Srwatson
436155131Srwatson	return (t);
437155131Srwatson}
438155131Srwatson
439155131Srwatson/*
440155131Srwatson * token ID                1 byte
441155131Srwatson * internet address        4 bytes
442155131Srwatson */
443155131Srwatsontoken_t *
444155131Srwatsonau_to_in_addr(struct in_addr *internet_addr)
445155131Srwatson{
446155131Srwatson	token_t *t;
447155131Srwatson	u_char *dptr = NULL;
448155131Srwatson
449159248Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
450155131Srwatson	if (t == NULL)
451155131Srwatson		return (NULL);
452155131Srwatson
453155131Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR);
454159248Srwatson	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
455155131Srwatson
456155131Srwatson	return (t);
457155131Srwatson}
458155131Srwatson
459155131Srwatson/*
460155131Srwatson * token ID                1 byte
461155131Srwatson * address type/length     4 bytes
462185573Srwatson * address                16 bytes
463155131Srwatson */
464155131Srwatsontoken_t *
465155131Srwatsonau_to_in_addr_ex(struct in6_addr *internet_addr)
466155131Srwatson{
467155131Srwatson	token_t *t;
468155131Srwatson	u_char *dptr = NULL;
469186647Srwatson	u_int32_t type = AU_IPv6;
470155131Srwatson
471159248Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
472155131Srwatson	if (t == NULL)
473155131Srwatson		return (NULL);
474155131Srwatson
475155131Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
476155131Srwatson	ADD_U_INT32(dptr, type);
477171537Srwatson	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
478155131Srwatson
479155131Srwatson	return (t);
480155131Srwatson}
481155131Srwatson
482155131Srwatson/*
483155131Srwatson * token ID                1 byte
484155131Srwatson * ip header		   20 bytes
485168777Srwatson *
486168777Srwatson * The IP header should be submitted in network byte order.
487155131Srwatson */
488155131Srwatsontoken_t *
489155131Srwatsonau_to_ip(struct ip *ip)
490155131Srwatson{
491155131Srwatson	token_t *t;
492155131Srwatson	u_char *dptr = NULL;
493155131Srwatson
494155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
495155131Srwatson	if (t == NULL)
496155131Srwatson		return (NULL);
497155131Srwatson
498155131Srwatson	ADD_U_CHAR(dptr, AUT_IP);
499155131Srwatson	ADD_MEM(dptr, ip, sizeof(struct ip));
500155131Srwatson
501155131Srwatson	return (t);
502155131Srwatson}
503155131Srwatson
504155131Srwatson/*
505155131Srwatson * token ID                1 byte
506155131Srwatson * object ID type          1 byte
507155131Srwatson * object ID               4 bytes
508155131Srwatson */
509155131Srwatsontoken_t *
510155131Srwatsonau_to_ipc(char type, int id)
511155131Srwatson{
512155131Srwatson	token_t *t;
513155131Srwatson	u_char *dptr = NULL;
514155131Srwatson
515155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
516155131Srwatson	if (t == NULL)
517155131Srwatson		return (NULL);
518155131Srwatson
519155131Srwatson	ADD_U_CHAR(dptr, AUT_IPC);
520155131Srwatson	ADD_U_CHAR(dptr, type);
521155131Srwatson	ADD_U_INT32(dptr, id);
522155131Srwatson
523155131Srwatson	return (t);
524155131Srwatson}
525155131Srwatson
526155131Srwatson/*
527155131Srwatson * token ID                1 byte
528155131Srwatson * owner user ID           4 bytes
529155131Srwatson * owner group ID          4 bytes
530155131Srwatson * creator user ID         4 bytes
531155131Srwatson * creator group ID        4 bytes
532155131Srwatson * access mode             4 bytes
533155131Srwatson * slot sequence #         4 bytes
534155131Srwatson * key                     4 bytes
535155131Srwatson */
536155131Srwatsontoken_t *
537155131Srwatsonau_to_ipc_perm(struct ipc_perm *perm)
538155131Srwatson{
539155131Srwatson	token_t *t;
540155131Srwatson	u_char *dptr = NULL;
541155131Srwatson	u_int16_t pad0 = 0;
542155131Srwatson
543189279Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
544189279Srwatson	    sizeof(u_int32_t));
545155131Srwatson	if (t == NULL)
546155131Srwatson		return (NULL);
547155131Srwatson
548155131Srwatson	ADD_U_CHAR(dptr, AUT_IPC_PERM);
549155131Srwatson
550155131Srwatson	/*
551186647Srwatson	 * Systems vary significantly in what types they use in struct
552186647Srwatson	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
553186647Srwatson	 * allow for that, as BSM define 32-bit values here.
554186647Srwatson	 * Some systems define the sizes for ipc_perm members as 2 bytes;
555186647Srwatson	 * BSM defines 4 so pad with 0.
556186647Srwatson	 *
557186647Srwatson	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
558186647Srwatson	 * need to be handled.
559155131Srwatson	 */
560186647Srwatson	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
561186647Srwatson		ADD_U_INT16(dptr, pad0);
562186647Srwatson		ADD_U_INT16(dptr, perm->uid);
563186647Srwatson		ADD_U_INT16(dptr, pad0);
564186647Srwatson		ADD_U_INT16(dptr, perm->gid);
565186647Srwatson		ADD_U_INT16(dptr, pad0);
566186647Srwatson		ADD_U_INT16(dptr, perm->cuid);
567186647Srwatson		ADD_U_INT16(dptr, pad0);
568186647Srwatson		ADD_U_INT16(dptr, perm->cgid);
569186647Srwatson	} else {
570186647Srwatson		ADD_U_INT32(dptr, perm->uid);
571186647Srwatson		ADD_U_INT32(dptr, perm->gid);
572186647Srwatson		ADD_U_INT32(dptr, perm->cuid);
573186647Srwatson		ADD_U_INT32(dptr, perm->cgid);
574186647Srwatson	}
575155131Srwatson
576155131Srwatson	ADD_U_INT16(dptr, pad0);
577155131Srwatson	ADD_U_INT16(dptr, perm->mode);
578155131Srwatson
579155131Srwatson	ADD_U_INT16(dptr, pad0);
580156283Srwatson
581156283Srwatson#ifdef HAVE_IPC_PERM___SEQ
582156283Srwatson	ADD_U_INT16(dptr, perm->__seq);
583185573Srwatson#else	/* HAVE_IPC_PERM___SEQ */
584185573Srwatson#ifdef  HAVE_IPC_PERM__SEQ
585185573Srwatson	ADD_U_INT16(dptr, perm->_seq);
586185573Srwatson#else	/* HAVE_IPC_PERM__SEQ */
587155131Srwatson	ADD_U_INT16(dptr, perm->seq);
588185573Srwatson#endif	/* HAVE_IPC_PERM__SEQ */
589185573Srwatson#endif	/* HAVE_IPC_PERM___SEQ */
590155131Srwatson
591156283Srwatson#ifdef HAVE_IPC_PERM___KEY
592156283Srwatson	ADD_U_INT32(dptr, perm->__key);
593185573Srwatson#else	/* HAVE_IPC_PERM___KEY */
594185573Srwatson#ifdef  HAVE_IPC_PERM__KEY
595185573Srwatson	ADD_U_INT32(dptr, perm->_key);
596185573Srwatson#else	/* HAVE_IPC_PERM__KEY */
597155131Srwatson	ADD_U_INT32(dptr, perm->key);
598185573Srwatson#endif	/* HAVE_IPC_PERM__KEY */
599185573Srwatson#endif	/* HAVE_IPC_PERM___KEY */
600155131Srwatson
601155131Srwatson	return (t);
602155131Srwatson}
603155131Srwatson
604155131Srwatson/*
605155131Srwatson * token ID                1 byte
606155131Srwatson * port IP address         2 bytes
607155131Srwatson */
608155131Srwatsontoken_t *
609155131Srwatsonau_to_iport(u_int16_t iport)
610155131Srwatson{
611155131Srwatson	token_t *t;
612155131Srwatson	u_char *dptr = NULL;
613155131Srwatson
614155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
615155131Srwatson	if (t == NULL)
616155131Srwatson		return (NULL);
617155131Srwatson
618155131Srwatson	ADD_U_CHAR(dptr, AUT_IPORT);
619155131Srwatson	ADD_U_INT16(dptr, iport);
620155131Srwatson
621155131Srwatson	return (t);
622155131Srwatson}
623155131Srwatson
624155131Srwatson/*
625155131Srwatson * token ID                1 byte
626155131Srwatson * size                    2 bytes
627155131Srwatson * data                    size bytes
628155131Srwatson */
629155131Srwatsontoken_t *
630185573Srwatsonau_to_opaque(const char *data, u_int16_t bytes)
631155131Srwatson{
632155131Srwatson	token_t *t;
633155131Srwatson	u_char *dptr = NULL;
634155131Srwatson
635155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
636155131Srwatson	if (t == NULL)
637155131Srwatson		return (NULL);
638155131Srwatson
639155131Srwatson	ADD_U_CHAR(dptr, AUT_OPAQUE);
640155131Srwatson	ADD_U_INT16(dptr, bytes);
641155131Srwatson	ADD_MEM(dptr, data, bytes);
642155131Srwatson
643155131Srwatson	return (t);
644155131Srwatson}
645155131Srwatson
646155131Srwatson/*
647155131Srwatson * token ID                1 byte
648155131Srwatson * seconds of time         4 bytes
649155131Srwatson * milliseconds of time    4 bytes
650155131Srwatson * file name len           2 bytes
651155131Srwatson * file pathname           N bytes + 1 terminating NULL byte
652155131Srwatson */
653155131Srwatsontoken_t *
654185573Srwatsonau_to_file(const char *file, struct timeval tm)
655155131Srwatson{
656155131Srwatson	token_t *t;
657155131Srwatson	u_char *dptr = NULL;
658155131Srwatson	u_int16_t filelen;
659155131Srwatson	u_int32_t timems;
660155131Srwatson
661155131Srwatson	filelen = strlen(file);
662155131Srwatson	filelen += 1;
663155131Srwatson
664155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
665155131Srwatson	    sizeof(u_int16_t) + filelen);
666155131Srwatson	if (t == NULL)
667155131Srwatson		return (NULL);
668155131Srwatson
669155131Srwatson	timems = tm.tv_usec/1000;
670155131Srwatson
671155131Srwatson	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
672155131Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
673155131Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
674155131Srwatson	ADD_U_INT16(dptr, filelen);
675155131Srwatson	ADD_STRING(dptr, file, filelen);
676155131Srwatson
677155131Srwatson	return (t);
678155131Srwatson}
679155131Srwatson
680155131Srwatson/*
681155131Srwatson * token ID                1 byte
682155131Srwatson * text length             2 bytes
683155131Srwatson * text                    N bytes + 1 terminating NULL byte
684155131Srwatson */
685155131Srwatsontoken_t *
686185573Srwatsonau_to_text(const char *text)
687155131Srwatson{
688155131Srwatson	token_t *t;
689155131Srwatson	u_char *dptr = NULL;
690155131Srwatson	u_int16_t textlen;
691155131Srwatson
692155131Srwatson	textlen = strlen(text);
693155131Srwatson	textlen += 1;
694155131Srwatson
695186647Srwatson	/* XXXRW: Should validate length against token size limit. */
696186647Srwatson
697155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
698155131Srwatson	if (t == NULL)
699155131Srwatson		return (NULL);
700155131Srwatson
701155131Srwatson	ADD_U_CHAR(dptr, AUT_TEXT);
702155131Srwatson	ADD_U_INT16(dptr, textlen);
703155131Srwatson	ADD_STRING(dptr, text, textlen);
704155131Srwatson
705155131Srwatson	return (t);
706155131Srwatson}
707155131Srwatson
708155131Srwatson/*
709155131Srwatson * token ID                1 byte
710155131Srwatson * path length             2 bytes
711155131Srwatson * path                    N bytes + 1 terminating NULL byte
712155131Srwatson */
713155131Srwatsontoken_t *
714185573Srwatsonau_to_path(const char *text)
715155131Srwatson{
716155131Srwatson	token_t *t;
717155131Srwatson	u_char *dptr = NULL;
718155131Srwatson	u_int16_t textlen;
719155131Srwatson
720155131Srwatson	textlen = strlen(text);
721155131Srwatson	textlen += 1;
722155131Srwatson
723155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
724155131Srwatson	if (t == NULL)
725155131Srwatson		return (NULL);
726155131Srwatson
727155131Srwatson	ADD_U_CHAR(dptr, AUT_PATH);
728155131Srwatson	ADD_U_INT16(dptr, textlen);
729155131Srwatson	ADD_STRING(dptr, text, textlen);
730155131Srwatson
731155131Srwatson	return (t);
732155131Srwatson}
733155131Srwatson
734155131Srwatson/*
735155131Srwatson * token ID                1 byte
736155131Srwatson * audit ID                4 bytes
737155131Srwatson * effective user ID       4 bytes
738155131Srwatson * effective group ID      4 bytes
739155131Srwatson * real user ID            4 bytes
740155131Srwatson * real group ID           4 bytes
741155131Srwatson * process ID              4 bytes
742155131Srwatson * session ID              4 bytes
743155131Srwatson * terminal ID
744155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
745155131Srwatson *   machine address       4 bytes
746155131Srwatson */
747155131Srwatsontoken_t *
748155131Srwatsonau_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
749155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
750155131Srwatson{
751155131Srwatson	token_t *t;
752155131Srwatson	u_char *dptr = NULL;
753155131Srwatson
754155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
755155131Srwatson	if (t == NULL)
756155131Srwatson		return (NULL);
757155131Srwatson
758155131Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32);
759155131Srwatson	ADD_U_INT32(dptr, auid);
760155131Srwatson	ADD_U_INT32(dptr, euid);
761155131Srwatson	ADD_U_INT32(dptr, egid);
762155131Srwatson	ADD_U_INT32(dptr, ruid);
763155131Srwatson	ADD_U_INT32(dptr, rgid);
764155131Srwatson	ADD_U_INT32(dptr, pid);
765155131Srwatson	ADD_U_INT32(dptr, sid);
766155131Srwatson	ADD_U_INT32(dptr, tid->port);
767186647Srwatson
768186647Srwatson	/*
769186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
770186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
771186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
772186647Srwatson	 * addresses for process32 tokens.
773186647Srwatson	 */
774159248Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
775155131Srwatson
776155131Srwatson	return (t);
777155131Srwatson}
778155131Srwatson
779155131Srwatsontoken_t *
780168777Srwatsonau_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
781168777Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
782155131Srwatson{
783168777Srwatson	token_t *t;
784168777Srwatson	u_char *dptr = NULL;
785155131Srwatson
786168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
787168777Srwatson	    sizeof(u_int64_t));
788168777Srwatson	if (t == NULL)
789168777Srwatson		return (NULL);
790168777Srwatson
791168777Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64);
792168777Srwatson	ADD_U_INT32(dptr, auid);
793168777Srwatson	ADD_U_INT32(dptr, euid);
794168777Srwatson	ADD_U_INT32(dptr, egid);
795168777Srwatson	ADD_U_INT32(dptr, ruid);
796168777Srwatson	ADD_U_INT32(dptr, rgid);
797168777Srwatson	ADD_U_INT32(dptr, pid);
798168777Srwatson	ADD_U_INT32(dptr, sid);
799168777Srwatson	ADD_U_INT64(dptr, tid->port);
800186647Srwatson
801186647Srwatson	/*
802186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
803186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
804186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
805186647Srwatson	 * addresses for process64 tokens.
806186647Srwatson	 */
807168777Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
808168777Srwatson
809168777Srwatson	return (t);
810155131Srwatson}
811155131Srwatson
812155131Srwatsontoken_t *
813168777Srwatsonau_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
814168777Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
815155131Srwatson{
816155131Srwatson
817155131Srwatson	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
818155131Srwatson	    tid));
819155131Srwatson}
820155131Srwatson
821155131Srwatson/*
822155131Srwatson * token ID                1 byte
823155131Srwatson * audit ID                4 bytes
824155131Srwatson * effective user ID       4 bytes
825155131Srwatson * effective group ID      4 bytes
826155131Srwatson * real user ID            4 bytes
827155131Srwatson * real group ID           4 bytes
828155131Srwatson * process ID              4 bytes
829155131Srwatson * session ID              4 bytes
830155131Srwatson * terminal ID
831155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
832155131Srwatson *   address type-len      4 bytes
833155131Srwatson *   machine address      16 bytes
834155131Srwatson */
835155131Srwatsontoken_t *
836155131Srwatsonau_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
837155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
838155131Srwatson{
839155131Srwatson	token_t *t;
840155131Srwatson	u_char *dptr = NULL;
841155131Srwatson
842159985Srwatson	if (tid->at_type == AU_IPv4)
843159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
844159985Srwatson		    10 * sizeof(u_int32_t));
845159985Srwatson	else if (tid->at_type == AU_IPv6)
846159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
847159985Srwatson		    13 * sizeof(u_int32_t));
848159985Srwatson	else {
849159985Srwatson		errno = EINVAL;
850159985Srwatson		return (NULL);
851159985Srwatson	}
852155131Srwatson	if (t == NULL)
853155131Srwatson		return (NULL);
854155131Srwatson
855155131Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
856155131Srwatson	ADD_U_INT32(dptr, auid);
857155131Srwatson	ADD_U_INT32(dptr, euid);
858155131Srwatson	ADD_U_INT32(dptr, egid);
859155131Srwatson	ADD_U_INT32(dptr, ruid);
860155131Srwatson	ADD_U_INT32(dptr, rgid);
861155131Srwatson	ADD_U_INT32(dptr, pid);
862155131Srwatson	ADD_U_INT32(dptr, sid);
863155131Srwatson	ADD_U_INT32(dptr, tid->at_port);
864155131Srwatson	ADD_U_INT32(dptr, tid->at_type);
865168777Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
866159985Srwatson	if (tid->at_type == AU_IPv6) {
867168777Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
868168777Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
869168777Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
870159985Srwatson	}
871155131Srwatson
872155131Srwatson	return (t);
873155131Srwatson}
874155131Srwatson
875155131Srwatsontoken_t *
876155131Srwatsonau_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
877155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
878155131Srwatson{
879168777Srwatson	token_t *t;
880168777Srwatson	u_char *dptr = NULL;
881155131Srwatson
882168777Srwatson	if (tid->at_type == AU_IPv4)
883168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
884168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
885168777Srwatson		    2 * sizeof(u_int32_t));
886168777Srwatson	else if (tid->at_type == AU_IPv6)
887168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
888168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
889168777Srwatson		    5 * sizeof(u_int32_t));
890168777Srwatson	else {
891168777Srwatson		errno = EINVAL;
892168777Srwatson		return (NULL);
893168777Srwatson	}
894168777Srwatson	if (t == NULL)
895168777Srwatson		return (NULL);
896168777Srwatson
897168777Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
898168777Srwatson	ADD_U_INT32(dptr, auid);
899168777Srwatson	ADD_U_INT32(dptr, euid);
900168777Srwatson	ADD_U_INT32(dptr, egid);
901168777Srwatson	ADD_U_INT32(dptr, ruid);
902168777Srwatson	ADD_U_INT32(dptr, rgid);
903168777Srwatson	ADD_U_INT32(dptr, pid);
904168777Srwatson	ADD_U_INT32(dptr, sid);
905168777Srwatson	ADD_U_INT64(dptr, tid->at_port);
906168777Srwatson	ADD_U_INT32(dptr, tid->at_type);
907168777Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
908168777Srwatson	if (tid->at_type == AU_IPv6) {
909168777Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
910168777Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
911168777Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
912168777Srwatson	}
913168777Srwatson
914168777Srwatson	return (t);
915155131Srwatson}
916155131Srwatson
917155131Srwatsontoken_t *
918155131Srwatsonau_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
919155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
920155131Srwatson{
921155131Srwatson
922155131Srwatson	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
923155131Srwatson	    tid));
924155131Srwatson}
925155131Srwatson
926155131Srwatson/*
927155131Srwatson * token ID                1 byte
928155131Srwatson * error status            1 byte
929155131Srwatson * return value            4 bytes/8 bytes (32-bit/64-bit value)
930155131Srwatson */
931155131Srwatsontoken_t *
932155131Srwatsonau_to_return32(char status, u_int32_t ret)
933155131Srwatson{
934155131Srwatson	token_t *t;
935155131Srwatson	u_char *dptr = NULL;
936155131Srwatson
937155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
938155131Srwatson	if (t == NULL)
939155131Srwatson		return (NULL);
940155131Srwatson
941155131Srwatson	ADD_U_CHAR(dptr, AUT_RETURN32);
942155131Srwatson	ADD_U_CHAR(dptr, status);
943155131Srwatson	ADD_U_INT32(dptr, ret);
944155131Srwatson
945155131Srwatson	return (t);
946155131Srwatson}
947155131Srwatson
948155131Srwatsontoken_t *
949155131Srwatsonau_to_return64(char status, u_int64_t ret)
950155131Srwatson{
951155131Srwatson	token_t *t;
952155131Srwatson	u_char *dptr = NULL;
953155131Srwatson
954155131Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
955155131Srwatson	if (t == NULL)
956155131Srwatson		return (NULL);
957155131Srwatson
958155131Srwatson	ADD_U_CHAR(dptr, AUT_RETURN64);
959155131Srwatson	ADD_U_CHAR(dptr, status);
960155131Srwatson	ADD_U_INT64(dptr, ret);
961155131Srwatson
962155131Srwatson	return (t);
963155131Srwatson}
964155131Srwatson
965155131Srwatsontoken_t *
966155131Srwatsonau_to_return(char status, u_int32_t ret)
967155131Srwatson{
968155131Srwatson
969155131Srwatson	return (au_to_return32(status, ret));
970155131Srwatson}
971155131Srwatson
972155131Srwatson/*
973155131Srwatson * token ID                1 byte
974155131Srwatson * sequence number         4 bytes
975155131Srwatson */
976155131Srwatsontoken_t *
977155131Srwatsonau_to_seq(long audit_count)
978155131Srwatson{
979155131Srwatson	token_t *t;
980155131Srwatson	u_char *dptr = NULL;
981155131Srwatson
982155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
983155131Srwatson	if (t == NULL)
984155131Srwatson		return (NULL);
985155131Srwatson
986155131Srwatson	ADD_U_CHAR(dptr, AUT_SEQ);
987155131Srwatson	ADD_U_INT32(dptr, audit_count);
988155131Srwatson
989155131Srwatson	return (t);
990155131Srwatson}
991155131Srwatson
992155131Srwatson/*
993155131Srwatson * token ID                1 byte
994186647Srwatson * socket domain           2 bytes
995186647Srwatson * socket type             2 bytes
996186647Srwatson * address type            2 byte
997186647Srwatson * local port              2 bytes
998186647Srwatson * local address           4 bytes/16 bytes (IPv4/IPv6 address)
999186647Srwatson * remote port             2 bytes
1000186647Srwatson * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
1001187214Srwatson *
1002187214Srwatson * Domain and type arguments to this routine are assumed to already have been
1003187214Srwatson * converted to the BSM constant space, so we don't do that here.
1004186647Srwatson */
1005186647Srwatsontoken_t *
1006186647Srwatsonau_to_socket_ex(u_short so_domain, u_short so_type,
1007186647Srwatson    struct sockaddr *sa_local, struct sockaddr *sa_remote)
1008186647Srwatson{
1009186647Srwatson	token_t *t;
1010186647Srwatson	u_char *dptr = NULL;
1011186647Srwatson	struct sockaddr_in *sin;
1012186647Srwatson	struct sockaddr_in6 *sin6;
1013186647Srwatson
1014186647Srwatson	if (so_domain == AF_INET)
1015186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1016186647Srwatson		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1017186647Srwatson	else if (so_domain == AF_INET6)
1018186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1019189279Srwatson		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
1020186647Srwatson	else {
1021186647Srwatson		errno = EINVAL;
1022186647Srwatson		return (NULL);
1023186647Srwatson	}
1024243750Srwatson	if (t == NULL)
1025243750Srwatson		return (NULL);
1026186647Srwatson
1027186647Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
1028189279Srwatson	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
1029189279Srwatson	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
1030186647Srwatson	if (so_domain == AF_INET) {
1031186647Srwatson		ADD_U_INT16(dptr, AU_IPv4);
1032186647Srwatson		sin = (struct sockaddr_in *)sa_local;
1033186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
1034186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
1035186647Srwatson		sin = (struct sockaddr_in *)sa_remote;
1036186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
1037186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
1038186647Srwatson	} else {
1039186647Srwatson		ADD_U_INT16(dptr, AU_IPv6);
1040186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_local;
1041186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
1042186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
1043186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_remote;
1044186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
1045186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
1046186647Srwatson	}
1047186647Srwatson
1048186647Srwatson	return (t);
1049186647Srwatson}
1050186647Srwatson
1051186647Srwatson/*
1052186647Srwatson * token ID                1 byte
1053155131Srwatson * socket family           2 bytes
1054195740Srwatson * path                    (up to) 104 bytes + NULL  (NULL terminated string)
1055155131Srwatson */
1056155131Srwatsontoken_t *
1057155131Srwatsonau_to_sock_unix(struct sockaddr_un *so)
1058155131Srwatson{
1059155131Srwatson	token_t *t;
1060155131Srwatson	u_char *dptr;
1061155131Srwatson
1062155131Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1063155131Srwatson	if (t == NULL)
1064155131Srwatson		return (NULL);
1065155131Srwatson
1066185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1067155131Srwatson	/* BSM token has two bytes for family */
1068155131Srwatson	ADD_U_CHAR(dptr, 0);
1069155131Srwatson	ADD_U_CHAR(dptr, so->sun_family);
1070155131Srwatson	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1071155131Srwatson
1072155131Srwatson	return (t);
1073155131Srwatson}
1074155131Srwatson
1075155131Srwatson/*
1076155131Srwatson * token ID                1 byte
1077155131Srwatson * socket family           2 bytes
1078155131Srwatson * local port              2 bytes
1079155131Srwatson * socket address          4 bytes
1080155131Srwatson */
1081155131Srwatsontoken_t *
1082155131Srwatsonau_to_sock_inet32(struct sockaddr_in *so)
1083155131Srwatson{
1084155131Srwatson	token_t *t;
1085155131Srwatson	u_char *dptr = NULL;
1086159248Srwatson	uint16_t family;
1087155131Srwatson
1088159248Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1089159248Srwatson	    sizeof(uint32_t));
1090155131Srwatson	if (t == NULL)
1091155131Srwatson		return (NULL);
1092155131Srwatson
1093155131Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1094155131Srwatson	/*
1095159248Srwatson	 * BSM defines the family field as 16 bits, but many operating
1096159248Srwatson	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1097159248Srwatson	 * writing into the token.  Assume that both the port and the address
1098159248Srwatson	 * in the sockaddr_in are already in network byte order, but family
1099159248Srwatson	 * is in local byte order.
1100159248Srwatson	 *
1101159248Srwatson	 * XXXRW: Should a name space conversion be taking place on the value
1102159248Srwatson	 * of sin_family?
1103185573Srwatson	 */
1104159248Srwatson	family = so->sin_family;
1105159248Srwatson	ADD_U_INT16(dptr, family);
1106159248Srwatson	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1107159248Srwatson	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1108155131Srwatson
1109155131Srwatson	return (t);
1110155131Srwatson}
1111155131Srwatson
1112155131Srwatsontoken_t *
1113155131Srwatsonau_to_sock_inet128(struct sockaddr_in6 *so)
1114155131Srwatson{
1115155131Srwatson	token_t *t;
1116155131Srwatson	u_char *dptr = NULL;
1117155131Srwatson
1118155131Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1119155131Srwatson	    4 * sizeof(u_int32_t));
1120155131Srwatson	if (t == NULL)
1121155131Srwatson		return (NULL);
1122155131Srwatson
1123155131Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1124155131Srwatson	/*
1125186647Srwatson	 * In BSD, sin6_family is one octet, but BSM defines the token to
1126186647Srwatson	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1127186647Srwatson	 * conditionally compiled.
1128185573Srwatson	 */
1129155131Srwatson	ADD_U_CHAR(dptr, 0);
1130155131Srwatson	ADD_U_CHAR(dptr, so->sin6_family);
1131155131Srwatson
1132155131Srwatson	ADD_U_INT16(dptr, so->sin6_port);
1133159248Srwatson	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1134155131Srwatson
1135155131Srwatson	return (t);
1136155131Srwatson}
1137155131Srwatson
1138155131Srwatsontoken_t *
1139155131Srwatsonau_to_sock_inet(struct sockaddr_in *so)
1140155131Srwatson{
1141155131Srwatson
1142155131Srwatson	return (au_to_sock_inet32(so));
1143155131Srwatson}
1144155131Srwatson
1145155131Srwatson/*
1146155131Srwatson * token ID                1 byte
1147155131Srwatson * audit ID                4 bytes
1148155131Srwatson * effective user ID       4 bytes
1149155131Srwatson * effective group ID      4 bytes
1150155131Srwatson * real user ID            4 bytes
1151155131Srwatson * real group ID           4 bytes
1152155131Srwatson * process ID              4 bytes
1153155131Srwatson * session ID              4 bytes
1154155131Srwatson * terminal ID
1155155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1156155131Srwatson *   machine address       4 bytes
1157155131Srwatson */
1158155131Srwatsontoken_t *
1159155131Srwatsonau_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1160155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1161155131Srwatson{
1162155131Srwatson	token_t *t;
1163155131Srwatson	u_char *dptr = NULL;
1164155131Srwatson
1165155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1166155131Srwatson	if (t == NULL)
1167155131Srwatson		return (NULL);
1168155131Srwatson
1169155131Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1170155131Srwatson	ADD_U_INT32(dptr, auid);
1171155131Srwatson	ADD_U_INT32(dptr, euid);
1172155131Srwatson	ADD_U_INT32(dptr, egid);
1173155131Srwatson	ADD_U_INT32(dptr, ruid);
1174155131Srwatson	ADD_U_INT32(dptr, rgid);
1175155131Srwatson	ADD_U_INT32(dptr, pid);
1176155131Srwatson	ADD_U_INT32(dptr, sid);
1177155131Srwatson	ADD_U_INT32(dptr, tid->port);
1178159248Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1179155131Srwatson
1180155131Srwatson	return (t);
1181155131Srwatson}
1182155131Srwatson
1183155131Srwatsontoken_t *
1184155131Srwatsonau_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1185155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1186155131Srwatson{
1187168777Srwatson	token_t *t;
1188168777Srwatson	u_char *dptr = NULL;
1189155131Srwatson
1190168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1191168777Srwatson	    sizeof(u_int64_t) + sizeof(u_int32_t));
1192168777Srwatson	if (t == NULL)
1193168777Srwatson		return (NULL);
1194168777Srwatson
1195168777Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1196168777Srwatson	ADD_U_INT32(dptr, auid);
1197168777Srwatson	ADD_U_INT32(dptr, euid);
1198168777Srwatson	ADD_U_INT32(dptr, egid);
1199168777Srwatson	ADD_U_INT32(dptr, ruid);
1200168777Srwatson	ADD_U_INT32(dptr, rgid);
1201168777Srwatson	ADD_U_INT32(dptr, pid);
1202168777Srwatson	ADD_U_INT32(dptr, sid);
1203168777Srwatson	ADD_U_INT64(dptr, tid->port);
1204168777Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1205168777Srwatson
1206168777Srwatson	return (t);
1207155131Srwatson}
1208155131Srwatson
1209155131Srwatsontoken_t *
1210155131Srwatsonau_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1211155131Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1212155131Srwatson{
1213155131Srwatson
1214155131Srwatson	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1215155131Srwatson	    tid));
1216155131Srwatson}
1217155131Srwatson
1218155131Srwatson/*
1219155131Srwatson * token ID                1 byte
1220155131Srwatson * audit ID                4 bytes
1221155131Srwatson * effective user ID       4 bytes
1222155131Srwatson * effective group ID      4 bytes
1223155131Srwatson * real user ID            4 bytes
1224155131Srwatson * real group ID           4 bytes
1225155131Srwatson * process ID              4 bytes
1226155131Srwatson * session ID              4 bytes
1227155131Srwatson * terminal ID
1228155131Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1229155131Srwatson *   address type/length   4 bytes
1230155131Srwatson *   machine address      16 bytes
1231155131Srwatson */
1232155131Srwatsontoken_t *
1233155131Srwatsonau_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1234155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1235155131Srwatson{
1236155131Srwatson	token_t *t;
1237155131Srwatson	u_char *dptr = NULL;
1238155131Srwatson
1239159985Srwatson	if (tid->at_type == AU_IPv4)
1240159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1241159985Srwatson		    sizeof(u_int32_t));
1242159985Srwatson	else if (tid->at_type == AU_IPv6)
1243159985Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1244159985Srwatson		    sizeof(u_int32_t));
1245159985Srwatson	else {
1246159985Srwatson		errno = EINVAL;
1247159985Srwatson		return (NULL);
1248159985Srwatson	}
1249155131Srwatson	if (t == NULL)
1250155131Srwatson		return (NULL);
1251155131Srwatson
1252155131Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1253155131Srwatson	ADD_U_INT32(dptr, auid);
1254155131Srwatson	ADD_U_INT32(dptr, euid);
1255155131Srwatson	ADD_U_INT32(dptr, egid);
1256155131Srwatson	ADD_U_INT32(dptr, ruid);
1257155131Srwatson	ADD_U_INT32(dptr, rgid);
1258155131Srwatson	ADD_U_INT32(dptr, pid);
1259155131Srwatson	ADD_U_INT32(dptr, sid);
1260155131Srwatson	ADD_U_INT32(dptr, tid->at_port);
1261155131Srwatson	ADD_U_INT32(dptr, tid->at_type);
1262168777Srwatson	if (tid->at_type == AU_IPv6)
1263168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1264168777Srwatson	else
1265168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1266155131Srwatson
1267155131Srwatson	return (t);
1268155131Srwatson}
1269155131Srwatson
1270155131Srwatsontoken_t *
1271155131Srwatsonau_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1272155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1273155131Srwatson{
1274168777Srwatson	token_t *t;
1275168777Srwatson	u_char *dptr = NULL;
1276155131Srwatson
1277168777Srwatson	if (tid->at_type == AU_IPv4)
1278168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1279168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1280168777Srwatson		    2 * sizeof(u_int32_t));
1281168777Srwatson	else if (tid->at_type == AU_IPv6)
1282168777Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1283168777Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1284168777Srwatson		    5 * sizeof(u_int32_t));
1285168777Srwatson	else {
1286168777Srwatson		errno = EINVAL;
1287168777Srwatson		return (NULL);
1288168777Srwatson	}
1289168777Srwatson	if (t == NULL)
1290168777Srwatson		return (NULL);
1291168777Srwatson
1292168777Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1293168777Srwatson	ADD_U_INT32(dptr, auid);
1294168777Srwatson	ADD_U_INT32(dptr, euid);
1295168777Srwatson	ADD_U_INT32(dptr, egid);
1296168777Srwatson	ADD_U_INT32(dptr, ruid);
1297168777Srwatson	ADD_U_INT32(dptr, rgid);
1298168777Srwatson	ADD_U_INT32(dptr, pid);
1299168777Srwatson	ADD_U_INT32(dptr, sid);
1300168777Srwatson	ADD_U_INT64(dptr, tid->at_port);
1301168777Srwatson	ADD_U_INT32(dptr, tid->at_type);
1302168777Srwatson	if (tid->at_type == AU_IPv6)
1303168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1304168777Srwatson	else
1305168777Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1306168777Srwatson
1307168777Srwatson	return (t);
1308155131Srwatson}
1309155131Srwatson
1310155131Srwatsontoken_t *
1311155131Srwatsonau_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1312155131Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1313155131Srwatson{
1314155131Srwatson
1315155131Srwatson	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1316155131Srwatson	    tid));
1317155131Srwatson}
1318155131Srwatson
1319156283Srwatson#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1320155131Srwatson/*
1321185573Srwatson * Collects audit information for the current process and creates a subject
1322185573Srwatson * token from it.
1323155131Srwatson */
1324155131Srwatsontoken_t *
1325155131Srwatsonau_to_me(void)
1326155131Srwatson{
1327155131Srwatson	auditinfo_t auinfo;
1328195740Srwatson	auditinfo_addr_t aia;
1329155131Srwatson
1330195740Srwatson	/*
1331195740Srwatson	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1332195740Srwatson	 * it, then fall back on to getaudit(2).
1333195740Srwatson	 */
1334195740Srwatson	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1335195740Srwatson		if (errno == ENOSYS) {
1336195740Srwatson			if (getaudit(&auinfo) != 0)
1337195740Srwatson				return (NULL);
1338195740Srwatson			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1339195740Srwatson				getegid(), getuid(), getgid(), getpid(),
1340195740Srwatson				auinfo.ai_asid, &auinfo.ai_termid));
1341195740Srwatson		} else {
1342195740Srwatson			/* getaudit_addr(2) failed for some other reason. */
1343243750Srwatson			return (NULL);
1344195740Srwatson		}
1345243750Srwatson	}
1346155131Srwatson
1347195740Srwatson	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1348195740Srwatson		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1349155131Srwatson}
1350155131Srwatson#endif
1351155131Srwatson
1352155131Srwatson/*
1353155131Srwatson * token ID				1 byte
1354155131Srwatson * count				4 bytes
1355155131Srwatson * text					count null-terminated strings
1356155131Srwatson */
1357155131Srwatsontoken_t *
1358161818Srwatsonau_to_exec_args(char **argv)
1359155131Srwatson{
1360155131Srwatson	token_t *t;
1361155131Srwatson	u_char *dptr = NULL;
1362155131Srwatson	const char *nextarg;
1363155131Srwatson	int i, count = 0;
1364155131Srwatson	size_t totlen = 0;
1365155131Srwatson
1366161630Srwatson	nextarg = *argv;
1367155131Srwatson
1368155131Srwatson	while (nextarg != NULL) {
1369155131Srwatson		int nextlen;
1370155131Srwatson
1371155131Srwatson		nextlen = strlen(nextarg);
1372155131Srwatson		totlen += nextlen + 1;
1373155131Srwatson		count++;
1374161630Srwatson		nextarg = *(argv + count);
1375155131Srwatson	}
1376155131Srwatson
1377155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1378155131Srwatson	if (t == NULL)
1379155131Srwatson		return (NULL);
1380155131Srwatson
1381155131Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1382155131Srwatson	ADD_U_INT32(dptr, count);
1383155131Srwatson
1384155131Srwatson	for (i = 0; i < count; i++) {
1385161630Srwatson		nextarg = *(argv + i);
1386155131Srwatson		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1387155131Srwatson	}
1388155131Srwatson
1389155131Srwatson	return (t);
1390155131Srwatson}
1391155131Srwatson
1392155131Srwatson/*
1393155131Srwatson * token ID				1 byte
1394155131Srwatson * count				4 bytes
1395155131Srwatson * text					count null-terminated strings
1396155131Srwatson */
1397155131Srwatsontoken_t *
1398161818Srwatsonau_to_exec_env(char **envp)
1399155131Srwatson{
1400155131Srwatson	token_t *t;
1401155131Srwatson	u_char *dptr = NULL;
1402155131Srwatson	int i, count = 0;
1403155131Srwatson	size_t totlen = 0;
1404155131Srwatson	const char *nextenv;
1405155131Srwatson
1406161630Srwatson	nextenv = *envp;
1407155131Srwatson
1408155131Srwatson	while (nextenv != NULL) {
1409155131Srwatson		int nextlen;
1410155131Srwatson
1411155131Srwatson		nextlen = strlen(nextenv);
1412155131Srwatson		totlen += nextlen + 1;
1413155131Srwatson		count++;
1414161630Srwatson		nextenv = *(envp + count);
1415155131Srwatson	}
1416155131Srwatson
1417155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1418155131Srwatson	if (t == NULL)
1419155131Srwatson		return (NULL);
1420155131Srwatson
1421155131Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1422155131Srwatson	ADD_U_INT32(dptr, count);
1423155131Srwatson
1424155131Srwatson	for (i = 0; i < count; i++) {
1425161630Srwatson		nextenv = *(envp + i);
1426155131Srwatson		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1427155131Srwatson	}
1428155131Srwatson
1429155131Srwatson	return (t);
1430155131Srwatson}
1431155131Srwatson
1432155131Srwatson/*
1433155131Srwatson * token ID                1 byte
1434186647Srwatson * zonename length         2 bytes
1435186647Srwatson * zonename                N bytes + 1 terminating NULL byte
1436186647Srwatson */
1437186647Srwatsontoken_t *
1438186647Srwatsonau_to_zonename(const char *zonename)
1439186647Srwatson{
1440186647Srwatson	u_char *dptr = NULL;
1441186647Srwatson	u_int16_t textlen;
1442186647Srwatson	token_t *t;
1443186647Srwatson
1444186647Srwatson	textlen = strlen(zonename) + 1;
1445186647Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1446186647Srwatson	if (t == NULL)
1447186647Srwatson		return (NULL);
1448186647Srwatson
1449186647Srwatson	ADD_U_CHAR(dptr, AUT_ZONENAME);
1450186647Srwatson	ADD_U_INT16(dptr, textlen);
1451186647Srwatson	ADD_STRING(dptr, zonename, textlen);
1452186647Srwatson	return (t);
1453186647Srwatson}
1454186647Srwatson
1455186647Srwatson/*
1456186647Srwatson * token ID                1 byte
1457155131Srwatson * record byte count       4 bytes
1458155131Srwatson * version #               1 byte    [2]
1459155131Srwatson * event type              2 bytes
1460155131Srwatson * event modifier          2 bytes
1461155131Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1462155131Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1463155131Srwatson */
1464155131Srwatsontoken_t *
1465159248Srwatsonau_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1466155131Srwatson    struct timeval tm)
1467155131Srwatson{
1468155131Srwatson	token_t *t;
1469155131Srwatson	u_char *dptr = NULL;
1470155131Srwatson	u_int32_t timems;
1471155131Srwatson
1472155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1473155131Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1474155131Srwatson	if (t == NULL)
1475155131Srwatson		return (NULL);
1476155131Srwatson
1477155131Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32);
1478155131Srwatson	ADD_U_INT32(dptr, rec_size);
1479161630Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1480155131Srwatson	ADD_U_INT16(dptr, e_type);
1481155131Srwatson	ADD_U_INT16(dptr, e_mod);
1482155131Srwatson
1483155131Srwatson	timems = tm.tv_usec/1000;
1484155131Srwatson	/* Add the timestamp */
1485155131Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1486155131Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1487155131Srwatson
1488155131Srwatson	return (t);
1489155131Srwatson}
1490155131Srwatson
1491185573Srwatson/*
1492185573Srwatson * token ID                1 byte
1493185573Srwatson * record byte count       4 bytes
1494185573Srwatson * version #               1 byte    [2]
1495185573Srwatson * event type              2 bytes
1496185573Srwatson * event modifier          2 bytes
1497185573Srwatson * address type/length     4 bytes
1498185573Srwatson * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1499185573Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1500185573Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1501185573Srwatson */
1502168777Srwatsontoken_t *
1503185573Srwatsonau_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1504185573Srwatson    struct timeval tm, struct auditinfo_addr *aia)
1505185573Srwatson{
1506185573Srwatson	token_t *t;
1507185573Srwatson	u_char *dptr = NULL;
1508186647Srwatson	u_int32_t timems;
1509186647Srwatson	au_tid_addr_t *tid;
1510185573Srwatson
1511186647Srwatson	tid = &aia->ai_termid;
1512185573Srwatson	if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6)
1513185573Srwatson		return (NULL);
1514185573Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1515185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1516185573Srwatson	    sizeof(u_int32_t) + tid->at_type);
1517243750Srwatson	if (t == NULL)
1518185573Srwatson		return (NULL);
1519185573Srwatson
1520185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1521185573Srwatson	ADD_U_INT32(dptr, rec_size);
1522185573Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1523185573Srwatson	ADD_U_INT16(dptr, e_type);
1524185573Srwatson	ADD_U_INT16(dptr, e_mod);
1525185573Srwatson
1526185573Srwatson	ADD_U_INT32(dptr, tid->at_type);
1527185573Srwatson	if (tid->at_type == AU_IPv6)
1528185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1529185573Srwatson	else
1530185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1531185573Srwatson	timems = tm.tv_usec/1000;
1532185573Srwatson	/* Add the timestamp */
1533185573Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1534185573Srwatson	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1535185573Srwatson
1536243750Srwatson	return (t);
1537185573Srwatson}
1538185573Srwatson
1539185573Srwatsontoken_t *
1540168777Srwatsonau_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1541168777Srwatson    struct timeval tm)
1542168777Srwatson{
1543168777Srwatson	token_t *t;
1544168777Srwatson	u_char *dptr = NULL;
1545168777Srwatson	u_int32_t timems;
1546168777Srwatson
1547168777Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1548168777Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1549168777Srwatson	if (t == NULL)
1550168777Srwatson		return (NULL);
1551168777Srwatson
1552168777Srwatson	ADD_U_CHAR(dptr, AUT_HEADER64);
1553168777Srwatson	ADD_U_INT32(dptr, rec_size);
1554168777Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1555168777Srwatson	ADD_U_INT16(dptr, e_type);
1556168777Srwatson	ADD_U_INT16(dptr, e_mod);
1557168777Srwatson
1558168777Srwatson	timems = tm.tv_usec/1000;
1559168777Srwatson	/* Add the timestamp */
1560168777Srwatson	ADD_U_INT64(dptr, tm.tv_sec);
1561168777Srwatson	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1562168777Srwatson
1563168777Srwatson	return (t);
1564168777Srwatson}
1565168777Srwatson
1566159248Srwatson#if !defined(KERNEL) && !defined(_KERNEL)
1567185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1568155131Srwatsontoken_t *
1569185573Srwatsonau_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1570185573Srwatson{
1571185573Srwatson	struct timeval tm;
1572185573Srwatson	struct auditinfo_addr aia;
1573185573Srwatson
1574185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1575185573Srwatson		return (NULL);
1576191273Srwatson	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1577185573Srwatson		if (errno != ENOSYS)
1578185573Srwatson			return (NULL);
1579185573Srwatson		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1580185573Srwatson	}
1581185573Srwatson	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1582185573Srwatson}
1583185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1584185573Srwatson
1585185573Srwatsontoken_t *
1586159248Srwatsonau_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1587159248Srwatson{
1588159248Srwatson	struct timeval tm;
1589159248Srwatson
1590159248Srwatson	if (gettimeofday(&tm, NULL) == -1)
1591159248Srwatson		return (NULL);
1592159248Srwatson	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1593159248Srwatson}
1594159248Srwatson
1595159248Srwatsontoken_t *
1596155131Srwatsonau_to_header64(__unused int rec_size, __unused au_event_t e_type,
1597155131Srwatson    __unused au_emod_t e_mod)
1598155131Srwatson{
1599168777Srwatson	struct timeval tm;
1600155131Srwatson
1601168777Srwatson	if (gettimeofday(&tm, NULL) == -1)
1602168777Srwatson		return (NULL);
1603168777Srwatson	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1604155131Srwatson}
1605155131Srwatson
1606155131Srwatsontoken_t *
1607155131Srwatsonau_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1608155131Srwatson{
1609155131Srwatson
1610155131Srwatson	return (au_to_header32(rec_size, e_type, e_mod));
1611155131Srwatson}
1612155131Srwatson
1613185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1614185573Srwatsontoken_t *
1615185573Srwatsonau_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1616185573Srwatson{
1617185573Srwatson
1618185573Srwatson	return (au_to_header32_ex(rec_size, e_type, e_mod));
1619185573Srwatson}
1620185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1621185573Srwatson#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1622185573Srwatson
1623155131Srwatson/*
1624155131Srwatson * token ID                1 byte
1625155131Srwatson * trailer magic number    2 bytes
1626155131Srwatson * record byte count       4 bytes
1627155131Srwatson */
1628155131Srwatsontoken_t *
1629155131Srwatsonau_to_trailer(int rec_size)
1630155131Srwatson{
1631155131Srwatson	token_t *t;
1632155131Srwatson	u_char *dptr = NULL;
1633186647Srwatson	u_int16_t magic = AUT_TRAILER_MAGIC;
1634155131Srwatson
1635155131Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1636155131Srwatson	    sizeof(u_int32_t));
1637155131Srwatson	if (t == NULL)
1638155131Srwatson		return (NULL);
1639155131Srwatson
1640155131Srwatson	ADD_U_CHAR(dptr, AUT_TRAILER);
1641155131Srwatson	ADD_U_INT16(dptr, magic);
1642155131Srwatson	ADD_U_INT32(dptr, rec_size);
1643155131Srwatson
1644155131Srwatson	return (t);
1645155131Srwatson}
1646