bsm_token.c revision 243751
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: head/sys/security/audit/audit_bsm_token.c 243751 2012-12-01 13:46:37Z rwatson $");
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
838155192Srwatson/*
839155192Srwatson * token ID                1 byte
840155192Srwatson * error status            1 byte
841155192Srwatson * return value            4 bytes/8 bytes (32-bit/64-bit value)
842155192Srwatson */
843155192Srwatsontoken_t *
844155192Srwatsonau_to_return32(char status, u_int32_t ret)
845155192Srwatson{
846155192Srwatson	token_t *t;
847155192Srwatson	u_char *dptr = NULL;
848155192Srwatson
849155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
850155192Srwatson
851155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN32);
852155192Srwatson	ADD_U_CHAR(dptr, status);
853155192Srwatson	ADD_U_INT32(dptr, ret);
854155192Srwatson
855155192Srwatson	return (t);
856155192Srwatson}
857155192Srwatson
858155192Srwatsontoken_t *
859155192Srwatsonau_to_return64(char status, u_int64_t ret)
860155192Srwatson{
861155192Srwatson	token_t *t;
862155192Srwatson	u_char *dptr = NULL;
863155192Srwatson
864155192Srwatson	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
865155192Srwatson
866155192Srwatson	ADD_U_CHAR(dptr, AUT_RETURN64);
867155192Srwatson	ADD_U_CHAR(dptr, status);
868155192Srwatson	ADD_U_INT64(dptr, ret);
869155192Srwatson
870155192Srwatson	return (t);
871155192Srwatson}
872155192Srwatson
873155192Srwatsontoken_t *
874155192Srwatsonau_to_return(char status, u_int32_t ret)
875155192Srwatson{
876155192Srwatson
877155192Srwatson	return (au_to_return32(status, ret));
878155192Srwatson}
879155192Srwatson
880155192Srwatson/*
881155192Srwatson * token ID                1 byte
882155192Srwatson * sequence number         4 bytes
883155192Srwatson */
884155192Srwatsontoken_t *
885155192Srwatsonau_to_seq(long audit_count)
886155192Srwatson{
887155192Srwatson	token_t *t;
888155192Srwatson	u_char *dptr = NULL;
889155192Srwatson
890155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
891155192Srwatson
892155192Srwatson	ADD_U_CHAR(dptr, AUT_SEQ);
893155192Srwatson	ADD_U_INT32(dptr, audit_count);
894155192Srwatson
895155192Srwatson	return (t);
896155192Srwatson}
897155192Srwatson
898155192Srwatson/*
899155192Srwatson * token ID                1 byte
900186647Srwatson * socket domain           2 bytes
901155192Srwatson * socket type             2 bytes
902186647Srwatson * address type            2 byte
903155192Srwatson * local port              2 bytes
904186647Srwatson * local address           4 bytes/16 bytes (IPv4/IPv6 address)
905155192Srwatson * remote port             2 bytes
906186647Srwatson * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
907187214Srwatson *
908187214Srwatson * Domain and type arguments to this routine are assumed to already have been
909187214Srwatson * converted to the BSM constant space, so we don't do that here.
910155192Srwatson */
911155192Srwatsontoken_t *
912186647Srwatsonau_to_socket_ex(u_short so_domain, u_short so_type,
913186647Srwatson    struct sockaddr *sa_local, struct sockaddr *sa_remote)
914155192Srwatson{
915186647Srwatson	token_t *t;
916186647Srwatson	u_char *dptr = NULL;
917186647Srwatson	struct sockaddr_in *sin;
918186647Srwatson	struct sockaddr_in6 *sin6;
919155192Srwatson
920186647Srwatson	if (so_domain == AF_INET)
921186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
922186647Srwatson		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
923186647Srwatson	else if (so_domain == AF_INET6)
924186647Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
925189279Srwatson		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
926186647Srwatson	else
927186647Srwatson		return (NULL);
928186647Srwatson
929186647Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
930189279Srwatson	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
931189279Srwatson	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
932186647Srwatson	if (so_domain == AF_INET) {
933186647Srwatson		ADD_U_INT16(dptr, AU_IPv4);
934186647Srwatson		sin = (struct sockaddr_in *)sa_local;
935186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
936186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
937186647Srwatson		sin = (struct sockaddr_in *)sa_remote;
938186647Srwatson		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
939186647Srwatson		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
940186647Srwatson	} else {
941186647Srwatson		ADD_U_INT16(dptr, AU_IPv6);
942186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_local;
943186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
944186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
945186647Srwatson		sin6 = (struct sockaddr_in6 *)sa_remote;
946186647Srwatson		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
947186647Srwatson		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
948186647Srwatson	}
949186647Srwatson
950186647Srwatson	return (t);
951155192Srwatson}
952155192Srwatson
953155192Srwatson/*
954155192Srwatson * Kernel-specific version of the above function.
955186647Srwatson *
956186647Srwatson * XXXRW: Should now use au_to_socket_ex() here.
957155192Srwatson */
958155192Srwatson#ifdef _KERNEL
959155192Srwatsontoken_t *
960155192Srwatsonkau_to_socket(struct socket_au_info *soi)
961155192Srwatson{
962155192Srwatson	token_t *t;
963155192Srwatson	u_char *dptr;
964155192Srwatson	u_int16_t so_type;
965155192Srwatson
966155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
967155192Srwatson	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
968186647Srwatson
969185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKET);
970155192Srwatson	/* Coerce the socket type into a short value */
971155192Srwatson	so_type = soi->so_type;
972155192Srwatson	ADD_U_INT16(dptr, so_type);
973155192Srwatson	ADD_U_INT16(dptr, soi->so_lport);
974155192Srwatson	ADD_U_INT32(dptr, soi->so_laddr);
975155192Srwatson	ADD_U_INT16(dptr, soi->so_rport);
976155192Srwatson	ADD_U_INT32(dptr, soi->so_raddr);
977155192Srwatson
978155192Srwatson	return (t);
979155192Srwatson}
980155192Srwatson#endif
981155192Srwatson
982155192Srwatson/*
983155192Srwatson * token ID                1 byte
984155192Srwatson * socket family           2 bytes
985195740Srwatson * path                    (up to) 104 bytes + NULL  (NULL terminated string)
986155192Srwatson */
987155192Srwatsontoken_t *
988155192Srwatsonau_to_sock_unix(struct sockaddr_un *so)
989155192Srwatson{
990155192Srwatson	token_t *t;
991155192Srwatson	u_char *dptr;
992155192Srwatson
993155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
994155192Srwatson
995185573Srwatson	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
996155192Srwatson	/* BSM token has two bytes for family */
997155192Srwatson	ADD_U_CHAR(dptr, 0);
998155192Srwatson	ADD_U_CHAR(dptr, so->sun_family);
999155192Srwatson	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1000155192Srwatson
1001155192Srwatson	return (t);
1002155192Srwatson}
1003155192Srwatson
1004155192Srwatson/*
1005155192Srwatson * token ID                1 byte
1006155192Srwatson * socket family           2 bytes
1007155192Srwatson * local port              2 bytes
1008155192Srwatson * socket address          4 bytes
1009155192Srwatson */
1010155192Srwatsontoken_t *
1011155192Srwatsonau_to_sock_inet32(struct sockaddr_in *so)
1012155192Srwatson{
1013155192Srwatson	token_t *t;
1014155192Srwatson	u_char *dptr = NULL;
1015159259Srwatson	uint16_t family;
1016155192Srwatson
1017159259Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1018159259Srwatson	    sizeof(uint32_t));
1019155192Srwatson
1020155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1021155192Srwatson	/*
1022159259Srwatson	 * BSM defines the family field as 16 bits, but many operating
1023159259Srwatson	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1024159259Srwatson	 * writing into the token.  Assume that both the port and the address
1025159259Srwatson	 * in the sockaddr_in are already in network byte order, but family
1026159259Srwatson	 * is in local byte order.
1027159259Srwatson	 *
1028159259Srwatson	 * XXXRW: Should a name space conversion be taking place on the value
1029159259Srwatson	 * of sin_family?
1030180709Srwatson	 */
1031159259Srwatson	family = so->sin_family;
1032159259Srwatson	ADD_U_INT16(dptr, family);
1033159259Srwatson	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1034159259Srwatson	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1035155192Srwatson
1036155192Srwatson	return (t);
1037155192Srwatson}
1038155192Srwatson
1039155192Srwatsontoken_t *
1040155192Srwatsonau_to_sock_inet128(struct sockaddr_in6 *so)
1041155192Srwatson{
1042155192Srwatson	token_t *t;
1043155192Srwatson	u_char *dptr = NULL;
1044155192Srwatson
1045155192Srwatson	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1046155192Srwatson	    4 * sizeof(u_int32_t));
1047155192Srwatson
1048155192Srwatson	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1049155192Srwatson	/*
1050186647Srwatson	 * In BSD, sin6_family is one octet, but BSM defines the token to
1051186647Srwatson	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1052186647Srwatson	 * conditionally compiled.
1053180709Srwatson	 */
1054155192Srwatson	ADD_U_CHAR(dptr, 0);
1055155192Srwatson	ADD_U_CHAR(dptr, so->sin6_family);
1056155192Srwatson
1057155192Srwatson	ADD_U_INT16(dptr, so->sin6_port);
1058159259Srwatson	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1059155192Srwatson
1060155192Srwatson	return (t);
1061155192Srwatson}
1062155192Srwatson
1063155192Srwatsontoken_t *
1064155192Srwatsonau_to_sock_inet(struct sockaddr_in *so)
1065155192Srwatson{
1066155192Srwatson
1067155192Srwatson	return (au_to_sock_inet32(so));
1068155192Srwatson}
1069155192Srwatson
1070155192Srwatson/*
1071155192Srwatson * token ID                1 byte
1072155192Srwatson * audit ID                4 bytes
1073155192Srwatson * effective user ID       4 bytes
1074155192Srwatson * effective group ID      4 bytes
1075155192Srwatson * real user ID            4 bytes
1076155192Srwatson * real group ID           4 bytes
1077155192Srwatson * process ID              4 bytes
1078155192Srwatson * session ID              4 bytes
1079155192Srwatson * terminal ID
1080155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1081155192Srwatson *   machine address       4 bytes
1082155192Srwatson */
1083155192Srwatsontoken_t *
1084155192Srwatsonau_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1085155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1086155192Srwatson{
1087155192Srwatson	token_t *t;
1088155192Srwatson	u_char *dptr = NULL;
1089155192Srwatson
1090155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1091155192Srwatson
1092155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1093155192Srwatson	ADD_U_INT32(dptr, auid);
1094155192Srwatson	ADD_U_INT32(dptr, euid);
1095155192Srwatson	ADD_U_INT32(dptr, egid);
1096155192Srwatson	ADD_U_INT32(dptr, ruid);
1097155192Srwatson	ADD_U_INT32(dptr, rgid);
1098155192Srwatson	ADD_U_INT32(dptr, pid);
1099155192Srwatson	ADD_U_INT32(dptr, sid);
1100155192Srwatson	ADD_U_INT32(dptr, tid->port);
1101159259Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1102155192Srwatson
1103155192Srwatson	return (t);
1104155192Srwatson}
1105155192Srwatson
1106155192Srwatsontoken_t *
1107155192Srwatsonau_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1108155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1109155192Srwatson{
1110168783Srwatson	token_t *t;
1111168783Srwatson	u_char *dptr = NULL;
1112155192Srwatson
1113168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1114168783Srwatson	    sizeof(u_int64_t) + sizeof(u_int32_t));
1115168783Srwatson
1116168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1117168783Srwatson	ADD_U_INT32(dptr, auid);
1118168783Srwatson	ADD_U_INT32(dptr, euid);
1119168783Srwatson	ADD_U_INT32(dptr, egid);
1120168783Srwatson	ADD_U_INT32(dptr, ruid);
1121168783Srwatson	ADD_U_INT32(dptr, rgid);
1122168783Srwatson	ADD_U_INT32(dptr, pid);
1123168783Srwatson	ADD_U_INT32(dptr, sid);
1124168783Srwatson	ADD_U_INT64(dptr, tid->port);
1125168783Srwatson	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1126168783Srwatson
1127168783Srwatson	return (t);
1128155192Srwatson}
1129155192Srwatson
1130155192Srwatsontoken_t *
1131155192Srwatsonau_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1132155192Srwatson    pid_t pid, au_asid_t sid, au_tid_t *tid)
1133155192Srwatson{
1134155192Srwatson
1135155192Srwatson	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1136155192Srwatson	    tid));
1137155192Srwatson}
1138155192Srwatson
1139155192Srwatson/*
1140155192Srwatson * token ID                1 byte
1141155192Srwatson * audit ID                4 bytes
1142155192Srwatson * effective user ID       4 bytes
1143155192Srwatson * effective group ID      4 bytes
1144155192Srwatson * real user ID            4 bytes
1145155192Srwatson * real group ID           4 bytes
1146155192Srwatson * process ID              4 bytes
1147155192Srwatson * session ID              4 bytes
1148155192Srwatson * terminal ID
1149155192Srwatson *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1150155192Srwatson *   address type/length   4 bytes
1151185573Srwatson *   machine address      16 bytes
1152155192Srwatson */
1153155192Srwatsontoken_t *
1154155192Srwatsonau_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1155155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1156155192Srwatson{
1157155192Srwatson	token_t *t;
1158155192Srwatson	u_char *dptr = NULL;
1159155192Srwatson
1160168688Scsjp	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1161168688Scsjp	    ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1162185573Srwatson
1163185573Srwatson	if (tid->at_type == AU_IPv4)
1164185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1165159686Swsalamon		    sizeof(u_int32_t));
1166159686Swsalamon	else
1167185573Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1168159686Swsalamon		    sizeof(u_int32_t));
1169155192Srwatson
1170155192Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1171155192Srwatson	ADD_U_INT32(dptr, auid);
1172155192Srwatson	ADD_U_INT32(dptr, euid);
1173155192Srwatson	ADD_U_INT32(dptr, egid);
1174155192Srwatson	ADD_U_INT32(dptr, ruid);
1175155192Srwatson	ADD_U_INT32(dptr, rgid);
1176155192Srwatson	ADD_U_INT32(dptr, pid);
1177155192Srwatson	ADD_U_INT32(dptr, sid);
1178155192Srwatson	ADD_U_INT32(dptr, tid->at_port);
1179155192Srwatson	ADD_U_INT32(dptr, tid->at_type);
1180185573Srwatson	if (tid->at_type == AU_IPv6)
1181168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1182185573Srwatson	else
1183168688Scsjp		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1184170131Srwatson
1185155192Srwatson	return (t);
1186155192Srwatson}
1187155192Srwatson
1188155192Srwatsontoken_t *
1189155192Srwatsonau_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1190155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1191155192Srwatson{
1192168783Srwatson	token_t *t;
1193168783Srwatson	u_char *dptr = NULL;
1194155192Srwatson
1195185573Srwatson	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1196185573Srwatson	    ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1197185573Srwatson
1198168783Srwatson	if (tid->at_type == AU_IPv4)
1199168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1200168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1201168783Srwatson		    2 * sizeof(u_int32_t));
1202185573Srwatson	else
1203168783Srwatson		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1204168783Srwatson		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1205168783Srwatson		    5 * sizeof(u_int32_t));
1206168783Srwatson
1207168783Srwatson	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1208168783Srwatson	ADD_U_INT32(dptr, auid);
1209168783Srwatson	ADD_U_INT32(dptr, euid);
1210168783Srwatson	ADD_U_INT32(dptr, egid);
1211168783Srwatson	ADD_U_INT32(dptr, ruid);
1212168783Srwatson	ADD_U_INT32(dptr, rgid);
1213168783Srwatson	ADD_U_INT32(dptr, pid);
1214168783Srwatson	ADD_U_INT32(dptr, sid);
1215168783Srwatson	ADD_U_INT64(dptr, tid->at_port);
1216168783Srwatson	ADD_U_INT32(dptr, tid->at_type);
1217168783Srwatson	if (tid->at_type == AU_IPv6)
1218168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1219168783Srwatson	else
1220168783Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1221168783Srwatson
1222168783Srwatson	return (t);
1223155192Srwatson}
1224155192Srwatson
1225155192Srwatsontoken_t *
1226155192Srwatsonau_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1227155192Srwatson    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1228155192Srwatson{
1229155192Srwatson
1230155192Srwatson	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1231155192Srwatson	    tid));
1232155192Srwatson}
1233155192Srwatson
1234156291Srwatson#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1235155192Srwatson/*
1236185573Srwatson * Collects audit information for the current process and creates a subject
1237185573Srwatson * token from it.
1238155192Srwatson */
1239155192Srwatsontoken_t *
1240155192Srwatsonau_to_me(void)
1241155192Srwatson{
1242155192Srwatson	auditinfo_t auinfo;
1243195740Srwatson	auditinfo_addr_t aia;
1244155192Srwatson
1245195740Srwatson	/*
1246195740Srwatson	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1247195740Srwatson	 * it, then fall back on to getaudit(2).
1248195740Srwatson	 */
1249195740Srwatson	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1250195740Srwatson		if (errno == ENOSYS) {
1251195740Srwatson			if (getaudit(&auinfo) != 0)
1252195740Srwatson				return (NULL);
1253195740Srwatson			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1254195740Srwatson				getegid(), getuid(), getgid(), getpid(),
1255195740Srwatson				auinfo.ai_asid, &auinfo.ai_termid));
1256195740Srwatson		} else {
1257195740Srwatson			/* getaudit_addr(2) failed for some other reason. */
1258243751Srwatson			return (NULL);
1259195740Srwatson		}
1260243751Srwatson	}
1261155192Srwatson
1262195740Srwatson	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1263195740Srwatson		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1264155192Srwatson}
1265155192Srwatson#endif
1266155192Srwatson
1267161813Swsalamon#if defined(_KERNEL) || defined(KERNEL)
1268161813Swsalamonstatic token_t *
1269161813Swsalamonau_to_exec_strings(char *strs, int count, u_char type)
1270161813Swsalamon{
1271161813Swsalamon	token_t *t;
1272161813Swsalamon	u_char *dptr = NULL;
1273161813Swsalamon	u_int32_t totlen;
1274161813Swsalamon	int ctr;
1275161813Swsalamon	char *p;
1276161813Swsalamon
1277161813Swsalamon	totlen = 0;
1278161813Swsalamon	ctr = count;
1279161813Swsalamon	p = strs;
1280161813Swsalamon	while (ctr-- > 0) {
1281161813Swsalamon		totlen += strlen(p) + 1;
1282161813Swsalamon		p = strs + totlen;
1283161813Swsalamon	}
1284161813Swsalamon	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1285161813Swsalamon	ADD_U_CHAR(dptr, type);
1286161813Swsalamon	ADD_U_INT32(dptr, count);
1287161813Swsalamon	ADD_STRING(dptr, strs, totlen);
1288161813Swsalamon
1289161813Swsalamon	return (t);
1290161813Swsalamon}
1291161813Swsalamon
1292155192Srwatson/*
1293155192Srwatson * token ID				1 byte
1294155192Srwatson * count				4 bytes
1295155192Srwatson * text					count null-terminated strings
1296155192Srwatson */
1297155192Srwatsontoken_t *
1298161813Swsalamonau_to_exec_args(char *args, int argc)
1299155192Srwatson{
1300162465Srwatson
1301161813Swsalamon	return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1302161813Swsalamon}
1303161813Swsalamon
1304161813Swsalamon/*
1305161813Swsalamon * token ID				1 byte
1306161813Swsalamon * count				4 bytes
1307161813Swsalamon * text					count null-terminated strings
1308161813Swsalamon */
1309161813Swsalamontoken_t *
1310161813Swsalamonau_to_exec_env(char *envs, int envc)
1311161813Swsalamon{
1312162465Srwatson
1313161813Swsalamon	return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1314161813Swsalamon}
1315161813Swsalamon#else
1316161813Swsalamon/*
1317161813Swsalamon * token ID				1 byte
1318161813Swsalamon * count				4 bytes
1319161813Swsalamon * text					count null-terminated strings
1320161813Swsalamon */
1321161813Swsalamontoken_t *
1322161813Swsalamonau_to_exec_args(char **argv)
1323161813Swsalamon{
1324155192Srwatson	token_t *t;
1325155192Srwatson	u_char *dptr = NULL;
1326155192Srwatson	const char *nextarg;
1327155192Srwatson	int i, count = 0;
1328155192Srwatson	size_t totlen = 0;
1329155192Srwatson
1330161813Swsalamon	nextarg = *argv;
1331155192Srwatson
1332155192Srwatson	while (nextarg != NULL) {
1333155192Srwatson		int nextlen;
1334155192Srwatson
1335155192Srwatson		nextlen = strlen(nextarg);
1336155192Srwatson		totlen += nextlen + 1;
1337155192Srwatson		count++;
1338161813Swsalamon		nextarg = *(argv + count);
1339155192Srwatson	}
1340155192Srwatson
1341155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1342155192Srwatson
1343155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1344155192Srwatson	ADD_U_INT32(dptr, count);
1345155192Srwatson
1346155192Srwatson	for (i = 0; i < count; i++) {
1347161813Swsalamon		nextarg = *(argv + i);
1348155192Srwatson		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1349155192Srwatson	}
1350155192Srwatson
1351155192Srwatson	return (t);
1352155192Srwatson}
1353155192Srwatson
1354155192Srwatson/*
1355155192Srwatson * token ID				1 byte
1356155192Srwatson * count				4 bytes
1357155192Srwatson * text					count null-terminated strings
1358155192Srwatson */
1359155192Srwatsontoken_t *
1360161813Swsalamonau_to_exec_env(char **envp)
1361155192Srwatson{
1362155192Srwatson	token_t *t;
1363155192Srwatson	u_char *dptr = NULL;
1364155192Srwatson	int i, count = 0;
1365155192Srwatson	size_t totlen = 0;
1366155192Srwatson	const char *nextenv;
1367155192Srwatson
1368161813Swsalamon	nextenv = *envp;
1369155192Srwatson
1370155192Srwatson	while (nextenv != NULL) {
1371155192Srwatson		int nextlen;
1372155192Srwatson
1373155192Srwatson		nextlen = strlen(nextenv);
1374155192Srwatson		totlen += nextlen + 1;
1375155192Srwatson		count++;
1376161813Swsalamon		nextenv = *(envp + count);
1377155192Srwatson	}
1378155192Srwatson
1379155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1380155192Srwatson
1381155192Srwatson	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1382155192Srwatson	ADD_U_INT32(dptr, count);
1383155192Srwatson
1384155192Srwatson	for (i = 0; i < count; i++) {
1385161813Swsalamon		nextenv = *(envp + i);
1386155192Srwatson		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1387155192Srwatson	}
1388155192Srwatson
1389155192Srwatson	return (t);
1390155192Srwatson}
1391161813Swsalamon#endif
1392155192Srwatson
1393155192Srwatson/*
1394155192Srwatson * token ID                1 byte
1395186647Srwatson * zonename length         2 bytes
1396186647Srwatson * zonename                N bytes + 1 terminating NULL byte
1397186647Srwatson */
1398186647Srwatsontoken_t *
1399186647Srwatsonau_to_zonename(const char *zonename)
1400186647Srwatson{
1401186647Srwatson	u_char *dptr = NULL;
1402186647Srwatson	u_int16_t textlen;
1403186647Srwatson	token_t *t;
1404186647Srwatson
1405186647Srwatson	textlen = strlen(zonename) + 1;
1406186647Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1407186647Srwatson
1408186647Srwatson	ADD_U_CHAR(dptr, AUT_ZONENAME);
1409186647Srwatson	ADD_U_INT16(dptr, textlen);
1410186647Srwatson	ADD_STRING(dptr, zonename, textlen);
1411186647Srwatson	return (t);
1412186647Srwatson}
1413186647Srwatson
1414186647Srwatson/*
1415186647Srwatson * token ID                1 byte
1416155192Srwatson * record byte count       4 bytes
1417185573Srwatson * version #               1 byte    [2]
1418184856Scsjp * event type              2 bytes
1419184856Scsjp * event modifier          2 bytes
1420185573Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1421185573Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1422184856Scsjp */
1423184856Scsjptoken_t *
1424185573Srwatsonau_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1425185573Srwatson    struct timeval tm)
1426184856Scsjp{
1427185573Srwatson	token_t *t;
1428184856Scsjp	u_char *dptr = NULL;
1429184856Scsjp	u_int32_t timems;
1430184856Scsjp
1431184856Scsjp	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1432185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1433184856Scsjp
1434185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32);
1435184856Scsjp	ADD_U_INT32(dptr, rec_size);
1436184856Scsjp	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1437184856Scsjp	ADD_U_INT16(dptr, e_type);
1438184856Scsjp	ADD_U_INT16(dptr, e_mod);
1439185573Srwatson
1440185573Srwatson	timems = tm.tv_usec/1000;
1441184856Scsjp	/* Add the timestamp */
1442184856Scsjp	ADD_U_INT32(dptr, tm.tv_sec);
1443185573Srwatson	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1444185573Srwatson
1445184856Scsjp	return (t);
1446184856Scsjp}
1447184856Scsjp
1448184856Scsjp/*
1449184856Scsjp * token ID                1 byte
1450184856Scsjp * record byte count       4 bytes
1451155192Srwatson * version #               1 byte    [2]
1452155192Srwatson * event type              2 bytes
1453155192Srwatson * event modifier          2 bytes
1454185573Srwatson * address type/length     4 bytes
1455185573Srwatson * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1456155192Srwatson * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1457155192Srwatson * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1458155192Srwatson */
1459155192Srwatsontoken_t *
1460185573Srwatsonau_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1461185573Srwatson    struct timeval tm, struct auditinfo_addr *aia)
1462155192Srwatson{
1463155192Srwatson	token_t *t;
1464155192Srwatson	u_char *dptr = NULL;
1465155192Srwatson	u_int32_t timems;
1466185573Srwatson	au_tid_addr_t *tid;
1467155192Srwatson
1468185573Srwatson	tid = &aia->ai_termid;
1469185573Srwatson	KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1470185573Srwatson	    ("au_to_header32_ex_tm: invalid address family"));
1471185573Srwatson
1472155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1473185573Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1474185573Srwatson	    sizeof(u_int32_t) + tid->at_type);
1475155192Srwatson
1476185573Srwatson	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1477155192Srwatson	ADD_U_INT32(dptr, rec_size);
1478161635Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1479155192Srwatson	ADD_U_INT16(dptr, e_type);
1480155192Srwatson	ADD_U_INT16(dptr, e_mod);
1481155192Srwatson
1482185573Srwatson	ADD_U_INT32(dptr, tid->at_type);
1483185573Srwatson	if (tid->at_type == AU_IPv6)
1484185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1485185573Srwatson	else
1486185573Srwatson		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1487155192Srwatson	timems = tm.tv_usec/1000;
1488155192Srwatson	/* Add the timestamp */
1489155192Srwatson	ADD_U_INT32(dptr, tm.tv_sec);
1490185573Srwatson	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1491155192Srwatson
1492243751Srwatson	return (t);
1493155192Srwatson}
1494155192Srwatson
1495168783Srwatsontoken_t *
1496168783Srwatsonau_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1497168783Srwatson    struct timeval tm)
1498168783Srwatson{
1499168783Srwatson	token_t *t;
1500168783Srwatson	u_char *dptr = NULL;
1501168783Srwatson	u_int32_t timems;
1502168783Srwatson
1503168783Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1504168783Srwatson	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1505168783Srwatson
1506168783Srwatson	ADD_U_CHAR(dptr, AUT_HEADER64);
1507168783Srwatson	ADD_U_INT32(dptr, rec_size);
1508168783Srwatson	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1509168783Srwatson	ADD_U_INT16(dptr, e_type);
1510168783Srwatson	ADD_U_INT16(dptr, e_mod);
1511168783Srwatson
1512168783Srwatson	timems = tm.tv_usec/1000;
1513168783Srwatson	/* Add the timestamp */
1514168783Srwatson	ADD_U_INT64(dptr, tm.tv_sec);
1515168783Srwatson	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1516168783Srwatson
1517168783Srwatson	return (t);
1518168783Srwatson}
1519168783Srwatson
1520185573Srwatson#if !defined(KERNEL) && !defined(_KERNEL)
1521185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1522185573Srwatsontoken_t *
1523185573Srwatsonau_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1524185573Srwatson{
1525185573Srwatson	struct timeval tm;
1526185573Srwatson	struct auditinfo_addr aia;
1527185573Srwatson
1528185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1529185573Srwatson		return (NULL);
1530191270Srwatson	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1531185573Srwatson		if (errno != ENOSYS)
1532185573Srwatson			return (NULL);
1533185573Srwatson		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1534185573Srwatson	}
1535185573Srwatson	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1536185573Srwatson}
1537185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1538185573Srwatson
1539185573Srwatsontoken_t *
1540185573Srwatsonau_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1541185573Srwatson{
1542185573Srwatson	struct timeval tm;
1543185573Srwatson
1544185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1545185573Srwatson		return (NULL);
1546185573Srwatson	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1547185573Srwatson}
1548185573Srwatson
1549185573Srwatsontoken_t *
1550185573Srwatsonau_to_header64(__unused int rec_size, __unused au_event_t e_type,
1551185573Srwatson    __unused au_emod_t e_mod)
1552185573Srwatson{
1553185573Srwatson	struct timeval tm;
1554185573Srwatson
1555185573Srwatson	if (gettimeofday(&tm, NULL) == -1)
1556185573Srwatson		return (NULL);
1557185573Srwatson	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1558185573Srwatson}
1559185573Srwatson
1560185573Srwatsontoken_t *
1561185573Srwatsonau_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1562185573Srwatson{
1563185573Srwatson
1564185573Srwatson	return (au_to_header32(rec_size, e_type, e_mod));
1565185573Srwatson}
1566185573Srwatson
1567185573Srwatson#ifdef HAVE_AUDIT_SYSCALLS
1568185573Srwatsontoken_t *
1569185573Srwatsonau_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1570185573Srwatson{
1571185573Srwatson
1572185573Srwatson	return (au_to_header32_ex(rec_size, e_type, e_mod));
1573185573Srwatson}
1574185573Srwatson#endif /* HAVE_AUDIT_SYSCALLS */
1575185573Srwatson#endif /* !defined(KERNEL) && !defined(_KERNEL) */
1576185573Srwatson
1577155192Srwatson/*
1578155192Srwatson * token ID                1 byte
1579155192Srwatson * trailer magic number    2 bytes
1580155192Srwatson * record byte count       4 bytes
1581155192Srwatson */
1582155192Srwatsontoken_t *
1583155192Srwatsonau_to_trailer(int rec_size)
1584155192Srwatson{
1585155192Srwatson	token_t *t;
1586155192Srwatson	u_char *dptr = NULL;
1587186647Srwatson	u_int16_t magic = AUT_TRAILER_MAGIC;
1588155192Srwatson
1589155192Srwatson	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1590155192Srwatson	    sizeof(u_int32_t));
1591155192Srwatson
1592155192Srwatson	ADD_U_CHAR(dptr, AUT_TRAILER);
1593155192Srwatson	ADD_U_INT16(dptr, magic);
1594155192Srwatson	ADD_U_INT32(dptr, rec_size);
1595155192Srwatson
1596155192Srwatson	return (t);
1597155192Srwatson}
1598