1181053Srwatson/*-
2187215Srwatson * Copyright (c) 2004-2009 Apple Inc.
3155192Srwatson * Copyright (c) 2005 SPARTA, Inc.
4155192Srwatson * All rights reserved.
5155192Srwatson *
6155192Srwatson * This code was developed in part by Robert N. M. Watson, Senior Principal
7155192Srwatson * Scientist, SPARTA, Inc.
8155192Srwatson *
9155192Srwatson * Redistribution and use in source and binary forms, with or without
10155192Srwatson * modification, are permitted provided that the following conditions
11155192Srwatson * are met:
12155192Srwatson * 1.  Redistributions of source code must retain the above copyright
13155192Srwatson *     notice, this list of conditions and the following disclaimer.
14155192Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
15155192Srwatson *     notice, this list of conditions and the following disclaimer in the
16155192Srwatson *     documentation and/or other materials provided with the distribution.
17180701Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
18155192Srwatson *     its contributors may be used to endorse or promote products derived
19155192Srwatson *     from this software without specific prior written permission.
20155192Srwatson *
21155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31155192Srwatson * POSSIBILITY OF SUCH DAMAGE.
32155192Srwatson */
33155192Srwatson
34178186Srwatson#include <sys/cdefs.h>
35178186Srwatson__FBSDID("$FreeBSD$");
36178186Srwatson
37196971Sphk#include <sys/param.h>
38155192Srwatson#include <sys/types.h>
39155192Srwatson#include <sys/endian.h>
40159259Srwatson#include <sys/queue.h>
41155192Srwatson#include <sys/socket.h>
42155192Srwatson#include <sys/time.h>
43155192Srwatson
44155192Srwatson#include <sys/ipc.h>
45155192Srwatson#include <sys/libkern.h>
46155192Srwatson#include <sys/malloc.h>
47155192Srwatson#include <sys/un.h>
48155192Srwatson
49155192Srwatson#include <netinet/in.h>
50155192Srwatson#include <netinet/in_systm.h>
51155192Srwatson#include <netinet/ip.h>
52155192Srwatson
53155192Srwatson
54155192Srwatson#include <bsm/audit.h>
55155192Srwatson#include <bsm/audit_internal.h>
56155192Srwatson#include <bsm/audit_record.h>
57155192Srwatson#include <security/audit/audit.h>
58155192Srwatson#include <security/audit/audit_private.h>
59155192Srwatson
60155192Srwatson#define	GET_TOKEN_AREA(t, dptr, length) do {				\
61155192Srwatson	t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);		\
62155192Srwatson	t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);	\
63155192Srwatson	t->len = length;						\
64155192Srwatson	dptr = t->t_data;						\
65155192Srwatson} while (0)
66155192Srwatson
67155192Srwatson/*
68155192Srwatson * token ID                1 byte
69243751Srwatson * success/failure         1 byte
70243751Srwatson * privstrlen              2 bytes
71243751Srwatson * privstr                 N bytes + 1 (\0 byte)
72243751Srwatson */
73243751Srwatsontoken_t *
74243751Srwatsonau_to_upriv(char sorf, char *priv)
75243751Srwatson{
76243751Srwatson	u_int16_t textlen;
77243751Srwatson	u_char *dptr;
78243751Srwatson	token_t *t;
79243751Srwatson
80243751Srwatson	textlen = strlen(priv) + 1;
81243751Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
82243751Srwatson	    sizeof(u_int16_t) + textlen);
83243751Srwatson
84243751Srwatson	ADD_U_CHAR(dptr, AUT_UPRIV);
85243751Srwatson	ADD_U_CHAR(dptr, sorf);
86243751Srwatson	ADD_U_INT16(dptr, textlen);
87243751Srwatson	ADD_STRING(dptr, priv, textlen);
88243751Srwatson	return (t);
89243751Srwatson}
90243751Srwatson
91243751Srwatson/*
92243751Srwatson * token ID		1 byte
93243751Srwatson * privtstrlen		2 bytes
94243751Srwatson * privtstr		N bytes + 1
95243751Srwatson * privstrlen		2 bytes
96243751Srwatson * privstr		N bytes + 1
97243751Srwatson */
98243751Srwatsontoken_t *
99243751Srwatsonau_to_privset(char *privtypestr, char *privstr)
100243751Srwatson{
101243751Srwatson	u_int16_t	 type_len, priv_len;
102243751Srwatson	u_char		*dptr;
103243751Srwatson	token_t		*t;
104243751Srwatson
105243751Srwatson	type_len = strlen(privtypestr) + 1;
106243751Srwatson	priv_len = strlen(privstr) + 1;
107243751Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
108243751Srwatson	    sizeof(u_int16_t) + type_len + priv_len);
109243751Srwatson
110243751Srwatson	ADD_U_CHAR(dptr, AUT_PRIV);
111243751Srwatson	ADD_U_INT16(dptr, type_len);
112243751Srwatson	ADD_STRING(dptr, privtypestr, type_len);
113243751Srwatson	ADD_U_INT16(dptr, priv_len);
114243751Srwatson	ADD_STRING(dptr, privstr, priv_len);
115243751Srwatson	return (t);
116243751Srwatson}
117243751Srwatson
118243751Srwatson/*
119243751Srwatson * token ID                1 byte
120155192Srwatson * argument #              1 byte
121155192Srwatson * argument value          4 bytes/8 bytes (32-bit/64-bit value)
122155192Srwatson * text length             2 bytes
123155192Srwatson * text                    N bytes + 1 terminating NULL byte
124155192Srwatson */
125155192Srwatsontoken_t *
126185573Srwatsonau_to_arg32(char n, const char *text, u_int32_t v)
127155192Srwatson{
128155192Srwatson	token_t *t;
129155192Srwatson	u_char *dptr = NULL;
130155192Srwatson	u_int16_t textlen;
131155192Srwatson
132155192Srwatson	textlen = strlen(text);
133155192Srwatson	textlen += 1;
134155192Srwatson
135155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
136155192Srwatson	    sizeof(u_int16_t) + textlen);
137155192Srwatson
138155192Srwatson	ADD_U_CHAR(dptr, AUT_ARG32);
139155192Srwatson	ADD_U_CHAR(dptr, n);
140155192Srwatson	ADD_U_INT32(dptr, v);
141155192Srwatson	ADD_U_INT16(dptr, textlen);
142155192Srwatson	ADD_STRING(dptr, text, textlen);
143155192Srwatson
144155192Srwatson	return (t);
145155192Srwatson}
146155192Srwatson
147155192Srwatsontoken_t *
148185573Srwatsonau_to_arg64(char n, const char *text, u_int64_t v)
149155192Srwatson{
150155192Srwatson	token_t *t;
151155192Srwatson	u_char *dptr = NULL;
152155192Srwatson	u_int16_t textlen;
153155192Srwatson
154155192Srwatson	textlen = strlen(text);
155155192Srwatson	textlen += 1;
156155192Srwatson
157155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
158155192Srwatson	    sizeof(u_int16_t) + textlen);
159155192Srwatson
160155192Srwatson	ADD_U_CHAR(dptr, AUT_ARG64);
161155192Srwatson	ADD_U_CHAR(dptr, n);
162155192Srwatson	ADD_U_INT64(dptr, v);
163155192Srwatson	ADD_U_INT16(dptr, textlen);
164155192Srwatson	ADD_STRING(dptr, text, textlen);
165155192Srwatson
166155192Srwatson	return (t);
167155192Srwatson}
168155192Srwatson
169155192Srwatsontoken_t *
170185573Srwatsonau_to_arg(char n, const char *text, u_int32_t v)
171155192Srwatson{
172155192Srwatson
173155192Srwatson	return (au_to_arg32(n, text, v));
174155192Srwatson}
175155192Srwatson
176155192Srwatson#if defined(_KERNEL) || defined(KERNEL)
177155192Srwatson/*
178155192Srwatson * token ID                1 byte
179155192Srwatson * file access mode        4 bytes
180155192Srwatson * owner user ID           4 bytes
181155192Srwatson * owner group ID          4 bytes
182155192Srwatson * file system ID          4 bytes
183155192Srwatson * node ID                 8 bytes
184155192Srwatson * device                  4 bytes/8 bytes (32-bit/64-bit)
185155192Srwatson */
186155192Srwatsontoken_t *
187155192Srwatsonau_to_attr32(struct vnode_au_info *vni)
188155192Srwatson{
189155192Srwatson	token_t *t;
190155192Srwatson	u_char *dptr = NULL;
191155192Srwatson	u_int16_t pad0_16 = 0;
192189279Srwatson	u_int32_t pad0_32 = 0;
193155192Srwatson
194155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
195155192Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
196155192Srwatson
197155192Srwatson	ADD_U_CHAR(dptr, AUT_ATTR32);
198155192Srwatson
199155192Srwatson	/*
200186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
201186647Srwatson	 * so pad with 0.
202186647Srwatson	 *
203186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
204186647Srwatson	 *
205186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
206155192Srwatson	 */
207155192Srwatson	ADD_U_INT16(dptr, pad0_16);
208155192Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
209155192Srwatson
210155192Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
211155192Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
212155192Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
213155192Srwatson
214155192Srwatson	/*
215181053Srwatson	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
216155192Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
217155192Srwatson	 * could pick this out at compile-time, it would be better, so as to
218155192Srwatson	 * avoid the else case below.
219155192Srwatson	 */
220155192Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
221155192Srwatson		ADD_U_INT32(dptr, pad0_32);
222155192Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
223155192Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
224155192Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
225155192Srwatson	else
226155192Srwatson		ADD_U_INT64(dptr, 0LL);
227155192Srwatson
228155192Srwatson	ADD_U_INT32(dptr, vni->vn_dev);
229155192Srwatson
230155192Srwatson	return (t);
231155192Srwatson}
232155192Srwatson
233155192Srwatsontoken_t *
234155192Srwatsonau_to_attr64(struct vnode_au_info *vni)
235155192Srwatson{
236168783Srwatson	token_t *t;
237168783Srwatson	u_char *dptr = NULL;
238168783Srwatson	u_int16_t pad0_16 = 0;
239189279Srwatson	u_int32_t pad0_32 = 0;
240155192Srwatson
241168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
242168783Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
243168783Srwatson
244168783Srwatson	ADD_U_CHAR(dptr, AUT_ATTR64);
245168783Srwatson
246168783Srwatson	/*
247186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
248186647Srwatson	 * so pad with 0.
249186647Srwatson	 *
250186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
251186647Srwatson	 *
252186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
253168783Srwatson	 */
254168783Srwatson	ADD_U_INT16(dptr, pad0_16);
255168783Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
256168783Srwatson
257168783Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
258168783Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
259168783Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
260168783Srwatson
261168783Srwatson	/*
262168783Srwatson	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
263168783Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
264168783Srwatson	 * could pick this out at compile-time, it would be better, so as to
265168783Srwatson	 * avoid the else case below.
266168783Srwatson	 */
267168783Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
268168783Srwatson		ADD_U_INT32(dptr, pad0_32);
269168783Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
270168783Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
271168783Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
272168783Srwatson	else
273168783Srwatson		ADD_U_INT64(dptr, 0LL);
274168783Srwatson
275168783Srwatson	ADD_U_INT64(dptr, vni->vn_dev);
276168783Srwatson
277168783Srwatson	return (t);
278155192Srwatson}
279155192Srwatson
280155192Srwatsontoken_t *
281155192Srwatsonau_to_attr(struct vnode_au_info *vni)
282155192Srwatson{
283155192Srwatson
284155192Srwatson	return (au_to_attr32(vni));
285155192Srwatson}
286155192Srwatson#endif /* !(defined(_KERNEL) || defined(KERNEL) */
287155192Srwatson
288155192Srwatson/*
289155192Srwatson * token ID                1 byte
290155192Srwatson * how to print            1 byte
291155192Srwatson * basic unit              1 byte
292155192Srwatson * unit count              1 byte
293155192Srwatson * data items              (depends on basic unit)
294155192Srwatson */
295155192Srwatsontoken_t *
296185573Srwatsonau_to_data(char unit_print, char unit_type, char unit_count, const char *p)
297155192Srwatson{
298155192Srwatson	token_t *t;
299155192Srwatson	u_char *dptr = NULL;
300155192Srwatson	size_t datasize, totdata;
301155192Srwatson
302155192Srwatson	/* Determine the size of the basic unit. */
303155192Srwatson	switch (unit_type) {
304155192Srwatson	case AUR_BYTE:
305159259Srwatson	/* case AUR_CHAR: */
306155192Srwatson		datasize = AUR_BYTE_SIZE;
307155192Srwatson		break;
308155192Srwatson
309155192Srwatson	case AUR_SHORT:
310155192Srwatson		datasize = AUR_SHORT_SIZE;
311155192Srwatson		break;
312155192Srwatson
313159259Srwatson	case AUR_INT32:
314159259Srwatson	/* case AUR_INT: */
315159259Srwatson		datasize = AUR_INT32_SIZE;
316155192Srwatson		break;
317155192Srwatson
318159259Srwatson	case AUR_INT64:
319159259Srwatson		datasize = AUR_INT64_SIZE;
320159259Srwatson		break;
321159259Srwatson
322155192Srwatson	default:
323180709Srwatson		return (NULL);
324155192Srwatson	}
325155192Srwatson
326155192Srwatson	totdata = datasize * unit_count;
327155192Srwatson
328159259Srwatson	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
329155192Srwatson
330186647Srwatson	/*
331186647Srwatson	 * XXXRW: We should be byte-swapping each data item for multi-byte
332186647Srwatson	 * types.
333186647Srwatson	 */
334155192Srwatson	ADD_U_CHAR(dptr, AUT_DATA);
335155192Srwatson	ADD_U_CHAR(dptr, unit_print);
336155192Srwatson	ADD_U_CHAR(dptr, unit_type);
337155192Srwatson	ADD_U_CHAR(dptr, unit_count);
338155192Srwatson	ADD_MEM(dptr, p, totdata);
339155192Srwatson
340155192Srwatson	return (t);
341155192Srwatson}
342155192Srwatson
343155192Srwatson
344155192Srwatson/*
345155192Srwatson * token ID                1 byte
346155192Srwatson * status		   4 bytes
347155192Srwatson * return value            4 bytes
348155192Srwatson */
349155192Srwatsontoken_t *
350155192Srwatsonau_to_exit(int retval, int err)
351155192Srwatson{
352155192Srwatson	token_t *t;
353155192Srwatson	u_char *dptr = NULL;
354155192Srwatson
355155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
356155192Srwatson
357155192Srwatson	ADD_U_CHAR(dptr, AUT_EXIT);
358155192Srwatson	ADD_U_INT32(dptr, err);
359155192Srwatson	ADD_U_INT32(dptr, retval);
360155192Srwatson
361155192Srwatson	return (t);
362155192Srwatson}
363155192Srwatson
364155192Srwatson/*
365155192Srwatson */
366155192Srwatsontoken_t *
367155192Srwatsonau_to_groups(int *groups)
368155192Srwatson{
369155192Srwatson
370185573Srwatson	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
371155192Srwatson}
372155192Srwatson
373155192Srwatson/*
374155192Srwatson * token ID                1 byte
375155192Srwatson * number groups           2 bytes
376155192Srwatson * group list              count * 4 bytes
377155192Srwatson */
378155192Srwatsontoken_t *
379155192Srwatsonau_to_newgroups(u_int16_t n, gid_t *groups)
380155192Srwatson{
381155192Srwatson	token_t *t;
382155192Srwatson	u_char *dptr = NULL;
383155192Srwatson	int i;
384155192Srwatson
385155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
386155192Srwatson	    n * sizeof(u_int32_t));
387155192Srwatson
388155192Srwatson	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
389155192Srwatson	ADD_U_INT16(dptr, n);
390155192Srwatson	for (i = 0; i < n; i++)
391155192Srwatson		ADD_U_INT32(dptr, groups[i]);
392155192Srwatson
393155192Srwatson	return (t);
394155192Srwatson}
395155192Srwatson
396155192Srwatson/*
397155192Srwatson * token ID                1 byte
398155192Srwatson * internet address        4 bytes
399155192Srwatson */
400155192Srwatsontoken_t *
401155192Srwatsonau_to_in_addr(struct in_addr *internet_addr)
402155192Srwatson{
403155192Srwatson	token_t *t;
404155192Srwatson	u_char *dptr = NULL;
405155192Srwatson
406159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
407155192Srwatson
408155192Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR);
409159259Srwatson	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
410155192Srwatson
411155192Srwatson	return (t);
412155192Srwatson}
413155192Srwatson
414155192Srwatson/*
415155192Srwatson * token ID                1 byte
416155192Srwatson * address type/length     4 bytes
417185573Srwatson * address                16 bytes
418155192Srwatson */
419155192Srwatsontoken_t *
420155192Srwatsonau_to_in_addr_ex(struct in6_addr *internet_addr)
421155192Srwatson{
422155192Srwatson	token_t *t;
423155192Srwatson	u_char *dptr = NULL;
424171066Scsjp	u_int32_t type = AU_IPv6;
425155192Srwatson
426159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
427155192Srwatson
428155192Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
429155192Srwatson	ADD_U_INT32(dptr, type);
430171066Scsjp	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
431155192Srwatson
432155192Srwatson	return (t);
433155192Srwatson}
434155192Srwatson
435155192Srwatson/*
436155192Srwatson * token ID                1 byte
437155192Srwatson * ip header		   20 bytes
438165604Srwatson *
439165604Srwatson * The IP header should be submitted in network byte order.
440155192Srwatson */
441155192Srwatsontoken_t *
442155192Srwatsonau_to_ip(struct ip *ip)
443155192Srwatson{
444155192Srwatson	token_t *t;
445155192Srwatson	u_char *dptr = NULL;
446155192Srwatson
447155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
448155192Srwatson
449155192Srwatson	ADD_U_CHAR(dptr, AUT_IP);
450155192Srwatson	ADD_MEM(dptr, ip, sizeof(struct ip));
451155192Srwatson
452155192Srwatson	return (t);
453155192Srwatson}
454155192Srwatson
455155192Srwatson/*
456155192Srwatson * token ID                1 byte
457155192Srwatson * object ID type          1 byte
458155192Srwatson * object ID               4 bytes
459155192Srwatson */
460155192Srwatsontoken_t *
461155192Srwatsonau_to_ipc(char type, int id)
462155192Srwatson{
463155192Srwatson	token_t *t;
464155192Srwatson	u_char *dptr = NULL;
465155192Srwatson
466155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
467155192Srwatson
468155192Srwatson	ADD_U_CHAR(dptr, AUT_IPC);
469155192Srwatson	ADD_U_CHAR(dptr, type);
470155192Srwatson	ADD_U_INT32(dptr, id);
471155192Srwatson
472155192Srwatson	return (t);
473155192Srwatson}
474155192Srwatson
475155192Srwatson/*
476155192Srwatson * token ID                1 byte
477155192Srwatson * owner user ID           4 bytes
478155192Srwatson * owner group ID          4 bytes
479155192Srwatson * creator user ID         4 bytes
480155192Srwatson * creator group ID        4 bytes
481155192Srwatson * access mode             4 bytes
482155192Srwatson * slot sequence #         4 bytes
483155192Srwatson * key                     4 bytes
484155192Srwatson */
485155192Srwatsontoken_t *
486155192Srwatsonau_to_ipc_perm(struct ipc_perm *perm)
487155192Srwatson{
488155192Srwatson	token_t *t;
489155192Srwatson	u_char *dptr = NULL;
490155192Srwatson	u_int16_t pad0 = 0;
491155192Srwatson
492189279Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
493189279Srwatson	    sizeof(u_int32_t));
494155192Srwatson
495155192Srwatson	ADD_U_CHAR(dptr, AUT_IPC_PERM);
496155192Srwatson
497155192Srwatson	/*
498186647Srwatson	 * Systems vary significantly in what types they use in struct
499186647Srwatson	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
500186647Srwatson	 * allow for that, as BSM define 32-bit values here.
501186647Srwatson	 * Some systems define the sizes for ipc_perm members as 2 bytes;
502186647Srwatson	 * BSM defines 4 so pad with 0.
503186647Srwatson	 *
504186647Srwatson	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
505186647Srwatson	 * need to be handled.
506155192Srwatson	 */
507186647Srwatson	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
508186647Srwatson		ADD_U_INT16(dptr, pad0);
509186647Srwatson		ADD_U_INT16(dptr, perm->uid);
510186647Srwatson		ADD_U_INT16(dptr, pad0);
511186647Srwatson		ADD_U_INT16(dptr, perm->gid);
512186647Srwatson		ADD_U_INT16(dptr, pad0);
513186647Srwatson		ADD_U_INT16(dptr, perm->cuid);
514186647Srwatson		ADD_U_INT16(dptr, pad0);
515186647Srwatson		ADD_U_INT16(dptr, perm->cgid);
516186647Srwatson	} else {
517186647Srwatson		ADD_U_INT32(dptr, perm->uid);
518186647Srwatson		ADD_U_INT32(dptr, perm->gid);
519186647Srwatson		ADD_U_INT32(dptr, perm->cuid);
520186647Srwatson		ADD_U_INT32(dptr, perm->cgid);
521186647Srwatson	}
522155192Srwatson
523155192Srwatson	ADD_U_INT16(dptr, pad0);
524186647Srwatson	ADD_U_INT16(dptr, perm->mode);
525155192Srwatson
526155192Srwatson	ADD_U_INT16(dptr, pad0);
527155192Srwatson
528155192Srwatson	ADD_U_INT16(dptr, perm->seq);
529155192Srwatson
530155192Srwatson	ADD_U_INT32(dptr, perm->key);
531155192Srwatson
532155192Srwatson	return (t);
533155192Srwatson}
534155192Srwatson
535155192Srwatson/*
536155192Srwatson * token ID                1 byte
537155192Srwatson * port IP address         2 bytes
538155192Srwatson */
539155192Srwatsontoken_t *
540155192Srwatsonau_to_iport(u_int16_t iport)
541155192Srwatson{
542155192Srwatson	token_t *t;
543155192Srwatson	u_char *dptr = NULL;
544155192Srwatson
545155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
546155192Srwatson
547155192Srwatson	ADD_U_CHAR(dptr, AUT_IPORT);
548155192Srwatson	ADD_U_INT16(dptr, iport);
549155192Srwatson
550155192Srwatson	return (t);
551155192Srwatson}
552155192Srwatson
553155192Srwatson/*
554155192Srwatson * token ID                1 byte
555155192Srwatson * size                    2 bytes
556155192Srwatson * data                    size bytes
557155192Srwatson */
558155192Srwatsontoken_t *
559185573Srwatsonau_to_opaque(const char *data, u_int16_t bytes)
560155192Srwatson{
561155192Srwatson	token_t *t;
562155192Srwatson	u_char *dptr = NULL;
563155192Srwatson
564155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
565155192Srwatson
566155192Srwatson	ADD_U_CHAR(dptr, AUT_OPAQUE);
567155192Srwatson	ADD_U_INT16(dptr, bytes);
568155192Srwatson	ADD_MEM(dptr, data, bytes);
569155192Srwatson
570155192Srwatson	return (t);
571155192Srwatson}
572155192Srwatson
573155192Srwatson/*
574155192Srwatson * token ID                1 byte
575155192Srwatson * seconds of time         4 bytes
576155192Srwatson * milliseconds of time    4 bytes
577155192Srwatson * file name len           2 bytes
578155192Srwatson * file pathname           N bytes + 1 terminating NULL byte
579155192Srwatson */
580155192Srwatsontoken_t *
581185573Srwatsonau_to_file(const char *file, struct timeval tm)
582155192Srwatson{
583155192Srwatson	token_t *t;
584155192Srwatson	u_char *dptr = NULL;
585155192Srwatson	u_int16_t filelen;
586155192Srwatson	u_int32_t timems;
587155192Srwatson
588155192Srwatson	filelen = strlen(file);
589155192Srwatson	filelen += 1;
590155192Srwatson
591155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
592155192Srwatson	    sizeof(u_int16_t) + filelen);
593155192Srwatson
594155192Srwatson	timems = tm.tv_usec/1000;
595155192Srwatson
596155192Srwatson	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
597155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
598155192Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
599155192Srwatson	ADD_U_INT16(dptr, filelen);
600155192Srwatson	ADD_STRING(dptr, file, filelen);
601155192Srwatson
602155192Srwatson	return (t);
603155192Srwatson}
604155192Srwatson
605155192Srwatson/*
606155192Srwatson * token ID                1 byte
607155192Srwatson * text length             2 bytes
608155192Srwatson * text                    N bytes + 1 terminating NULL byte
609155192Srwatson */
610155192Srwatsontoken_t *
611185573Srwatsonau_to_text(const char *text)
612155192Srwatson{
613155192Srwatson	token_t *t;
614155192Srwatson	u_char *dptr = NULL;
615155192Srwatson	u_int16_t textlen;
616155192Srwatson
617155192Srwatson	textlen = strlen(text);
618155192Srwatson	textlen += 1;
619155192Srwatson
620186647Srwatson	/* XXXRW: Should validate length against token size limit. */
621186647Srwatson
622155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
623155192Srwatson
624155192Srwatson	ADD_U_CHAR(dptr, AUT_TEXT);
625155192Srwatson	ADD_U_INT16(dptr, textlen);
626155192Srwatson	ADD_STRING(dptr, text, textlen);
627155192Srwatson
628155192Srwatson	return (t);
629155192Srwatson}
630155192Srwatson
631155192Srwatson/*
632155192Srwatson * token ID                1 byte
633155192Srwatson * path length             2 bytes
634155192Srwatson * path                    N bytes + 1 terminating NULL byte
635155192Srwatson */
636155192Srwatsontoken_t *
637185573Srwatsonau_to_path(const char *text)
638155192Srwatson{
639155192Srwatson	token_t *t;
640155192Srwatson	u_char *dptr = NULL;
641155192Srwatson	u_int16_t textlen;
642155192Srwatson
643155192Srwatson	textlen = strlen(text);
644155192Srwatson	textlen += 1;
645155192Srwatson
646155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
647155192Srwatson
648155192Srwatson	ADD_U_CHAR(dptr, AUT_PATH);
649155192Srwatson	ADD_U_INT16(dptr, textlen);
650155192Srwatson	ADD_STRING(dptr, text, textlen);
651155192Srwatson
652155192Srwatson	return (t);
653155192Srwatson}
654155192Srwatson
655155192Srwatson/*
656155192Srwatson * token ID                1 byte
657155192Srwatson * audit ID                4 bytes
658155192Srwatson * effective user ID       4 bytes
659155192Srwatson * effective group ID      4 bytes
660155192Srwatson * real user ID            4 bytes
661155192Srwatson * real group ID           4 bytes
662155192Srwatson * process ID              4 bytes
663155192Srwatson * session ID              4 bytes
664155192Srwatson * terminal ID
665155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
666155192Srwatson *   machine address       4 bytes
667155192Srwatson */
668155192Srwatsontoken_t *
669155192Srwatsonau_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
670155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
671155192Srwatson{
672155192Srwatson	token_t *t;
673155192Srwatson	u_char *dptr = NULL;
674155192Srwatson
675155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
676155192Srwatson
677155192Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32);
678155192Srwatson	ADD_U_INT32(dptr, auid);
679155192Srwatson	ADD_U_INT32(dptr, euid);
680155192Srwatson	ADD_U_INT32(dptr, egid);
681155192Srwatson	ADD_U_INT32(dptr, ruid);
682155192Srwatson	ADD_U_INT32(dptr, rgid);
683155192Srwatson	ADD_U_INT32(dptr, pid);
684155192Srwatson	ADD_U_INT32(dptr, sid);
685155192Srwatson	ADD_U_INT32(dptr, tid->port);
686186647Srwatson
687186647Srwatson	/*
688186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
689186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
690186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
691186647Srwatson	 * addresses for process32 tokens.
692186647Srwatson	 */
693159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
694155192Srwatson
695155192Srwatson	return (t);
696155192Srwatson}
697155192Srwatson
698155192Srwatsontoken_t *
699168783Srwatsonau_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
700168783Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
701155192Srwatson{
702168783Srwatson	token_t *t;
703168783Srwatson	u_char *dptr = NULL;
704155192Srwatson
705168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
706168783Srwatson	    sizeof(u_int64_t));
707168783Srwatson
708168783Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64);
709168783Srwatson	ADD_U_INT32(dptr, auid);
710168783Srwatson	ADD_U_INT32(dptr, euid);
711168783Srwatson	ADD_U_INT32(dptr, egid);
712168783Srwatson	ADD_U_INT32(dptr, ruid);
713168783Srwatson	ADD_U_INT32(dptr, rgid);
714168783Srwatson	ADD_U_INT32(dptr, pid);
715168783Srwatson	ADD_U_INT32(dptr, sid);
716168783Srwatson	ADD_U_INT64(dptr, tid->port);
717186647Srwatson
718186647Srwatson	/*
719186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
720186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
721186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
722186647Srwatson	 * addresses for process64 tokens.
723186647Srwatson	 */
724168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
725168783Srwatson
726168783Srwatson	return (t);
727155192Srwatson}
728155192Srwatson
729155192Srwatsontoken_t *
730168783Srwatsonau_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
731168783Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
732155192Srwatson{
733155192Srwatson
734155192Srwatson	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
735155192Srwatson	    tid));
736155192Srwatson}
737155192Srwatson
738155192Srwatson/*
739155192Srwatson * token ID                1 byte
740155192Srwatson * audit ID                4 bytes
741155192Srwatson * effective user ID       4 bytes
742155192Srwatson * effective group ID      4 bytes
743155192Srwatson * real user ID            4 bytes
744155192Srwatson * real group ID           4 bytes
745155192Srwatson * process ID              4 bytes
746155192Srwatson * session ID              4 bytes
747155192Srwatson * terminal ID
748155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
749155192Srwatson *   address type-len      4 bytes
750185573Srwatson *   machine address      16 bytes
751155192Srwatson */
752155192Srwatsontoken_t *
753155192Srwatsonau_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
754155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
755155192Srwatson{
756155192Srwatson	token_t *t;
757155192Srwatson	u_char *dptr = NULL;
758155192Srwatson
759168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
760168688Scsjp	    ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
761185573Srwatson	if (tid->at_type == AU_IPv4)
762185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
763185573Srwatson		    10 * sizeof(u_int32_t));
764159686Swsalamon	else
765185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
766185573Srwatson		    13 * sizeof(u_int32_t));
767155192Srwatson
768155192Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
769155192Srwatson	ADD_U_INT32(dptr, auid);
770155192Srwatson	ADD_U_INT32(dptr, euid);
771155192Srwatson	ADD_U_INT32(dptr, egid);
772155192Srwatson	ADD_U_INT32(dptr, ruid);
773155192Srwatson	ADD_U_INT32(dptr, rgid);
774155192Srwatson	ADD_U_INT32(dptr, pid);
775155192Srwatson	ADD_U_INT32(dptr, sid);
776155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
777155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
778185573Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
779185573Srwatson	if (tid->at_type == AU_IPv6) {
780185573Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
781185573Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
782185573Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
783185573Srwatson	}
784170131Srwatson
785155192Srwatson	return (t);
786155192Srwatson}
787155192Srwatson
788155192Srwatsontoken_t *
789155192Srwatsonau_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
790155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
791155192Srwatson{
792168783Srwatson	token_t *t;
793168783Srwatson	u_char *dptr = NULL;
794155192Srwatson
795168783Srwatson	if (tid->at_type == AU_IPv4)
796168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
797168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
798168783Srwatson		    2 * sizeof(u_int32_t));
799168783Srwatson	else if (tid->at_type == AU_IPv6)
800168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
801168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
802168783Srwatson		    5 * sizeof(u_int32_t));
803168783Srwatson	else
804168783Srwatson		panic("au_to_process64_ex: invalidate at_type (%d)",
805168783Srwatson		    tid->at_type);
806168783Srwatson
807168783Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
808168783Srwatson	ADD_U_INT32(dptr, auid);
809168783Srwatson	ADD_U_INT32(dptr, euid);
810168783Srwatson	ADD_U_INT32(dptr, egid);
811168783Srwatson	ADD_U_INT32(dptr, ruid);
812168783Srwatson	ADD_U_INT32(dptr, rgid);
813168783Srwatson	ADD_U_INT32(dptr, pid);
814168783Srwatson	ADD_U_INT32(dptr, sid);
815168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
816168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
817168783Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
818168783Srwatson	if (tid->at_type == AU_IPv6) {
819168783Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
820168783Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
821168783Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
822168783Srwatson	}
823168783Srwatson
824168783Srwatson	return (t);
825155192Srwatson}
826155192Srwatson
827155192Srwatsontoken_t *
828155192Srwatsonau_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
829155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
830155192Srwatson{
831155192Srwatson
832155192Srwatson	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
833155192Srwatson	    tid));
834155192Srwatson}
835155192Srwatson
836255219Spjdtoken_t *
837255219Spjdau_to_rights(cap_rights_t *rightsp)
838255219Spjd{
839255219Spjd	token_t *t;
840255219Spjd	u_char *dptr;
841255219Spjd	int i;
842255219Spjd
843255219Spjd	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(*rightsp));
844255219Spjd
845255219Spjd	ADD_U_CHAR(dptr, AUT_RIGHTS);
846255219Spjd	for (i = 0; i < nitems(rightsp->cr_rights); i++)
847255219Spjd		ADD_U_INT64(dptr, rightsp->cr_rights[i]);
848255219Spjd
849255219Spjd	return (t);
850255219Spjd}
851255219Spjd
852155192Srwatson/*
853155192Srwatson * token ID                1 byte
854155192Srwatson * error status            1 byte
855155192Srwatson * return value            4 bytes/8 bytes (32-bit/64-bit value)
856155192Srwatson */
857155192Srwatsontoken_t *
858155192Srwatsonau_to_return32(char status, u_int32_t ret)
859155192Srwatson{
860155192Srwatson	token_t *t;
861155192Srwatson	u_char *dptr = NULL;
862155192Srwatson
863155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
864155192Srwatson
865155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN32);
866155192Srwatson	ADD_U_CHAR(dptr, status);
867155192Srwatson	ADD_U_INT32(dptr, ret);
868155192Srwatson
869155192Srwatson	return (t);
870155192Srwatson}
871155192Srwatson
872155192Srwatsontoken_t *
873155192Srwatsonau_to_return64(char status, u_int64_t ret)
874155192Srwatson{
875155192Srwatson	token_t *t;
876155192Srwatson	u_char *dptr = NULL;
877155192Srwatson
878155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
879155192Srwatson
880155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN64);
881155192Srwatson	ADD_U_CHAR(dptr, status);
882155192Srwatson	ADD_U_INT64(dptr, ret);
883155192Srwatson
884155192Srwatson	return (t);
885155192Srwatson}
886155192Srwatson
887155192Srwatsontoken_t *
888155192Srwatsonau_to_return(char status, u_int32_t ret)
889155192Srwatson{
890155192Srwatson
891155192Srwatson	return (au_to_return32(status, ret));
892155192Srwatson}
893155192Srwatson
894155192Srwatson/*
895155192Srwatson * token ID                1 byte
896155192Srwatson * sequence number         4 bytes
897155192Srwatson */
898155192Srwatsontoken_t *
899155192Srwatsonau_to_seq(long audit_count)
900155192Srwatson{
901155192Srwatson	token_t *t;
902155192Srwatson	u_char *dptr = NULL;
903155192Srwatson
904155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
905155192Srwatson
906155192Srwatson	ADD_U_CHAR(dptr, AUT_SEQ);
907155192Srwatson	ADD_U_INT32(dptr, audit_count);
908155192Srwatson
909155192Srwatson	return (t);
910155192Srwatson}
911155192Srwatson
912155192Srwatson/*
913155192Srwatson * token ID                1 byte
914186647Srwatson * socket domain           2 bytes
915155192Srwatson * socket type             2 bytes
916186647Srwatson * address type            2 byte
917155192Srwatson * local port              2 bytes
918186647Srwatson * local address           4 bytes/16 bytes (IPv4/IPv6 address)
919155192Srwatson * remote port             2 bytes
920186647Srwatson * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
921187214Srwatson *
922187214Srwatson * Domain and type arguments to this routine are assumed to already have been
923187214Srwatson * converted to the BSM constant space, so we don't do that here.
924155192Srwatson */
925155192Srwatsontoken_t *
926186647Srwatsonau_to_socket_ex(u_short so_domain, u_short so_type,
927186647Srwatson    struct sockaddr *sa_local, struct sockaddr *sa_remote)
928155192Srwatson{
929186647Srwatson	token_t *t;
930186647Srwatson	u_char *dptr = NULL;
931186647Srwatson	struct sockaddr_in *sin;
932186647Srwatson	struct sockaddr_in6 *sin6;
933155192Srwatson
934186647Srwatson	if (so_domain == AF_INET)
935186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
936186647Srwatson		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
937186647Srwatson	else if (so_domain == AF_INET6)
938186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
939189279Srwatson		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
940186647Srwatson	else
941186647Srwatson		return (NULL);
942186647Srwatson
943186647Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
944189279Srwatson	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
945189279Srwatson	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
946186647Srwatson	if (so_domain == AF_INET) {
947186647Srwatson		ADD_U_INT16(dptr, AU_IPv4);
948186647Srwatson		sin = (struct sockaddr_in *)sa_local;
949186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
950186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
951186647Srwatson		sin = (struct sockaddr_in *)sa_remote;
952186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
953186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
954186647Srwatson	} else {
955186647Srwatson		ADD_U_INT16(dptr, AU_IPv6);
956186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_local;
957186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
958186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
959186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_remote;
960186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
961186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
962186647Srwatson	}
963186647Srwatson
964186647Srwatson	return (t);
965155192Srwatson}
966155192Srwatson
967155192Srwatson/*
968155192Srwatson * Kernel-specific version of the above function.
969186647Srwatson *
970186647Srwatson * XXXRW: Should now use au_to_socket_ex() here.
971155192Srwatson */
972155192Srwatson#ifdef _KERNEL
973155192Srwatsontoken_t *
974155192Srwatsonkau_to_socket(struct socket_au_info *soi)
975155192Srwatson{
976155192Srwatson	token_t *t;
977155192Srwatson	u_char *dptr;
978155192Srwatson	u_int16_t so_type;
979155192Srwatson
980155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
981155192Srwatson	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
982186647Srwatson
983185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET);
984155192Srwatson	/* Coerce the socket type into a short value */
985155192Srwatson	so_type = soi->so_type;
986155192Srwatson	ADD_U_INT16(dptr, so_type);
987155192Srwatson	ADD_U_INT16(dptr, soi->so_lport);
988155192Srwatson	ADD_U_INT32(dptr, soi->so_laddr);
989155192Srwatson	ADD_U_INT16(dptr, soi->so_rport);
990155192Srwatson	ADD_U_INT32(dptr, soi->so_raddr);
991155192Srwatson
992155192Srwatson	return (t);
993155192Srwatson}
994155192Srwatson#endif
995155192Srwatson
996155192Srwatson/*
997155192Srwatson * token ID                1 byte
998155192Srwatson * socket family           2 bytes
999195740Srwatson * path                    (up to) 104 bytes + NULL  (NULL terminated string)
1000155192Srwatson */
1001155192Srwatsontoken_t *
1002155192Srwatsonau_to_sock_unix(struct sockaddr_un *so)
1003155192Srwatson{
1004155192Srwatson	token_t *t;
1005155192Srwatson	u_char *dptr;
1006155192Srwatson
1007155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1008155192Srwatson
1009185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1010155192Srwatson	/* BSM token has two bytes for family */
1011155192Srwatson	ADD_U_CHAR(dptr, 0);
1012155192Srwatson	ADD_U_CHAR(dptr, so->sun_family);
1013155192Srwatson	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1014155192Srwatson
1015155192Srwatson	return (t);
1016155192Srwatson}
1017155192Srwatson
1018155192Srwatson/*
1019155192Srwatson * token ID                1 byte
1020155192Srwatson * socket family           2 bytes
1021155192Srwatson * local port              2 bytes
1022155192Srwatson * socket address          4 bytes
1023155192Srwatson */
1024155192Srwatsontoken_t *
1025155192Srwatsonau_to_sock_inet32(struct sockaddr_in *so)
1026155192Srwatson{
1027155192Srwatson	token_t *t;
1028155192Srwatson	u_char *dptr = NULL;
1029159259Srwatson	uint16_t family;
1030155192Srwatson
1031159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1032159259Srwatson	    sizeof(uint32_t));
1033155192Srwatson
1034155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1035155192Srwatson	/*
1036159259Srwatson	 * BSM defines the family field as 16 bits, but many operating
1037159259Srwatson	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1038159259Srwatson	 * writing into the token.  Assume that both the port and the address
1039159259Srwatson	 * in the sockaddr_in are already in network byte order, but family
1040159259Srwatson	 * is in local byte order.
1041159259Srwatson	 *
1042159259Srwatson	 * XXXRW: Should a name space conversion be taking place on the value
1043159259Srwatson	 * of sin_family?
1044180709Srwatson	 */
1045159259Srwatson	family = so->sin_family;
1046159259Srwatson	ADD_U_INT16(dptr, family);
1047159259Srwatson	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1048159259Srwatson	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1049155192Srwatson
1050155192Srwatson	return (t);
1051155192Srwatson}
1052155192Srwatson
1053155192Srwatsontoken_t *
1054155192Srwatsonau_to_sock_inet128(struct sockaddr_in6 *so)
1055155192Srwatson{
1056155192Srwatson	token_t *t;
1057155192Srwatson	u_char *dptr = NULL;
1058155192Srwatson
1059155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1060155192Srwatson	    4 * sizeof(u_int32_t));
1061155192Srwatson
1062155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1063155192Srwatson	/*
1064186647Srwatson	 * In BSD, sin6_family is one octet, but BSM defines the token to
1065186647Srwatson	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1066186647Srwatson	 * conditionally compiled.
1067180709Srwatson	 */
1068155192Srwatson	ADD_U_CHAR(dptr, 0);
1069155192Srwatson	ADD_U_CHAR(dptr, so->sin6_family);
1070155192Srwatson
1071155192Srwatson	ADD_U_INT16(dptr, so->sin6_port);
1072159259Srwatson	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1073155192Srwatson
1074155192Srwatson	return (t);
1075155192Srwatson}
1076155192Srwatson
1077155192Srwatsontoken_t *
1078155192Srwatsonau_to_sock_inet(struct sockaddr_in *so)
1079155192Srwatson{
1080155192Srwatson
1081155192Srwatson	return (au_to_sock_inet32(so));
1082155192Srwatson}
1083155192Srwatson
1084155192Srwatson/*
1085155192Srwatson * token ID                1 byte
1086155192Srwatson * audit ID                4 bytes
1087155192Srwatson * effective user ID       4 bytes
1088155192Srwatson * effective group ID      4 bytes
1089155192Srwatson * real user ID            4 bytes
1090155192Srwatson * real group ID           4 bytes
1091155192Srwatson * process ID              4 bytes
1092155192Srwatson * session ID              4 bytes
1093155192Srwatson * terminal ID
1094155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1095155192Srwatson *   machine address       4 bytes
1096155192Srwatson */
1097155192Srwatsontoken_t *
1098155192Srwatsonau_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1099155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1100155192Srwatson{
1101155192Srwatson	token_t *t;
1102155192Srwatson	u_char *dptr = NULL;
1103155192Srwatson
1104155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1105155192Srwatson
1106155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1107155192Srwatson	ADD_U_INT32(dptr, auid);
1108155192Srwatson	ADD_U_INT32(dptr, euid);
1109155192Srwatson	ADD_U_INT32(dptr, egid);
1110155192Srwatson	ADD_U_INT32(dptr, ruid);
1111155192Srwatson	ADD_U_INT32(dptr, rgid);
1112155192Srwatson	ADD_U_INT32(dptr, pid);
1113155192Srwatson	ADD_U_INT32(dptr, sid);
1114155192Srwatson	ADD_U_INT32(dptr, tid->port);
1115159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1116155192Srwatson
1117155192Srwatson	return (t);
1118155192Srwatson}
1119155192Srwatson
1120155192Srwatsontoken_t *
1121155192Srwatsonau_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1122155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1123155192Srwatson{
1124168783Srwatson	token_t *t;
1125168783Srwatson	u_char *dptr = NULL;
1126155192Srwatson
1127168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1128168783Srwatson	    sizeof(u_int64_t) + sizeof(u_int32_t));
1129168783Srwatson
1130168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1131168783Srwatson	ADD_U_INT32(dptr, auid);
1132168783Srwatson	ADD_U_INT32(dptr, euid);
1133168783Srwatson	ADD_U_INT32(dptr, egid);
1134168783Srwatson	ADD_U_INT32(dptr, ruid);
1135168783Srwatson	ADD_U_INT32(dptr, rgid);
1136168783Srwatson	ADD_U_INT32(dptr, pid);
1137168783Srwatson	ADD_U_INT32(dptr, sid);
1138168783Srwatson	ADD_U_INT64(dptr, tid->port);
1139168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1140168783Srwatson
1141168783Srwatson	return (t);
1142155192Srwatson}
1143155192Srwatson
1144155192Srwatsontoken_t *
1145155192Srwatsonau_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1146155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1147155192Srwatson{
1148155192Srwatson
1149155192Srwatson	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1150155192Srwatson	    tid));
1151155192Srwatson}
1152155192Srwatson
1153155192Srwatson/*
1154155192Srwatson * token ID                1 byte
1155155192Srwatson * audit ID                4 bytes
1156155192Srwatson * effective user ID       4 bytes
1157155192Srwatson * effective group ID      4 bytes
1158155192Srwatson * real user ID            4 bytes
1159155192Srwatson * real group ID           4 bytes
1160155192Srwatson * process ID              4 bytes
1161155192Srwatson * session ID              4 bytes
1162155192Srwatson * terminal ID
1163155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1164155192Srwatson *   address type/length   4 bytes
1165185573Srwatson *   machine address      16 bytes
1166155192Srwatson */
1167155192Srwatsontoken_t *
1168155192Srwatsonau_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1169155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1170155192Srwatson{
1171155192Srwatson	token_t *t;
1172155192Srwatson	u_char *dptr = NULL;
1173155192Srwatson
1174168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1175168688Scsjp	    ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1176185573Srwatson
1177185573Srwatson	if (tid->at_type == AU_IPv4)
1178185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1179159686Swsalamon		    sizeof(u_int32_t));
1180159686Swsalamon	else
1181185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1182159686Swsalamon		    sizeof(u_int32_t));
1183155192Srwatson
1184155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1185155192Srwatson	ADD_U_INT32(dptr, auid);
1186155192Srwatson	ADD_U_INT32(dptr, euid);
1187155192Srwatson	ADD_U_INT32(dptr, egid);
1188155192Srwatson	ADD_U_INT32(dptr, ruid);
1189155192Srwatson	ADD_U_INT32(dptr, rgid);
1190155192Srwatson	ADD_U_INT32(dptr, pid);
1191155192Srwatson	ADD_U_INT32(dptr, sid);
1192155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
1193155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
1194185573Srwatson	if (tid->at_type == AU_IPv6)
1195168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1196185573Srwatson	else
1197168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1198170131Srwatson
1199155192Srwatson	return (t);
1200155192Srwatson}
1201155192Srwatson
1202155192Srwatsontoken_t *
1203155192Srwatsonau_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1204155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1205155192Srwatson{
1206168783Srwatson	token_t *t;
1207168783Srwatson	u_char *dptr = NULL;
1208155192Srwatson
1209185573Srwatson	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1210185573Srwatson	    ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1211185573Srwatson
1212168783Srwatson	if (tid->at_type == AU_IPv4)
1213168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1214168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1215168783Srwatson		    2 * sizeof(u_int32_t));
1216185573Srwatson	else
1217168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1218168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1219168783Srwatson		    5 * sizeof(u_int32_t));
1220168783Srwatson
1221168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1222168783Srwatson	ADD_U_INT32(dptr, auid);
1223168783Srwatson	ADD_U_INT32(dptr, euid);
1224168783Srwatson	ADD_U_INT32(dptr, egid);
1225168783Srwatson	ADD_U_INT32(dptr, ruid);
1226168783Srwatson	ADD_U_INT32(dptr, rgid);
1227168783Srwatson	ADD_U_INT32(dptr, pid);
1228168783Srwatson	ADD_U_INT32(dptr, sid);
1229168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
1230168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
1231168783Srwatson	if (tid->at_type == AU_IPv6)
1232168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1233168783Srwatson	else
1234168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1235168783Srwatson
1236168783Srwatson	return (t);
1237155192Srwatson}
1238155192Srwatson
1239155192Srwatsontoken_t *
1240155192Srwatsonau_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1241155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1242155192Srwatson{
1243155192Srwatson
1244155192Srwatson	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1245155192Srwatson	    tid));
1246155192Srwatson}
1247155192Srwatson
1248156291Srwatson#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1249155192Srwatson/*
1250185573Srwatson * Collects audit information for the current process and creates a subject
1251185573Srwatson * token from it.
1252155192Srwatson */
1253155192Srwatsontoken_t *
1254155192Srwatsonau_to_me(void)
1255155192Srwatson{
1256155192Srwatson	auditinfo_t auinfo;
1257195740Srwatson	auditinfo_addr_t aia;
1258155192Srwatson
1259195740Srwatson	/*
1260195740Srwatson	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1261195740Srwatson	 * it, then fall back on to getaudit(2).
1262195740Srwatson	 */
1263195740Srwatson	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1264195740Srwatson		if (errno == ENOSYS) {
1265195740Srwatson			if (getaudit(&auinfo) != 0)
1266195740Srwatson				return (NULL);
1267195740Srwatson			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1268195740Srwatson				getegid(), getuid(), getgid(), getpid(),
1269195740Srwatson				auinfo.ai_asid, &auinfo.ai_termid));
1270195740Srwatson		} else {
1271195740Srwatson			/* getaudit_addr(2) failed for some other reason. */
1272243751Srwatson			return (NULL);
1273195740Srwatson		}
1274243751Srwatson	}
1275155192Srwatson
1276195740Srwatson	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1277195740Srwatson		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1278155192Srwatson}
1279155192Srwatson#endif
1280155192Srwatson
1281161813Swsalamon#if defined(_KERNEL) || defined(KERNEL)
1282161813Swsalamonstatic token_t *
1283161813Swsalamonau_to_exec_strings(char *strs, int count, u_char type)
1284161813Swsalamon{
1285161813Swsalamon	token_t *t;
1286161813Swsalamon	u_char *dptr = NULL;
1287161813Swsalamon	u_int32_t totlen;
1288161813Swsalamon	int ctr;
1289161813Swsalamon	char *p;
1290161813Swsalamon
1291161813Swsalamon	totlen = 0;
1292161813Swsalamon	ctr = count;
1293161813Swsalamon	p = strs;
1294161813Swsalamon	while (ctr-- > 0) {
1295161813Swsalamon		totlen += strlen(p) + 1;
1296161813Swsalamon		p = strs + totlen;
1297161813Swsalamon	}
1298161813Swsalamon	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1299161813Swsalamon	ADD_U_CHAR(dptr, type);
1300161813Swsalamon	ADD_U_INT32(dptr, count);
1301161813Swsalamon	ADD_STRING(dptr, strs, totlen);
1302161813Swsalamon
1303161813Swsalamon	return (t);
1304161813Swsalamon}
1305161813Swsalamon
1306155192Srwatson/*
1307155192Srwatson * token ID				1 byte
1308155192Srwatson * count				4 bytes
1309155192Srwatson * text					count null-terminated strings
1310155192Srwatson */
1311155192Srwatsontoken_t *
1312161813Swsalamonau_to_exec_args(char *args, int argc)
1313155192Srwatson{
1314162465Srwatson
1315161813Swsalamon	return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1316161813Swsalamon}
1317161813Swsalamon
1318161813Swsalamon/*
1319161813Swsalamon * token ID				1 byte
1320161813Swsalamon * count				4 bytes
1321161813Swsalamon * text					count null-terminated strings
1322161813Swsalamon */
1323161813Swsalamontoken_t *
1324161813Swsalamonau_to_exec_env(char *envs, int envc)
1325161813Swsalamon{
1326162465Srwatson
1327161813Swsalamon	return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1328161813Swsalamon}
1329161813Swsalamon#else
1330161813Swsalamon/*
1331161813Swsalamon * token ID				1 byte
1332161813Swsalamon * count				4 bytes
1333161813Swsalamon * text					count null-terminated strings
1334161813Swsalamon */
1335161813Swsalamontoken_t *
1336161813Swsalamonau_to_exec_args(char **argv)
1337161813Swsalamon{
1338155192Srwatson	token_t *t;
1339155192Srwatson	u_char *dptr = NULL;
1340155192Srwatson	const char *nextarg;
1341155192Srwatson	int i, count = 0;
1342155192Srwatson	size_t totlen = 0;
1343155192Srwatson
1344161813Swsalamon	nextarg = *argv;
1345155192Srwatson
1346155192Srwatson	while (nextarg != NULL) {
1347155192Srwatson		int nextlen;
1348155192Srwatson
1349155192Srwatson		nextlen = strlen(nextarg);
1350155192Srwatson		totlen += nextlen + 1;
1351155192Srwatson		count++;
1352161813Swsalamon		nextarg = *(argv + count);
1353155192Srwatson	}
1354155192Srwatson
1355155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1356155192Srwatson
1357155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1358155192Srwatson	ADD_U_INT32(dptr, count);
1359155192Srwatson
1360155192Srwatson	for (i = 0; i < count; i++) {
1361161813Swsalamon		nextarg = *(argv + i);
1362155192Srwatson		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1363155192Srwatson	}
1364155192Srwatson
1365155192Srwatson	return (t);
1366155192Srwatson}
1367155192Srwatson
1368155192Srwatson/*
1369155192Srwatson * token ID				1 byte
1370155192Srwatson * count				4 bytes
1371155192Srwatson * text					count null-terminated strings
1372155192Srwatson */
1373155192Srwatsontoken_t *
1374161813Swsalamonau_to_exec_env(char **envp)
1375155192Srwatson{
1376155192Srwatson	token_t *t;
1377155192Srwatson	u_char *dptr = NULL;
1378155192Srwatson	int i, count = 0;
1379155192Srwatson	size_t totlen = 0;
1380155192Srwatson	const char *nextenv;
1381155192Srwatson
1382161813Swsalamon	nextenv = *envp;
1383155192Srwatson
1384155192Srwatson	while (nextenv != NULL) {
1385155192Srwatson		int nextlen;
1386155192Srwatson
1387155192Srwatson		nextlen = strlen(nextenv);
1388155192Srwatson		totlen += nextlen + 1;
1389155192Srwatson		count++;
1390161813Swsalamon		nextenv = *(envp + count);
1391155192Srwatson	}
1392155192Srwatson
1393155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1394155192Srwatson
1395155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1396155192Srwatson	ADD_U_INT32(dptr, count);
1397155192Srwatson
1398155192Srwatson	for (i = 0; i < count; i++) {
1399161813Swsalamon		nextenv = *(envp + i);
1400155192Srwatson		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1401155192Srwatson	}
1402155192Srwatson
1403155192Srwatson	return (t);
1404155192Srwatson}
1405161813Swsalamon#endif
1406155192Srwatson
1407155192Srwatson/*
1408155192Srwatson * token ID                1 byte
1409186647Srwatson * zonename length         2 bytes
1410186647Srwatson * zonename                N bytes + 1 terminating NULL byte
1411186647Srwatson */
1412186647Srwatsontoken_t *
1413186647Srwatsonau_to_zonename(const char *zonename)
1414186647Srwatson{
1415186647Srwatson	u_char *dptr = NULL;
1416186647Srwatson	u_int16_t textlen;
1417186647Srwatson	token_t *t;
1418186647Srwatson
1419186647Srwatson	textlen = strlen(zonename) + 1;
1420186647Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1421186647Srwatson
1422186647Srwatson	ADD_U_CHAR(dptr, AUT_ZONENAME);
1423186647Srwatson	ADD_U_INT16(dptr, textlen);
1424186647Srwatson	ADD_STRING(dptr, zonename, textlen);
1425186647Srwatson	return (t);
1426186647Srwatson}
1427186647Srwatson
1428186647Srwatson/*
1429186647Srwatson * token ID                1 byte
1430155192Srwatson * record byte count       4 bytes
1431185573Srwatson * version #               1 byte    [2]
1432184856Scsjp * event type              2 bytes
1433184856Scsjp * event modifier          2 bytes
1434185573Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1435185573Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1436184856Scsjp */
1437184856Scsjptoken_t *
1438185573Srwatsonau_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1439185573Srwatson    struct timeval tm)
1440184856Scsjp{
1441185573Srwatson	token_t *t;
1442184856Scsjp	u_char *dptr = NULL;
1443184856Scsjp	u_int32_t timems;
1444184856Scsjp
1445184856Scsjp	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1446185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1447184856Scsjp
1448185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32);
1449184856Scsjp	ADD_U_INT32(dptr, rec_size);
1450184856Scsjp	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1451184856Scsjp	ADD_U_INT16(dptr, e_type);
1452184856Scsjp	ADD_U_INT16(dptr, e_mod);
1453185573Srwatson
1454185573Srwatson	timems = tm.tv_usec/1000;
1455184856Scsjp	/* Add the timestamp */
1456184856Scsjp	ADD_U_INT32(dptr, tm.tv_sec);
1457185573Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1458185573Srwatson
1459184856Scsjp	return (t);
1460184856Scsjp}
1461184856Scsjp
1462184856Scsjp/*
1463184856Scsjp * token ID                1 byte
1464184856Scsjp * record byte count       4 bytes
1465155192Srwatson * version #               1 byte    [2]
1466155192Srwatson * event type              2 bytes
1467155192Srwatson * event modifier          2 bytes
1468185573Srwatson * address type/length     4 bytes
1469185573Srwatson * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1470155192Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1471155192Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1472155192Srwatson */
1473155192Srwatsontoken_t *
1474185573Srwatsonau_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1475185573Srwatson    struct timeval tm, struct auditinfo_addr *aia)
1476155192Srwatson{
1477155192Srwatson	token_t *t;
1478155192Srwatson	u_char *dptr = NULL;
1479155192Srwatson	u_int32_t timems;
1480185573Srwatson	au_tid_addr_t *tid;
1481155192Srwatson
1482185573Srwatson	tid = &aia->ai_termid;
1483185573Srwatson	KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1484185573Srwatson	    ("au_to_header32_ex_tm: invalid address family"));
1485185573Srwatson
1486155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1487185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1488185573Srwatson	    sizeof(u_int32_t) + tid->at_type);
1489155192Srwatson
1490185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1491155192Srwatson	ADD_U_INT32(dptr, rec_size);
1492161635Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1493155192Srwatson	ADD_U_INT16(dptr, e_type);
1494155192Srwatson	ADD_U_INT16(dptr, e_mod);
1495155192Srwatson
1496185573Srwatson	ADD_U_INT32(dptr, tid->at_type);
1497185573Srwatson	if (tid->at_type == AU_IPv6)
1498185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1499185573Srwatson	else
1500185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1501155192Srwatson	timems = tm.tv_usec/1000;
1502155192Srwatson	/* Add the timestamp */
1503155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1504185573Srwatson	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1505155192Srwatson
1506243751Srwatson	return (t);
1507155192Srwatson}
1508155192Srwatson
1509168783Srwatsontoken_t *
1510168783Srwatsonau_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1511168783Srwatson    struct timeval tm)
1512168783Srwatson{
1513168783Srwatson	token_t *t;
1514168783Srwatson	u_char *dptr = NULL;
1515168783Srwatson	u_int32_t timems;
1516168783Srwatson
1517168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1518168783Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1519168783Srwatson
1520168783Srwatson	ADD_U_CHAR(dptr, AUT_HEADER64);
1521168783Srwatson	ADD_U_INT32(dptr, rec_size);
1522168783Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1523168783Srwatson	ADD_U_INT16(dptr, e_type);
1524168783Srwatson	ADD_U_INT16(dptr, e_mod);
1525168783Srwatson
1526168783Srwatson	timems = tm.tv_usec/1000;
1527168783Srwatson	/* Add the timestamp */
1528168783Srwatson	ADD_U_INT64(dptr, tm.tv_sec);
1529168783Srwatson	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1530168783Srwatson
1531168783Srwatson	return (t);
1532168783Srwatson}
1533168783Srwatson
1534185573Srwatson#if !defined(KERNEL) && !defined(_KERNEL)
1535185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1536185573Srwatsontoken_t *
1537185573Srwatsonau_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1538185573Srwatson{
1539185573Srwatson	struct timeval tm;
1540185573Srwatson	struct auditinfo_addr aia;
1541185573Srwatson
1542185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1543185573Srwatson		return (NULL);
1544191270Srwatson	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1545185573Srwatson		if (errno != ENOSYS)
1546185573Srwatson			return (NULL);
1547185573Srwatson		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1548185573Srwatson	}
1549185573Srwatson	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1550185573Srwatson}
1551185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1552185573Srwatson
1553185573Srwatsontoken_t *
1554185573Srwatsonau_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1555185573Srwatson{
1556185573Srwatson	struct timeval tm;
1557185573Srwatson
1558185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1559185573Srwatson		return (NULL);
1560185573Srwatson	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1561185573Srwatson}
1562185573Srwatson
1563185573Srwatsontoken_t *
1564185573Srwatsonau_to_header64(__unused int rec_size, __unused au_event_t e_type,
1565185573Srwatson    __unused au_emod_t e_mod)
1566185573Srwatson{
1567185573Srwatson	struct timeval tm;
1568185573Srwatson
1569185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1570185573Srwatson		return (NULL);
1571185573Srwatson	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1572185573Srwatson}
1573185573Srwatson
1574185573Srwatsontoken_t *
1575185573Srwatsonau_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1576185573Srwatson{
1577185573Srwatson
1578185573Srwatson	return (au_to_header32(rec_size, e_type, e_mod));
1579185573Srwatson}
1580185573Srwatson
1581185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1582185573Srwatsontoken_t *
1583185573Srwatsonau_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1584185573Srwatson{
1585185573Srwatson
1586185573Srwatson	return (au_to_header32_ex(rec_size, e_type, e_mod));
1587185573Srwatson}
1588185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1589185573Srwatson#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1590185573Srwatson
1591155192Srwatson/*
1592155192Srwatson * token ID                1 byte
1593155192Srwatson * trailer magic number    2 bytes
1594155192Srwatson * record byte count       4 bytes
1595155192Srwatson */
1596155192Srwatsontoken_t *
1597155192Srwatsonau_to_trailer(int rec_size)
1598155192Srwatson{
1599155192Srwatson	token_t *t;
1600155192Srwatson	u_char *dptr = NULL;
1601186647Srwatson	u_int16_t magic = AUT_TRAILER_MAGIC;
1602155192Srwatson
1603155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1604155192Srwatson	    sizeof(u_int32_t));
1605155192Srwatson
1606155192Srwatson	ADD_U_CHAR(dptr, AUT_TRAILER);
1607155192Srwatson	ADD_U_INT16(dptr, magic);
1608155192Srwatson	ADD_U_INT32(dptr, rec_size);
1609155192Srwatson
1610155192Srwatson	return (t);
1611155192Srwatson}
1612