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