xref: /freebsd/contrib/openbsm/libbsm/bsm_token.c (revision aa77200569e397d6ff1fdb4d255d0fa254d0a128)
152267f74SRobert Watson /*-
206edd2f1SRobert Watson  * Copyright (c) 2004-2009 Apple Inc.
3ca0716f5SRobert Watson  * Copyright (c) 2005 SPARTA, Inc.
4ca0716f5SRobert Watson  * All rights reserved.
5ca0716f5SRobert Watson  *
6ca0716f5SRobert Watson  * This code was developed in part by Robert N. M. Watson, Senior Principal
7ca0716f5SRobert Watson  * Scientist, SPARTA, Inc.
8ca0716f5SRobert Watson  *
9ca0716f5SRobert Watson  * Redistribution and use in source and binary forms, with or without
10ca0716f5SRobert Watson  * modification, are permitted provided that the following conditions
11ca0716f5SRobert Watson  * are met:
12ca0716f5SRobert Watson  * 1.  Redistributions of source code must retain the above copyright
13ca0716f5SRobert Watson  *     notice, this list of conditions and the following disclaimer.
14ca0716f5SRobert Watson  * 2.  Redistributions in binary form must reproduce the above copyright
15ca0716f5SRobert Watson  *     notice, this list of conditions and the following disclaimer in the
16ca0716f5SRobert Watson  *     documentation and/or other materials provided with the distribution.
1752267f74SRobert Watson  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
18ca0716f5SRobert Watson  *     its contributors may be used to endorse or promote products derived
19ca0716f5SRobert Watson  *     from this software without specific prior written permission.
20ca0716f5SRobert Watson  *
21ca0716f5SRobert Watson  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22ca0716f5SRobert Watson  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23ca0716f5SRobert Watson  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24ca0716f5SRobert Watson  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25ca0716f5SRobert Watson  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26ca0716f5SRobert Watson  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27ca0716f5SRobert Watson  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28ca0716f5SRobert Watson  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29ca0716f5SRobert Watson  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30ca0716f5SRobert Watson  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31ca0716f5SRobert Watson  * POSSIBILITY OF SUCH DAMAGE.
32ca0716f5SRobert Watson  *
33*aa772005SRobert Watson  * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#99 $
34ca0716f5SRobert Watson  */
35ca0716f5SRobert Watson 
36ca0716f5SRobert Watson #include <sys/types.h>
373b97a967SRobert Watson 
383b97a967SRobert Watson #include <config/config.h>
39*aa772005SRobert Watson 
40*aa772005SRobert Watson #ifdef USE_ENDIAN_H
413b97a967SRobert Watson #include <endian.h>
42*aa772005SRobert Watson #endif
43*aa772005SRobert Watson #ifdef USE_SYS_ENDIAN_H
44*aa772005SRobert Watson #include <sys/endian.h>
45*aa772005SRobert Watson #endif
46*aa772005SRobert Watson #ifdef USE_MACHINE_ENDIAN_H
47*aa772005SRobert Watson #include <machine/endian.h>
48*aa772005SRobert Watson #endif
49*aa772005SRobert Watson #ifdef USE_COMPAT_ENDIAN_H
503b97a967SRobert Watson #include <compat/endian.h>
51*aa772005SRobert Watson #endif
52*aa772005SRobert Watson #ifdef USE_COMPAT_ENDIAN_ENC_H
53*aa772005SRobert Watson #include <compat/endian_enc.h>
54*aa772005SRobert Watson #endif
55*aa772005SRobert Watson 
563b97a967SRobert Watson #ifdef HAVE_FULL_QUEUE_H
573b97a967SRobert Watson #include <sys/queue.h>
583b97a967SRobert Watson #else /* !HAVE_FULL_QUEUE_H */
593b97a967SRobert Watson #include <compat/queue.h>
603b97a967SRobert Watson #endif /* !HAVE_FULL_QUEUE_H */
613b97a967SRobert Watson 
62ca0716f5SRobert Watson #include <sys/socket.h>
63ca0716f5SRobert Watson #include <sys/time.h>
64ca0716f5SRobert Watson #include <sys/un.h>
65ca0716f5SRobert Watson 
66ca0716f5SRobert Watson #include <sys/ipc.h>
67ca0716f5SRobert Watson 
68ca0716f5SRobert Watson #include <netinet/in.h>
69ca0716f5SRobert Watson #include <netinet/in_systm.h>
70ca0716f5SRobert Watson #include <netinet/ip.h>
71ca0716f5SRobert Watson 
72ca0716f5SRobert Watson #include <assert.h>
73ca0716f5SRobert Watson #include <errno.h>
74ca0716f5SRobert Watson #include <string.h>
75ca0716f5SRobert Watson #include <stdlib.h>
76ca0716f5SRobert Watson #include <unistd.h>
77ca0716f5SRobert Watson 
78ca0716f5SRobert Watson #include <bsm/audit_internal.h>
79ca0716f5SRobert Watson #include <bsm/libbsm.h>
80ca0716f5SRobert Watson 
81ca0716f5SRobert Watson #define	GET_TOKEN_AREA(t, dptr, length) do {				\
82ca0716f5SRobert Watson 	(t) = malloc(sizeof(token_t));					\
83ca0716f5SRobert Watson 	if ((t) != NULL) {						\
84ca0716f5SRobert Watson 		(t)->len = (length);					\
85*aa772005SRobert Watson 		(dptr) = (t->t_data) = calloc((length), sizeof(u_char)); \
86ca0716f5SRobert Watson 		if ((dptr) == NULL) {					\
87ca0716f5SRobert Watson 			free(t);					\
88ca0716f5SRobert Watson 			(t) = NULL;					\
89*aa772005SRobert Watson 		}							\
90ca0716f5SRobert Watson 	} else								\
91ca0716f5SRobert Watson 		(dptr) = NULL;						\
9252267f74SRobert Watson 	assert((t) == NULL || (dptr) != NULL);				\
93ca0716f5SRobert Watson } while (0)
94ca0716f5SRobert Watson 
95ca0716f5SRobert Watson /*
96ca0716f5SRobert Watson  * token ID                1 byte
97*aa772005SRobert Watson  * success/failure         1 byte
98*aa772005SRobert Watson  * privstrlen              2 bytes
99*aa772005SRobert Watson  * privstr                 N bytes + 1 (\0 byte)
100*aa772005SRobert Watson  */
101*aa772005SRobert Watson token_t *
102*aa772005SRobert Watson au_to_upriv(char sorf, char *priv)
103*aa772005SRobert Watson {
104*aa772005SRobert Watson 	u_int16_t textlen;
105*aa772005SRobert Watson 	u_char *dptr;
106*aa772005SRobert Watson 	token_t *t;
107*aa772005SRobert Watson 
108*aa772005SRobert Watson 	textlen = strlen(priv) + 1;
109*aa772005SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
110*aa772005SRobert Watson 	    sizeof(u_int16_t) + textlen);
111*aa772005SRobert Watson 	if (t == NULL)
112*aa772005SRobert Watson 		return (NULL);
113*aa772005SRobert Watson 	ADD_U_CHAR(dptr, AUT_UPRIV);
114*aa772005SRobert Watson 	ADD_U_CHAR(dptr, sorf);
115*aa772005SRobert Watson 	ADD_U_INT16(dptr, textlen);
116*aa772005SRobert Watson 	ADD_STRING(dptr, priv, textlen);
117*aa772005SRobert Watson 	return (t);
118*aa772005SRobert Watson }
119*aa772005SRobert Watson 
120*aa772005SRobert Watson /*
121*aa772005SRobert Watson  * token ID		1 byte
122*aa772005SRobert Watson  * privtstrlen		2 bytes
123*aa772005SRobert Watson  * privtstr		N bytes + 1
124*aa772005SRobert Watson  * privstrlen		2 bytes
125*aa772005SRobert Watson  * privstr		N bytes + 1
126*aa772005SRobert Watson  */
127*aa772005SRobert Watson token_t *
128*aa772005SRobert Watson au_to_privset(char *privtypestr, char *privstr)
129*aa772005SRobert Watson {
130*aa772005SRobert Watson 	u_int16_t	 type_len, priv_len;
131*aa772005SRobert Watson 	u_char		*dptr;
132*aa772005SRobert Watson 	token_t		*t;
133*aa772005SRobert Watson 
134*aa772005SRobert Watson 	type_len = strlen(privtypestr) + 1;
135*aa772005SRobert Watson 	priv_len = strlen(privstr) + 1;
136*aa772005SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
137*aa772005SRobert Watson 	    sizeof(u_int16_t) + type_len + priv_len);
138*aa772005SRobert Watson 	if (t == NULL)
139*aa772005SRobert Watson 		return (NULL);
140*aa772005SRobert Watson 	ADD_U_CHAR(dptr, AUT_PRIV);
141*aa772005SRobert Watson 	ADD_U_INT16(dptr, type_len);
142*aa772005SRobert Watson 	ADD_STRING(dptr, privtypestr, type_len);
143*aa772005SRobert Watson 	ADD_U_INT16(dptr, priv_len);
144*aa772005SRobert Watson 	ADD_STRING(dptr, privstr, priv_len);
145*aa772005SRobert Watson 	return (t);
146*aa772005SRobert Watson }
147*aa772005SRobert Watson 
148*aa772005SRobert Watson /*
149*aa772005SRobert Watson  * token ID                1 byte
150ca0716f5SRobert Watson  * argument #              1 byte
151ca0716f5SRobert Watson  * argument value          4 bytes/8 bytes (32-bit/64-bit value)
152ca0716f5SRobert Watson  * text length             2 bytes
153ca0716f5SRobert Watson  * text                    N bytes + 1 terminating NULL byte
154ca0716f5SRobert Watson  */
155ca0716f5SRobert Watson token_t *
15652267f74SRobert Watson au_to_arg32(char n, const char *text, u_int32_t v)
157ca0716f5SRobert Watson {
158ca0716f5SRobert Watson 	token_t *t;
159ca0716f5SRobert Watson 	u_char *dptr = NULL;
160ca0716f5SRobert Watson 	u_int16_t textlen;
161ca0716f5SRobert Watson 
162ca0716f5SRobert Watson 	textlen = strlen(text);
163ca0716f5SRobert Watson 	textlen += 1;
164ca0716f5SRobert Watson 
165ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
166ca0716f5SRobert Watson 	    sizeof(u_int16_t) + textlen);
167ca0716f5SRobert Watson 	if (t == NULL)
168ca0716f5SRobert Watson 		return (NULL);
169ca0716f5SRobert Watson 
170ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_ARG32);
171ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, n);
172ca0716f5SRobert Watson 	ADD_U_INT32(dptr, v);
173ca0716f5SRobert Watson 	ADD_U_INT16(dptr, textlen);
174ca0716f5SRobert Watson 	ADD_STRING(dptr, text, textlen);
175ca0716f5SRobert Watson 
176ca0716f5SRobert Watson 	return (t);
177ca0716f5SRobert Watson }
178ca0716f5SRobert Watson 
179ca0716f5SRobert Watson token_t *
18052267f74SRobert Watson au_to_arg64(char n, const char *text, u_int64_t v)
181ca0716f5SRobert Watson {
182ca0716f5SRobert Watson 	token_t *t;
183ca0716f5SRobert Watson 	u_char *dptr = NULL;
184ca0716f5SRobert Watson 	u_int16_t textlen;
185ca0716f5SRobert Watson 
186ca0716f5SRobert Watson 	textlen = strlen(text);
187ca0716f5SRobert Watson 	textlen += 1;
188ca0716f5SRobert Watson 
189ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
190ca0716f5SRobert Watson 	    sizeof(u_int16_t) + textlen);
191ca0716f5SRobert Watson 	if (t == NULL)
192ca0716f5SRobert Watson 		return (NULL);
193ca0716f5SRobert Watson 
194ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_ARG64);
195ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, n);
196ca0716f5SRobert Watson 	ADD_U_INT64(dptr, v);
197ca0716f5SRobert Watson 	ADD_U_INT16(dptr, textlen);
198ca0716f5SRobert Watson 	ADD_STRING(dptr, text, textlen);
199ca0716f5SRobert Watson 
200ca0716f5SRobert Watson 	return (t);
201ca0716f5SRobert Watson }
202ca0716f5SRobert Watson 
203ca0716f5SRobert Watson token_t *
20452267f74SRobert Watson au_to_arg(char n, const char *text, u_int32_t v)
205ca0716f5SRobert Watson {
206ca0716f5SRobert Watson 
207ca0716f5SRobert Watson 	return (au_to_arg32(n, text, v));
208ca0716f5SRobert Watson }
209ca0716f5SRobert Watson 
210ca0716f5SRobert Watson #if defined(_KERNEL) || defined(KERNEL)
211ca0716f5SRobert Watson /*
212ca0716f5SRobert Watson  * token ID                1 byte
213ca0716f5SRobert Watson  * file access mode        4 bytes
214ca0716f5SRobert Watson  * owner user ID           4 bytes
215ca0716f5SRobert Watson  * owner group ID          4 bytes
216ca0716f5SRobert Watson  * file system ID          4 bytes
217ca0716f5SRobert Watson  * node ID                 8 bytes
218ca0716f5SRobert Watson  * device                  4 bytes/8 bytes (32-bit/64-bit)
219ca0716f5SRobert Watson  */
220ca0716f5SRobert Watson token_t *
221ca0716f5SRobert Watson au_to_attr32(struct vnode_au_info *vni)
222ca0716f5SRobert Watson {
223ca0716f5SRobert Watson 	token_t *t;
224ca0716f5SRobert Watson 	u_char *dptr = NULL;
225ca0716f5SRobert Watson 	u_int16_t pad0_16 = 0;
22606edd2f1SRobert Watson 	u_int32_t pad0_32 = 0;
227ca0716f5SRobert Watson 
228ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
229ca0716f5SRobert Watson 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
230ca0716f5SRobert Watson 	if (t == NULL)
231ca0716f5SRobert Watson 		return (NULL);
232ca0716f5SRobert Watson 
233ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_ATTR32);
234ca0716f5SRobert Watson 
235ca0716f5SRobert Watson 	/*
2367a0a89d2SRobert Watson 	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
2377a0a89d2SRobert Watson 	 * so pad with 0.
2387a0a89d2SRobert Watson 	 *
2397a0a89d2SRobert Watson 	 * XXXRW: Possibly should be conditionally compiled.
2407a0a89d2SRobert Watson 	 *
2417a0a89d2SRobert Watson 	 * XXXRW: Should any conversions take place on the mode?
242ca0716f5SRobert Watson 	 */
243ca0716f5SRobert Watson 	ADD_U_INT16(dptr, pad0_16);
244ca0716f5SRobert Watson 	ADD_U_INT16(dptr, vni->vn_mode);
245ca0716f5SRobert Watson 
246ca0716f5SRobert Watson 	ADD_U_INT32(dptr, vni->vn_uid);
247ca0716f5SRobert Watson 	ADD_U_INT32(dptr, vni->vn_gid);
248ca0716f5SRobert Watson 	ADD_U_INT32(dptr, vni->vn_fsid);
249ca0716f5SRobert Watson 
250ca0716f5SRobert Watson 	/*
25152267f74SRobert Watson 	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
252ca0716f5SRobert Watson 	 * Attempt to handle both, and let the compiler sort it out.  If we
253ca0716f5SRobert Watson 	 * could pick this out at compile-time, it would be better, so as to
254ca0716f5SRobert Watson 	 * avoid the else case below.
255ca0716f5SRobert Watson 	 */
256ca0716f5SRobert Watson 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
257ca0716f5SRobert Watson 		ADD_U_INT32(dptr, pad0_32);
258ca0716f5SRobert Watson 		ADD_U_INT32(dptr, vni->vn_fileid);
259ca0716f5SRobert Watson 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
260ca0716f5SRobert Watson 		ADD_U_INT64(dptr, vni->vn_fileid);
261ca0716f5SRobert Watson 	else
262ca0716f5SRobert Watson 		ADD_U_INT64(dptr, 0LL);
263ca0716f5SRobert Watson 
264ca0716f5SRobert Watson 	ADD_U_INT32(dptr, vni->vn_dev);
265ca0716f5SRobert Watson 
266ca0716f5SRobert Watson 	return (t);
267ca0716f5SRobert Watson }
268ca0716f5SRobert Watson 
269ca0716f5SRobert Watson token_t *
270ca0716f5SRobert Watson au_to_attr64(struct vnode_au_info *vni)
271ca0716f5SRobert Watson {
272bc168a6cSRobert Watson 	token_t *t;
273bc168a6cSRobert Watson 	u_char *dptr = NULL;
274bc168a6cSRobert Watson 	u_int16_t pad0_16 = 0;
27506edd2f1SRobert Watson 	u_int32_t pad0_32 = 0;
276ca0716f5SRobert Watson 
277bc168a6cSRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
278bc168a6cSRobert Watson 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
279bc168a6cSRobert Watson 	if (t == NULL)
280ca0716f5SRobert Watson 		return (NULL);
281bc168a6cSRobert Watson 
282bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUT_ATTR64);
283bc168a6cSRobert Watson 
284bc168a6cSRobert Watson 	/*
2857a0a89d2SRobert Watson 	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
2867a0a89d2SRobert Watson 	 * so pad with 0.
2877a0a89d2SRobert Watson 	 *
2887a0a89d2SRobert Watson 	 * XXXRW: Possibly should be conditionally compiled.
2897a0a89d2SRobert Watson 	 *
2907a0a89d2SRobert Watson 	 * XXXRW: Should any conversions take place on the mode?
291bc168a6cSRobert Watson 	 */
292bc168a6cSRobert Watson 	ADD_U_INT16(dptr, pad0_16);
293bc168a6cSRobert Watson 	ADD_U_INT16(dptr, vni->vn_mode);
294bc168a6cSRobert Watson 
295bc168a6cSRobert Watson 	ADD_U_INT32(dptr, vni->vn_uid);
296bc168a6cSRobert Watson 	ADD_U_INT32(dptr, vni->vn_gid);
297bc168a6cSRobert Watson 	ADD_U_INT32(dptr, vni->vn_fsid);
298bc168a6cSRobert Watson 
299bc168a6cSRobert Watson 	/*
300bc168a6cSRobert Watson 	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
301bc168a6cSRobert Watson 	 * Attempt to handle both, and let the compiler sort it out.  If we
302bc168a6cSRobert Watson 	 * could pick this out at compile-time, it would be better, so as to
303bc168a6cSRobert Watson 	 * avoid the else case below.
304bc168a6cSRobert Watson 	 */
305bc168a6cSRobert Watson 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
306bc168a6cSRobert Watson 		ADD_U_INT32(dptr, pad0_32);
307bc168a6cSRobert Watson 		ADD_U_INT32(dptr, vni->vn_fileid);
308bc168a6cSRobert Watson 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
309bc168a6cSRobert Watson 		ADD_U_INT64(dptr, vni->vn_fileid);
310bc168a6cSRobert Watson 	else
311bc168a6cSRobert Watson 		ADD_U_INT64(dptr, 0LL);
312bc168a6cSRobert Watson 
313bc168a6cSRobert Watson 	ADD_U_INT64(dptr, vni->vn_dev);
314bc168a6cSRobert Watson 
315bc168a6cSRobert Watson 	return (t);
316ca0716f5SRobert Watson }
317ca0716f5SRobert Watson 
318ca0716f5SRobert Watson token_t *
319ca0716f5SRobert Watson au_to_attr(struct vnode_au_info *vni)
320ca0716f5SRobert Watson {
321ca0716f5SRobert Watson 
322ca0716f5SRobert Watson 	return (au_to_attr32(vni));
323ca0716f5SRobert Watson }
324ca0716f5SRobert Watson #endif /* !(defined(_KERNEL) || defined(KERNEL) */
325ca0716f5SRobert Watson 
326ca0716f5SRobert Watson /*
327ca0716f5SRobert Watson  * token ID                1 byte
328ca0716f5SRobert Watson  * how to print            1 byte
329ca0716f5SRobert Watson  * basic unit              1 byte
330ca0716f5SRobert Watson  * unit count              1 byte
331ca0716f5SRobert Watson  * data items              (depends on basic unit)
332ca0716f5SRobert Watson  */
333ca0716f5SRobert Watson token_t *
33452267f74SRobert Watson au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
335ca0716f5SRobert Watson {
336ca0716f5SRobert Watson 	token_t *t;
337ca0716f5SRobert Watson 	u_char *dptr = NULL;
338ca0716f5SRobert Watson 	size_t datasize, totdata;
339ca0716f5SRobert Watson 
340ca0716f5SRobert Watson 	/* Determine the size of the basic unit. */
341ca0716f5SRobert Watson 	switch (unit_type) {
342ca0716f5SRobert Watson 	case AUR_BYTE:
343506764c6SRobert Watson 	/* case AUR_CHAR: */
344ca0716f5SRobert Watson 		datasize = AUR_BYTE_SIZE;
345ca0716f5SRobert Watson 		break;
346ca0716f5SRobert Watson 
347ca0716f5SRobert Watson 	case AUR_SHORT:
348ca0716f5SRobert Watson 		datasize = AUR_SHORT_SIZE;
349ca0716f5SRobert Watson 		break;
350ca0716f5SRobert Watson 
351506764c6SRobert Watson 	case AUR_INT32:
352506764c6SRobert Watson 	/* case AUR_INT: */
353506764c6SRobert Watson 		datasize = AUR_INT32_SIZE;
354506764c6SRobert Watson 		break;
355506764c6SRobert Watson 
356506764c6SRobert Watson 	case AUR_INT64:
357506764c6SRobert Watson 		datasize = AUR_INT64_SIZE;
358ca0716f5SRobert Watson 		break;
359ca0716f5SRobert Watson 
360ca0716f5SRobert Watson 	default:
361ca0716f5SRobert Watson 		errno = EINVAL;
362ca0716f5SRobert Watson 		return (NULL);
363ca0716f5SRobert Watson 	}
364ca0716f5SRobert Watson 
365ca0716f5SRobert Watson 	totdata = datasize * unit_count;
366ca0716f5SRobert Watson 
367506764c6SRobert Watson 	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
368ca0716f5SRobert Watson 	if (t == NULL)
369ca0716f5SRobert Watson 		return (NULL);
370ca0716f5SRobert Watson 
3717a0a89d2SRobert Watson 	/*
3727a0a89d2SRobert Watson 	 * XXXRW: We should be byte-swapping each data item for multi-byte
3737a0a89d2SRobert Watson 	 * types.
3747a0a89d2SRobert Watson 	 */
375ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_DATA);
376ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, unit_print);
377ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, unit_type);
378ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, unit_count);
379ca0716f5SRobert Watson 	ADD_MEM(dptr, p, totdata);
380ca0716f5SRobert Watson 
381ca0716f5SRobert Watson 	return (t);
382ca0716f5SRobert Watson }
383ca0716f5SRobert Watson 
384ca0716f5SRobert Watson 
385ca0716f5SRobert Watson /*
386ca0716f5SRobert Watson  * token ID                1 byte
387ca0716f5SRobert Watson  * status		   4 bytes
388ca0716f5SRobert Watson  * return value            4 bytes
389ca0716f5SRobert Watson  */
390ca0716f5SRobert Watson token_t *
391ca0716f5SRobert Watson au_to_exit(int retval, int err)
392ca0716f5SRobert Watson {
393ca0716f5SRobert Watson 	token_t *t;
394ca0716f5SRobert Watson 	u_char *dptr = NULL;
395ca0716f5SRobert Watson 
396ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
397ca0716f5SRobert Watson 	if (t == NULL)
398ca0716f5SRobert Watson 		return (NULL);
399ca0716f5SRobert Watson 
400ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_EXIT);
401ca0716f5SRobert Watson 	ADD_U_INT32(dptr, err);
402ca0716f5SRobert Watson 	ADD_U_INT32(dptr, retval);
403ca0716f5SRobert Watson 
404ca0716f5SRobert Watson 	return (t);
405ca0716f5SRobert Watson }
406ca0716f5SRobert Watson 
407ca0716f5SRobert Watson /*
408ca0716f5SRobert Watson  */
409ca0716f5SRobert Watson token_t *
410ca0716f5SRobert Watson au_to_groups(int *groups)
411ca0716f5SRobert Watson {
412ca0716f5SRobert Watson 
413bc168a6cSRobert Watson 	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
414ca0716f5SRobert Watson }
415ca0716f5SRobert Watson 
416ca0716f5SRobert Watson /*
417ca0716f5SRobert Watson  * token ID                1 byte
418ca0716f5SRobert Watson  * number groups           2 bytes
419ca0716f5SRobert Watson  * group list              count * 4 bytes
420ca0716f5SRobert Watson  */
421ca0716f5SRobert Watson token_t *
422ca0716f5SRobert Watson au_to_newgroups(u_int16_t n, gid_t *groups)
423ca0716f5SRobert Watson {
424ca0716f5SRobert Watson 	token_t *t;
425ca0716f5SRobert Watson 	u_char *dptr = NULL;
426ca0716f5SRobert Watson 	int i;
427ca0716f5SRobert Watson 
428ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
429ca0716f5SRobert Watson 	    n * sizeof(u_int32_t));
430ca0716f5SRobert Watson 	if (t == NULL)
431ca0716f5SRobert Watson 		return (NULL);
432ca0716f5SRobert Watson 
433ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
434ca0716f5SRobert Watson 	ADD_U_INT16(dptr, n);
435ca0716f5SRobert Watson 	for (i = 0; i < n; i++)
436ca0716f5SRobert Watson 		ADD_U_INT32(dptr, groups[i]);
437ca0716f5SRobert Watson 
438ca0716f5SRobert Watson 	return (t);
439ca0716f5SRobert Watson }
440ca0716f5SRobert Watson 
441ca0716f5SRobert Watson /*
442ca0716f5SRobert Watson  * token ID                1 byte
443ca0716f5SRobert Watson  * internet address        4 bytes
444ca0716f5SRobert Watson  */
445ca0716f5SRobert Watson token_t *
446ca0716f5SRobert Watson au_to_in_addr(struct in_addr *internet_addr)
447ca0716f5SRobert Watson {
448ca0716f5SRobert Watson 	token_t *t;
449ca0716f5SRobert Watson 	u_char *dptr = NULL;
450ca0716f5SRobert Watson 
451506764c6SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
452ca0716f5SRobert Watson 	if (t == NULL)
453ca0716f5SRobert Watson 		return (NULL);
454ca0716f5SRobert Watson 
455ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_IN_ADDR);
456506764c6SRobert Watson 	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
457ca0716f5SRobert Watson 
458ca0716f5SRobert Watson 	return (t);
459ca0716f5SRobert Watson }
460ca0716f5SRobert Watson 
461ca0716f5SRobert Watson /*
462ca0716f5SRobert Watson  * token ID                1 byte
463ca0716f5SRobert Watson  * address type/length     4 bytes
46452267f74SRobert Watson  * address                16 bytes
465ca0716f5SRobert Watson  */
466ca0716f5SRobert Watson token_t *
467ca0716f5SRobert Watson au_to_in_addr_ex(struct in6_addr *internet_addr)
468ca0716f5SRobert Watson {
469ca0716f5SRobert Watson 	token_t *t;
470ca0716f5SRobert Watson 	u_char *dptr = NULL;
4717a0a89d2SRobert Watson 	u_int32_t type = AU_IPv6;
472ca0716f5SRobert Watson 
473506764c6SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
474ca0716f5SRobert Watson 	if (t == NULL)
475ca0716f5SRobert Watson 		return (NULL);
476ca0716f5SRobert Watson 
477ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
478ca0716f5SRobert Watson 	ADD_U_INT32(dptr, type);
4790814440eSRobert Watson 	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
480ca0716f5SRobert Watson 
481ca0716f5SRobert Watson 	return (t);
482ca0716f5SRobert Watson }
483ca0716f5SRobert Watson 
484ca0716f5SRobert Watson /*
485ca0716f5SRobert Watson  * token ID                1 byte
486ca0716f5SRobert Watson  * ip header		   20 bytes
487bc168a6cSRobert Watson  *
488bc168a6cSRobert Watson  * The IP header should be submitted in network byte order.
489ca0716f5SRobert Watson  */
490ca0716f5SRobert Watson token_t *
491ca0716f5SRobert Watson au_to_ip(struct ip *ip)
492ca0716f5SRobert Watson {
493ca0716f5SRobert Watson 	token_t *t;
494ca0716f5SRobert Watson 	u_char *dptr = NULL;
495ca0716f5SRobert Watson 
496ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
497ca0716f5SRobert Watson 	if (t == NULL)
498ca0716f5SRobert Watson 		return (NULL);
499ca0716f5SRobert Watson 
500ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_IP);
501ca0716f5SRobert Watson 	ADD_MEM(dptr, ip, sizeof(struct ip));
502ca0716f5SRobert Watson 
503ca0716f5SRobert Watson 	return (t);
504ca0716f5SRobert Watson }
505ca0716f5SRobert Watson 
506ca0716f5SRobert Watson /*
507ca0716f5SRobert Watson  * token ID                1 byte
508ca0716f5SRobert Watson  * object ID type          1 byte
509ca0716f5SRobert Watson  * object ID               4 bytes
510ca0716f5SRobert Watson  */
511ca0716f5SRobert Watson token_t *
512ca0716f5SRobert Watson au_to_ipc(char type, int id)
513ca0716f5SRobert Watson {
514ca0716f5SRobert Watson 	token_t *t;
515ca0716f5SRobert Watson 	u_char *dptr = NULL;
516ca0716f5SRobert Watson 
517ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
518ca0716f5SRobert Watson 	if (t == NULL)
519ca0716f5SRobert Watson 		return (NULL);
520ca0716f5SRobert Watson 
521ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_IPC);
522ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, type);
523ca0716f5SRobert Watson 	ADD_U_INT32(dptr, id);
524ca0716f5SRobert Watson 
525ca0716f5SRobert Watson 	return (t);
526ca0716f5SRobert Watson }
527ca0716f5SRobert Watson 
528ca0716f5SRobert Watson /*
529ca0716f5SRobert Watson  * token ID                1 byte
530ca0716f5SRobert Watson  * owner user ID           4 bytes
531ca0716f5SRobert Watson  * owner group ID          4 bytes
532ca0716f5SRobert Watson  * creator user ID         4 bytes
533ca0716f5SRobert Watson  * creator group ID        4 bytes
534ca0716f5SRobert Watson  * access mode             4 bytes
535ca0716f5SRobert Watson  * slot sequence #         4 bytes
536ca0716f5SRobert Watson  * key                     4 bytes
537ca0716f5SRobert Watson  */
538ca0716f5SRobert Watson token_t *
539ca0716f5SRobert Watson au_to_ipc_perm(struct ipc_perm *perm)
540ca0716f5SRobert Watson {
541ca0716f5SRobert Watson 	token_t *t;
542ca0716f5SRobert Watson 	u_char *dptr = NULL;
543ca0716f5SRobert Watson 	u_int16_t pad0 = 0;
544ca0716f5SRobert Watson 
54506edd2f1SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
54606edd2f1SRobert Watson 	    sizeof(u_int32_t));
547ca0716f5SRobert Watson 	if (t == NULL)
548ca0716f5SRobert Watson 		return (NULL);
549ca0716f5SRobert Watson 
550ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_IPC_PERM);
551ca0716f5SRobert Watson 
552ca0716f5SRobert Watson 	/*
5537a0a89d2SRobert Watson 	 * Systems vary significantly in what types they use in struct
5547a0a89d2SRobert Watson 	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
5557a0a89d2SRobert Watson 	 * allow for that, as BSM define 32-bit values here.
5567a0a89d2SRobert Watson 	 * Some systems define the sizes for ipc_perm members as 2 bytes;
5577a0a89d2SRobert Watson 	 * BSM defines 4 so pad with 0.
5587a0a89d2SRobert Watson 	 *
5597a0a89d2SRobert Watson 	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
5607a0a89d2SRobert Watson 	 * need to be handled.
561ca0716f5SRobert Watson 	 */
5627a0a89d2SRobert Watson 	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
563ca0716f5SRobert Watson 		ADD_U_INT16(dptr, pad0);
564ca0716f5SRobert Watson 		ADD_U_INT16(dptr, perm->uid);
565ca0716f5SRobert Watson 		ADD_U_INT16(dptr, pad0);
566ca0716f5SRobert Watson 		ADD_U_INT16(dptr, perm->gid);
567ca0716f5SRobert Watson 		ADD_U_INT16(dptr, pad0);
568ca0716f5SRobert Watson 		ADD_U_INT16(dptr, perm->cuid);
569ca0716f5SRobert Watson 		ADD_U_INT16(dptr, pad0);
570ca0716f5SRobert Watson 		ADD_U_INT16(dptr, perm->cgid);
5717a0a89d2SRobert Watson 	} else {
5727a0a89d2SRobert Watson 		ADD_U_INT32(dptr, perm->uid);
5737a0a89d2SRobert Watson 		ADD_U_INT32(dptr, perm->gid);
5747a0a89d2SRobert Watson 		ADD_U_INT32(dptr, perm->cuid);
5757a0a89d2SRobert Watson 		ADD_U_INT32(dptr, perm->cgid);
5767a0a89d2SRobert Watson 	}
577ca0716f5SRobert Watson 
578ca0716f5SRobert Watson 	ADD_U_INT16(dptr, pad0);
579ca0716f5SRobert Watson 	ADD_U_INT16(dptr, perm->mode);
580ca0716f5SRobert Watson 
581ca0716f5SRobert Watson 	ADD_U_INT16(dptr, pad0);
582ca0716f5SRobert Watson 
5833b97a967SRobert Watson #ifdef HAVE_IPC_PERM___SEQ
5843b97a967SRobert Watson 	ADD_U_INT16(dptr, perm->__seq);
58552267f74SRobert Watson #else	/* HAVE_IPC_PERM___SEQ */
58652267f74SRobert Watson #ifdef  HAVE_IPC_PERM__SEQ
58752267f74SRobert Watson 	ADD_U_INT16(dptr, perm->_seq);
58852267f74SRobert Watson #else	/* HAVE_IPC_PERM__SEQ */
5893b97a967SRobert Watson 	ADD_U_INT16(dptr, perm->seq);
59052267f74SRobert Watson #endif	/* HAVE_IPC_PERM__SEQ */
59152267f74SRobert Watson #endif	/* HAVE_IPC_PERM___SEQ */
5923b97a967SRobert Watson 
5933b97a967SRobert Watson #ifdef HAVE_IPC_PERM___KEY
5943b97a967SRobert Watson 	ADD_U_INT32(dptr, perm->__key);
59552267f74SRobert Watson #else	/* HAVE_IPC_PERM___KEY */
59652267f74SRobert Watson #ifdef  HAVE_IPC_PERM__KEY
59752267f74SRobert Watson 	ADD_U_INT32(dptr, perm->_key);
59852267f74SRobert Watson #else	/* HAVE_IPC_PERM__KEY */
599ca0716f5SRobert Watson 	ADD_U_INT32(dptr, perm->key);
60052267f74SRobert Watson #endif	/* HAVE_IPC_PERM__KEY */
60152267f74SRobert Watson #endif	/* HAVE_IPC_PERM___KEY */
602ca0716f5SRobert Watson 
603ca0716f5SRobert Watson 	return (t);
604ca0716f5SRobert Watson }
605ca0716f5SRobert Watson 
606ca0716f5SRobert Watson /*
607ca0716f5SRobert Watson  * token ID                1 byte
608ca0716f5SRobert Watson  * port IP address         2 bytes
609ca0716f5SRobert Watson  */
610ca0716f5SRobert Watson token_t *
611ca0716f5SRobert Watson au_to_iport(u_int16_t iport)
612ca0716f5SRobert Watson {
613ca0716f5SRobert Watson 	token_t *t;
614ca0716f5SRobert Watson 	u_char *dptr = NULL;
615ca0716f5SRobert Watson 
616ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
617ca0716f5SRobert Watson 	if (t == NULL)
618ca0716f5SRobert Watson 		return (NULL);
619ca0716f5SRobert Watson 
620ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_IPORT);
621ca0716f5SRobert Watson 	ADD_U_INT16(dptr, iport);
622ca0716f5SRobert Watson 
623ca0716f5SRobert Watson 	return (t);
624ca0716f5SRobert Watson }
625ca0716f5SRobert Watson 
626ca0716f5SRobert Watson /*
627ca0716f5SRobert Watson  * token ID                1 byte
628ca0716f5SRobert Watson  * size                    2 bytes
629ca0716f5SRobert Watson  * data                    size bytes
630ca0716f5SRobert Watson  */
631ca0716f5SRobert Watson token_t *
63252267f74SRobert Watson au_to_opaque(const char *data, u_int16_t bytes)
633ca0716f5SRobert Watson {
634ca0716f5SRobert Watson 	token_t *t;
635ca0716f5SRobert Watson 	u_char *dptr = NULL;
636ca0716f5SRobert Watson 
637ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
638ca0716f5SRobert Watson 	if (t == NULL)
639ca0716f5SRobert Watson 		return (NULL);
640ca0716f5SRobert Watson 
641ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_OPAQUE);
642ca0716f5SRobert Watson 	ADD_U_INT16(dptr, bytes);
643ca0716f5SRobert Watson 	ADD_MEM(dptr, data, bytes);
644ca0716f5SRobert Watson 
645ca0716f5SRobert Watson 	return (t);
646ca0716f5SRobert Watson }
647ca0716f5SRobert Watson 
648ca0716f5SRobert Watson /*
649ca0716f5SRobert Watson  * token ID                1 byte
650ca0716f5SRobert Watson  * seconds of time         4 bytes
651ca0716f5SRobert Watson  * milliseconds of time    4 bytes
652ca0716f5SRobert Watson  * file name len           2 bytes
653ca0716f5SRobert Watson  * file pathname           N bytes + 1 terminating NULL byte
654ca0716f5SRobert Watson  */
655ca0716f5SRobert Watson token_t *
65652267f74SRobert Watson au_to_file(const char *file, struct timeval tm)
657ca0716f5SRobert Watson {
658ca0716f5SRobert Watson 	token_t *t;
659ca0716f5SRobert Watson 	u_char *dptr = NULL;
660ca0716f5SRobert Watson 	u_int16_t filelen;
661ca0716f5SRobert Watson 	u_int32_t timems;
662ca0716f5SRobert Watson 
663ca0716f5SRobert Watson 	filelen = strlen(file);
664ca0716f5SRobert Watson 	filelen += 1;
665ca0716f5SRobert Watson 
666ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
667ca0716f5SRobert Watson 	    sizeof(u_int16_t) + filelen);
668ca0716f5SRobert Watson 	if (t == NULL)
669ca0716f5SRobert Watson 		return (NULL);
670ca0716f5SRobert Watson 
671ca0716f5SRobert Watson 	timems = tm.tv_usec/1000;
672ca0716f5SRobert Watson 
673ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
674ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tm.tv_sec);
675ca0716f5SRobert Watson 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
676ca0716f5SRobert Watson 	ADD_U_INT16(dptr, filelen);
677ca0716f5SRobert Watson 	ADD_STRING(dptr, file, filelen);
678ca0716f5SRobert Watson 
679ca0716f5SRobert Watson 	return (t);
680ca0716f5SRobert Watson }
681ca0716f5SRobert Watson 
682ca0716f5SRobert Watson /*
683ca0716f5SRobert Watson  * token ID                1 byte
684ca0716f5SRobert Watson  * text length             2 bytes
685ca0716f5SRobert Watson  * text                    N bytes + 1 terminating NULL byte
686ca0716f5SRobert Watson  */
687ca0716f5SRobert Watson token_t *
68852267f74SRobert Watson au_to_text(const char *text)
689ca0716f5SRobert Watson {
690ca0716f5SRobert Watson 	token_t *t;
691ca0716f5SRobert Watson 	u_char *dptr = NULL;
692ca0716f5SRobert Watson 	u_int16_t textlen;
693ca0716f5SRobert Watson 
694ca0716f5SRobert Watson 	textlen = strlen(text);
695ca0716f5SRobert Watson 	textlen += 1;
696ca0716f5SRobert Watson 
6977a0a89d2SRobert Watson 	/* XXXRW: Should validate length against token size limit. */
6987a0a89d2SRobert Watson 
699ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
700ca0716f5SRobert Watson 	if (t == NULL)
701ca0716f5SRobert Watson 		return (NULL);
702ca0716f5SRobert Watson 
703ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_TEXT);
704ca0716f5SRobert Watson 	ADD_U_INT16(dptr, textlen);
705ca0716f5SRobert Watson 	ADD_STRING(dptr, text, textlen);
706ca0716f5SRobert Watson 
707ca0716f5SRobert Watson 	return (t);
708ca0716f5SRobert Watson }
709ca0716f5SRobert Watson 
710ca0716f5SRobert Watson /*
711ca0716f5SRobert Watson  * token ID                1 byte
712ca0716f5SRobert Watson  * path length             2 bytes
713ca0716f5SRobert Watson  * path                    N bytes + 1 terminating NULL byte
714ca0716f5SRobert Watson  */
715ca0716f5SRobert Watson token_t *
71652267f74SRobert Watson au_to_path(const char *text)
717ca0716f5SRobert Watson {
718ca0716f5SRobert Watson 	token_t *t;
719ca0716f5SRobert Watson 	u_char *dptr = NULL;
720ca0716f5SRobert Watson 	u_int16_t textlen;
721ca0716f5SRobert Watson 
722ca0716f5SRobert Watson 	textlen = strlen(text);
723ca0716f5SRobert Watson 	textlen += 1;
724ca0716f5SRobert Watson 
725ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
726ca0716f5SRobert Watson 	if (t == NULL)
727ca0716f5SRobert Watson 		return (NULL);
728ca0716f5SRobert Watson 
729ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_PATH);
730ca0716f5SRobert Watson 	ADD_U_INT16(dptr, textlen);
731ca0716f5SRobert Watson 	ADD_STRING(dptr, text, textlen);
732ca0716f5SRobert Watson 
733ca0716f5SRobert Watson 	return (t);
734ca0716f5SRobert Watson }
735ca0716f5SRobert Watson 
736ca0716f5SRobert Watson /*
737ca0716f5SRobert Watson  * token ID                1 byte
738ca0716f5SRobert Watson  * audit ID                4 bytes
739ca0716f5SRobert Watson  * effective user ID       4 bytes
740ca0716f5SRobert Watson  * effective group ID      4 bytes
741ca0716f5SRobert Watson  * real user ID            4 bytes
742ca0716f5SRobert Watson  * real group ID           4 bytes
743ca0716f5SRobert Watson  * process ID              4 bytes
744ca0716f5SRobert Watson  * session ID              4 bytes
745ca0716f5SRobert Watson  * terminal ID
746ca0716f5SRobert Watson  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
747ca0716f5SRobert Watson  *   machine address       4 bytes
748ca0716f5SRobert Watson  */
749ca0716f5SRobert Watson token_t *
750ca0716f5SRobert Watson au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
751ca0716f5SRobert Watson     pid_t pid, au_asid_t sid, au_tid_t *tid)
752ca0716f5SRobert Watson {
753ca0716f5SRobert Watson 	token_t *t;
754ca0716f5SRobert Watson 	u_char *dptr = NULL;
755ca0716f5SRobert Watson 
756ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
757ca0716f5SRobert Watson 	if (t == NULL)
758ca0716f5SRobert Watson 		return (NULL);
759ca0716f5SRobert Watson 
760ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_PROCESS32);
761ca0716f5SRobert Watson 	ADD_U_INT32(dptr, auid);
762ca0716f5SRobert Watson 	ADD_U_INT32(dptr, euid);
763ca0716f5SRobert Watson 	ADD_U_INT32(dptr, egid);
764ca0716f5SRobert Watson 	ADD_U_INT32(dptr, ruid);
765ca0716f5SRobert Watson 	ADD_U_INT32(dptr, rgid);
766ca0716f5SRobert Watson 	ADD_U_INT32(dptr, pid);
767ca0716f5SRobert Watson 	ADD_U_INT32(dptr, sid);
768ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tid->port);
7697a0a89d2SRobert Watson 
7707a0a89d2SRobert Watson 	/*
7717a0a89d2SRobert Watson 	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
7727a0a89d2SRobert Watson 	 * address type and 16 bytes of address, but for IPv4 addresses it
7737a0a89d2SRobert Watson 	 * simply writes the 4-byte address directly.  We support only IPv4
7747a0a89d2SRobert Watson 	 * addresses for process32 tokens.
7757a0a89d2SRobert Watson 	 */
776506764c6SRobert Watson 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
777ca0716f5SRobert Watson 
778ca0716f5SRobert Watson 	return (t);
779ca0716f5SRobert Watson }
780ca0716f5SRobert Watson 
781ca0716f5SRobert Watson token_t *
782bc168a6cSRobert Watson au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
783bc168a6cSRobert Watson     pid_t pid, au_asid_t sid, au_tid_t *tid)
784ca0716f5SRobert Watson {
785bc168a6cSRobert Watson 	token_t *t;
786bc168a6cSRobert Watson 	u_char *dptr = NULL;
787ca0716f5SRobert Watson 
788bc168a6cSRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
789bc168a6cSRobert Watson 	    sizeof(u_int64_t));
790bc168a6cSRobert Watson 	if (t == NULL)
791ca0716f5SRobert Watson 		return (NULL);
792bc168a6cSRobert Watson 
793bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUT_PROCESS64);
794bc168a6cSRobert Watson 	ADD_U_INT32(dptr, auid);
795bc168a6cSRobert Watson 	ADD_U_INT32(dptr, euid);
796bc168a6cSRobert Watson 	ADD_U_INT32(dptr, egid);
797bc168a6cSRobert Watson 	ADD_U_INT32(dptr, ruid);
798bc168a6cSRobert Watson 	ADD_U_INT32(dptr, rgid);
799bc168a6cSRobert Watson 	ADD_U_INT32(dptr, pid);
800bc168a6cSRobert Watson 	ADD_U_INT32(dptr, sid);
801bc168a6cSRobert Watson 	ADD_U_INT64(dptr, tid->port);
8027a0a89d2SRobert Watson 
8037a0a89d2SRobert Watson 	/*
8047a0a89d2SRobert Watson 	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
8057a0a89d2SRobert Watson 	 * address type and 16 bytes of address, but for IPv4 addresses it
8067a0a89d2SRobert Watson 	 * simply writes the 4-byte address directly.  We support only IPv4
8077a0a89d2SRobert Watson 	 * addresses for process64 tokens.
8087a0a89d2SRobert Watson 	 */
809bc168a6cSRobert Watson 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
810bc168a6cSRobert Watson 
811bc168a6cSRobert Watson 	return (t);
812ca0716f5SRobert Watson }
813ca0716f5SRobert Watson 
814ca0716f5SRobert Watson token_t *
815bc168a6cSRobert Watson au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
816bc168a6cSRobert Watson     pid_t pid, au_asid_t sid, au_tid_t *tid)
817ca0716f5SRobert Watson {
818ca0716f5SRobert Watson 
819ca0716f5SRobert Watson 	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
820ca0716f5SRobert Watson 	    tid));
821ca0716f5SRobert Watson }
822ca0716f5SRobert Watson 
823ca0716f5SRobert Watson /*
824ca0716f5SRobert Watson  * token ID                1 byte
825ca0716f5SRobert Watson  * audit ID                4 bytes
826ca0716f5SRobert Watson  * effective user ID       4 bytes
827ca0716f5SRobert Watson  * effective group ID      4 bytes
828ca0716f5SRobert Watson  * real user ID            4 bytes
829ca0716f5SRobert Watson  * real group ID           4 bytes
830ca0716f5SRobert Watson  * process ID              4 bytes
831ca0716f5SRobert Watson  * session ID              4 bytes
832ca0716f5SRobert Watson  * terminal ID
833ca0716f5SRobert Watson  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
834ca0716f5SRobert Watson  *   address type-len      4 bytes
835ca0716f5SRobert Watson  *   machine address      16 bytes
836ca0716f5SRobert Watson  */
837ca0716f5SRobert Watson token_t *
838ca0716f5SRobert Watson au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
839ca0716f5SRobert Watson     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
840ca0716f5SRobert Watson {
841ca0716f5SRobert Watson 	token_t *t;
842ca0716f5SRobert Watson 	u_char *dptr = NULL;
843ca0716f5SRobert Watson 
844d9af45c4SRobert Watson 	if (tid->at_type == AU_IPv4)
845d9af45c4SRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
846d9af45c4SRobert Watson 		    10 * sizeof(u_int32_t));
847d9af45c4SRobert Watson 	else if (tid->at_type == AU_IPv6)
848d9af45c4SRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
849d9af45c4SRobert Watson 		    13 * sizeof(u_int32_t));
850d9af45c4SRobert Watson 	else {
851d9af45c4SRobert Watson 		errno = EINVAL;
852d9af45c4SRobert Watson 		return (NULL);
853d9af45c4SRobert Watson 	}
854ca0716f5SRobert Watson 	if (t == NULL)
855ca0716f5SRobert Watson 		return (NULL);
856ca0716f5SRobert Watson 
857ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
858ca0716f5SRobert Watson 	ADD_U_INT32(dptr, auid);
859ca0716f5SRobert Watson 	ADD_U_INT32(dptr, euid);
860ca0716f5SRobert Watson 	ADD_U_INT32(dptr, egid);
861ca0716f5SRobert Watson 	ADD_U_INT32(dptr, ruid);
862ca0716f5SRobert Watson 	ADD_U_INT32(dptr, rgid);
863ca0716f5SRobert Watson 	ADD_U_INT32(dptr, pid);
864ca0716f5SRobert Watson 	ADD_U_INT32(dptr, sid);
865ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tid->at_port);
866ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tid->at_type);
867bc168a6cSRobert Watson 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
868d9af45c4SRobert Watson 	if (tid->at_type == AU_IPv6) {
869bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
870bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
871bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
872d9af45c4SRobert Watson 	}
873ca0716f5SRobert Watson 
874ca0716f5SRobert Watson 	return (t);
875ca0716f5SRobert Watson }
876ca0716f5SRobert Watson 
877ca0716f5SRobert Watson token_t *
878ca0716f5SRobert Watson au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
879ca0716f5SRobert Watson     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
880ca0716f5SRobert Watson {
881bc168a6cSRobert Watson 	token_t *t;
882bc168a6cSRobert Watson 	u_char *dptr = NULL;
883ca0716f5SRobert Watson 
884bc168a6cSRobert Watson 	if (tid->at_type == AU_IPv4)
885bc168a6cSRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
886bc168a6cSRobert Watson 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
887bc168a6cSRobert Watson 		    2 * sizeof(u_int32_t));
888bc168a6cSRobert Watson 	else if (tid->at_type == AU_IPv6)
889bc168a6cSRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
890bc168a6cSRobert Watson 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
891bc168a6cSRobert Watson 		    5 * sizeof(u_int32_t));
892bc168a6cSRobert Watson 	else {
893bc168a6cSRobert Watson 		errno = EINVAL;
894ca0716f5SRobert Watson 		return (NULL);
895ca0716f5SRobert Watson 	}
896bc168a6cSRobert Watson 	if (t == NULL)
897bc168a6cSRobert Watson 		return (NULL);
898bc168a6cSRobert Watson 
899bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
900bc168a6cSRobert Watson 	ADD_U_INT32(dptr, auid);
901bc168a6cSRobert Watson 	ADD_U_INT32(dptr, euid);
902bc168a6cSRobert Watson 	ADD_U_INT32(dptr, egid);
903bc168a6cSRobert Watson 	ADD_U_INT32(dptr, ruid);
904bc168a6cSRobert Watson 	ADD_U_INT32(dptr, rgid);
905bc168a6cSRobert Watson 	ADD_U_INT32(dptr, pid);
906bc168a6cSRobert Watson 	ADD_U_INT32(dptr, sid);
907bc168a6cSRobert Watson 	ADD_U_INT64(dptr, tid->at_port);
908bc168a6cSRobert Watson 	ADD_U_INT32(dptr, tid->at_type);
909bc168a6cSRobert Watson 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
910bc168a6cSRobert Watson 	if (tid->at_type == AU_IPv6) {
911bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
912bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
913bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
914bc168a6cSRobert Watson 	}
915bc168a6cSRobert Watson 
916bc168a6cSRobert Watson 	return (t);
917bc168a6cSRobert Watson }
918ca0716f5SRobert Watson 
919ca0716f5SRobert Watson token_t *
920ca0716f5SRobert Watson au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
921ca0716f5SRobert Watson     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
922ca0716f5SRobert Watson {
923ca0716f5SRobert Watson 
924ca0716f5SRobert Watson 	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
925ca0716f5SRobert Watson 	    tid));
926ca0716f5SRobert Watson }
927ca0716f5SRobert Watson 
928ca0716f5SRobert Watson /*
929ca0716f5SRobert Watson  * token ID                1 byte
930ca0716f5SRobert Watson  * error status            1 byte
931ca0716f5SRobert Watson  * return value            4 bytes/8 bytes (32-bit/64-bit value)
932ca0716f5SRobert Watson  */
933ca0716f5SRobert Watson token_t *
934ca0716f5SRobert Watson au_to_return32(char status, u_int32_t ret)
935ca0716f5SRobert Watson {
936ca0716f5SRobert Watson 	token_t *t;
937ca0716f5SRobert Watson 	u_char *dptr = NULL;
938ca0716f5SRobert Watson 
939ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
940ca0716f5SRobert Watson 	if (t == NULL)
941ca0716f5SRobert Watson 		return (NULL);
942ca0716f5SRobert Watson 
943ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_RETURN32);
944ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, status);
945ca0716f5SRobert Watson 	ADD_U_INT32(dptr, ret);
946ca0716f5SRobert Watson 
947ca0716f5SRobert Watson 	return (t);
948ca0716f5SRobert Watson }
949ca0716f5SRobert Watson 
950ca0716f5SRobert Watson token_t *
951ca0716f5SRobert Watson au_to_return64(char status, u_int64_t ret)
952ca0716f5SRobert Watson {
953ca0716f5SRobert Watson 	token_t *t;
954ca0716f5SRobert Watson 	u_char *dptr = NULL;
955ca0716f5SRobert Watson 
956ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
957ca0716f5SRobert Watson 	if (t == NULL)
958ca0716f5SRobert Watson 		return (NULL);
959ca0716f5SRobert Watson 
960ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_RETURN64);
961ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, status);
962ca0716f5SRobert Watson 	ADD_U_INT64(dptr, ret);
963ca0716f5SRobert Watson 
964ca0716f5SRobert Watson 	return (t);
965ca0716f5SRobert Watson }
966ca0716f5SRobert Watson 
967ca0716f5SRobert Watson token_t *
968ca0716f5SRobert Watson au_to_return(char status, u_int32_t ret)
969ca0716f5SRobert Watson {
970ca0716f5SRobert Watson 
971ca0716f5SRobert Watson 	return (au_to_return32(status, ret));
972ca0716f5SRobert Watson }
973ca0716f5SRobert Watson 
974ca0716f5SRobert Watson /*
975ca0716f5SRobert Watson  * token ID                1 byte
976ca0716f5SRobert Watson  * sequence number         4 bytes
977ca0716f5SRobert Watson  */
978ca0716f5SRobert Watson token_t *
979ca0716f5SRobert Watson au_to_seq(long audit_count)
980ca0716f5SRobert Watson {
981ca0716f5SRobert Watson 	token_t *t;
982ca0716f5SRobert Watson 	u_char *dptr = NULL;
983ca0716f5SRobert Watson 
984ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
985ca0716f5SRobert Watson 	if (t == NULL)
986ca0716f5SRobert Watson 		return (NULL);
987ca0716f5SRobert Watson 
988ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_SEQ);
989ca0716f5SRobert Watson 	ADD_U_INT32(dptr, audit_count);
990ca0716f5SRobert Watson 
991ca0716f5SRobert Watson 	return (t);
992ca0716f5SRobert Watson }
993ca0716f5SRobert Watson 
994ca0716f5SRobert Watson /*
995ca0716f5SRobert Watson  * token ID                1 byte
9967a0a89d2SRobert Watson  * socket domain           2 bytes
9977a0a89d2SRobert Watson  * socket type             2 bytes
9987a0a89d2SRobert Watson  * address type            2 byte
9997a0a89d2SRobert Watson  * local port              2 bytes
10007a0a89d2SRobert Watson  * local address           4 bytes/16 bytes (IPv4/IPv6 address)
10017a0a89d2SRobert Watson  * remote port             2 bytes
10027a0a89d2SRobert Watson  * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
1003c74c7b73SRobert Watson  *
1004c74c7b73SRobert Watson  * Domain and type arguments to this routine are assumed to already have been
1005c74c7b73SRobert Watson  * converted to the BSM constant space, so we don't do that here.
10067a0a89d2SRobert Watson  */
10077a0a89d2SRobert Watson token_t *
10087a0a89d2SRobert Watson au_to_socket_ex(u_short so_domain, u_short so_type,
10097a0a89d2SRobert Watson     struct sockaddr *sa_local, struct sockaddr *sa_remote)
10107a0a89d2SRobert Watson {
10117a0a89d2SRobert Watson 	token_t *t;
10127a0a89d2SRobert Watson 	u_char *dptr = NULL;
10137a0a89d2SRobert Watson 	struct sockaddr_in *sin;
10147a0a89d2SRobert Watson 	struct sockaddr_in6 *sin6;
10157a0a89d2SRobert Watson 
10167a0a89d2SRobert Watson 	if (so_domain == AF_INET)
10177a0a89d2SRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
10187a0a89d2SRobert Watson 		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
10197a0a89d2SRobert Watson 	else if (so_domain == AF_INET6)
10207a0a89d2SRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
102106edd2f1SRobert Watson 		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
10227a0a89d2SRobert Watson 	else {
10237a0a89d2SRobert Watson 		errno = EINVAL;
10247a0a89d2SRobert Watson 		return (NULL);
10257a0a89d2SRobert Watson 	}
1026*aa772005SRobert Watson 	if (t == NULL)
1027*aa772005SRobert Watson 		return (NULL);
10287a0a89d2SRobert Watson 
10297a0a89d2SRobert Watson 	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
103006edd2f1SRobert Watson 	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
103106edd2f1SRobert Watson 	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
10327a0a89d2SRobert Watson 	if (so_domain == AF_INET) {
10337a0a89d2SRobert Watson 		ADD_U_INT16(dptr, AU_IPv4);
10347a0a89d2SRobert Watson 		sin = (struct sockaddr_in *)sa_local;
10357a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
10367a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
10377a0a89d2SRobert Watson 		sin = (struct sockaddr_in *)sa_remote;
10387a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
10397a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
10407a0a89d2SRobert Watson 	} else {
10417a0a89d2SRobert Watson 		ADD_U_INT16(dptr, AU_IPv6);
10427a0a89d2SRobert Watson 		sin6 = (struct sockaddr_in6 *)sa_local;
10437a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
10447a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
10457a0a89d2SRobert Watson 		sin6 = (struct sockaddr_in6 *)sa_remote;
10467a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
10477a0a89d2SRobert Watson 		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
10487a0a89d2SRobert Watson 	}
10497a0a89d2SRobert Watson 
10507a0a89d2SRobert Watson 	return (t);
10517a0a89d2SRobert Watson }
10527a0a89d2SRobert Watson 
10537a0a89d2SRobert Watson /*
10547a0a89d2SRobert Watson  * token ID                1 byte
1055ca0716f5SRobert Watson  * socket family           2 bytes
1056597df30eSRobert Watson  * path                    (up to) 104 bytes + NULL  (NULL terminated string)
1057ca0716f5SRobert Watson  */
1058ca0716f5SRobert Watson token_t *
1059ca0716f5SRobert Watson au_to_sock_unix(struct sockaddr_un *so)
1060ca0716f5SRobert Watson {
1061ca0716f5SRobert Watson 	token_t *t;
1062ca0716f5SRobert Watson 	u_char *dptr;
1063ca0716f5SRobert Watson 
1064ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1065ca0716f5SRobert Watson 	if (t == NULL)
1066ca0716f5SRobert Watson 		return (NULL);
1067ca0716f5SRobert Watson 
106852267f74SRobert Watson 	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1069ca0716f5SRobert Watson 	/* BSM token has two bytes for family */
1070ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, 0);
1071ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, so->sun_family);
1072ca0716f5SRobert Watson 	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1073ca0716f5SRobert Watson 
1074ca0716f5SRobert Watson 	return (t);
1075ca0716f5SRobert Watson }
1076ca0716f5SRobert Watson 
1077ca0716f5SRobert Watson /*
1078ca0716f5SRobert Watson  * token ID                1 byte
1079ca0716f5SRobert Watson  * socket family           2 bytes
1080ca0716f5SRobert Watson  * local port              2 bytes
1081ca0716f5SRobert Watson  * socket address          4 bytes
1082ca0716f5SRobert Watson  */
1083ca0716f5SRobert Watson token_t *
1084ca0716f5SRobert Watson au_to_sock_inet32(struct sockaddr_in *so)
1085ca0716f5SRobert Watson {
1086ca0716f5SRobert Watson 	token_t *t;
1087ca0716f5SRobert Watson 	u_char *dptr = NULL;
1088506764c6SRobert Watson 	uint16_t family;
1089ca0716f5SRobert Watson 
1090506764c6SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1091506764c6SRobert Watson 	    sizeof(uint32_t));
1092ca0716f5SRobert Watson 	if (t == NULL)
1093ca0716f5SRobert Watson 		return (NULL);
1094ca0716f5SRobert Watson 
1095ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1096ca0716f5SRobert Watson 	/*
1097506764c6SRobert Watson 	 * BSM defines the family field as 16 bits, but many operating
1098506764c6SRobert Watson 	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1099506764c6SRobert Watson 	 * writing into the token.  Assume that both the port and the address
1100506764c6SRobert Watson 	 * in the sockaddr_in are already in network byte order, but family
1101506764c6SRobert Watson 	 * is in local byte order.
1102506764c6SRobert Watson 	 *
1103506764c6SRobert Watson 	 * XXXRW: Should a name space conversion be taking place on the value
1104506764c6SRobert Watson 	 * of sin_family?
1105ca0716f5SRobert Watson 	 */
1106506764c6SRobert Watson 	family = so->sin_family;
1107506764c6SRobert Watson 	ADD_U_INT16(dptr, family);
1108506764c6SRobert Watson 	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1109506764c6SRobert Watson 	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1110ca0716f5SRobert Watson 
1111ca0716f5SRobert Watson 	return (t);
1112ca0716f5SRobert Watson }
1113ca0716f5SRobert Watson 
1114ca0716f5SRobert Watson token_t *
1115ca0716f5SRobert Watson au_to_sock_inet128(struct sockaddr_in6 *so)
1116ca0716f5SRobert Watson {
1117ca0716f5SRobert Watson 	token_t *t;
1118ca0716f5SRobert Watson 	u_char *dptr = NULL;
1119ca0716f5SRobert Watson 
1120ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1121ca0716f5SRobert Watson 	    4 * sizeof(u_int32_t));
1122ca0716f5SRobert Watson 	if (t == NULL)
1123ca0716f5SRobert Watson 		return (NULL);
1124ca0716f5SRobert Watson 
1125ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1126ca0716f5SRobert Watson 	/*
11277a0a89d2SRobert Watson 	 * In BSD, sin6_family is one octet, but BSM defines the token to
11287a0a89d2SRobert Watson 	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
11297a0a89d2SRobert Watson 	 * conditionally compiled.
1130ca0716f5SRobert Watson 	 */
1131ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, 0);
1132ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, so->sin6_family);
1133ca0716f5SRobert Watson 
1134ca0716f5SRobert Watson 	ADD_U_INT16(dptr, so->sin6_port);
1135506764c6SRobert Watson 	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1136ca0716f5SRobert Watson 
1137ca0716f5SRobert Watson 	return (t);
1138ca0716f5SRobert Watson }
1139ca0716f5SRobert Watson 
1140ca0716f5SRobert Watson token_t *
1141ca0716f5SRobert Watson au_to_sock_inet(struct sockaddr_in *so)
1142ca0716f5SRobert Watson {
1143ca0716f5SRobert Watson 
1144ca0716f5SRobert Watson 	return (au_to_sock_inet32(so));
1145ca0716f5SRobert Watson }
1146ca0716f5SRobert Watson 
1147ca0716f5SRobert Watson /*
1148ca0716f5SRobert Watson  * token ID                1 byte
1149ca0716f5SRobert Watson  * audit ID                4 bytes
1150ca0716f5SRobert Watson  * effective user ID       4 bytes
1151ca0716f5SRobert Watson  * effective group ID      4 bytes
1152ca0716f5SRobert Watson  * real user ID            4 bytes
1153ca0716f5SRobert Watson  * real group ID           4 bytes
1154ca0716f5SRobert Watson  * process ID              4 bytes
1155ca0716f5SRobert Watson  * session ID              4 bytes
1156ca0716f5SRobert Watson  * terminal ID
1157ca0716f5SRobert Watson  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1158ca0716f5SRobert Watson  *   machine address       4 bytes
1159ca0716f5SRobert Watson  */
1160ca0716f5SRobert Watson token_t *
1161ca0716f5SRobert Watson au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1162ca0716f5SRobert Watson     pid_t pid, au_asid_t sid, au_tid_t *tid)
1163ca0716f5SRobert Watson {
1164ca0716f5SRobert Watson 	token_t *t;
1165ca0716f5SRobert Watson 	u_char *dptr = NULL;
1166ca0716f5SRobert Watson 
1167ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1168ca0716f5SRobert Watson 	if (t == NULL)
1169ca0716f5SRobert Watson 		return (NULL);
1170ca0716f5SRobert Watson 
1171ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1172ca0716f5SRobert Watson 	ADD_U_INT32(dptr, auid);
1173ca0716f5SRobert Watson 	ADD_U_INT32(dptr, euid);
1174ca0716f5SRobert Watson 	ADD_U_INT32(dptr, egid);
1175ca0716f5SRobert Watson 	ADD_U_INT32(dptr, ruid);
1176ca0716f5SRobert Watson 	ADD_U_INT32(dptr, rgid);
1177ca0716f5SRobert Watson 	ADD_U_INT32(dptr, pid);
1178ca0716f5SRobert Watson 	ADD_U_INT32(dptr, sid);
1179ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tid->port);
1180506764c6SRobert Watson 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1181ca0716f5SRobert Watson 
1182ca0716f5SRobert Watson 	return (t);
1183ca0716f5SRobert Watson }
1184ca0716f5SRobert Watson 
1185ca0716f5SRobert Watson token_t *
1186ca0716f5SRobert Watson au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1187ca0716f5SRobert Watson     pid_t pid, au_asid_t sid, au_tid_t *tid)
1188ca0716f5SRobert Watson {
1189bc168a6cSRobert Watson 	token_t *t;
1190bc168a6cSRobert Watson 	u_char *dptr = NULL;
1191ca0716f5SRobert Watson 
1192bc168a6cSRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1193bc168a6cSRobert Watson 	    sizeof(u_int64_t) + sizeof(u_int32_t));
1194bc168a6cSRobert Watson 	if (t == NULL)
1195ca0716f5SRobert Watson 		return (NULL);
1196bc168a6cSRobert Watson 
1197bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1198bc168a6cSRobert Watson 	ADD_U_INT32(dptr, auid);
1199bc168a6cSRobert Watson 	ADD_U_INT32(dptr, euid);
1200bc168a6cSRobert Watson 	ADD_U_INT32(dptr, egid);
1201bc168a6cSRobert Watson 	ADD_U_INT32(dptr, ruid);
1202bc168a6cSRobert Watson 	ADD_U_INT32(dptr, rgid);
1203bc168a6cSRobert Watson 	ADD_U_INT32(dptr, pid);
1204bc168a6cSRobert Watson 	ADD_U_INT32(dptr, sid);
1205bc168a6cSRobert Watson 	ADD_U_INT64(dptr, tid->port);
1206bc168a6cSRobert Watson 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1207bc168a6cSRobert Watson 
1208bc168a6cSRobert Watson 	return (t);
1209ca0716f5SRobert Watson }
1210ca0716f5SRobert Watson 
1211ca0716f5SRobert Watson token_t *
1212ca0716f5SRobert Watson au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1213ca0716f5SRobert Watson     pid_t pid, au_asid_t sid, au_tid_t *tid)
1214ca0716f5SRobert Watson {
1215ca0716f5SRobert Watson 
1216ca0716f5SRobert Watson 	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1217ca0716f5SRobert Watson 	    tid));
1218ca0716f5SRobert Watson }
1219ca0716f5SRobert Watson 
1220ca0716f5SRobert Watson /*
1221ca0716f5SRobert Watson  * token ID                1 byte
1222ca0716f5SRobert Watson  * audit ID                4 bytes
1223ca0716f5SRobert Watson  * effective user ID       4 bytes
1224ca0716f5SRobert Watson  * effective group ID      4 bytes
1225ca0716f5SRobert Watson  * real user ID            4 bytes
1226ca0716f5SRobert Watson  * real group ID           4 bytes
1227ca0716f5SRobert Watson  * process ID              4 bytes
1228ca0716f5SRobert Watson  * session ID              4 bytes
1229ca0716f5SRobert Watson  * terminal ID
1230ca0716f5SRobert Watson  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1231ca0716f5SRobert Watson  *   address type/length   4 bytes
1232ca0716f5SRobert Watson  *   machine address      16 bytes
1233ca0716f5SRobert Watson  */
1234ca0716f5SRobert Watson token_t *
1235ca0716f5SRobert Watson au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1236ca0716f5SRobert Watson     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1237ca0716f5SRobert Watson {
1238ca0716f5SRobert Watson 	token_t *t;
1239ca0716f5SRobert Watson 	u_char *dptr = NULL;
1240ca0716f5SRobert Watson 
1241d9af45c4SRobert Watson 	if (tid->at_type == AU_IPv4)
1242d9af45c4SRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1243d9af45c4SRobert Watson 		    sizeof(u_int32_t));
1244d9af45c4SRobert Watson 	else if (tid->at_type == AU_IPv6)
1245d9af45c4SRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1246d9af45c4SRobert Watson 		    sizeof(u_int32_t));
1247d9af45c4SRobert Watson 	else {
1248d9af45c4SRobert Watson 		errno = EINVAL;
1249d9af45c4SRobert Watson 		return (NULL);
1250d9af45c4SRobert Watson 	}
1251ca0716f5SRobert Watson 	if (t == NULL)
1252ca0716f5SRobert Watson 		return (NULL);
1253ca0716f5SRobert Watson 
1254ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1255ca0716f5SRobert Watson 	ADD_U_INT32(dptr, auid);
1256ca0716f5SRobert Watson 	ADD_U_INT32(dptr, euid);
1257ca0716f5SRobert Watson 	ADD_U_INT32(dptr, egid);
1258ca0716f5SRobert Watson 	ADD_U_INT32(dptr, ruid);
1259ca0716f5SRobert Watson 	ADD_U_INT32(dptr, rgid);
1260ca0716f5SRobert Watson 	ADD_U_INT32(dptr, pid);
1261ca0716f5SRobert Watson 	ADD_U_INT32(dptr, sid);
1262ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tid->at_port);
1263ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tid->at_type);
1264bc168a6cSRobert Watson 	if (tid->at_type == AU_IPv6)
1265bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1266bc168a6cSRobert Watson 	else
1267bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1268ca0716f5SRobert Watson 
1269ca0716f5SRobert Watson 	return (t);
1270ca0716f5SRobert Watson }
1271ca0716f5SRobert Watson 
1272ca0716f5SRobert Watson token_t *
1273ca0716f5SRobert Watson au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1274ca0716f5SRobert Watson     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1275ca0716f5SRobert Watson {
1276bc168a6cSRobert Watson 	token_t *t;
1277bc168a6cSRobert Watson 	u_char *dptr = NULL;
1278ca0716f5SRobert Watson 
1279bc168a6cSRobert Watson 	if (tid->at_type == AU_IPv4)
1280bc168a6cSRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1281bc168a6cSRobert Watson 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1282bc168a6cSRobert Watson 		    2 * sizeof(u_int32_t));
1283bc168a6cSRobert Watson 	else if (tid->at_type == AU_IPv6)
1284bc168a6cSRobert Watson 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1285bc168a6cSRobert Watson 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1286bc168a6cSRobert Watson 		    5 * sizeof(u_int32_t));
1287bc168a6cSRobert Watson 	else {
1288bc168a6cSRobert Watson 		errno = EINVAL;
1289ca0716f5SRobert Watson 		return (NULL);
1290ca0716f5SRobert Watson 	}
1291bc168a6cSRobert Watson 	if (t == NULL)
1292bc168a6cSRobert Watson 		return (NULL);
1293bc168a6cSRobert Watson 
1294bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1295bc168a6cSRobert Watson 	ADD_U_INT32(dptr, auid);
1296bc168a6cSRobert Watson 	ADD_U_INT32(dptr, euid);
1297bc168a6cSRobert Watson 	ADD_U_INT32(dptr, egid);
1298bc168a6cSRobert Watson 	ADD_U_INT32(dptr, ruid);
1299bc168a6cSRobert Watson 	ADD_U_INT32(dptr, rgid);
1300bc168a6cSRobert Watson 	ADD_U_INT32(dptr, pid);
1301bc168a6cSRobert Watson 	ADD_U_INT32(dptr, sid);
1302bc168a6cSRobert Watson 	ADD_U_INT64(dptr, tid->at_port);
1303bc168a6cSRobert Watson 	ADD_U_INT32(dptr, tid->at_type);
1304bc168a6cSRobert Watson 	if (tid->at_type == AU_IPv6)
1305bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1306bc168a6cSRobert Watson 	else
1307bc168a6cSRobert Watson 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1308bc168a6cSRobert Watson 
1309bc168a6cSRobert Watson 	return (t);
1310bc168a6cSRobert Watson }
1311ca0716f5SRobert Watson 
1312ca0716f5SRobert Watson token_t *
1313ca0716f5SRobert Watson au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1314ca0716f5SRobert Watson     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1315ca0716f5SRobert Watson {
1316ca0716f5SRobert Watson 
1317ca0716f5SRobert Watson 	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1318ca0716f5SRobert Watson 	    tid));
1319ca0716f5SRobert Watson }
1320ca0716f5SRobert Watson 
13213b97a967SRobert Watson #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1322ca0716f5SRobert Watson /*
132352267f74SRobert Watson  * Collects audit information for the current process and creates a subject
132452267f74SRobert Watson  * token from it.
1325ca0716f5SRobert Watson  */
1326ca0716f5SRobert Watson token_t *
1327ca0716f5SRobert Watson au_to_me(void)
1328ca0716f5SRobert Watson {
1329ca0716f5SRobert Watson 	auditinfo_t auinfo;
1330597df30eSRobert Watson 	auditinfo_addr_t aia;
1331ca0716f5SRobert Watson 
1332597df30eSRobert Watson 	/*
1333597df30eSRobert Watson 	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1334597df30eSRobert Watson 	 * it, then fall back on to getaudit(2).
1335597df30eSRobert Watson 	 */
1336597df30eSRobert Watson 	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1337597df30eSRobert Watson 		if (errno == ENOSYS) {
1338ca0716f5SRobert Watson 			if (getaudit(&auinfo) != 0)
1339ca0716f5SRobert Watson 				return (NULL);
1340597df30eSRobert Watson 			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1341597df30eSRobert Watson 				getegid(), getuid(), getgid(), getpid(),
1342597df30eSRobert Watson 				auinfo.ai_asid, &auinfo.ai_termid));
1343597df30eSRobert Watson 		} else {
1344597df30eSRobert Watson 			/* getaudit_addr(2) failed for some other reason. */
1345597df30eSRobert Watson 			return (NULL);
1346597df30eSRobert Watson 		}
1347597df30eSRobert Watson 	}
1348ca0716f5SRobert Watson 
1349597df30eSRobert Watson 	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1350597df30eSRobert Watson 		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1351ca0716f5SRobert Watson }
1352ca0716f5SRobert Watson #endif
1353ca0716f5SRobert Watson 
1354ca0716f5SRobert Watson /*
1355ca0716f5SRobert Watson  * token ID				1 byte
1356ca0716f5SRobert Watson  * count				4 bytes
1357ca0716f5SRobert Watson  * text					count null-terminated strings
1358ca0716f5SRobert Watson  */
1359ca0716f5SRobert Watson token_t *
136085feadf6SRobert Watson au_to_exec_args(char **argv)
1361ca0716f5SRobert Watson {
1362ca0716f5SRobert Watson 	token_t *t;
1363ca0716f5SRobert Watson 	u_char *dptr = NULL;
1364ca0716f5SRobert Watson 	const char *nextarg;
1365ca0716f5SRobert Watson 	int i, count = 0;
1366ca0716f5SRobert Watson 	size_t totlen = 0;
1367ca0716f5SRobert Watson 
136822ccb20dSRobert Watson 	nextarg = *argv;
1369ca0716f5SRobert Watson 
1370ca0716f5SRobert Watson 	while (nextarg != NULL) {
1371ca0716f5SRobert Watson 		int nextlen;
1372ca0716f5SRobert Watson 
1373ca0716f5SRobert Watson 		nextlen = strlen(nextarg);
1374ca0716f5SRobert Watson 		totlen += nextlen + 1;
1375ca0716f5SRobert Watson 		count++;
137622ccb20dSRobert Watson 		nextarg = *(argv + count);
1377ca0716f5SRobert Watson 	}
1378ca0716f5SRobert Watson 
1379ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1380ca0716f5SRobert Watson 	if (t == NULL)
1381ca0716f5SRobert Watson 		return (NULL);
1382ca0716f5SRobert Watson 
1383ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1384ca0716f5SRobert Watson 	ADD_U_INT32(dptr, count);
1385ca0716f5SRobert Watson 
1386ca0716f5SRobert Watson 	for (i = 0; i < count; i++) {
138722ccb20dSRobert Watson 		nextarg = *(argv + i);
1388ca0716f5SRobert Watson 		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1389ca0716f5SRobert Watson 	}
1390ca0716f5SRobert Watson 
1391ca0716f5SRobert Watson 	return (t);
1392ca0716f5SRobert Watson }
1393ca0716f5SRobert Watson 
1394ca0716f5SRobert Watson /*
1395ca0716f5SRobert Watson  * token ID				1 byte
1396ca0716f5SRobert Watson  * count				4 bytes
1397ca0716f5SRobert Watson  * text					count null-terminated strings
1398ca0716f5SRobert Watson  */
1399ca0716f5SRobert Watson token_t *
140085feadf6SRobert Watson au_to_exec_env(char **envp)
1401ca0716f5SRobert Watson {
1402ca0716f5SRobert Watson 	token_t *t;
1403ca0716f5SRobert Watson 	u_char *dptr = NULL;
1404ca0716f5SRobert Watson 	int i, count = 0;
1405ca0716f5SRobert Watson 	size_t totlen = 0;
1406ca0716f5SRobert Watson 	const char *nextenv;
1407ca0716f5SRobert Watson 
140822ccb20dSRobert Watson 	nextenv = *envp;
1409ca0716f5SRobert Watson 
1410ca0716f5SRobert Watson 	while (nextenv != NULL) {
1411ca0716f5SRobert Watson 		int nextlen;
1412ca0716f5SRobert Watson 
1413ca0716f5SRobert Watson 		nextlen = strlen(nextenv);
1414ca0716f5SRobert Watson 		totlen += nextlen + 1;
1415ca0716f5SRobert Watson 		count++;
141622ccb20dSRobert Watson 		nextenv = *(envp + count);
1417ca0716f5SRobert Watson 	}
1418ca0716f5SRobert Watson 
1419ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1420ca0716f5SRobert Watson 	if (t == NULL)
1421ca0716f5SRobert Watson 		return (NULL);
1422ca0716f5SRobert Watson 
1423ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1424ca0716f5SRobert Watson 	ADD_U_INT32(dptr, count);
1425ca0716f5SRobert Watson 
1426ca0716f5SRobert Watson 	for (i = 0; i < count; i++) {
142722ccb20dSRobert Watson 		nextenv = *(envp + i);
1428ca0716f5SRobert Watson 		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1429ca0716f5SRobert Watson 	}
1430ca0716f5SRobert Watson 
1431ca0716f5SRobert Watson 	return (t);
1432ca0716f5SRobert Watson }
1433ca0716f5SRobert Watson 
1434ca0716f5SRobert Watson /*
1435ca0716f5SRobert Watson  * token ID                1 byte
14367a0a89d2SRobert Watson  * zonename length         2 bytes
14377a0a89d2SRobert Watson  * zonename                N bytes + 1 terminating NULL byte
14387a0a89d2SRobert Watson  */
14397a0a89d2SRobert Watson token_t *
14407a0a89d2SRobert Watson au_to_zonename(const char *zonename)
14417a0a89d2SRobert Watson {
14427a0a89d2SRobert Watson 	u_char *dptr = NULL;
14437a0a89d2SRobert Watson 	u_int16_t textlen;
14447a0a89d2SRobert Watson 	token_t *t;
14457a0a89d2SRobert Watson 
14467a0a89d2SRobert Watson 	textlen = strlen(zonename) + 1;
14477a0a89d2SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
14487a0a89d2SRobert Watson 	if (t == NULL)
14497a0a89d2SRobert Watson 		return (NULL);
14507a0a89d2SRobert Watson 
14517a0a89d2SRobert Watson 	ADD_U_CHAR(dptr, AUT_ZONENAME);
14527a0a89d2SRobert Watson 	ADD_U_INT16(dptr, textlen);
14537a0a89d2SRobert Watson 	ADD_STRING(dptr, zonename, textlen);
14547a0a89d2SRobert Watson 	return (t);
14557a0a89d2SRobert Watson }
14567a0a89d2SRobert Watson 
14577a0a89d2SRobert Watson /*
14587a0a89d2SRobert Watson  * token ID                1 byte
1459ca0716f5SRobert Watson  * record byte count       4 bytes
1460ca0716f5SRobert Watson  * version #               1 byte    [2]
1461ca0716f5SRobert Watson  * event type              2 bytes
1462ca0716f5SRobert Watson  * event modifier          2 bytes
1463ca0716f5SRobert Watson  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1464ca0716f5SRobert Watson  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1465ca0716f5SRobert Watson  */
1466ca0716f5SRobert Watson token_t *
1467506764c6SRobert Watson au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1468ca0716f5SRobert Watson     struct timeval tm)
1469ca0716f5SRobert Watson {
1470ca0716f5SRobert Watson 	token_t *t;
1471ca0716f5SRobert Watson 	u_char *dptr = NULL;
1472ca0716f5SRobert Watson 	u_int32_t timems;
1473ca0716f5SRobert Watson 
1474ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1475ca0716f5SRobert Watson 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1476ca0716f5SRobert Watson 	if (t == NULL)
1477ca0716f5SRobert Watson 		return (NULL);
1478ca0716f5SRobert Watson 
1479ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_HEADER32);
1480ca0716f5SRobert Watson 	ADD_U_INT32(dptr, rec_size);
148122ccb20dSRobert Watson 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1482ca0716f5SRobert Watson 	ADD_U_INT16(dptr, e_type);
1483ca0716f5SRobert Watson 	ADD_U_INT16(dptr, e_mod);
1484ca0716f5SRobert Watson 
1485ca0716f5SRobert Watson 	timems = tm.tv_usec/1000;
1486ca0716f5SRobert Watson 	/* Add the timestamp */
1487ca0716f5SRobert Watson 	ADD_U_INT32(dptr, tm.tv_sec);
1488ca0716f5SRobert Watson 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1489ca0716f5SRobert Watson 
1490ca0716f5SRobert Watson 	return (t);
1491ca0716f5SRobert Watson }
1492ca0716f5SRobert Watson 
149352267f74SRobert Watson /*
149452267f74SRobert Watson  * token ID                1 byte
149552267f74SRobert Watson  * record byte count       4 bytes
149652267f74SRobert Watson  * version #               1 byte    [2]
149752267f74SRobert Watson  * event type              2 bytes
149852267f74SRobert Watson  * event modifier          2 bytes
149952267f74SRobert Watson  * address type/length     4 bytes
150052267f74SRobert Watson  * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
150152267f74SRobert Watson  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
150252267f74SRobert Watson  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
150352267f74SRobert Watson  */
150452267f74SRobert Watson token_t *
150552267f74SRobert Watson au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
150652267f74SRobert Watson     struct timeval tm, struct auditinfo_addr *aia)
150752267f74SRobert Watson {
150852267f74SRobert Watson 	token_t *t;
150952267f74SRobert Watson 	u_char *dptr = NULL;
15107a0a89d2SRobert Watson 	u_int32_t timems;
15117a0a89d2SRobert Watson 	au_tid_addr_t *tid;
151252267f74SRobert Watson 
15137a0a89d2SRobert Watson 	tid = &aia->ai_termid;
151452267f74SRobert Watson 	if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6)
151552267f74SRobert Watson 		return (NULL);
151652267f74SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
151752267f74SRobert Watson 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
151852267f74SRobert Watson 	    sizeof(u_int32_t) + tid->at_type);
151952267f74SRobert Watson 	if (t == NULL)
152052267f74SRobert Watson 		return (NULL);
152152267f74SRobert Watson 
152252267f74SRobert Watson 	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
152352267f74SRobert Watson 	ADD_U_INT32(dptr, rec_size);
152452267f74SRobert Watson 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
152552267f74SRobert Watson 	ADD_U_INT16(dptr, e_type);
152652267f74SRobert Watson 	ADD_U_INT16(dptr, e_mod);
152752267f74SRobert Watson 
152852267f74SRobert Watson 	ADD_U_INT32(dptr, tid->at_type);
152952267f74SRobert Watson 	if (tid->at_type == AU_IPv6)
153052267f74SRobert Watson 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
153152267f74SRobert Watson 	else
153252267f74SRobert Watson 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
153352267f74SRobert Watson 	timems = tm.tv_usec/1000;
153452267f74SRobert Watson 	/* Add the timestamp */
153552267f74SRobert Watson 	ADD_U_INT32(dptr, tm.tv_sec);
153652267f74SRobert Watson 	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
153752267f74SRobert Watson 
153852267f74SRobert Watson 	return (t);
153952267f74SRobert Watson }
154052267f74SRobert Watson 
1541bc168a6cSRobert Watson token_t *
1542bc168a6cSRobert Watson au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1543bc168a6cSRobert Watson     struct timeval tm)
1544bc168a6cSRobert Watson {
1545bc168a6cSRobert Watson 	token_t *t;
1546bc168a6cSRobert Watson 	u_char *dptr = NULL;
1547bc168a6cSRobert Watson 	u_int32_t timems;
1548bc168a6cSRobert Watson 
1549bc168a6cSRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1550bc168a6cSRobert Watson 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1551bc168a6cSRobert Watson 	if (t == NULL)
1552bc168a6cSRobert Watson 		return (NULL);
1553bc168a6cSRobert Watson 
1554bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUT_HEADER64);
1555bc168a6cSRobert Watson 	ADD_U_INT32(dptr, rec_size);
1556bc168a6cSRobert Watson 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1557bc168a6cSRobert Watson 	ADD_U_INT16(dptr, e_type);
1558bc168a6cSRobert Watson 	ADD_U_INT16(dptr, e_mod);
1559bc168a6cSRobert Watson 
1560bc168a6cSRobert Watson 	timems = tm.tv_usec/1000;
1561bc168a6cSRobert Watson 	/* Add the timestamp */
1562bc168a6cSRobert Watson 	ADD_U_INT64(dptr, tm.tv_sec);
1563bc168a6cSRobert Watson 	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1564bc168a6cSRobert Watson 
1565bc168a6cSRobert Watson 	return (t);
1566bc168a6cSRobert Watson }
1567bc168a6cSRobert Watson 
1568506764c6SRobert Watson #if !defined(KERNEL) && !defined(_KERNEL)
156952267f74SRobert Watson #ifdef HAVE_AUDIT_SYSCALLS
157052267f74SRobert Watson token_t *
157152267f74SRobert Watson au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
157252267f74SRobert Watson {
157352267f74SRobert Watson 	struct timeval tm;
157452267f74SRobert Watson 	struct auditinfo_addr aia;
157552267f74SRobert Watson 
157652267f74SRobert Watson 	if (gettimeofday(&tm, NULL) == -1)
157752267f74SRobert Watson 		return (NULL);
1578c0020399SRobert Watson 	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
157952267f74SRobert Watson 		if (errno != ENOSYS)
158052267f74SRobert Watson 			return (NULL);
158152267f74SRobert Watson 		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
158252267f74SRobert Watson 	}
158352267f74SRobert Watson 	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
158452267f74SRobert Watson }
158552267f74SRobert Watson #endif /* HAVE_AUDIT_SYSCALLS */
158652267f74SRobert Watson 
1587506764c6SRobert Watson token_t *
1588506764c6SRobert Watson au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1589506764c6SRobert Watson {
1590506764c6SRobert Watson 	struct timeval tm;
1591506764c6SRobert Watson 
1592506764c6SRobert Watson 	if (gettimeofday(&tm, NULL) == -1)
1593506764c6SRobert Watson 		return (NULL);
1594506764c6SRobert Watson 	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1595506764c6SRobert Watson }
1596506764c6SRobert Watson 
1597ca0716f5SRobert Watson token_t *
1598ca0716f5SRobert Watson au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1599ca0716f5SRobert Watson     __unused au_emod_t e_mod)
1600ca0716f5SRobert Watson {
1601bc168a6cSRobert Watson 	struct timeval tm;
1602ca0716f5SRobert Watson 
1603bc168a6cSRobert Watson 	if (gettimeofday(&tm, NULL) == -1)
1604ca0716f5SRobert Watson 		return (NULL);
1605bc168a6cSRobert Watson 	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1606ca0716f5SRobert Watson }
1607ca0716f5SRobert Watson 
1608ca0716f5SRobert Watson token_t *
1609ca0716f5SRobert Watson au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1610ca0716f5SRobert Watson {
1611ca0716f5SRobert Watson 
1612ca0716f5SRobert Watson 	return (au_to_header32(rec_size, e_type, e_mod));
1613ca0716f5SRobert Watson }
161452267f74SRobert Watson 
161552267f74SRobert Watson #ifdef HAVE_AUDIT_SYSCALLS
161652267f74SRobert Watson token_t *
161752267f74SRobert Watson au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
161852267f74SRobert Watson {
161952267f74SRobert Watson 
162052267f74SRobert Watson 	return (au_to_header32_ex(rec_size, e_type, e_mod));
162152267f74SRobert Watson }
162252267f74SRobert Watson #endif /* HAVE_AUDIT_SYSCALLS */
162352267f74SRobert Watson #endif /* !defined(KERNEL) && !defined(_KERNEL) */
1624ca0716f5SRobert Watson 
1625ca0716f5SRobert Watson /*
1626ca0716f5SRobert Watson  * token ID                1 byte
1627ca0716f5SRobert Watson  * trailer magic number    2 bytes
1628ca0716f5SRobert Watson  * record byte count       4 bytes
1629ca0716f5SRobert Watson  */
1630ca0716f5SRobert Watson token_t *
1631ca0716f5SRobert Watson au_to_trailer(int rec_size)
1632ca0716f5SRobert Watson {
1633ca0716f5SRobert Watson 	token_t *t;
1634ca0716f5SRobert Watson 	u_char *dptr = NULL;
16357a0a89d2SRobert Watson 	u_int16_t magic = AUT_TRAILER_MAGIC;
1636ca0716f5SRobert Watson 
1637ca0716f5SRobert Watson 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1638ca0716f5SRobert Watson 	    sizeof(u_int32_t));
1639ca0716f5SRobert Watson 	if (t == NULL)
1640ca0716f5SRobert Watson 		return (NULL);
1641ca0716f5SRobert Watson 
1642ca0716f5SRobert Watson 	ADD_U_CHAR(dptr, AUT_TRAILER);
1643ca0716f5SRobert Watson 	ADD_U_INT16(dptr, magic);
1644ca0716f5SRobert Watson 	ADD_U_INT32(dptr, rec_size);
1645ca0716f5SRobert Watson 
1646ca0716f5SRobert Watson 	return (t);
1647ca0716f5SRobert Watson }
1648