1181053Srwatson/*-
2187215Srwatson * Copyright (c) 2004-2009 Apple Inc.
3155192Srwatson * Copyright (c) 2005 SPARTA, Inc.
4155192Srwatson * All rights reserved.
5155192Srwatson *
6155192Srwatson * This code was developed in part by Robert N. M. Watson, Senior Principal
7155192Srwatson * Scientist, SPARTA, Inc.
8155192Srwatson *
9155192Srwatson * Redistribution and use in source and binary forms, with or without
10155192Srwatson * modification, are permitted provided that the following conditions
11155192Srwatson * are met:
12155192Srwatson * 1.  Redistributions of source code must retain the above copyright
13155192Srwatson *     notice, this list of conditions and the following disclaimer.
14155192Srwatson * 2.  Redistributions in binary form must reproduce the above copyright
15155192Srwatson *     notice, this list of conditions and the following disclaimer in the
16155192Srwatson *     documentation and/or other materials provided with the distribution.
17180701Srwatson * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
18155192Srwatson *     its contributors may be used to endorse or promote products derived
19155192Srwatson *     from this software without specific prior written permission.
20155192Srwatson *
21155192Srwatson * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22155192Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23155192Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24155192Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25155192Srwatson * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26155192Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27155192Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28155192Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29155192Srwatson * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30155192Srwatson * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31155192Srwatson * POSSIBILITY OF SUCH DAMAGE.
32185573Srwatson *
33243751Srwatson * P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#99
34155192Srwatson */
35155192Srwatson
36178186Srwatson#include <sys/cdefs.h>
37178186Srwatson__FBSDID("$FreeBSD$");
38178186Srwatson
39196971Sphk#include <sys/param.h>
40155192Srwatson#include <sys/types.h>
41155192Srwatson#include <sys/endian.h>
42159259Srwatson#include <sys/queue.h>
43155192Srwatson#include <sys/socket.h>
44155192Srwatson#include <sys/time.h>
45155192Srwatson
46155192Srwatson#include <sys/ipc.h>
47155192Srwatson#include <sys/libkern.h>
48155192Srwatson#include <sys/malloc.h>
49155192Srwatson#include <sys/un.h>
50155192Srwatson
51155192Srwatson#include <netinet/in.h>
52155192Srwatson#include <netinet/in_systm.h>
53155192Srwatson#include <netinet/ip.h>
54155192Srwatson
55155192Srwatson
56155192Srwatson#include <bsm/audit.h>
57155192Srwatson#include <bsm/audit_internal.h>
58155192Srwatson#include <bsm/audit_record.h>
59155192Srwatson#include <security/audit/audit.h>
60155192Srwatson#include <security/audit/audit_private.h>
61155192Srwatson
62155192Srwatson#define	GET_TOKEN_AREA(t, dptr, length) do {				\
63155192Srwatson	t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);		\
64155192Srwatson	t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);	\
65155192Srwatson	t->len = length;						\
66155192Srwatson	dptr = t->t_data;						\
67155192Srwatson} while (0)
68155192Srwatson
69155192Srwatson/*
70155192Srwatson * token ID                1 byte
71243751Srwatson * success/failure         1 byte
72243751Srwatson * privstrlen              2 bytes
73243751Srwatson * privstr                 N bytes + 1 (\0 byte)
74243751Srwatson */
75243751Srwatsontoken_t *
76243751Srwatsonau_to_upriv(char sorf, char *priv)
77243751Srwatson{
78243751Srwatson	u_int16_t textlen;
79243751Srwatson	u_char *dptr;
80243751Srwatson	token_t *t;
81243751Srwatson
82243751Srwatson	textlen = strlen(priv) + 1;
83243751Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
84243751Srwatson	    sizeof(u_int16_t) + textlen);
85243751Srwatson
86243751Srwatson	ADD_U_CHAR(dptr, AUT_UPRIV);
87243751Srwatson	ADD_U_CHAR(dptr, sorf);
88243751Srwatson	ADD_U_INT16(dptr, textlen);
89243751Srwatson	ADD_STRING(dptr, priv, textlen);
90243751Srwatson	return (t);
91243751Srwatson}
92243751Srwatson
93243751Srwatson/*
94243751Srwatson * token ID		1 byte
95243751Srwatson * privtstrlen		2 bytes
96243751Srwatson * privtstr		N bytes + 1
97243751Srwatson * privstrlen		2 bytes
98243751Srwatson * privstr		N bytes + 1
99243751Srwatson */
100243751Srwatsontoken_t *
101243751Srwatsonau_to_privset(char *privtypestr, char *privstr)
102243751Srwatson{
103243751Srwatson	u_int16_t	 type_len, priv_len;
104243751Srwatson	u_char		*dptr;
105243751Srwatson	token_t		*t;
106243751Srwatson
107243751Srwatson	type_len = strlen(privtypestr) + 1;
108243751Srwatson	priv_len = strlen(privstr) + 1;
109243751Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
110243751Srwatson	    sizeof(u_int16_t) + type_len + priv_len);
111243751Srwatson
112243751Srwatson	ADD_U_CHAR(dptr, AUT_PRIV);
113243751Srwatson	ADD_U_INT16(dptr, type_len);
114243751Srwatson	ADD_STRING(dptr, privtypestr, type_len);
115243751Srwatson	ADD_U_INT16(dptr, priv_len);
116243751Srwatson	ADD_STRING(dptr, privstr, priv_len);
117243751Srwatson	return (t);
118243751Srwatson}
119243751Srwatson
120243751Srwatson/*
121243751Srwatson * token ID                1 byte
122155192Srwatson * argument #              1 byte
123155192Srwatson * argument value          4 bytes/8 bytes (32-bit/64-bit value)
124155192Srwatson * text length             2 bytes
125155192Srwatson * text                    N bytes + 1 terminating NULL byte
126155192Srwatson */
127155192Srwatsontoken_t *
128185573Srwatsonau_to_arg32(char n, const char *text, u_int32_t v)
129155192Srwatson{
130155192Srwatson	token_t *t;
131155192Srwatson	u_char *dptr = NULL;
132155192Srwatson	u_int16_t textlen;
133155192Srwatson
134155192Srwatson	textlen = strlen(text);
135155192Srwatson	textlen += 1;
136155192Srwatson
137155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
138155192Srwatson	    sizeof(u_int16_t) + textlen);
139155192Srwatson
140155192Srwatson	ADD_U_CHAR(dptr, AUT_ARG32);
141155192Srwatson	ADD_U_CHAR(dptr, n);
142155192Srwatson	ADD_U_INT32(dptr, v);
143155192Srwatson	ADD_U_INT16(dptr, textlen);
144155192Srwatson	ADD_STRING(dptr, text, textlen);
145155192Srwatson
146155192Srwatson	return (t);
147155192Srwatson}
148155192Srwatson
149155192Srwatsontoken_t *
150185573Srwatsonau_to_arg64(char n, const char *text, u_int64_t v)
151155192Srwatson{
152155192Srwatson	token_t *t;
153155192Srwatson	u_char *dptr = NULL;
154155192Srwatson	u_int16_t textlen;
155155192Srwatson
156155192Srwatson	textlen = strlen(text);
157155192Srwatson	textlen += 1;
158155192Srwatson
159155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
160155192Srwatson	    sizeof(u_int16_t) + textlen);
161155192Srwatson
162155192Srwatson	ADD_U_CHAR(dptr, AUT_ARG64);
163155192Srwatson	ADD_U_CHAR(dptr, n);
164155192Srwatson	ADD_U_INT64(dptr, v);
165155192Srwatson	ADD_U_INT16(dptr, textlen);
166155192Srwatson	ADD_STRING(dptr, text, textlen);
167155192Srwatson
168155192Srwatson	return (t);
169155192Srwatson}
170155192Srwatson
171155192Srwatsontoken_t *
172185573Srwatsonau_to_arg(char n, const char *text, u_int32_t v)
173155192Srwatson{
174155192Srwatson
175155192Srwatson	return (au_to_arg32(n, text, v));
176155192Srwatson}
177155192Srwatson
178155192Srwatson#if defined(_KERNEL) || defined(KERNEL)
179155192Srwatson/*
180155192Srwatson * token ID                1 byte
181155192Srwatson * file access mode        4 bytes
182155192Srwatson * owner user ID           4 bytes
183155192Srwatson * owner group ID          4 bytes
184155192Srwatson * file system ID          4 bytes
185155192Srwatson * node ID                 8 bytes
186155192Srwatson * device                  4 bytes/8 bytes (32-bit/64-bit)
187155192Srwatson */
188155192Srwatsontoken_t *
189155192Srwatsonau_to_attr32(struct vnode_au_info *vni)
190155192Srwatson{
191155192Srwatson	token_t *t;
192155192Srwatson	u_char *dptr = NULL;
193155192Srwatson	u_int16_t pad0_16 = 0;
194189279Srwatson	u_int32_t pad0_32 = 0;
195155192Srwatson
196155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
197155192Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
198155192Srwatson
199155192Srwatson	ADD_U_CHAR(dptr, AUT_ATTR32);
200155192Srwatson
201155192Srwatson	/*
202186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
203186647Srwatson	 * so pad with 0.
204186647Srwatson	 *
205186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
206186647Srwatson	 *
207186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
208155192Srwatson	 */
209155192Srwatson	ADD_U_INT16(dptr, pad0_16);
210155192Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
211155192Srwatson
212155192Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
213155192Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
214155192Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
215155192Srwatson
216155192Srwatson	/*
217181053Srwatson	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
218155192Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
219155192Srwatson	 * could pick this out at compile-time, it would be better, so as to
220155192Srwatson	 * avoid the else case below.
221155192Srwatson	 */
222155192Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
223155192Srwatson		ADD_U_INT32(dptr, pad0_32);
224155192Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
225155192Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
226155192Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
227155192Srwatson	else
228155192Srwatson		ADD_U_INT64(dptr, 0LL);
229155192Srwatson
230155192Srwatson	ADD_U_INT32(dptr, vni->vn_dev);
231155192Srwatson
232155192Srwatson	return (t);
233155192Srwatson}
234155192Srwatson
235155192Srwatsontoken_t *
236155192Srwatsonau_to_attr64(struct vnode_au_info *vni)
237155192Srwatson{
238168783Srwatson	token_t *t;
239168783Srwatson	u_char *dptr = NULL;
240168783Srwatson	u_int16_t pad0_16 = 0;
241189279Srwatson	u_int32_t pad0_32 = 0;
242155192Srwatson
243168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
244168783Srwatson	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
245168783Srwatson
246168783Srwatson	ADD_U_CHAR(dptr, AUT_ATTR64);
247168783Srwatson
248168783Srwatson	/*
249186647Srwatson	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
250186647Srwatson	 * so pad with 0.
251186647Srwatson	 *
252186647Srwatson	 * XXXRW: Possibly should be conditionally compiled.
253186647Srwatson	 *
254186647Srwatson	 * XXXRW: Should any conversions take place on the mode?
255168783Srwatson	 */
256168783Srwatson	ADD_U_INT16(dptr, pad0_16);
257168783Srwatson	ADD_U_INT16(dptr, vni->vn_mode);
258168783Srwatson
259168783Srwatson	ADD_U_INT32(dptr, vni->vn_uid);
260168783Srwatson	ADD_U_INT32(dptr, vni->vn_gid);
261168783Srwatson	ADD_U_INT32(dptr, vni->vn_fsid);
262168783Srwatson
263168783Srwatson	/*
264168783Srwatson	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
265168783Srwatson	 * Attempt to handle both, and let the compiler sort it out.  If we
266168783Srwatson	 * could pick this out at compile-time, it would be better, so as to
267168783Srwatson	 * avoid the else case below.
268168783Srwatson	 */
269168783Srwatson	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
270168783Srwatson		ADD_U_INT32(dptr, pad0_32);
271168783Srwatson		ADD_U_INT32(dptr, vni->vn_fileid);
272168783Srwatson	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
273168783Srwatson		ADD_U_INT64(dptr, vni->vn_fileid);
274168783Srwatson	else
275168783Srwatson		ADD_U_INT64(dptr, 0LL);
276168783Srwatson
277168783Srwatson	ADD_U_INT64(dptr, vni->vn_dev);
278168783Srwatson
279168783Srwatson	return (t);
280155192Srwatson}
281155192Srwatson
282155192Srwatsontoken_t *
283155192Srwatsonau_to_attr(struct vnode_au_info *vni)
284155192Srwatson{
285155192Srwatson
286155192Srwatson	return (au_to_attr32(vni));
287155192Srwatson}
288155192Srwatson#endif /* !(defined(_KERNEL) || defined(KERNEL) */
289155192Srwatson
290155192Srwatson/*
291155192Srwatson * token ID                1 byte
292155192Srwatson * how to print            1 byte
293155192Srwatson * basic unit              1 byte
294155192Srwatson * unit count              1 byte
295155192Srwatson * data items              (depends on basic unit)
296155192Srwatson */
297155192Srwatsontoken_t *
298185573Srwatsonau_to_data(char unit_print, char unit_type, char unit_count, const char *p)
299155192Srwatson{
300155192Srwatson	token_t *t;
301155192Srwatson	u_char *dptr = NULL;
302155192Srwatson	size_t datasize, totdata;
303155192Srwatson
304155192Srwatson	/* Determine the size of the basic unit. */
305155192Srwatson	switch (unit_type) {
306155192Srwatson	case AUR_BYTE:
307159259Srwatson	/* case AUR_CHAR: */
308155192Srwatson		datasize = AUR_BYTE_SIZE;
309155192Srwatson		break;
310155192Srwatson
311155192Srwatson	case AUR_SHORT:
312155192Srwatson		datasize = AUR_SHORT_SIZE;
313155192Srwatson		break;
314155192Srwatson
315159259Srwatson	case AUR_INT32:
316159259Srwatson	/* case AUR_INT: */
317159259Srwatson		datasize = AUR_INT32_SIZE;
318155192Srwatson		break;
319155192Srwatson
320159259Srwatson	case AUR_INT64:
321159259Srwatson		datasize = AUR_INT64_SIZE;
322159259Srwatson		break;
323159259Srwatson
324155192Srwatson	default:
325180709Srwatson		return (NULL);
326155192Srwatson	}
327155192Srwatson
328155192Srwatson	totdata = datasize * unit_count;
329155192Srwatson
330159259Srwatson	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
331155192Srwatson
332186647Srwatson	/*
333186647Srwatson	 * XXXRW: We should be byte-swapping each data item for multi-byte
334186647Srwatson	 * types.
335186647Srwatson	 */
336155192Srwatson	ADD_U_CHAR(dptr, AUT_DATA);
337155192Srwatson	ADD_U_CHAR(dptr, unit_print);
338155192Srwatson	ADD_U_CHAR(dptr, unit_type);
339155192Srwatson	ADD_U_CHAR(dptr, unit_count);
340155192Srwatson	ADD_MEM(dptr, p, totdata);
341155192Srwatson
342155192Srwatson	return (t);
343155192Srwatson}
344155192Srwatson
345155192Srwatson
346155192Srwatson/*
347155192Srwatson * token ID                1 byte
348155192Srwatson * status		   4 bytes
349155192Srwatson * return value            4 bytes
350155192Srwatson */
351155192Srwatsontoken_t *
352155192Srwatsonau_to_exit(int retval, int err)
353155192Srwatson{
354155192Srwatson	token_t *t;
355155192Srwatson	u_char *dptr = NULL;
356155192Srwatson
357155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
358155192Srwatson
359155192Srwatson	ADD_U_CHAR(dptr, AUT_EXIT);
360155192Srwatson	ADD_U_INT32(dptr, err);
361155192Srwatson	ADD_U_INT32(dptr, retval);
362155192Srwatson
363155192Srwatson	return (t);
364155192Srwatson}
365155192Srwatson
366155192Srwatson/*
367155192Srwatson */
368155192Srwatsontoken_t *
369155192Srwatsonau_to_groups(int *groups)
370155192Srwatson{
371155192Srwatson
372185573Srwatson	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
373155192Srwatson}
374155192Srwatson
375155192Srwatson/*
376155192Srwatson * token ID                1 byte
377155192Srwatson * number groups           2 bytes
378155192Srwatson * group list              count * 4 bytes
379155192Srwatson */
380155192Srwatsontoken_t *
381155192Srwatsonau_to_newgroups(u_int16_t n, gid_t *groups)
382155192Srwatson{
383155192Srwatson	token_t *t;
384155192Srwatson	u_char *dptr = NULL;
385155192Srwatson	int i;
386155192Srwatson
387155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
388155192Srwatson	    n * sizeof(u_int32_t));
389155192Srwatson
390155192Srwatson	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
391155192Srwatson	ADD_U_INT16(dptr, n);
392155192Srwatson	for (i = 0; i < n; i++)
393155192Srwatson		ADD_U_INT32(dptr, groups[i]);
394155192Srwatson
395155192Srwatson	return (t);
396155192Srwatson}
397155192Srwatson
398155192Srwatson/*
399155192Srwatson * token ID                1 byte
400155192Srwatson * internet address        4 bytes
401155192Srwatson */
402155192Srwatsontoken_t *
403155192Srwatsonau_to_in_addr(struct in_addr *internet_addr)
404155192Srwatson{
405155192Srwatson	token_t *t;
406155192Srwatson	u_char *dptr = NULL;
407155192Srwatson
408159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
409155192Srwatson
410155192Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR);
411159259Srwatson	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
412155192Srwatson
413155192Srwatson	return (t);
414155192Srwatson}
415155192Srwatson
416155192Srwatson/*
417155192Srwatson * token ID                1 byte
418155192Srwatson * address type/length     4 bytes
419185573Srwatson * address                16 bytes
420155192Srwatson */
421155192Srwatsontoken_t *
422155192Srwatsonau_to_in_addr_ex(struct in6_addr *internet_addr)
423155192Srwatson{
424155192Srwatson	token_t *t;
425155192Srwatson	u_char *dptr = NULL;
426171066Scsjp	u_int32_t type = AU_IPv6;
427155192Srwatson
428159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
429155192Srwatson
430155192Srwatson	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
431155192Srwatson	ADD_U_INT32(dptr, type);
432171066Scsjp	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
433155192Srwatson
434155192Srwatson	return (t);
435155192Srwatson}
436155192Srwatson
437155192Srwatson/*
438155192Srwatson * token ID                1 byte
439155192Srwatson * ip header		   20 bytes
440165604Srwatson *
441165604Srwatson * The IP header should be submitted in network byte order.
442155192Srwatson */
443155192Srwatsontoken_t *
444155192Srwatsonau_to_ip(struct ip *ip)
445155192Srwatson{
446155192Srwatson	token_t *t;
447155192Srwatson	u_char *dptr = NULL;
448155192Srwatson
449155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
450155192Srwatson
451155192Srwatson	ADD_U_CHAR(dptr, AUT_IP);
452155192Srwatson	ADD_MEM(dptr, ip, sizeof(struct ip));
453155192Srwatson
454155192Srwatson	return (t);
455155192Srwatson}
456155192Srwatson
457155192Srwatson/*
458155192Srwatson * token ID                1 byte
459155192Srwatson * object ID type          1 byte
460155192Srwatson * object ID               4 bytes
461155192Srwatson */
462155192Srwatsontoken_t *
463155192Srwatsonau_to_ipc(char type, int id)
464155192Srwatson{
465155192Srwatson	token_t *t;
466155192Srwatson	u_char *dptr = NULL;
467155192Srwatson
468155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
469155192Srwatson
470155192Srwatson	ADD_U_CHAR(dptr, AUT_IPC);
471155192Srwatson	ADD_U_CHAR(dptr, type);
472155192Srwatson	ADD_U_INT32(dptr, id);
473155192Srwatson
474155192Srwatson	return (t);
475155192Srwatson}
476155192Srwatson
477155192Srwatson/*
478155192Srwatson * token ID                1 byte
479155192Srwatson * owner user ID           4 bytes
480155192Srwatson * owner group ID          4 bytes
481155192Srwatson * creator user ID         4 bytes
482155192Srwatson * creator group ID        4 bytes
483155192Srwatson * access mode             4 bytes
484155192Srwatson * slot sequence #         4 bytes
485155192Srwatson * key                     4 bytes
486155192Srwatson */
487155192Srwatsontoken_t *
488155192Srwatsonau_to_ipc_perm(struct ipc_perm *perm)
489155192Srwatson{
490155192Srwatson	token_t *t;
491155192Srwatson	u_char *dptr = NULL;
492155192Srwatson	u_int16_t pad0 = 0;
493155192Srwatson
494189279Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
495189279Srwatson	    sizeof(u_int32_t));
496155192Srwatson
497155192Srwatson	ADD_U_CHAR(dptr, AUT_IPC_PERM);
498155192Srwatson
499155192Srwatson	/*
500186647Srwatson	 * Systems vary significantly in what types they use in struct
501186647Srwatson	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
502186647Srwatson	 * allow for that, as BSM define 32-bit values here.
503186647Srwatson	 * Some systems define the sizes for ipc_perm members as 2 bytes;
504186647Srwatson	 * BSM defines 4 so pad with 0.
505186647Srwatson	 *
506186647Srwatson	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
507186647Srwatson	 * need to be handled.
508155192Srwatson	 */
509186647Srwatson	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
510186647Srwatson		ADD_U_INT16(dptr, pad0);
511186647Srwatson		ADD_U_INT16(dptr, perm->uid);
512186647Srwatson		ADD_U_INT16(dptr, pad0);
513186647Srwatson		ADD_U_INT16(dptr, perm->gid);
514186647Srwatson		ADD_U_INT16(dptr, pad0);
515186647Srwatson		ADD_U_INT16(dptr, perm->cuid);
516186647Srwatson		ADD_U_INT16(dptr, pad0);
517186647Srwatson		ADD_U_INT16(dptr, perm->cgid);
518186647Srwatson	} else {
519186647Srwatson		ADD_U_INT32(dptr, perm->uid);
520186647Srwatson		ADD_U_INT32(dptr, perm->gid);
521186647Srwatson		ADD_U_INT32(dptr, perm->cuid);
522186647Srwatson		ADD_U_INT32(dptr, perm->cgid);
523186647Srwatson	}
524155192Srwatson
525155192Srwatson	ADD_U_INT16(dptr, pad0);
526186647Srwatson	ADD_U_INT16(dptr, perm->mode);
527155192Srwatson
528155192Srwatson	ADD_U_INT16(dptr, pad0);
529155192Srwatson
530155192Srwatson	ADD_U_INT16(dptr, perm->seq);
531155192Srwatson
532155192Srwatson	ADD_U_INT32(dptr, perm->key);
533155192Srwatson
534155192Srwatson	return (t);
535155192Srwatson}
536155192Srwatson
537155192Srwatson/*
538155192Srwatson * token ID                1 byte
539155192Srwatson * port IP address         2 bytes
540155192Srwatson */
541155192Srwatsontoken_t *
542155192Srwatsonau_to_iport(u_int16_t iport)
543155192Srwatson{
544155192Srwatson	token_t *t;
545155192Srwatson	u_char *dptr = NULL;
546155192Srwatson
547155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
548155192Srwatson
549155192Srwatson	ADD_U_CHAR(dptr, AUT_IPORT);
550155192Srwatson	ADD_U_INT16(dptr, iport);
551155192Srwatson
552155192Srwatson	return (t);
553155192Srwatson}
554155192Srwatson
555155192Srwatson/*
556155192Srwatson * token ID                1 byte
557155192Srwatson * size                    2 bytes
558155192Srwatson * data                    size bytes
559155192Srwatson */
560155192Srwatsontoken_t *
561185573Srwatsonau_to_opaque(const char *data, u_int16_t bytes)
562155192Srwatson{
563155192Srwatson	token_t *t;
564155192Srwatson	u_char *dptr = NULL;
565155192Srwatson
566155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
567155192Srwatson
568155192Srwatson	ADD_U_CHAR(dptr, AUT_OPAQUE);
569155192Srwatson	ADD_U_INT16(dptr, bytes);
570155192Srwatson	ADD_MEM(dptr, data, bytes);
571155192Srwatson
572155192Srwatson	return (t);
573155192Srwatson}
574155192Srwatson
575155192Srwatson/*
576155192Srwatson * token ID                1 byte
577155192Srwatson * seconds of time         4 bytes
578155192Srwatson * milliseconds of time    4 bytes
579155192Srwatson * file name len           2 bytes
580155192Srwatson * file pathname           N bytes + 1 terminating NULL byte
581155192Srwatson */
582155192Srwatsontoken_t *
583185573Srwatsonau_to_file(const char *file, struct timeval tm)
584155192Srwatson{
585155192Srwatson	token_t *t;
586155192Srwatson	u_char *dptr = NULL;
587155192Srwatson	u_int16_t filelen;
588155192Srwatson	u_int32_t timems;
589155192Srwatson
590155192Srwatson	filelen = strlen(file);
591155192Srwatson	filelen += 1;
592155192Srwatson
593155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
594155192Srwatson	    sizeof(u_int16_t) + filelen);
595155192Srwatson
596155192Srwatson	timems = tm.tv_usec/1000;
597155192Srwatson
598155192Srwatson	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
599155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
600155192Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
601155192Srwatson	ADD_U_INT16(dptr, filelen);
602155192Srwatson	ADD_STRING(dptr, file, filelen);
603155192Srwatson
604155192Srwatson	return (t);
605155192Srwatson}
606155192Srwatson
607155192Srwatson/*
608155192Srwatson * token ID                1 byte
609155192Srwatson * text length             2 bytes
610155192Srwatson * text                    N bytes + 1 terminating NULL byte
611155192Srwatson */
612155192Srwatsontoken_t *
613185573Srwatsonau_to_text(const char *text)
614155192Srwatson{
615155192Srwatson	token_t *t;
616155192Srwatson	u_char *dptr = NULL;
617155192Srwatson	u_int16_t textlen;
618155192Srwatson
619155192Srwatson	textlen = strlen(text);
620155192Srwatson	textlen += 1;
621155192Srwatson
622186647Srwatson	/* XXXRW: Should validate length against token size limit. */
623186647Srwatson
624155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
625155192Srwatson
626155192Srwatson	ADD_U_CHAR(dptr, AUT_TEXT);
627155192Srwatson	ADD_U_INT16(dptr, textlen);
628155192Srwatson	ADD_STRING(dptr, text, textlen);
629155192Srwatson
630155192Srwatson	return (t);
631155192Srwatson}
632155192Srwatson
633155192Srwatson/*
634155192Srwatson * token ID                1 byte
635155192Srwatson * path length             2 bytes
636155192Srwatson * path                    N bytes + 1 terminating NULL byte
637155192Srwatson */
638155192Srwatsontoken_t *
639185573Srwatsonau_to_path(const char *text)
640155192Srwatson{
641155192Srwatson	token_t *t;
642155192Srwatson	u_char *dptr = NULL;
643155192Srwatson	u_int16_t textlen;
644155192Srwatson
645155192Srwatson	textlen = strlen(text);
646155192Srwatson	textlen += 1;
647155192Srwatson
648155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
649155192Srwatson
650155192Srwatson	ADD_U_CHAR(dptr, AUT_PATH);
651155192Srwatson	ADD_U_INT16(dptr, textlen);
652155192Srwatson	ADD_STRING(dptr, text, textlen);
653155192Srwatson
654155192Srwatson	return (t);
655155192Srwatson}
656155192Srwatson
657155192Srwatson/*
658155192Srwatson * token ID                1 byte
659155192Srwatson * audit ID                4 bytes
660155192Srwatson * effective user ID       4 bytes
661155192Srwatson * effective group ID      4 bytes
662155192Srwatson * real user ID            4 bytes
663155192Srwatson * real group ID           4 bytes
664155192Srwatson * process ID              4 bytes
665155192Srwatson * session ID              4 bytes
666155192Srwatson * terminal ID
667155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
668155192Srwatson *   machine address       4 bytes
669155192Srwatson */
670155192Srwatsontoken_t *
671155192Srwatsonau_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
672155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
673155192Srwatson{
674155192Srwatson	token_t *t;
675155192Srwatson	u_char *dptr = NULL;
676155192Srwatson
677155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
678155192Srwatson
679155192Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32);
680155192Srwatson	ADD_U_INT32(dptr, auid);
681155192Srwatson	ADD_U_INT32(dptr, euid);
682155192Srwatson	ADD_U_INT32(dptr, egid);
683155192Srwatson	ADD_U_INT32(dptr, ruid);
684155192Srwatson	ADD_U_INT32(dptr, rgid);
685155192Srwatson	ADD_U_INT32(dptr, pid);
686155192Srwatson	ADD_U_INT32(dptr, sid);
687155192Srwatson	ADD_U_INT32(dptr, tid->port);
688186647Srwatson
689186647Srwatson	/*
690186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
691186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
692186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
693186647Srwatson	 * addresses for process32 tokens.
694186647Srwatson	 */
695159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
696155192Srwatson
697155192Srwatson	return (t);
698155192Srwatson}
699155192Srwatson
700155192Srwatsontoken_t *
701168783Srwatsonau_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
702168783Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
703155192Srwatson{
704168783Srwatson	token_t *t;
705168783Srwatson	u_char *dptr = NULL;
706155192Srwatson
707168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
708168783Srwatson	    sizeof(u_int64_t));
709168783Srwatson
710168783Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64);
711168783Srwatson	ADD_U_INT32(dptr, auid);
712168783Srwatson	ADD_U_INT32(dptr, euid);
713168783Srwatson	ADD_U_INT32(dptr, egid);
714168783Srwatson	ADD_U_INT32(dptr, ruid);
715168783Srwatson	ADD_U_INT32(dptr, rgid);
716168783Srwatson	ADD_U_INT32(dptr, pid);
717168783Srwatson	ADD_U_INT32(dptr, sid);
718168783Srwatson	ADD_U_INT64(dptr, tid->port);
719186647Srwatson
720186647Srwatson	/*
721186647Srwatson	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
722186647Srwatson	 * address type and 16 bytes of address, but for IPv4 addresses it
723186647Srwatson	 * simply writes the 4-byte address directly.  We support only IPv4
724186647Srwatson	 * addresses for process64 tokens.
725186647Srwatson	 */
726168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
727168783Srwatson
728168783Srwatson	return (t);
729155192Srwatson}
730155192Srwatson
731155192Srwatsontoken_t *
732168783Srwatsonau_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
733168783Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
734155192Srwatson{
735155192Srwatson
736155192Srwatson	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
737155192Srwatson	    tid));
738155192Srwatson}
739155192Srwatson
740155192Srwatson/*
741155192Srwatson * token ID                1 byte
742155192Srwatson * audit ID                4 bytes
743155192Srwatson * effective user ID       4 bytes
744155192Srwatson * effective group ID      4 bytes
745155192Srwatson * real user ID            4 bytes
746155192Srwatson * real group ID           4 bytes
747155192Srwatson * process ID              4 bytes
748155192Srwatson * session ID              4 bytes
749155192Srwatson * terminal ID
750155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
751155192Srwatson *   address type-len      4 bytes
752185573Srwatson *   machine address      16 bytes
753155192Srwatson */
754155192Srwatsontoken_t *
755155192Srwatsonau_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
756155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
757155192Srwatson{
758155192Srwatson	token_t *t;
759155192Srwatson	u_char *dptr = NULL;
760155192Srwatson
761168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
762168688Scsjp	    ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
763185573Srwatson	if (tid->at_type == AU_IPv4)
764185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
765185573Srwatson		    10 * sizeof(u_int32_t));
766159686Swsalamon	else
767185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
768185573Srwatson		    13 * sizeof(u_int32_t));
769155192Srwatson
770155192Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
771155192Srwatson	ADD_U_INT32(dptr, auid);
772155192Srwatson	ADD_U_INT32(dptr, euid);
773155192Srwatson	ADD_U_INT32(dptr, egid);
774155192Srwatson	ADD_U_INT32(dptr, ruid);
775155192Srwatson	ADD_U_INT32(dptr, rgid);
776155192Srwatson	ADD_U_INT32(dptr, pid);
777155192Srwatson	ADD_U_INT32(dptr, sid);
778155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
779155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
780185573Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
781185573Srwatson	if (tid->at_type == AU_IPv6) {
782185573Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
783185573Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
784185573Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
785185573Srwatson	}
786170131Srwatson
787155192Srwatson	return (t);
788155192Srwatson}
789155192Srwatson
790155192Srwatsontoken_t *
791155192Srwatsonau_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
792155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
793155192Srwatson{
794168783Srwatson	token_t *t;
795168783Srwatson	u_char *dptr = NULL;
796155192Srwatson
797168783Srwatson	if (tid->at_type == AU_IPv4)
798168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
799168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
800168783Srwatson		    2 * sizeof(u_int32_t));
801168783Srwatson	else if (tid->at_type == AU_IPv6)
802168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
803168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
804168783Srwatson		    5 * sizeof(u_int32_t));
805168783Srwatson	else
806168783Srwatson		panic("au_to_process64_ex: invalidate at_type (%d)",
807168783Srwatson		    tid->at_type);
808168783Srwatson
809168783Srwatson	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
810168783Srwatson	ADD_U_INT32(dptr, auid);
811168783Srwatson	ADD_U_INT32(dptr, euid);
812168783Srwatson	ADD_U_INT32(dptr, egid);
813168783Srwatson	ADD_U_INT32(dptr, ruid);
814168783Srwatson	ADD_U_INT32(dptr, rgid);
815168783Srwatson	ADD_U_INT32(dptr, pid);
816168783Srwatson	ADD_U_INT32(dptr, sid);
817168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
818168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
819168783Srwatson	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
820168783Srwatson	if (tid->at_type == AU_IPv6) {
821168783Srwatson		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
822168783Srwatson		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
823168783Srwatson		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
824168783Srwatson	}
825168783Srwatson
826168783Srwatson	return (t);
827155192Srwatson}
828155192Srwatson
829155192Srwatsontoken_t *
830155192Srwatsonau_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
831155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
832155192Srwatson{
833155192Srwatson
834155192Srwatson	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
835155192Srwatson	    tid));
836155192Srwatson}
837155192Srwatson
838255219Spjdtoken_t *
839255219Spjdau_to_rights(cap_rights_t *rightsp)
840255219Spjd{
841255219Spjd	token_t *t;
842255219Spjd	u_char *dptr;
843255219Spjd	int i;
844255219Spjd
845255219Spjd	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(*rightsp));
846255219Spjd
847255219Spjd	ADD_U_CHAR(dptr, AUT_RIGHTS);
848255219Spjd	for (i = 0; i < nitems(rightsp->cr_rights); i++)
849255219Spjd		ADD_U_INT64(dptr, rightsp->cr_rights[i]);
850255219Spjd
851255219Spjd	return (t);
852255219Spjd}
853255219Spjd
854155192Srwatson/*
855155192Srwatson * token ID                1 byte
856155192Srwatson * error status            1 byte
857155192Srwatson * return value            4 bytes/8 bytes (32-bit/64-bit value)
858155192Srwatson */
859155192Srwatsontoken_t *
860155192Srwatsonau_to_return32(char status, u_int32_t ret)
861155192Srwatson{
862155192Srwatson	token_t *t;
863155192Srwatson	u_char *dptr = NULL;
864155192Srwatson
865155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
866155192Srwatson
867155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN32);
868155192Srwatson	ADD_U_CHAR(dptr, status);
869155192Srwatson	ADD_U_INT32(dptr, ret);
870155192Srwatson
871155192Srwatson	return (t);
872155192Srwatson}
873155192Srwatson
874155192Srwatsontoken_t *
875155192Srwatsonau_to_return64(char status, u_int64_t ret)
876155192Srwatson{
877155192Srwatson	token_t *t;
878155192Srwatson	u_char *dptr = NULL;
879155192Srwatson
880155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
881155192Srwatson
882155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN64);
883155192Srwatson	ADD_U_CHAR(dptr, status);
884155192Srwatson	ADD_U_INT64(dptr, ret);
885155192Srwatson
886155192Srwatson	return (t);
887155192Srwatson}
888155192Srwatson
889155192Srwatsontoken_t *
890155192Srwatsonau_to_return(char status, u_int32_t ret)
891155192Srwatson{
892155192Srwatson
893155192Srwatson	return (au_to_return32(status, ret));
894155192Srwatson}
895155192Srwatson
896155192Srwatson/*
897155192Srwatson * token ID                1 byte
898155192Srwatson * sequence number         4 bytes
899155192Srwatson */
900155192Srwatsontoken_t *
901155192Srwatsonau_to_seq(long audit_count)
902155192Srwatson{
903155192Srwatson	token_t *t;
904155192Srwatson	u_char *dptr = NULL;
905155192Srwatson
906155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
907155192Srwatson
908155192Srwatson	ADD_U_CHAR(dptr, AUT_SEQ);
909155192Srwatson	ADD_U_INT32(dptr, audit_count);
910155192Srwatson
911155192Srwatson	return (t);
912155192Srwatson}
913155192Srwatson
914155192Srwatson/*
915155192Srwatson * token ID                1 byte
916186647Srwatson * socket domain           2 bytes
917155192Srwatson * socket type             2 bytes
918186647Srwatson * address type            2 byte
919155192Srwatson * local port              2 bytes
920186647Srwatson * local address           4 bytes/16 bytes (IPv4/IPv6 address)
921155192Srwatson * remote port             2 bytes
922186647Srwatson * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
923187214Srwatson *
924187214Srwatson * Domain and type arguments to this routine are assumed to already have been
925187214Srwatson * converted to the BSM constant space, so we don't do that here.
926155192Srwatson */
927155192Srwatsontoken_t *
928186647Srwatsonau_to_socket_ex(u_short so_domain, u_short so_type,
929186647Srwatson    struct sockaddr *sa_local, struct sockaddr *sa_remote)
930155192Srwatson{
931186647Srwatson	token_t *t;
932186647Srwatson	u_char *dptr = NULL;
933186647Srwatson	struct sockaddr_in *sin;
934186647Srwatson	struct sockaddr_in6 *sin6;
935155192Srwatson
936186647Srwatson	if (so_domain == AF_INET)
937186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
938186647Srwatson		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
939186647Srwatson	else if (so_domain == AF_INET6)
940186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
941189279Srwatson		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
942186647Srwatson	else
943186647Srwatson		return (NULL);
944186647Srwatson
945186647Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
946189279Srwatson	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
947189279Srwatson	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
948186647Srwatson	if (so_domain == AF_INET) {
949186647Srwatson		ADD_U_INT16(dptr, AU_IPv4);
950186647Srwatson		sin = (struct sockaddr_in *)sa_local;
951186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
952186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
953186647Srwatson		sin = (struct sockaddr_in *)sa_remote;
954186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
955186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
956186647Srwatson	} else {
957186647Srwatson		ADD_U_INT16(dptr, AU_IPv6);
958186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_local;
959186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
960186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
961186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_remote;
962186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
963186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
964186647Srwatson	}
965186647Srwatson
966186647Srwatson	return (t);
967155192Srwatson}
968155192Srwatson
969155192Srwatson/*
970155192Srwatson * Kernel-specific version of the above function.
971186647Srwatson *
972186647Srwatson * XXXRW: Should now use au_to_socket_ex() here.
973155192Srwatson */
974155192Srwatson#ifdef _KERNEL
975155192Srwatsontoken_t *
976155192Srwatsonkau_to_socket(struct socket_au_info *soi)
977155192Srwatson{
978155192Srwatson	token_t *t;
979155192Srwatson	u_char *dptr;
980155192Srwatson	u_int16_t so_type;
981155192Srwatson
982155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
983155192Srwatson	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
984186647Srwatson
985185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET);
986155192Srwatson	/* Coerce the socket type into a short value */
987155192Srwatson	so_type = soi->so_type;
988155192Srwatson	ADD_U_INT16(dptr, so_type);
989155192Srwatson	ADD_U_INT16(dptr, soi->so_lport);
990155192Srwatson	ADD_U_INT32(dptr, soi->so_laddr);
991155192Srwatson	ADD_U_INT16(dptr, soi->so_rport);
992155192Srwatson	ADD_U_INT32(dptr, soi->so_raddr);
993155192Srwatson
994155192Srwatson	return (t);
995155192Srwatson}
996155192Srwatson#endif
997155192Srwatson
998155192Srwatson/*
999155192Srwatson * token ID                1 byte
1000155192Srwatson * socket family           2 bytes
1001195740Srwatson * path                    (up to) 104 bytes + NULL  (NULL terminated string)
1002155192Srwatson */
1003155192Srwatsontoken_t *
1004155192Srwatsonau_to_sock_unix(struct sockaddr_un *so)
1005155192Srwatson{
1006155192Srwatson	token_t *t;
1007155192Srwatson	u_char *dptr;
1008155192Srwatson
1009155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1010155192Srwatson
1011185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1012155192Srwatson	/* BSM token has two bytes for family */
1013155192Srwatson	ADD_U_CHAR(dptr, 0);
1014155192Srwatson	ADD_U_CHAR(dptr, so->sun_family);
1015155192Srwatson	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1016155192Srwatson
1017155192Srwatson	return (t);
1018155192Srwatson}
1019155192Srwatson
1020155192Srwatson/*
1021155192Srwatson * token ID                1 byte
1022155192Srwatson * socket family           2 bytes
1023155192Srwatson * local port              2 bytes
1024155192Srwatson * socket address          4 bytes
1025155192Srwatson */
1026155192Srwatsontoken_t *
1027155192Srwatsonau_to_sock_inet32(struct sockaddr_in *so)
1028155192Srwatson{
1029155192Srwatson	token_t *t;
1030155192Srwatson	u_char *dptr = NULL;
1031159259Srwatson	uint16_t family;
1032155192Srwatson
1033159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1034159259Srwatson	    sizeof(uint32_t));
1035155192Srwatson
1036155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1037155192Srwatson	/*
1038159259Srwatson	 * BSM defines the family field as 16 bits, but many operating
1039159259Srwatson	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1040159259Srwatson	 * writing into the token.  Assume that both the port and the address
1041159259Srwatson	 * in the sockaddr_in are already in network byte order, but family
1042159259Srwatson	 * is in local byte order.
1043159259Srwatson	 *
1044159259Srwatson	 * XXXRW: Should a name space conversion be taking place on the value
1045159259Srwatson	 * of sin_family?
1046180709Srwatson	 */
1047159259Srwatson	family = so->sin_family;
1048159259Srwatson	ADD_U_INT16(dptr, family);
1049159259Srwatson	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1050159259Srwatson	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1051155192Srwatson
1052155192Srwatson	return (t);
1053155192Srwatson}
1054155192Srwatson
1055155192Srwatsontoken_t *
1056155192Srwatsonau_to_sock_inet128(struct sockaddr_in6 *so)
1057155192Srwatson{
1058155192Srwatson	token_t *t;
1059155192Srwatson	u_char *dptr = NULL;
1060155192Srwatson
1061155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1062155192Srwatson	    4 * sizeof(u_int32_t));
1063155192Srwatson
1064155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1065155192Srwatson	/*
1066186647Srwatson	 * In BSD, sin6_family is one octet, but BSM defines the token to
1067186647Srwatson	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1068186647Srwatson	 * conditionally compiled.
1069180709Srwatson	 */
1070155192Srwatson	ADD_U_CHAR(dptr, 0);
1071155192Srwatson	ADD_U_CHAR(dptr, so->sin6_family);
1072155192Srwatson
1073155192Srwatson	ADD_U_INT16(dptr, so->sin6_port);
1074159259Srwatson	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1075155192Srwatson
1076155192Srwatson	return (t);
1077155192Srwatson}
1078155192Srwatson
1079155192Srwatsontoken_t *
1080155192Srwatsonau_to_sock_inet(struct sockaddr_in *so)
1081155192Srwatson{
1082155192Srwatson
1083155192Srwatson	return (au_to_sock_inet32(so));
1084155192Srwatson}
1085155192Srwatson
1086155192Srwatson/*
1087155192Srwatson * token ID                1 byte
1088155192Srwatson * audit ID                4 bytes
1089155192Srwatson * effective user ID       4 bytes
1090155192Srwatson * effective group ID      4 bytes
1091155192Srwatson * real user ID            4 bytes
1092155192Srwatson * real group ID           4 bytes
1093155192Srwatson * process ID              4 bytes
1094155192Srwatson * session ID              4 bytes
1095155192Srwatson * terminal ID
1096155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1097155192Srwatson *   machine address       4 bytes
1098155192Srwatson */
1099155192Srwatsontoken_t *
1100155192Srwatsonau_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1101155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1102155192Srwatson{
1103155192Srwatson	token_t *t;
1104155192Srwatson	u_char *dptr = NULL;
1105155192Srwatson
1106155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1107155192Srwatson
1108155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1109155192Srwatson	ADD_U_INT32(dptr, auid);
1110155192Srwatson	ADD_U_INT32(dptr, euid);
1111155192Srwatson	ADD_U_INT32(dptr, egid);
1112155192Srwatson	ADD_U_INT32(dptr, ruid);
1113155192Srwatson	ADD_U_INT32(dptr, rgid);
1114155192Srwatson	ADD_U_INT32(dptr, pid);
1115155192Srwatson	ADD_U_INT32(dptr, sid);
1116155192Srwatson	ADD_U_INT32(dptr, tid->port);
1117159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1118155192Srwatson
1119155192Srwatson	return (t);
1120155192Srwatson}
1121155192Srwatson
1122155192Srwatsontoken_t *
1123155192Srwatsonau_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1124155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1125155192Srwatson{
1126168783Srwatson	token_t *t;
1127168783Srwatson	u_char *dptr = NULL;
1128155192Srwatson
1129168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1130168783Srwatson	    sizeof(u_int64_t) + sizeof(u_int32_t));
1131168783Srwatson
1132168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1133168783Srwatson	ADD_U_INT32(dptr, auid);
1134168783Srwatson	ADD_U_INT32(dptr, euid);
1135168783Srwatson	ADD_U_INT32(dptr, egid);
1136168783Srwatson	ADD_U_INT32(dptr, ruid);
1137168783Srwatson	ADD_U_INT32(dptr, rgid);
1138168783Srwatson	ADD_U_INT32(dptr, pid);
1139168783Srwatson	ADD_U_INT32(dptr, sid);
1140168783Srwatson	ADD_U_INT64(dptr, tid->port);
1141168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1142168783Srwatson
1143168783Srwatson	return (t);
1144155192Srwatson}
1145155192Srwatson
1146155192Srwatsontoken_t *
1147155192Srwatsonau_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1148155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1149155192Srwatson{
1150155192Srwatson
1151155192Srwatson	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1152155192Srwatson	    tid));
1153155192Srwatson}
1154155192Srwatson
1155155192Srwatson/*
1156155192Srwatson * token ID                1 byte
1157155192Srwatson * audit ID                4 bytes
1158155192Srwatson * effective user ID       4 bytes
1159155192Srwatson * effective group ID      4 bytes
1160155192Srwatson * real user ID            4 bytes
1161155192Srwatson * real group ID           4 bytes
1162155192Srwatson * process ID              4 bytes
1163155192Srwatson * session ID              4 bytes
1164155192Srwatson * terminal ID
1165155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1166155192Srwatson *   address type/length   4 bytes
1167185573Srwatson *   machine address      16 bytes
1168155192Srwatson */
1169155192Srwatsontoken_t *
1170155192Srwatsonau_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1171155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1172155192Srwatson{
1173155192Srwatson	token_t *t;
1174155192Srwatson	u_char *dptr = NULL;
1175155192Srwatson
1176168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1177168688Scsjp	    ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1178185573Srwatson
1179185573Srwatson	if (tid->at_type == AU_IPv4)
1180185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1181159686Swsalamon		    sizeof(u_int32_t));
1182159686Swsalamon	else
1183185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1184159686Swsalamon		    sizeof(u_int32_t));
1185155192Srwatson
1186155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1187155192Srwatson	ADD_U_INT32(dptr, auid);
1188155192Srwatson	ADD_U_INT32(dptr, euid);
1189155192Srwatson	ADD_U_INT32(dptr, egid);
1190155192Srwatson	ADD_U_INT32(dptr, ruid);
1191155192Srwatson	ADD_U_INT32(dptr, rgid);
1192155192Srwatson	ADD_U_INT32(dptr, pid);
1193155192Srwatson	ADD_U_INT32(dptr, sid);
1194155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
1195155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
1196185573Srwatson	if (tid->at_type == AU_IPv6)
1197168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1198185573Srwatson	else
1199168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1200170131Srwatson
1201155192Srwatson	return (t);
1202155192Srwatson}
1203155192Srwatson
1204155192Srwatsontoken_t *
1205155192Srwatsonau_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1206155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1207155192Srwatson{
1208168783Srwatson	token_t *t;
1209168783Srwatson	u_char *dptr = NULL;
1210155192Srwatson
1211185573Srwatson	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1212185573Srwatson	    ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1213185573Srwatson
1214168783Srwatson	if (tid->at_type == AU_IPv4)
1215168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1216168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1217168783Srwatson		    2 * sizeof(u_int32_t));
1218185573Srwatson	else
1219168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1220168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1221168783Srwatson		    5 * sizeof(u_int32_t));
1222168783Srwatson
1223168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1224168783Srwatson	ADD_U_INT32(dptr, auid);
1225168783Srwatson	ADD_U_INT32(dptr, euid);
1226168783Srwatson	ADD_U_INT32(dptr, egid);
1227168783Srwatson	ADD_U_INT32(dptr, ruid);
1228168783Srwatson	ADD_U_INT32(dptr, rgid);
1229168783Srwatson	ADD_U_INT32(dptr, pid);
1230168783Srwatson	ADD_U_INT32(dptr, sid);
1231168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
1232168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
1233168783Srwatson	if (tid->at_type == AU_IPv6)
1234168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1235168783Srwatson	else
1236168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1237168783Srwatson
1238168783Srwatson	return (t);
1239155192Srwatson}
1240155192Srwatson
1241155192Srwatsontoken_t *
1242155192Srwatsonau_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1243155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1244155192Srwatson{
1245155192Srwatson
1246155192Srwatson	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1247155192Srwatson	    tid));
1248155192Srwatson}
1249155192Srwatson
1250156291Srwatson#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1251155192Srwatson/*
1252185573Srwatson * Collects audit information for the current process and creates a subject
1253185573Srwatson * token from it.
1254155192Srwatson */
1255155192Srwatsontoken_t *
1256155192Srwatsonau_to_me(void)
1257155192Srwatson{
1258155192Srwatson	auditinfo_t auinfo;
1259195740Srwatson	auditinfo_addr_t aia;
1260155192Srwatson
1261195740Srwatson	/*
1262195740Srwatson	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1263195740Srwatson	 * it, then fall back on to getaudit(2).
1264195740Srwatson	 */
1265195740Srwatson	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1266195740Srwatson		if (errno == ENOSYS) {
1267195740Srwatson			if (getaudit(&auinfo) != 0)
1268195740Srwatson				return (NULL);
1269195740Srwatson			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1270195740Srwatson				getegid(), getuid(), getgid(), getpid(),
1271195740Srwatson				auinfo.ai_asid, &auinfo.ai_termid));
1272195740Srwatson		} else {
1273195740Srwatson			/* getaudit_addr(2) failed for some other reason. */
1274243751Srwatson			return (NULL);
1275195740Srwatson		}
1276243751Srwatson	}
1277155192Srwatson
1278195740Srwatson	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1279195740Srwatson		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1280155192Srwatson}
1281155192Srwatson#endif
1282155192Srwatson
1283161813Swsalamon#if defined(_KERNEL) || defined(KERNEL)
1284161813Swsalamonstatic token_t *
1285161813Swsalamonau_to_exec_strings(char *strs, int count, u_char type)
1286161813Swsalamon{
1287161813Swsalamon	token_t *t;
1288161813Swsalamon	u_char *dptr = NULL;
1289161813Swsalamon	u_int32_t totlen;
1290161813Swsalamon	int ctr;
1291161813Swsalamon	char *p;
1292161813Swsalamon
1293161813Swsalamon	totlen = 0;
1294161813Swsalamon	ctr = count;
1295161813Swsalamon	p = strs;
1296161813Swsalamon	while (ctr-- > 0) {
1297161813Swsalamon		totlen += strlen(p) + 1;
1298161813Swsalamon		p = strs + totlen;
1299161813Swsalamon	}
1300161813Swsalamon	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1301161813Swsalamon	ADD_U_CHAR(dptr, type);
1302161813Swsalamon	ADD_U_INT32(dptr, count);
1303161813Swsalamon	ADD_STRING(dptr, strs, totlen);
1304161813Swsalamon
1305161813Swsalamon	return (t);
1306161813Swsalamon}
1307161813Swsalamon
1308155192Srwatson/*
1309155192Srwatson * token ID				1 byte
1310155192Srwatson * count				4 bytes
1311155192Srwatson * text					count null-terminated strings
1312155192Srwatson */
1313155192Srwatsontoken_t *
1314161813Swsalamonau_to_exec_args(char *args, int argc)
1315155192Srwatson{
1316162465Srwatson
1317161813Swsalamon	return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1318161813Swsalamon}
1319161813Swsalamon
1320161813Swsalamon/*
1321161813Swsalamon * token ID				1 byte
1322161813Swsalamon * count				4 bytes
1323161813Swsalamon * text					count null-terminated strings
1324161813Swsalamon */
1325161813Swsalamontoken_t *
1326161813Swsalamonau_to_exec_env(char *envs, int envc)
1327161813Swsalamon{
1328162465Srwatson
1329161813Swsalamon	return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1330161813Swsalamon}
1331161813Swsalamon#else
1332161813Swsalamon/*
1333161813Swsalamon * token ID				1 byte
1334161813Swsalamon * count				4 bytes
1335161813Swsalamon * text					count null-terminated strings
1336161813Swsalamon */
1337161813Swsalamontoken_t *
1338161813Swsalamonau_to_exec_args(char **argv)
1339161813Swsalamon{
1340155192Srwatson	token_t *t;
1341155192Srwatson	u_char *dptr = NULL;
1342155192Srwatson	const char *nextarg;
1343155192Srwatson	int i, count = 0;
1344155192Srwatson	size_t totlen = 0;
1345155192Srwatson
1346161813Swsalamon	nextarg = *argv;
1347155192Srwatson
1348155192Srwatson	while (nextarg != NULL) {
1349155192Srwatson		int nextlen;
1350155192Srwatson
1351155192Srwatson		nextlen = strlen(nextarg);
1352155192Srwatson		totlen += nextlen + 1;
1353155192Srwatson		count++;
1354161813Swsalamon		nextarg = *(argv + count);
1355155192Srwatson	}
1356155192Srwatson
1357155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1358155192Srwatson
1359155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1360155192Srwatson	ADD_U_INT32(dptr, count);
1361155192Srwatson
1362155192Srwatson	for (i = 0; i < count; i++) {
1363161813Swsalamon		nextarg = *(argv + i);
1364155192Srwatson		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1365155192Srwatson	}
1366155192Srwatson
1367155192Srwatson	return (t);
1368155192Srwatson}
1369155192Srwatson
1370155192Srwatson/*
1371155192Srwatson * token ID				1 byte
1372155192Srwatson * count				4 bytes
1373155192Srwatson * text					count null-terminated strings
1374155192Srwatson */
1375155192Srwatsontoken_t *
1376161813Swsalamonau_to_exec_env(char **envp)
1377155192Srwatson{
1378155192Srwatson	token_t *t;
1379155192Srwatson	u_char *dptr = NULL;
1380155192Srwatson	int i, count = 0;
1381155192Srwatson	size_t totlen = 0;
1382155192Srwatson	const char *nextenv;
1383155192Srwatson
1384161813Swsalamon	nextenv = *envp;
1385155192Srwatson
1386155192Srwatson	while (nextenv != NULL) {
1387155192Srwatson		int nextlen;
1388155192Srwatson
1389155192Srwatson		nextlen = strlen(nextenv);
1390155192Srwatson		totlen += nextlen + 1;
1391155192Srwatson		count++;
1392161813Swsalamon		nextenv = *(envp + count);
1393155192Srwatson	}
1394155192Srwatson
1395155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1396155192Srwatson
1397155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1398155192Srwatson	ADD_U_INT32(dptr, count);
1399155192Srwatson
1400155192Srwatson	for (i = 0; i < count; i++) {
1401161813Swsalamon		nextenv = *(envp + i);
1402155192Srwatson		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1403155192Srwatson	}
1404155192Srwatson
1405155192Srwatson	return (t);
1406155192Srwatson}
1407161813Swsalamon#endif
1408155192Srwatson
1409155192Srwatson/*
1410155192Srwatson * token ID                1 byte
1411186647Srwatson * zonename length         2 bytes
1412186647Srwatson * zonename                N bytes + 1 terminating NULL byte
1413186647Srwatson */
1414186647Srwatsontoken_t *
1415186647Srwatsonau_to_zonename(const char *zonename)
1416186647Srwatson{
1417186647Srwatson	u_char *dptr = NULL;
1418186647Srwatson	u_int16_t textlen;
1419186647Srwatson	token_t *t;
1420186647Srwatson
1421186647Srwatson	textlen = strlen(zonename) + 1;
1422186647Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1423186647Srwatson
1424186647Srwatson	ADD_U_CHAR(dptr, AUT_ZONENAME);
1425186647Srwatson	ADD_U_INT16(dptr, textlen);
1426186647Srwatson	ADD_STRING(dptr, zonename, textlen);
1427186647Srwatson	return (t);
1428186647Srwatson}
1429186647Srwatson
1430186647Srwatson/*
1431186647Srwatson * token ID                1 byte
1432155192Srwatson * record byte count       4 bytes
1433185573Srwatson * version #               1 byte    [2]
1434184856Scsjp * event type              2 bytes
1435184856Scsjp * event modifier          2 bytes
1436185573Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1437185573Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1438184856Scsjp */
1439184856Scsjptoken_t *
1440185573Srwatsonau_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1441185573Srwatson    struct timeval tm)
1442184856Scsjp{
1443185573Srwatson	token_t *t;
1444184856Scsjp	u_char *dptr = NULL;
1445184856Scsjp	u_int32_t timems;
1446184856Scsjp
1447184856Scsjp	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1448185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1449184856Scsjp
1450185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32);
1451184856Scsjp	ADD_U_INT32(dptr, rec_size);
1452184856Scsjp	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1453184856Scsjp	ADD_U_INT16(dptr, e_type);
1454184856Scsjp	ADD_U_INT16(dptr, e_mod);
1455185573Srwatson
1456185573Srwatson	timems = tm.tv_usec/1000;
1457184856Scsjp	/* Add the timestamp */
1458184856Scsjp	ADD_U_INT32(dptr, tm.tv_sec);
1459185573Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1460185573Srwatson
1461184856Scsjp	return (t);
1462184856Scsjp}
1463184856Scsjp
1464184856Scsjp/*
1465184856Scsjp * token ID                1 byte
1466184856Scsjp * record byte count       4 bytes
1467155192Srwatson * version #               1 byte    [2]
1468155192Srwatson * event type              2 bytes
1469155192Srwatson * event modifier          2 bytes
1470185573Srwatson * address type/length     4 bytes
1471185573Srwatson * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1472155192Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1473155192Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1474155192Srwatson */
1475155192Srwatsontoken_t *
1476185573Srwatsonau_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1477185573Srwatson    struct timeval tm, struct auditinfo_addr *aia)
1478155192Srwatson{
1479155192Srwatson	token_t *t;
1480155192Srwatson	u_char *dptr = NULL;
1481155192Srwatson	u_int32_t timems;
1482185573Srwatson	au_tid_addr_t *tid;
1483155192Srwatson
1484185573Srwatson	tid = &aia->ai_termid;
1485185573Srwatson	KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1486185573Srwatson	    ("au_to_header32_ex_tm: invalid address family"));
1487185573Srwatson
1488155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1489185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1490185573Srwatson	    sizeof(u_int32_t) + tid->at_type);
1491155192Srwatson
1492185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1493155192Srwatson	ADD_U_INT32(dptr, rec_size);
1494161635Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1495155192Srwatson	ADD_U_INT16(dptr, e_type);
1496155192Srwatson	ADD_U_INT16(dptr, e_mod);
1497155192Srwatson
1498185573Srwatson	ADD_U_INT32(dptr, tid->at_type);
1499185573Srwatson	if (tid->at_type == AU_IPv6)
1500185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1501185573Srwatson	else
1502185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1503155192Srwatson	timems = tm.tv_usec/1000;
1504155192Srwatson	/* Add the timestamp */
1505155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1506185573Srwatson	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1507155192Srwatson
1508243751Srwatson	return (t);
1509155192Srwatson}
1510155192Srwatson
1511168783Srwatsontoken_t *
1512168783Srwatsonau_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1513168783Srwatson    struct timeval tm)
1514168783Srwatson{
1515168783Srwatson	token_t *t;
1516168783Srwatson	u_char *dptr = NULL;
1517168783Srwatson	u_int32_t timems;
1518168783Srwatson
1519168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1520168783Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1521168783Srwatson
1522168783Srwatson	ADD_U_CHAR(dptr, AUT_HEADER64);
1523168783Srwatson	ADD_U_INT32(dptr, rec_size);
1524168783Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1525168783Srwatson	ADD_U_INT16(dptr, e_type);
1526168783Srwatson	ADD_U_INT16(dptr, e_mod);
1527168783Srwatson
1528168783Srwatson	timems = tm.tv_usec/1000;
1529168783Srwatson	/* Add the timestamp */
1530168783Srwatson	ADD_U_INT64(dptr, tm.tv_sec);
1531168783Srwatson	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1532168783Srwatson
1533168783Srwatson	return (t);
1534168783Srwatson}
1535168783Srwatson
1536185573Srwatson#if !defined(KERNEL) && !defined(_KERNEL)
1537185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1538185573Srwatsontoken_t *
1539185573Srwatsonau_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1540185573Srwatson{
1541185573Srwatson	struct timeval tm;
1542185573Srwatson	struct auditinfo_addr aia;
1543185573Srwatson
1544185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1545185573Srwatson		return (NULL);
1546191270Srwatson	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1547185573Srwatson		if (errno != ENOSYS)
1548185573Srwatson			return (NULL);
1549185573Srwatson		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1550185573Srwatson	}
1551185573Srwatson	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1552185573Srwatson}
1553185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1554185573Srwatson
1555185573Srwatsontoken_t *
1556185573Srwatsonau_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1557185573Srwatson{
1558185573Srwatson	struct timeval tm;
1559185573Srwatson
1560185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1561185573Srwatson		return (NULL);
1562185573Srwatson	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1563185573Srwatson}
1564185573Srwatson
1565185573Srwatsontoken_t *
1566185573Srwatsonau_to_header64(__unused int rec_size, __unused au_event_t e_type,
1567185573Srwatson    __unused au_emod_t e_mod)
1568185573Srwatson{
1569185573Srwatson	struct timeval tm;
1570185573Srwatson
1571185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1572185573Srwatson		return (NULL);
1573185573Srwatson	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1574185573Srwatson}
1575185573Srwatson
1576185573Srwatsontoken_t *
1577185573Srwatsonau_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1578185573Srwatson{
1579185573Srwatson
1580185573Srwatson	return (au_to_header32(rec_size, e_type, e_mod));
1581185573Srwatson}
1582185573Srwatson
1583185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1584185573Srwatsontoken_t *
1585185573Srwatsonau_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1586185573Srwatson{
1587185573Srwatson
1588185573Srwatson	return (au_to_header32_ex(rec_size, e_type, e_mod));
1589185573Srwatson}
1590185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1591185573Srwatson#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1592185573Srwatson
1593155192Srwatson/*
1594155192Srwatson * token ID                1 byte
1595155192Srwatson * trailer magic number    2 bytes
1596155192Srwatson * record byte count       4 bytes
1597155192Srwatson */
1598155192Srwatsontoken_t *
1599155192Srwatsonau_to_trailer(int rec_size)
1600155192Srwatson{
1601155192Srwatson	token_t *t;
1602155192Srwatson	u_char *dptr = NULL;
1603186647Srwatson	u_int16_t magic = AUT_TRAILER_MAGIC;
1604155192Srwatson
1605155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1606155192Srwatson	    sizeof(u_int32_t));
1607155192Srwatson
1608155192Srwatson	ADD_U_CHAR(dptr, AUT_TRAILER);
1609155192Srwatson	ADD_U_INT16(dptr, magic);
1610155192Srwatson	ADD_U_INT32(dptr, rec_size);
1611155192Srwatson
1612155192Srwatson	return (t);
1613155192Srwatson}
1614