xref: /freebsd/sys/security/audit/bsm_token.c (revision 1db64f89363c97858961c4df0b7d02f3223723cf)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 2004-2009 Apple Inc.
5  * Copyright (c) 2005 SPARTA, Inc.
6  * All rights reserved.
7  *
8  * This code was developed in part by Robert N. M. Watson, Senior Principal
9  * Scientist, SPARTA, Inc.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1.  Redistributions of source code must retain the above copyright
15  *     notice, this list of conditions and the following disclaimer.
16  * 2.  Redistributions in binary form must reproduce the above copyright
17  *     notice, this list of conditions and the following disclaimer in the
18  *     documentation and/or other materials provided with the distribution.
19  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
20  *     its contributors may be used to endorse or promote products derived
21  *     from this software without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
27  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #include <sys/param.h>
37 #include <sys/types.h>
38 #include <sys/endian.h>
39 #include <sys/queue.h>
40 #include <sys/socket.h>
41 #include <sys/time.h>
42 
43 #include <sys/ipc.h>
44 #include <sys/libkern.h>
45 #include <sys/malloc.h>
46 #include <sys/un.h>
47 
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/ip.h>
51 
52 #include <bsm/audit.h>
53 #include <bsm/audit_internal.h>
54 #include <bsm/audit_record.h>
55 #include <security/audit/audit.h>
56 #include <security/audit/audit_private.h>
57 
58 #define	GET_TOKEN_AREA(t, dptr, length) do {				\
59 	t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);		\
60 	t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);	\
61 	t->len = length;						\
62 	dptr = t->t_data;						\
63 } while (0)
64 
65 /*
66  * token ID                1 byte
67  * success/failure         1 byte
68  * privstrlen              2 bytes
69  * privstr                 N bytes + 1 (\0 byte)
70  */
71 token_t *
72 au_to_upriv(char sorf, char *priv)
73 {
74 	u_int16_t textlen;
75 	u_char *dptr;
76 	token_t *t;
77 
78 	textlen = strlen(priv) + 1;
79 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
80 	    sizeof(u_int16_t) + textlen);
81 
82 	ADD_U_CHAR(dptr, AUT_UPRIV);
83 	ADD_U_CHAR(dptr, sorf);
84 	ADD_U_INT16(dptr, textlen);
85 	ADD_STRING(dptr, priv, textlen);
86 	return (t);
87 }
88 
89 /*
90  * token ID		1 byte
91  * privtstrlen		2 bytes
92  * privtstr		N bytes + 1
93  * privstrlen		2 bytes
94  * privstr		N bytes + 1
95  */
96 token_t *
97 au_to_privset(char *privtypestr, char *privstr)
98 {
99 	u_int16_t	 type_len, priv_len;
100 	u_char		*dptr;
101 	token_t		*t;
102 
103 	type_len = strlen(privtypestr) + 1;
104 	priv_len = strlen(privstr) + 1;
105 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
106 	    sizeof(u_int16_t) + type_len + priv_len);
107 
108 	ADD_U_CHAR(dptr, AUT_PRIV);
109 	ADD_U_INT16(dptr, type_len);
110 	ADD_STRING(dptr, privtypestr, type_len);
111 	ADD_U_INT16(dptr, priv_len);
112 	ADD_STRING(dptr, privstr, priv_len);
113 	return (t);
114 }
115 
116 /*
117  * token ID                1 byte
118  * argument #              1 byte
119  * argument value          4 bytes/8 bytes (32-bit/64-bit value)
120  * text length             2 bytes
121  * text                    N bytes + 1 terminating NULL byte
122  */
123 token_t *
124 au_to_arg32(char n, const char *text, u_int32_t v)
125 {
126 	token_t *t;
127 	u_char *dptr = NULL;
128 	u_int16_t textlen;
129 
130 	textlen = strlen(text);
131 	textlen += 1;
132 
133 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
134 	    sizeof(u_int16_t) + textlen);
135 
136 	ADD_U_CHAR(dptr, AUT_ARG32);
137 	ADD_U_CHAR(dptr, n);
138 	ADD_U_INT32(dptr, v);
139 	ADD_U_INT16(dptr, textlen);
140 	ADD_STRING(dptr, text, textlen);
141 
142 	return (t);
143 }
144 
145 token_t *
146 au_to_arg64(char n, const char *text, u_int64_t v)
147 {
148 	token_t *t;
149 	u_char *dptr = NULL;
150 	u_int16_t textlen;
151 
152 	textlen = strlen(text);
153 	textlen += 1;
154 
155 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
156 	    sizeof(u_int16_t) + textlen);
157 
158 	ADD_U_CHAR(dptr, AUT_ARG64);
159 	ADD_U_CHAR(dptr, n);
160 	ADD_U_INT64(dptr, v);
161 	ADD_U_INT16(dptr, textlen);
162 	ADD_STRING(dptr, text, textlen);
163 
164 	return (t);
165 }
166 
167 token_t *
168 au_to_arg(char n, const char *text, u_int32_t v)
169 {
170 
171 	return (au_to_arg32(n, text, v));
172 }
173 
174 #if defined(_KERNEL) || defined(KERNEL)
175 /*
176  * token ID                1 byte
177  * file access mode        4 bytes
178  * owner user ID           4 bytes
179  * owner group ID          4 bytes
180  * file system ID          4 bytes
181  * node ID                 8 bytes
182  * device                  4 bytes/8 bytes (32-bit/64-bit)
183  */
184 token_t *
185 au_to_attr32(struct vnode_au_info *vni)
186 {
187 	token_t *t;
188 	u_char *dptr = NULL;
189 	u_int16_t pad0_16 = 0;
190 	u_int32_t pad0_32 = 0;
191 
192 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
193 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
194 
195 	ADD_U_CHAR(dptr, AUT_ATTR32);
196 
197 	/*
198 	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
199 	 * so pad with 0.
200 	 *
201 	 * XXXRW: Possibly should be conditionally compiled.
202 	 *
203 	 * XXXRW: Should any conversions take place on the mode?
204 	 */
205 	ADD_U_INT16(dptr, pad0_16);
206 	ADD_U_INT16(dptr, vni->vn_mode);
207 
208 	ADD_U_INT32(dptr, vni->vn_uid);
209 	ADD_U_INT32(dptr, vni->vn_gid);
210 	ADD_U_INT32(dptr, vni->vn_fsid);
211 
212 	/*
213 	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
214 	 * Attempt to handle both, and let the compiler sort it out.  If we
215 	 * could pick this out at compile-time, it would be better, so as to
216 	 * avoid the else case below.
217 	 */
218 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
219 		ADD_U_INT32(dptr, pad0_32);
220 		ADD_U_INT32(dptr, vni->vn_fileid);
221 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
222 		ADD_U_INT64(dptr, vni->vn_fileid);
223 	else
224 		ADD_U_INT64(dptr, 0LL);
225 
226 	ADD_U_INT32(dptr, vni->vn_dev);
227 
228 	return (t);
229 }
230 
231 token_t *
232 au_to_attr64(struct vnode_au_info *vni)
233 {
234 	token_t *t;
235 	u_char *dptr = NULL;
236 	u_int16_t pad0_16 = 0;
237 	u_int32_t pad0_32 = 0;
238 
239 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
240 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
241 
242 	ADD_U_CHAR(dptr, AUT_ATTR64);
243 
244 	/*
245 	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
246 	 * so pad with 0.
247 	 *
248 	 * XXXRW: Possibly should be conditionally compiled.
249 	 *
250 	 * XXXRW: Should any conversions take place on the mode?
251 	 */
252 	ADD_U_INT16(dptr, pad0_16);
253 	ADD_U_INT16(dptr, vni->vn_mode);
254 
255 	ADD_U_INT32(dptr, vni->vn_uid);
256 	ADD_U_INT32(dptr, vni->vn_gid);
257 	ADD_U_INT32(dptr, vni->vn_fsid);
258 
259 	/*
260 	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
261 	 * Attempt to handle both, and let the compiler sort it out.  If we
262 	 * could pick this out at compile-time, it would be better, so as to
263 	 * avoid the else case below.
264 	 */
265 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
266 		ADD_U_INT32(dptr, pad0_32);
267 		ADD_U_INT32(dptr, vni->vn_fileid);
268 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
269 		ADD_U_INT64(dptr, vni->vn_fileid);
270 	else
271 		ADD_U_INT64(dptr, 0LL);
272 
273 	ADD_U_INT64(dptr, vni->vn_dev);
274 
275 	return (t);
276 }
277 
278 token_t *
279 au_to_attr(struct vnode_au_info *vni)
280 {
281 
282 	return (au_to_attr32(vni));
283 }
284 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
285 
286 /*
287  * token ID                1 byte
288  * how to print            1 byte
289  * basic unit              1 byte
290  * unit count              1 byte
291  * data items              (depends on basic unit)
292  */
293 token_t *
294 au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
295 {
296 	token_t *t;
297 	u_char *dptr = NULL;
298 	size_t datasize, totdata;
299 
300 	/* Determine the size of the basic unit. */
301 	switch (unit_type) {
302 	case AUR_BYTE:
303 	/* case AUR_CHAR: */
304 		datasize = AUR_BYTE_SIZE;
305 		break;
306 
307 	case AUR_SHORT:
308 		datasize = AUR_SHORT_SIZE;
309 		break;
310 
311 	case AUR_INT32:
312 	/* case AUR_INT: */
313 		datasize = AUR_INT32_SIZE;
314 		break;
315 
316 	case AUR_INT64:
317 		datasize = AUR_INT64_SIZE;
318 		break;
319 
320 	default:
321 		return (NULL);
322 	}
323 
324 	totdata = datasize * unit_count;
325 
326 	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
327 
328 	/*
329 	 * XXXRW: We should be byte-swapping each data item for multi-byte
330 	 * types.
331 	 */
332 	ADD_U_CHAR(dptr, AUT_DATA);
333 	ADD_U_CHAR(dptr, unit_print);
334 	ADD_U_CHAR(dptr, unit_type);
335 	ADD_U_CHAR(dptr, unit_count);
336 	ADD_MEM(dptr, p, totdata);
337 
338 	return (t);
339 }
340 
341 /*
342  * token ID                1 byte
343  * status		   4 bytes
344  * return value            4 bytes
345  */
346 token_t *
347 au_to_exit(int retval, int err)
348 {
349 	token_t *t;
350 	u_char *dptr = NULL;
351 
352 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
353 
354 	ADD_U_CHAR(dptr, AUT_EXIT);
355 	ADD_U_INT32(dptr, err);
356 	ADD_U_INT32(dptr, retval);
357 
358 	return (t);
359 }
360 
361 /*
362  */
363 token_t *
364 au_to_groups(int *groups)
365 {
366 
367 	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
368 }
369 
370 /*
371  * token ID                1 byte
372  * number groups           2 bytes
373  * group list              count * 4 bytes
374  */
375 token_t *
376 au_to_newgroups(u_int16_t n, gid_t *groups)
377 {
378 	token_t *t;
379 	u_char *dptr = NULL;
380 	int i;
381 
382 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
383 	    n * sizeof(u_int32_t));
384 
385 	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
386 	ADD_U_INT16(dptr, n);
387 	for (i = 0; i < n; i++)
388 		ADD_U_INT32(dptr, groups[i]);
389 
390 	return (t);
391 }
392 
393 /*
394  * token ID                1 byte
395  * internet address        4 bytes
396  */
397 token_t *
398 au_to_in_addr(struct in_addr *internet_addr)
399 {
400 	token_t *t;
401 	u_char *dptr = NULL;
402 
403 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
404 
405 	ADD_U_CHAR(dptr, AUT_IN_ADDR);
406 	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
407 
408 	return (t);
409 }
410 
411 /*
412  * token ID                1 byte
413  * address type/length     4 bytes
414  * address                16 bytes
415  */
416 token_t *
417 au_to_in_addr_ex(struct in6_addr *internet_addr)
418 {
419 	token_t *t;
420 	u_char *dptr = NULL;
421 	u_int32_t type = AU_IPv6;
422 
423 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
424 
425 	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
426 	ADD_U_INT32(dptr, type);
427 	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
428 
429 	return (t);
430 }
431 
432 /*
433  * token ID                1 byte
434  * ip header		   20 bytes
435  *
436  * The IP header should be submitted in network byte order.
437  */
438 token_t *
439 au_to_ip(struct ip *ip)
440 {
441 	token_t *t;
442 	u_char *dptr = NULL;
443 
444 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
445 
446 	ADD_U_CHAR(dptr, AUT_IP);
447 	ADD_MEM(dptr, ip, sizeof(struct ip));
448 
449 	return (t);
450 }
451 
452 /*
453  * token ID                1 byte
454  * object ID type          1 byte
455  * object ID               4 bytes
456  */
457 token_t *
458 au_to_ipc(char type, int id)
459 {
460 	token_t *t;
461 	u_char *dptr = NULL;
462 
463 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
464 
465 	ADD_U_CHAR(dptr, AUT_IPC);
466 	ADD_U_CHAR(dptr, type);
467 	ADD_U_INT32(dptr, id);
468 
469 	return (t);
470 }
471 
472 /*
473  * token ID                1 byte
474  * owner user ID           4 bytes
475  * owner group ID          4 bytes
476  * creator user ID         4 bytes
477  * creator group ID        4 bytes
478  * access mode             4 bytes
479  * slot sequence #         4 bytes
480  * key                     4 bytes
481  */
482 token_t *
483 au_to_ipc_perm(struct ipc_perm *perm)
484 {
485 	token_t *t;
486 	u_char *dptr = NULL;
487 	u_int16_t pad0 = 0;
488 
489 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
490 	    sizeof(u_int32_t));
491 
492 	ADD_U_CHAR(dptr, AUT_IPC_PERM);
493 
494 	/*
495 	 * Systems vary significantly in what types they use in struct
496 	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
497 	 * allow for that, as BSM define 32-bit values here.
498 	 * Some systems define the sizes for ipc_perm members as 2 bytes;
499 	 * BSM defines 4 so pad with 0.
500 	 *
501 	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
502 	 * need to be handled.
503 	 */
504 	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
505 		ADD_U_INT16(dptr, pad0);
506 		ADD_U_INT16(dptr, perm->uid);
507 		ADD_U_INT16(dptr, pad0);
508 		ADD_U_INT16(dptr, perm->gid);
509 		ADD_U_INT16(dptr, pad0);
510 		ADD_U_INT16(dptr, perm->cuid);
511 		ADD_U_INT16(dptr, pad0);
512 		ADD_U_INT16(dptr, perm->cgid);
513 	} else {
514 		ADD_U_INT32(dptr, perm->uid);
515 		ADD_U_INT32(dptr, perm->gid);
516 		ADD_U_INT32(dptr, perm->cuid);
517 		ADD_U_INT32(dptr, perm->cgid);
518 	}
519 
520 	ADD_U_INT16(dptr, pad0);
521 	ADD_U_INT16(dptr, perm->mode);
522 
523 	ADD_U_INT16(dptr, pad0);
524 
525 	ADD_U_INT16(dptr, perm->seq);
526 
527 	ADD_U_INT32(dptr, perm->key);
528 
529 	return (t);
530 }
531 
532 /*
533  * token ID                1 byte
534  * port IP address         2 bytes
535  */
536 token_t *
537 au_to_iport(u_int16_t iport)
538 {
539 	token_t *t;
540 	u_char *dptr = NULL;
541 
542 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
543 
544 	ADD_U_CHAR(dptr, AUT_IPORT);
545 	ADD_U_INT16(dptr, iport);
546 
547 	return (t);
548 }
549 
550 /*
551  * token ID                1 byte
552  * size                    2 bytes
553  * data                    size bytes
554  */
555 token_t *
556 au_to_opaque(const char *data, u_int16_t bytes)
557 {
558 	token_t *t;
559 	u_char *dptr = NULL;
560 
561 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
562 
563 	ADD_U_CHAR(dptr, AUT_OPAQUE);
564 	ADD_U_INT16(dptr, bytes);
565 	ADD_MEM(dptr, data, bytes);
566 
567 	return (t);
568 }
569 
570 /*
571  * token ID                1 byte
572  * seconds of time         4 bytes
573  * milliseconds of time    4 bytes
574  * file name len           2 bytes
575  * file pathname           N bytes + 1 terminating NULL byte
576  */
577 token_t *
578 au_to_file(const char *file, struct timeval tm)
579 {
580 	token_t *t;
581 	u_char *dptr = NULL;
582 	u_int16_t filelen;
583 	u_int32_t timems;
584 
585 	filelen = strlen(file);
586 	filelen += 1;
587 
588 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
589 	    sizeof(u_int16_t) + filelen);
590 
591 	timems = tm.tv_usec/1000;
592 
593 	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
594 	ADD_U_INT32(dptr, tm.tv_sec);
595 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
596 	ADD_U_INT16(dptr, filelen);
597 	ADD_STRING(dptr, file, filelen);
598 
599 	return (t);
600 }
601 
602 /*
603  * token ID                1 byte
604  * text length             2 bytes
605  * text                    N bytes + 1 terminating NULL byte
606  */
607 token_t *
608 au_to_text(const char *text)
609 {
610 	token_t *t;
611 	u_char *dptr = NULL;
612 	u_int16_t textlen;
613 
614 	textlen = strlen(text);
615 	textlen += 1;
616 
617 	/* XXXRW: Should validate length against token size limit. */
618 
619 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
620 
621 	ADD_U_CHAR(dptr, AUT_TEXT);
622 	ADD_U_INT16(dptr, textlen);
623 	ADD_STRING(dptr, text, textlen);
624 
625 	return (t);
626 }
627 
628 /*
629  * token ID                1 byte
630  * path length             2 bytes
631  * path                    N bytes + 1 terminating NULL byte
632  */
633 token_t *
634 au_to_path(const char *text)
635 {
636 	token_t *t;
637 	u_char *dptr = NULL;
638 	u_int16_t textlen;
639 
640 	textlen = strlen(text);
641 	textlen += 1;
642 
643 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
644 
645 	ADD_U_CHAR(dptr, AUT_PATH);
646 	ADD_U_INT16(dptr, textlen);
647 	ADD_STRING(dptr, text, textlen);
648 
649 	return (t);
650 }
651 
652 /*
653  * token ID                1 byte
654  * audit ID                4 bytes
655  * effective user ID       4 bytes
656  * effective group ID      4 bytes
657  * real user ID            4 bytes
658  * real group ID           4 bytes
659  * process ID              4 bytes
660  * session ID              4 bytes
661  * terminal ID
662  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
663  *   machine address       4 bytes
664  */
665 token_t *
666 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
667     pid_t pid, au_asid_t sid, au_tid_t *tid)
668 {
669 	token_t *t;
670 	u_char *dptr = NULL;
671 
672 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
673 
674 	ADD_U_CHAR(dptr, AUT_PROCESS32);
675 	ADD_U_INT32(dptr, auid);
676 	ADD_U_INT32(dptr, euid);
677 	ADD_U_INT32(dptr, egid);
678 	ADD_U_INT32(dptr, ruid);
679 	ADD_U_INT32(dptr, rgid);
680 	ADD_U_INT32(dptr, pid);
681 	ADD_U_INT32(dptr, sid);
682 	ADD_U_INT32(dptr, tid->port);
683 
684 	/*
685 	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
686 	 * address type and 16 bytes of address, but for IPv4 addresses it
687 	 * simply writes the 4-byte address directly.  We support only IPv4
688 	 * addresses for process32 tokens.
689 	 */
690 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
691 
692 	return (t);
693 }
694 
695 token_t *
696 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
697     pid_t pid, au_asid_t sid, au_tid_t *tid)
698 {
699 	token_t *t;
700 	u_char *dptr = NULL;
701 
702 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
703 	    sizeof(u_int64_t));
704 
705 	ADD_U_CHAR(dptr, AUT_PROCESS64);
706 	ADD_U_INT32(dptr, auid);
707 	ADD_U_INT32(dptr, euid);
708 	ADD_U_INT32(dptr, egid);
709 	ADD_U_INT32(dptr, ruid);
710 	ADD_U_INT32(dptr, rgid);
711 	ADD_U_INT32(dptr, pid);
712 	ADD_U_INT32(dptr, sid);
713 	ADD_U_INT64(dptr, tid->port);
714 
715 	/*
716 	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
717 	 * address type and 16 bytes of address, but for IPv4 addresses it
718 	 * simply writes the 4-byte address directly.  We support only IPv4
719 	 * addresses for process64 tokens.
720 	 */
721 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
722 
723 	return (t);
724 }
725 
726 token_t *
727 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
728     pid_t pid, au_asid_t sid, au_tid_t *tid)
729 {
730 
731 	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
732 	    tid));
733 }
734 
735 /*
736  * token ID                1 byte
737  * audit ID                4 bytes
738  * effective user ID       4 bytes
739  * effective group ID      4 bytes
740  * real user ID            4 bytes
741  * real group ID           4 bytes
742  * process ID              4 bytes
743  * session ID              4 bytes
744  * terminal ID
745  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
746  *   address type-len      4 bytes
747  *   machine address      16 bytes
748  */
749 token_t *
750 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
751     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
752 {
753 	token_t *t;
754 	u_char *dptr = NULL;
755 
756 	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
757 	    ("au_to_process32_ex: type %u", (unsigned int)tid->at_type));
758 	if (tid->at_type == AU_IPv4)
759 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
760 		    10 * sizeof(u_int32_t));
761 	else
762 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
763 		    13 * sizeof(u_int32_t));
764 
765 	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
766 	ADD_U_INT32(dptr, auid);
767 	ADD_U_INT32(dptr, euid);
768 	ADD_U_INT32(dptr, egid);
769 	ADD_U_INT32(dptr, ruid);
770 	ADD_U_INT32(dptr, rgid);
771 	ADD_U_INT32(dptr, pid);
772 	ADD_U_INT32(dptr, sid);
773 	ADD_U_INT32(dptr, tid->at_port);
774 	ADD_U_INT32(dptr, tid->at_type);
775 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
776 	if (tid->at_type == AU_IPv6) {
777 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
778 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
779 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
780 	}
781 
782 	return (t);
783 }
784 
785 token_t *
786 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
787     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
788 {
789 	token_t *t;
790 	u_char *dptr = NULL;
791 
792 	if (tid->at_type == AU_IPv4)
793 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
794 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
795 		    2 * sizeof(u_int32_t));
796 	else if (tid->at_type == AU_IPv6)
797 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
798 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
799 		    5 * sizeof(u_int32_t));
800 	else
801 		panic("au_to_process64_ex: invalidate at_type (%d)",
802 		    tid->at_type);
803 
804 	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
805 	ADD_U_INT32(dptr, auid);
806 	ADD_U_INT32(dptr, euid);
807 	ADD_U_INT32(dptr, egid);
808 	ADD_U_INT32(dptr, ruid);
809 	ADD_U_INT32(dptr, rgid);
810 	ADD_U_INT32(dptr, pid);
811 	ADD_U_INT32(dptr, sid);
812 	ADD_U_INT64(dptr, tid->at_port);
813 	ADD_U_INT32(dptr, tid->at_type);
814 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
815 	if (tid->at_type == AU_IPv6) {
816 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
817 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
818 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
819 	}
820 
821 	return (t);
822 }
823 
824 token_t *
825 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
826     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
827 {
828 
829 	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
830 	    tid));
831 }
832 
833 token_t *
834 au_to_rights(cap_rights_t *rightsp)
835 {
836 	token_t *t;
837 	u_char *dptr;
838 	int i;
839 
840 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(*rightsp));
841 
842 	ADD_U_CHAR(dptr, AUT_RIGHTS);
843 	for (i = 0; i < nitems(rightsp->cr_rights); i++)
844 		ADD_U_INT64(dptr, rightsp->cr_rights[i]);
845 
846 	return (t);
847 }
848 
849 /*
850  * token ID                1 byte
851  * error status            1 byte
852  * return value            4 bytes/8 bytes (32-bit/64-bit value)
853  */
854 token_t *
855 au_to_return32(char status, u_int32_t ret)
856 {
857 	token_t *t;
858 	u_char *dptr = NULL;
859 
860 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
861 
862 	ADD_U_CHAR(dptr, AUT_RETURN32);
863 	ADD_U_CHAR(dptr, status);
864 	ADD_U_INT32(dptr, ret);
865 
866 	return (t);
867 }
868 
869 token_t *
870 au_to_return64(char status, u_int64_t ret)
871 {
872 	token_t *t;
873 	u_char *dptr = NULL;
874 
875 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
876 
877 	ADD_U_CHAR(dptr, AUT_RETURN64);
878 	ADD_U_CHAR(dptr, status);
879 	ADD_U_INT64(dptr, ret);
880 
881 	return (t);
882 }
883 
884 token_t *
885 au_to_return(char status, u_int32_t ret)
886 {
887 
888 	return (au_to_return32(status, ret));
889 }
890 
891 /*
892  * token ID                1 byte
893  * sequence number         4 bytes
894  */
895 token_t *
896 au_to_seq(long audit_count)
897 {
898 	token_t *t;
899 	u_char *dptr = NULL;
900 
901 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
902 
903 	ADD_U_CHAR(dptr, AUT_SEQ);
904 	ADD_U_INT32(dptr, audit_count);
905 
906 	return (t);
907 }
908 
909 /*
910  * token ID                1 byte
911  * socket domain           2 bytes
912  * socket type             2 bytes
913  * address type            2 byte
914  * local port              2 bytes
915  * local address           4 bytes/16 bytes (IPv4/IPv6 address)
916  * remote port             2 bytes
917  * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
918  *
919  * Domain and type arguments to this routine are assumed to already have been
920  * converted to the BSM constant space, so we don't do that here.
921  */
922 token_t *
923 au_to_socket_ex(u_short so_domain, u_short so_type,
924     struct sockaddr *sa_local, struct sockaddr *sa_remote)
925 {
926 	token_t *t;
927 	u_char *dptr = NULL;
928 	struct sockaddr_in *sin;
929 	struct sockaddr_in6 *sin6;
930 
931 	if (so_domain == AF_INET)
932 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
933 		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
934 	else if (so_domain == AF_INET6)
935 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
936 		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
937 	else
938 		return (NULL);
939 
940 	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
941 	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
942 	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
943 	if (so_domain == AF_INET) {
944 		ADD_U_INT16(dptr, AU_IPv4);
945 		sin = (struct sockaddr_in *)sa_local;
946 		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
947 		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
948 		sin = (struct sockaddr_in *)sa_remote;
949 		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
950 		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
951 	} else {
952 		ADD_U_INT16(dptr, AU_IPv6);
953 		sin6 = (struct sockaddr_in6 *)sa_local;
954 		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
955 		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
956 		sin6 = (struct sockaddr_in6 *)sa_remote;
957 		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
958 		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
959 	}
960 
961 	return (t);
962 }
963 
964 /*
965  * Kernel-specific version of the above function.
966  *
967  * XXXRW: Should now use au_to_socket_ex() here.
968  */
969 #ifdef _KERNEL
970 token_t *
971 kau_to_socket(struct socket_au_info *soi)
972 {
973 	token_t *t;
974 	u_char *dptr;
975 	u_int16_t so_type;
976 
977 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
978 	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
979 
980 	ADD_U_CHAR(dptr, AUT_SOCKET);
981 	/* Coerce the socket type into a short value */
982 	so_type = soi->so_type;
983 	ADD_U_INT16(dptr, so_type);
984 	ADD_U_INT16(dptr, soi->so_lport);
985 	ADD_U_INT32(dptr, soi->so_laddr);
986 	ADD_U_INT16(dptr, soi->so_rport);
987 	ADD_U_INT32(dptr, soi->so_raddr);
988 
989 	return (t);
990 }
991 #endif
992 
993 /*
994  * token ID                1 byte
995  * socket family           2 bytes
996  * path                    (up to) 104 bytes + NULL  (NULL terminated string)
997  */
998 token_t *
999 au_to_sock_unix(struct sockaddr_un *so)
1000 {
1001 	token_t *t;
1002 	u_char *dptr;
1003 
1004 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1005 
1006 	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1007 	/* BSM token has two bytes for family */
1008 	ADD_U_CHAR(dptr, 0);
1009 	ADD_U_CHAR(dptr, so->sun_family);
1010 	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1011 
1012 	return (t);
1013 }
1014 
1015 /*
1016  * token ID                1 byte
1017  * socket family           2 bytes
1018  * local port              2 bytes
1019  * socket address          4 bytes
1020  */
1021 token_t *
1022 au_to_sock_inet32(struct sockaddr_in *so)
1023 {
1024 	token_t *t;
1025 	u_char *dptr = NULL;
1026 	uint16_t family;
1027 
1028 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1029 	    sizeof(uint32_t));
1030 
1031 	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1032 	/*
1033 	 * BSM defines the family field as 16 bits, but many operating
1034 	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1035 	 * writing into the token.  Assume that both the port and the address
1036 	 * in the sockaddr_in are already in network byte order, but family
1037 	 * is in local byte order.
1038 	 *
1039 	 * XXXRW: Should a name space conversion be taking place on the value
1040 	 * of sin_family?
1041 	 */
1042 	family = so->sin_family;
1043 	ADD_U_INT16(dptr, family);
1044 	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1045 	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1046 
1047 	return (t);
1048 }
1049 
1050 token_t *
1051 au_to_sock_inet128(struct sockaddr_in6 *so)
1052 {
1053 	token_t *t;
1054 	u_char *dptr = NULL;
1055 
1056 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1057 	    4 * sizeof(u_int32_t));
1058 
1059 	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1060 	/*
1061 	 * In BSD, sin6_family is one octet, but BSM defines the token to
1062 	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1063 	 * conditionally compiled.
1064 	 */
1065 	ADD_U_CHAR(dptr, 0);
1066 	ADD_U_CHAR(dptr, so->sin6_family);
1067 
1068 	ADD_U_INT16(dptr, so->sin6_port);
1069 	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1070 
1071 	return (t);
1072 }
1073 
1074 token_t *
1075 au_to_sock_inet(struct sockaddr_in *so)
1076 {
1077 
1078 	return (au_to_sock_inet32(so));
1079 }
1080 
1081 /*
1082  * token ID                1 byte
1083  * audit ID                4 bytes
1084  * effective user ID       4 bytes
1085  * effective group ID      4 bytes
1086  * real user ID            4 bytes
1087  * real group ID           4 bytes
1088  * process ID              4 bytes
1089  * session ID              4 bytes
1090  * terminal ID
1091  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1092  *   machine address       4 bytes
1093  */
1094 token_t *
1095 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1096     pid_t pid, au_asid_t sid, au_tid_t *tid)
1097 {
1098 	token_t *t;
1099 	u_char *dptr = NULL;
1100 
1101 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1102 
1103 	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1104 	ADD_U_INT32(dptr, auid);
1105 	ADD_U_INT32(dptr, euid);
1106 	ADD_U_INT32(dptr, egid);
1107 	ADD_U_INT32(dptr, ruid);
1108 	ADD_U_INT32(dptr, rgid);
1109 	ADD_U_INT32(dptr, pid);
1110 	ADD_U_INT32(dptr, sid);
1111 	ADD_U_INT32(dptr, tid->port);
1112 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1113 
1114 	return (t);
1115 }
1116 
1117 token_t *
1118 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1119     pid_t pid, au_asid_t sid, au_tid_t *tid)
1120 {
1121 	token_t *t;
1122 	u_char *dptr = NULL;
1123 
1124 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1125 	    sizeof(u_int64_t) + sizeof(u_int32_t));
1126 
1127 	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1128 	ADD_U_INT32(dptr, auid);
1129 	ADD_U_INT32(dptr, euid);
1130 	ADD_U_INT32(dptr, egid);
1131 	ADD_U_INT32(dptr, ruid);
1132 	ADD_U_INT32(dptr, rgid);
1133 	ADD_U_INT32(dptr, pid);
1134 	ADD_U_INT32(dptr, sid);
1135 	ADD_U_INT64(dptr, tid->port);
1136 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1137 
1138 	return (t);
1139 }
1140 
1141 token_t *
1142 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1143     pid_t pid, au_asid_t sid, au_tid_t *tid)
1144 {
1145 
1146 	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1147 	    tid));
1148 }
1149 
1150 /*
1151  * token ID                1 byte
1152  * audit ID                4 bytes
1153  * effective user ID       4 bytes
1154  * effective group ID      4 bytes
1155  * real user ID            4 bytes
1156  * real group ID           4 bytes
1157  * process ID              4 bytes
1158  * session ID              4 bytes
1159  * terminal ID
1160  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1161  *   address type/length   4 bytes
1162  *   machine address      16 bytes
1163  */
1164 token_t *
1165 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1166     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1167 {
1168 	token_t *t;
1169 	u_char *dptr = NULL;
1170 
1171 	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1172 	    ("au_to_subject32_ex: type %u", (unsigned int)tid->at_type));
1173 
1174 	if (tid->at_type == AU_IPv4)
1175 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1176 		    sizeof(u_int32_t));
1177 	else
1178 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1179 		    sizeof(u_int32_t));
1180 
1181 	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1182 	ADD_U_INT32(dptr, auid);
1183 	ADD_U_INT32(dptr, euid);
1184 	ADD_U_INT32(dptr, egid);
1185 	ADD_U_INT32(dptr, ruid);
1186 	ADD_U_INT32(dptr, rgid);
1187 	ADD_U_INT32(dptr, pid);
1188 	ADD_U_INT32(dptr, sid);
1189 	ADD_U_INT32(dptr, tid->at_port);
1190 	ADD_U_INT32(dptr, tid->at_type);
1191 	if (tid->at_type == AU_IPv6)
1192 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1193 	else
1194 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1195 
1196 	return (t);
1197 }
1198 
1199 token_t *
1200 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1201     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1202 {
1203 	token_t *t;
1204 	u_char *dptr = NULL;
1205 
1206 	KASSERT((tid->at_type == AU_IPv4) || (tid->at_type == AU_IPv6),
1207 	    ("au_to_subject64_ex: type %u", (unsigned int)tid->at_type));
1208 
1209 	if (tid->at_type == AU_IPv4)
1210 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1211 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1212 		    2 * sizeof(u_int32_t));
1213 	else
1214 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1215 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1216 		    5 * sizeof(u_int32_t));
1217 
1218 	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1219 	ADD_U_INT32(dptr, auid);
1220 	ADD_U_INT32(dptr, euid);
1221 	ADD_U_INT32(dptr, egid);
1222 	ADD_U_INT32(dptr, ruid);
1223 	ADD_U_INT32(dptr, rgid);
1224 	ADD_U_INT32(dptr, pid);
1225 	ADD_U_INT32(dptr, sid);
1226 	ADD_U_INT64(dptr, tid->at_port);
1227 	ADD_U_INT32(dptr, tid->at_type);
1228 	if (tid->at_type == AU_IPv6)
1229 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1230 	else
1231 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1232 
1233 	return (t);
1234 }
1235 
1236 token_t *
1237 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1238     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1239 {
1240 
1241 	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1242 	    tid));
1243 }
1244 
1245 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1246 /*
1247  * Collects audit information for the current process and creates a subject
1248  * token from it.
1249  */
1250 token_t *
1251 au_to_me(void)
1252 {
1253 	auditinfo_t auinfo;
1254 	auditinfo_addr_t aia;
1255 
1256 	/*
1257 	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1258 	 * it, then fall back on to getaudit(2).
1259 	 */
1260 	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1261 		if (errno == ENOSYS) {
1262 			if (getaudit(&auinfo) != 0)
1263 				return (NULL);
1264 			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1265 				getegid(), getuid(), getgid(), getpid(),
1266 				auinfo.ai_asid, &auinfo.ai_termid));
1267 		} else {
1268 			/* getaudit_addr(2) failed for some other reason. */
1269 			return (NULL);
1270 		}
1271 	}
1272 
1273 	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1274 		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1275 }
1276 #endif
1277 
1278 #if defined(_KERNEL) || defined(KERNEL)
1279 static token_t *
1280 au_to_exec_strings(char *strs, int count, u_char type)
1281 {
1282 	token_t *t;
1283 	u_char *dptr = NULL;
1284 	u_int32_t totlen;
1285 	int ctr;
1286 	char *p;
1287 
1288 	totlen = 0;
1289 	ctr = count;
1290 	p = strs;
1291 	while (ctr-- > 0) {
1292 		totlen += strlen(p) + 1;
1293 		p = strs + totlen;
1294 	}
1295 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1296 	ADD_U_CHAR(dptr, type);
1297 	ADD_U_INT32(dptr, count);
1298 	ADD_STRING(dptr, strs, totlen);
1299 
1300 	return (t);
1301 }
1302 
1303 /*
1304  * token ID				1 byte
1305  * count				4 bytes
1306  * text					count null-terminated strings
1307  */
1308 token_t *
1309 au_to_exec_args(char *args, int argc)
1310 {
1311 
1312 	return (au_to_exec_strings(args, argc, AUT_EXEC_ARGS));
1313 }
1314 
1315 /*
1316  * token ID				1 byte
1317  * count				4 bytes
1318  * text					count null-terminated strings
1319  */
1320 token_t *
1321 au_to_exec_env(char *envs, int envc)
1322 {
1323 
1324 	return (au_to_exec_strings(envs, envc, AUT_EXEC_ENV));
1325 }
1326 #else
1327 /*
1328  * token ID				1 byte
1329  * count				4 bytes
1330  * text					count null-terminated strings
1331  */
1332 token_t *
1333 au_to_exec_args(char **argv)
1334 {
1335 	token_t *t;
1336 	u_char *dptr = NULL;
1337 	const char *nextarg;
1338 	int i, count = 0;
1339 	size_t totlen = 0;
1340 
1341 	nextarg = *argv;
1342 
1343 	while (nextarg != NULL) {
1344 		int nextlen;
1345 
1346 		nextlen = strlen(nextarg);
1347 		totlen += nextlen + 1;
1348 		count++;
1349 		nextarg = *(argv + count);
1350 	}
1351 
1352 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1353 
1354 	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1355 	ADD_U_INT32(dptr, count);
1356 
1357 	for (i = 0; i < count; i++) {
1358 		nextarg = *(argv + i);
1359 		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1360 	}
1361 
1362 	return (t);
1363 }
1364 
1365 /*
1366  * token ID				1 byte
1367  * count				4 bytes
1368  * text					count null-terminated strings
1369  */
1370 token_t *
1371 au_to_exec_env(char **envp)
1372 {
1373 	token_t *t;
1374 	u_char *dptr = NULL;
1375 	int i, count = 0;
1376 	size_t totlen = 0;
1377 	const char *nextenv;
1378 
1379 	nextenv = *envp;
1380 
1381 	while (nextenv != NULL) {
1382 		int nextlen;
1383 
1384 		nextlen = strlen(nextenv);
1385 		totlen += nextlen + 1;
1386 		count++;
1387 		nextenv = *(envp + count);
1388 	}
1389 
1390 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1391 
1392 	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1393 	ADD_U_INT32(dptr, count);
1394 
1395 	for (i = 0; i < count; i++) {
1396 		nextenv = *(envp + i);
1397 		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1398 	}
1399 
1400 	return (t);
1401 }
1402 #endif
1403 
1404 /*
1405  * token ID                1 byte
1406  * zonename length         2 bytes
1407  * zonename                N bytes + 1 terminating NULL byte
1408  */
1409 token_t *
1410 au_to_zonename(const char *zonename)
1411 {
1412 	u_char *dptr = NULL;
1413 	u_int16_t textlen;
1414 	token_t *t;
1415 
1416 	textlen = strlen(zonename) + 1;
1417 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1418 
1419 	ADD_U_CHAR(dptr, AUT_ZONENAME);
1420 	ADD_U_INT16(dptr, textlen);
1421 	ADD_STRING(dptr, zonename, textlen);
1422 	return (t);
1423 }
1424 
1425 /*
1426  * token ID                1 byte
1427  * record byte count       4 bytes
1428  * version #               1 byte    [2]
1429  * event type              2 bytes
1430  * event modifier          2 bytes
1431  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1432  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1433  */
1434 token_t *
1435 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1436     struct timeval tm)
1437 {
1438 	token_t *t;
1439 	u_char *dptr = NULL;
1440 	u_int32_t timems;
1441 
1442 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1443 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1444 
1445 	ADD_U_CHAR(dptr, AUT_HEADER32);
1446 	ADD_U_INT32(dptr, rec_size);
1447 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1448 	ADD_U_INT16(dptr, e_type);
1449 	ADD_U_INT16(dptr, e_mod);
1450 
1451 	timems = tm.tv_usec/1000;
1452 	/* Add the timestamp */
1453 	ADD_U_INT32(dptr, tm.tv_sec);
1454 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1455 
1456 	return (t);
1457 }
1458 
1459 /*
1460  * token ID                1 byte
1461  * record byte count       4 bytes
1462  * version #               1 byte    [2]
1463  * event type              2 bytes
1464  * event modifier          2 bytes
1465  * address type/length     4 bytes
1466  * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1467  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1468  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1469  */
1470 token_t *
1471 au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1472     struct timeval tm, struct auditinfo_addr *aia)
1473 {
1474 	token_t *t;
1475 	u_char *dptr = NULL;
1476 	u_int32_t timems;
1477 	au_tid_addr_t *tid;
1478 
1479 	tid = &aia->ai_termid;
1480 	KASSERT(tid->at_type == AU_IPv4 || tid->at_type == AU_IPv6,
1481 	    ("au_to_header32_ex_tm: invalid address family"));
1482 
1483 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1484 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1485 	    sizeof(u_int32_t) + tid->at_type);
1486 
1487 	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1488 	ADD_U_INT32(dptr, rec_size);
1489 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1490 	ADD_U_INT16(dptr, e_type);
1491 	ADD_U_INT16(dptr, e_mod);
1492 
1493 	ADD_U_INT32(dptr, tid->at_type);
1494 	if (tid->at_type == AU_IPv6)
1495 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1496 	else
1497 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1498 	timems = tm.tv_usec/1000;
1499 	/* Add the timestamp */
1500 	ADD_U_INT32(dptr, tm.tv_sec);
1501 	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1502 
1503 	return (t);
1504 }
1505 
1506 token_t *
1507 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1508     struct timeval tm)
1509 {
1510 	token_t *t;
1511 	u_char *dptr = NULL;
1512 	u_int32_t timems;
1513 
1514 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1515 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1516 
1517 	ADD_U_CHAR(dptr, AUT_HEADER64);
1518 	ADD_U_INT32(dptr, rec_size);
1519 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1520 	ADD_U_INT16(dptr, e_type);
1521 	ADD_U_INT16(dptr, e_mod);
1522 
1523 	timems = tm.tv_usec/1000;
1524 	/* Add the timestamp */
1525 	ADD_U_INT64(dptr, tm.tv_sec);
1526 	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1527 
1528 	return (t);
1529 }
1530 
1531 #if !defined(KERNEL) && !defined(_KERNEL)
1532 #ifdef HAVE_AUDIT_SYSCALLS
1533 token_t *
1534 au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1535 {
1536 	struct timeval tm;
1537 	struct auditinfo_addr aia;
1538 
1539 	if (gettimeofday(&tm, NULL) == -1)
1540 		return (NULL);
1541 	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1542 		if (errno != ENOSYS)
1543 			return (NULL);
1544 		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1545 	}
1546 	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1547 }
1548 #endif /* HAVE_AUDIT_SYSCALLS */
1549 
1550 token_t *
1551 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1552 {
1553 	struct timeval tm;
1554 
1555 	if (gettimeofday(&tm, NULL) == -1)
1556 		return (NULL);
1557 	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1558 }
1559 
1560 token_t *
1561 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1562     __unused au_emod_t e_mod)
1563 {
1564 	struct timeval tm;
1565 
1566 	if (gettimeofday(&tm, NULL) == -1)
1567 		return (NULL);
1568 	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1569 }
1570 
1571 token_t *
1572 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1573 {
1574 
1575 	return (au_to_header32(rec_size, e_type, e_mod));
1576 }
1577 
1578 #ifdef HAVE_AUDIT_SYSCALLS
1579 token_t *
1580 au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1581 {
1582 
1583 	return (au_to_header32_ex(rec_size, e_type, e_mod));
1584 }
1585 #endif /* HAVE_AUDIT_SYSCALLS */
1586 #endif /* !defined(KERNEL) && !defined(_KERNEL) */
1587 
1588 /*
1589  * token ID                1 byte
1590  * trailer magic number    2 bytes
1591  * record byte count       4 bytes
1592  */
1593 token_t *
1594 au_to_trailer(int rec_size)
1595 {
1596 	token_t *t;
1597 	u_char *dptr = NULL;
1598 	u_int16_t magic = AUT_TRAILER_MAGIC;
1599 
1600 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1601 	    sizeof(u_int32_t));
1602 
1603 	ADD_U_CHAR(dptr, AUT_TRAILER);
1604 	ADD_U_INT16(dptr, magic);
1605 	ADD_U_INT32(dptr, rec_size);
1606 
1607 	return (t);
1608 }
1609