xref: /freebsd/contrib/openbsm/libbsm/bsm_token.c (revision 1669d8afc64812c8d2d1d147ae1fd42ff441e1b1)
1 /*
2  * Copyright (c) 2004 Apple Computer, 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 Computer, 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#63 $
34  */
35 
36 #include <sys/types.h>
37 
38 #include <config/config.h>
39 #ifdef HAVE_SYS_ENDIAN_H
40 #include <sys/endian.h>
41 #else /* !HAVE_SYS_ENDIAN_H */
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 */
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, 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 
125 token_t *
126 au_to_arg64(char n, char *text, u_int64_t v)
127 {
128 	token_t *t;
129 	u_char *dptr = NULL;
130 	u_int16_t textlen;
131 
132 	textlen = strlen(text);
133 	textlen += 1;
134 
135 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
136 	    sizeof(u_int16_t) + textlen);
137 	if (t == NULL)
138 		return (NULL);
139 
140 	ADD_U_CHAR(dptr, AUT_ARG64);
141 	ADD_U_CHAR(dptr, n);
142 	ADD_U_INT64(dptr, v);
143 	ADD_U_INT16(dptr, textlen);
144 	ADD_STRING(dptr, text, textlen);
145 
146 	return (t);
147 
148 }
149 
150 token_t *
151 au_to_arg(char n, char *text, u_int32_t v)
152 {
153 
154 	return (au_to_arg32(n, text, v));
155 }
156 
157 #if defined(_KERNEL) || defined(KERNEL)
158 /*
159  * token ID                1 byte
160  * file access mode        4 bytes
161  * owner user ID           4 bytes
162  * owner group ID          4 bytes
163  * file system ID          4 bytes
164  * node ID                 8 bytes
165  * device                  4 bytes/8 bytes (32-bit/64-bit)
166  */
167 token_t *
168 au_to_attr32(struct vnode_au_info *vni)
169 {
170 	token_t *t;
171 	u_char *dptr = NULL;
172 	u_int16_t pad0_16 = 0;
173 	u_int16_t pad0_32 = 0;
174 
175 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
176 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
177 	if (t == NULL)
178 		return (NULL);
179 
180 	ADD_U_CHAR(dptr, AUT_ATTR32);
181 
182 	/*
183 	 * Darwin defines the size for the file mode
184 	 * as 2 bytes; BSM defines 4 so pad with 0
185 	 */
186 	ADD_U_INT16(dptr, pad0_16);
187 	ADD_U_INT16(dptr, vni->vn_mode);
188 
189 	ADD_U_INT32(dptr, vni->vn_uid);
190 	ADD_U_INT32(dptr, vni->vn_gid);
191 	ADD_U_INT32(dptr, vni->vn_fsid);
192 
193 	/*
194 	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
195 	 * Attempt to handle both, and let the compiler sort it out.  If we
196 	 * could pick this out at compile-time, it would be better, so as to
197 	 * avoid the else case below.
198 	 */
199 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
200 		ADD_U_INT32(dptr, pad0_32);
201 		ADD_U_INT32(dptr, vni->vn_fileid);
202 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
203 		ADD_U_INT64(dptr, vni->vn_fileid);
204 	else
205 		ADD_U_INT64(dptr, 0LL);
206 
207 	ADD_U_INT32(dptr, vni->vn_dev);
208 
209 	return (t);
210 }
211 
212 token_t *
213 au_to_attr64(struct vnode_au_info *vni)
214 {
215 	token_t *t;
216 	u_char *dptr = NULL;
217 	u_int16_t pad0_16 = 0;
218 	u_int16_t pad0_32 = 0;
219 
220 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
221 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
222 	if (t == NULL)
223 		return (NULL);
224 
225 	ADD_U_CHAR(dptr, AUT_ATTR64);
226 
227 	/*
228 	 * Darwin defines the size for the file mode
229 	 * as 2 bytes; BSM defines 4 so pad with 0
230 	 */
231 	ADD_U_INT16(dptr, pad0_16);
232 	ADD_U_INT16(dptr, vni->vn_mode);
233 
234 	ADD_U_INT32(dptr, vni->vn_uid);
235 	ADD_U_INT32(dptr, vni->vn_gid);
236 	ADD_U_INT32(dptr, vni->vn_fsid);
237 
238 	/*
239 	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
240 	 * Attempt to handle both, and let the compiler sort it out.  If we
241 	 * could pick this out at compile-time, it would be better, so as to
242 	 * avoid the else case below.
243 	 */
244 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
245 		ADD_U_INT32(dptr, pad0_32);
246 		ADD_U_INT32(dptr, vni->vn_fileid);
247 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
248 		ADD_U_INT64(dptr, vni->vn_fileid);
249 	else
250 		ADD_U_INT64(dptr, 0LL);
251 
252 	ADD_U_INT64(dptr, vni->vn_dev);
253 
254 	return (t);
255 }
256 
257 token_t *
258 au_to_attr(struct vnode_au_info *vni)
259 {
260 
261 	return (au_to_attr32(vni));
262 }
263 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
264 
265 /*
266  * token ID                1 byte
267  * how to print            1 byte
268  * basic unit              1 byte
269  * unit count              1 byte
270  * data items              (depends on basic unit)
271  */
272 token_t *
273 au_to_data(char unit_print, char unit_type, char unit_count, char *p)
274 {
275 	token_t *t;
276 	u_char *dptr = NULL;
277 	size_t datasize, totdata;
278 
279 	/* Determine the size of the basic unit. */
280 	switch (unit_type) {
281 	case AUR_BYTE:
282 	/* case AUR_CHAR: */
283 		datasize = AUR_BYTE_SIZE;
284 		break;
285 
286 	case AUR_SHORT:
287 		datasize = AUR_SHORT_SIZE;
288 		break;
289 
290 	case AUR_INT32:
291 	/* case AUR_INT: */
292 		datasize = AUR_INT32_SIZE;
293 		break;
294 
295 	case AUR_INT64:
296 		datasize = AUR_INT64_SIZE;
297 		break;
298 
299 	default:
300 		errno = EINVAL;
301  		return (NULL);
302 	}
303 
304 	totdata = datasize * unit_count;
305 
306 	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
307 	if (t == NULL)
308 		return (NULL);
309 
310 	ADD_U_CHAR(dptr, AUT_DATA);
311 	ADD_U_CHAR(dptr, unit_print);
312 	ADD_U_CHAR(dptr, unit_type);
313 	ADD_U_CHAR(dptr, unit_count);
314 	ADD_MEM(dptr, p, totdata);
315 
316 	return (t);
317 }
318 
319 
320 /*
321  * token ID                1 byte
322  * status		   4 bytes
323  * return value            4 bytes
324  */
325 token_t *
326 au_to_exit(int retval, int err)
327 {
328 	token_t *t;
329 	u_char *dptr = NULL;
330 
331 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
332 	if (t == NULL)
333 		return (NULL);
334 
335 	ADD_U_CHAR(dptr, AUT_EXIT);
336 	ADD_U_INT32(dptr, err);
337 	ADD_U_INT32(dptr, retval);
338 
339 	return (t);
340 }
341 
342 /*
343  */
344 token_t *
345 au_to_groups(int *groups)
346 {
347 
348 	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t*)groups));
349 }
350 
351 /*
352  * token ID                1 byte
353  * number groups           2 bytes
354  * group list              count * 4 bytes
355  */
356 token_t *
357 au_to_newgroups(u_int16_t n, gid_t *groups)
358 {
359 	token_t *t;
360 	u_char *dptr = NULL;
361 	int i;
362 
363 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
364 	    n * sizeof(u_int32_t));
365 	if (t == NULL)
366 		return (NULL);
367 
368 	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
369 	ADD_U_INT16(dptr, n);
370 	for (i = 0; i < n; i++)
371 		ADD_U_INT32(dptr, groups[i]);
372 
373 	return (t);
374 }
375 
376 /*
377  * token ID                1 byte
378  * internet address        4 bytes
379  */
380 token_t *
381 au_to_in_addr(struct in_addr *internet_addr)
382 {
383 	token_t *t;
384 	u_char *dptr = NULL;
385 
386 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
387 	if (t == NULL)
388 		return (NULL);
389 
390 	ADD_U_CHAR(dptr, AUT_IN_ADDR);
391 	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
392 
393 	return (t);
394 }
395 
396 /*
397  * token ID                1 byte
398  * address type/length     4 bytes
399  * Address                16 bytes
400  */
401 token_t *
402 au_to_in_addr_ex(struct in6_addr *internet_addr)
403 {
404 	token_t *t;
405 	u_char *dptr = NULL;
406 	u_int32_t type = AF_INET6;
407 
408 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
409 	if (t == NULL)
410 		return (NULL);
411 
412 	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
413 	ADD_U_INT32(dptr, type);
414 	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
415 
416 	return (t);
417 }
418 
419 /*
420  * token ID                1 byte
421  * ip header		   20 bytes
422  *
423  * The IP header should be submitted in network byte order.
424  */
425 token_t *
426 au_to_ip(struct ip *ip)
427 {
428 	token_t *t;
429 	u_char *dptr = NULL;
430 
431 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
432 	if (t == NULL)
433 		return (NULL);
434 
435 	ADD_U_CHAR(dptr, AUT_IP);
436 	ADD_MEM(dptr, ip, sizeof(struct ip));
437 
438 	return (t);
439 }
440 
441 /*
442  * token ID                1 byte
443  * object ID type          1 byte
444  * object ID               4 bytes
445  */
446 token_t *
447 au_to_ipc(char type, int id)
448 {
449 	token_t *t;
450 	u_char *dptr = NULL;
451 
452 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
453 	if (t == NULL)
454 		return (NULL);
455 
456 	ADD_U_CHAR(dptr, AUT_IPC);
457 	ADD_U_CHAR(dptr, type);
458 	ADD_U_INT32(dptr, id);
459 
460 	return (t);
461 }
462 
463 /*
464  * token ID                1 byte
465  * owner user ID           4 bytes
466  * owner group ID          4 bytes
467  * creator user ID         4 bytes
468  * creator group ID        4 bytes
469  * access mode             4 bytes
470  * slot sequence #         4 bytes
471  * key                     4 bytes
472  */
473 token_t *
474 au_to_ipc_perm(struct ipc_perm *perm)
475 {
476 	token_t *t;
477 	u_char *dptr = NULL;
478 	u_int16_t pad0 = 0;
479 
480 	GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
481 	if (t == NULL)
482 		return (NULL);
483 
484 	ADD_U_CHAR(dptr, AUT_IPC_PERM);
485 
486 	/*
487 	 * Darwin defines the sizes for ipc_perm members
488 	 * as 2 bytes; BSM defines 4 so pad with 0
489 	 */
490 	ADD_U_INT16(dptr, pad0);
491 	ADD_U_INT16(dptr, perm->uid);
492 
493 	ADD_U_INT16(dptr, pad0);
494 	ADD_U_INT16(dptr, perm->gid);
495 
496 	ADD_U_INT16(dptr, pad0);
497 	ADD_U_INT16(dptr, perm->cuid);
498 
499 	ADD_U_INT16(dptr, pad0);
500 	ADD_U_INT16(dptr, perm->cgid);
501 
502 	ADD_U_INT16(dptr, pad0);
503 	ADD_U_INT16(dptr, perm->mode);
504 
505 	ADD_U_INT16(dptr, pad0);
506 
507 #ifdef HAVE_IPC_PERM___SEQ
508 	ADD_U_INT16(dptr, perm->__seq);
509 #else
510 	ADD_U_INT16(dptr, perm->seq);
511 #endif
512 
513 #ifdef HAVE_IPC_PERM___KEY
514 	ADD_U_INT32(dptr, perm->__key);
515 #else
516 	ADD_U_INT32(dptr, perm->key);
517 #endif
518 
519 	return (t);
520 }
521 
522 /*
523  * token ID                1 byte
524  * port IP address         2 bytes
525  */
526 token_t *
527 au_to_iport(u_int16_t iport)
528 {
529 	token_t *t;
530 	u_char *dptr = NULL;
531 
532 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
533 	if (t == NULL)
534 		return (NULL);
535 
536 	ADD_U_CHAR(dptr, AUT_IPORT);
537 	ADD_U_INT16(dptr, iport);
538 
539 	return (t);
540 }
541 
542 /*
543  * token ID                1 byte
544  * size                    2 bytes
545  * data                    size bytes
546  */
547 token_t *
548 au_to_opaque(char *data, u_int16_t bytes)
549 {
550 	token_t *t;
551 	u_char *dptr = NULL;
552 
553 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
554 	if (t == NULL)
555 		return (NULL);
556 
557 	ADD_U_CHAR(dptr, AUT_OPAQUE);
558 	ADD_U_INT16(dptr, bytes);
559 	ADD_MEM(dptr, data, bytes);
560 
561 	return (t);
562 }
563 
564 /*
565  * token ID                1 byte
566  * seconds of time         4 bytes
567  * milliseconds of time    4 bytes
568  * file name len           2 bytes
569  * file pathname           N bytes + 1 terminating NULL byte
570  */
571 token_t *
572 au_to_file(char *file, struct timeval tm)
573 {
574 	token_t *t;
575 	u_char *dptr = NULL;
576 	u_int16_t filelen;
577 	u_int32_t timems;
578 
579 	filelen = strlen(file);
580 	filelen += 1;
581 
582 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
583 	    sizeof(u_int16_t) + filelen);
584 	if (t == NULL)
585 		return (NULL);
586 
587 	timems = tm.tv_usec/1000;
588 
589 	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
590 	ADD_U_INT32(dptr, tm.tv_sec);
591 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
592 	ADD_U_INT16(dptr, filelen);
593 	ADD_STRING(dptr, file, filelen);
594 
595 	return (t);
596 }
597 
598 /*
599  * token ID                1 byte
600  * text length             2 bytes
601  * text                    N bytes + 1 terminating NULL byte
602  */
603 token_t *
604 au_to_text(char *text)
605 {
606 	token_t *t;
607 	u_char *dptr = NULL;
608 	u_int16_t textlen;
609 
610 	textlen = strlen(text);
611 	textlen += 1;
612 
613 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
614 	if (t == NULL)
615 		return (NULL);
616 
617 	ADD_U_CHAR(dptr, AUT_TEXT);
618 	ADD_U_INT16(dptr, textlen);
619 	ADD_STRING(dptr, text, textlen);
620 
621 	return (t);
622 }
623 
624 /*
625  * token ID                1 byte
626  * path length             2 bytes
627  * path                    N bytes + 1 terminating NULL byte
628  */
629 token_t *
630 au_to_path(char *text)
631 {
632 	token_t *t;
633 	u_char *dptr = NULL;
634 	u_int16_t textlen;
635 
636 	textlen = strlen(text);
637 	textlen += 1;
638 
639 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
640 	if (t == NULL)
641 		return (NULL);
642 
643 	ADD_U_CHAR(dptr, AUT_PATH);
644 	ADD_U_INT16(dptr, textlen);
645 	ADD_STRING(dptr, text, textlen);
646 
647 	return (t);
648 }
649 
650 /*
651  * token ID                1 byte
652  * audit ID                4 bytes
653  * effective user ID       4 bytes
654  * effective group ID      4 bytes
655  * real user ID            4 bytes
656  * real group ID           4 bytes
657  * process ID              4 bytes
658  * session ID              4 bytes
659  * terminal ID
660  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
661  *   machine address       4 bytes
662  */
663 token_t *
664 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
665     pid_t pid, au_asid_t sid, au_tid_t *tid)
666 {
667 	token_t *t;
668 	u_char *dptr = NULL;
669 
670 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
671 	if (t == NULL)
672 		return (NULL);
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 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
684 
685 	return (t);
686 }
687 
688 token_t *
689 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
690     pid_t pid, au_asid_t sid, au_tid_t *tid)
691 {
692 	token_t *t;
693 	u_char *dptr = NULL;
694 
695 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
696 	    sizeof(u_int64_t));
697 	if (t == NULL)
698 		return (NULL);
699 
700 	ADD_U_CHAR(dptr, AUT_PROCESS64);
701 	ADD_U_INT32(dptr, auid);
702 	ADD_U_INT32(dptr, euid);
703 	ADD_U_INT32(dptr, egid);
704 	ADD_U_INT32(dptr, ruid);
705 	ADD_U_INT32(dptr, rgid);
706 	ADD_U_INT32(dptr, pid);
707 	ADD_U_INT32(dptr, sid);
708 	ADD_U_INT64(dptr, tid->port);
709 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
710 
711 	return (t);
712 }
713 
714 token_t *
715 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
716     pid_t pid, au_asid_t sid, au_tid_t *tid)
717 {
718 
719 	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
720 	    tid));
721 }
722 
723 /*
724  * token ID                1 byte
725  * audit ID                4 bytes
726  * effective user ID       4 bytes
727  * effective group ID      4 bytes
728  * real user ID            4 bytes
729  * real group ID           4 bytes
730  * process ID              4 bytes
731  * session ID              4 bytes
732  * terminal ID
733  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
734  *   address type-len      4 bytes
735  *   machine address      16 bytes
736  */
737 token_t *
738 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
739     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
740 {
741 	token_t *t;
742 	u_char *dptr = NULL;
743 
744 	if (tid->at_type == AU_IPv4)
745 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
746 		    10 * sizeof(u_int32_t));
747 	else if (tid->at_type == AU_IPv6)
748 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
749 		    13 * sizeof(u_int32_t));
750 	else {
751 		errno = EINVAL;
752 		return (NULL);
753 	}
754 	if (t == NULL)
755 		return (NULL);
756 
757 	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
758 	ADD_U_INT32(dptr, auid);
759 	ADD_U_INT32(dptr, euid);
760 	ADD_U_INT32(dptr, egid);
761 	ADD_U_INT32(dptr, ruid);
762 	ADD_U_INT32(dptr, rgid);
763 	ADD_U_INT32(dptr, pid);
764 	ADD_U_INT32(dptr, sid);
765 	ADD_U_INT32(dptr, tid->at_port);
766 	ADD_U_INT32(dptr, tid->at_type);
767 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
768 	if (tid->at_type == AU_IPv6) {
769 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
770 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
771 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
772 	}
773 
774 	return (t);
775 }
776 
777 token_t *
778 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
779     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
780 {
781 	token_t *t;
782 	u_char *dptr = NULL;
783 
784 	if (tid->at_type == AU_IPv4)
785 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
786 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
787 		    2 * sizeof(u_int32_t));
788 	else if (tid->at_type == AU_IPv6)
789 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
790 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
791 		    5 * sizeof(u_int32_t));
792 	else {
793 		errno = EINVAL;
794 		return (NULL);
795 	}
796 	if (t == NULL)
797 		return (NULL);
798 
799 	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
800 	ADD_U_INT32(dptr, auid);
801 	ADD_U_INT32(dptr, euid);
802 	ADD_U_INT32(dptr, egid);
803 	ADD_U_INT32(dptr, ruid);
804 	ADD_U_INT32(dptr, rgid);
805 	ADD_U_INT32(dptr, pid);
806 	ADD_U_INT32(dptr, sid);
807 	ADD_U_INT64(dptr, tid->at_port);
808 	ADD_U_INT32(dptr, tid->at_type);
809 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
810 	if (tid->at_type == AU_IPv6) {
811 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
812 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
813 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
814 	}
815 
816 	return (t);
817 }
818 
819 token_t *
820 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
821     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
822 {
823 
824 	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
825 	    tid));
826 }
827 
828 /*
829  * token ID                1 byte
830  * error status            1 byte
831  * return value            4 bytes/8 bytes (32-bit/64-bit value)
832  */
833 token_t *
834 au_to_return32(char status, u_int32_t ret)
835 {
836 	token_t *t;
837 	u_char *dptr = NULL;
838 
839 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
840 	if (t == NULL)
841 		return (NULL);
842 
843 	ADD_U_CHAR(dptr, AUT_RETURN32);
844 	ADD_U_CHAR(dptr, status);
845 	ADD_U_INT32(dptr, ret);
846 
847 	return (t);
848 }
849 
850 token_t *
851 au_to_return64(char status, u_int64_t ret)
852 {
853 	token_t *t;
854 	u_char *dptr = NULL;
855 
856 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
857 	if (t == NULL)
858 		return (NULL);
859 
860 	ADD_U_CHAR(dptr, AUT_RETURN64);
861 	ADD_U_CHAR(dptr, status);
862 	ADD_U_INT64(dptr, ret);
863 
864 	return (t);
865 }
866 
867 token_t *
868 au_to_return(char status, u_int32_t ret)
869 {
870 
871 	return (au_to_return32(status, ret));
872 }
873 
874 /*
875  * token ID                1 byte
876  * sequence number         4 bytes
877  */
878 token_t *
879 au_to_seq(long audit_count)
880 {
881 	token_t *t;
882 	u_char *dptr = NULL;
883 
884 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
885 	if (t == NULL)
886 		return (NULL);
887 
888 	ADD_U_CHAR(dptr, AUT_SEQ);
889 	ADD_U_INT32(dptr, audit_count);
890 
891 	return (t);
892 }
893 
894 /*
895  * token ID                1 byte
896  * socket family           2 bytes
897  * path                    104 bytes
898  */
899 token_t *
900 au_to_sock_unix(struct sockaddr_un *so)
901 {
902 	token_t *t;
903 	u_char *dptr;
904 
905 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
906 	if (t == NULL)
907 		return (NULL);
908 
909 	ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
910 	/* BSM token has two bytes for family */
911 	ADD_U_CHAR(dptr, 0);
912 	ADD_U_CHAR(dptr, so->sun_family);
913 	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
914 
915 	return (t);
916 }
917 
918 /*
919  * token ID                1 byte
920  * socket family           2 bytes
921  * local port              2 bytes
922  * socket address          4 bytes
923  */
924 token_t *
925 au_to_sock_inet32(struct sockaddr_in *so)
926 {
927 	token_t *t;
928 	u_char *dptr = NULL;
929 	uint16_t family;
930 
931 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
932 	    sizeof(uint32_t));
933 	if (t == NULL)
934 		return (NULL);
935 
936 	ADD_U_CHAR(dptr, AUT_SOCKINET32);
937 	/*
938 	 * BSM defines the family field as 16 bits, but many operating
939 	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
940 	 * writing into the token.  Assume that both the port and the address
941 	 * in the sockaddr_in are already in network byte order, but family
942 	 * is in local byte order.
943 	 *
944 	 * XXXRW: Should a name space conversion be taking place on the value
945 	 * of sin_family?
946  	 */
947 	family = so->sin_family;
948 	ADD_U_INT16(dptr, family);
949 	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
950 	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
951 
952 	return (t);
953 
954 }
955 
956 token_t *
957 au_to_sock_inet128(struct sockaddr_in6 *so)
958 {
959 	token_t *t;
960 	u_char *dptr = NULL;
961 
962 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
963 	    4 * sizeof(u_int32_t));
964 	if (t == NULL)
965 		return (NULL);
966 
967 	ADD_U_CHAR(dptr, AUT_SOCKINET128);
968 	/*
969 	 * In Darwin, sin6_family is one octet, but BSM defines the token
970  	 * to store two. So we copy in a 0 first.
971  	 */
972 	ADD_U_CHAR(dptr, 0);
973 	ADD_U_CHAR(dptr, so->sin6_family);
974 
975 	ADD_U_INT16(dptr, so->sin6_port);
976 	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
977 
978 	return (t);
979 
980 }
981 
982 token_t *
983 au_to_sock_inet(struct sockaddr_in *so)
984 {
985 
986 	return (au_to_sock_inet32(so));
987 }
988 
989 /*
990  * token ID                1 byte
991  * audit ID                4 bytes
992  * effective user ID       4 bytes
993  * effective group ID      4 bytes
994  * real user ID            4 bytes
995  * real group ID           4 bytes
996  * process ID              4 bytes
997  * session ID              4 bytes
998  * terminal ID
999  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1000  *   machine address       4 bytes
1001  */
1002 token_t *
1003 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1004     pid_t pid, au_asid_t sid, au_tid_t *tid)
1005 {
1006 	token_t *t;
1007 	u_char *dptr = NULL;
1008 
1009 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1010 	if (t == NULL)
1011 		return (NULL);
1012 
1013 	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1014 	ADD_U_INT32(dptr, auid);
1015 	ADD_U_INT32(dptr, euid);
1016 	ADD_U_INT32(dptr, egid);
1017 	ADD_U_INT32(dptr, ruid);
1018 	ADD_U_INT32(dptr, rgid);
1019 	ADD_U_INT32(dptr, pid);
1020 	ADD_U_INT32(dptr, sid);
1021 	ADD_U_INT32(dptr, tid->port);
1022 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1023 
1024 	return (t);
1025 }
1026 
1027 token_t *
1028 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1029     pid_t pid, au_asid_t sid, au_tid_t *tid)
1030 {
1031 	token_t *t;
1032 	u_char *dptr = NULL;
1033 
1034 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1035 	    sizeof(u_int64_t) + sizeof(u_int32_t));
1036 	if (t == NULL)
1037 		return (NULL);
1038 
1039 	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1040 	ADD_U_INT32(dptr, auid);
1041 	ADD_U_INT32(dptr, euid);
1042 	ADD_U_INT32(dptr, egid);
1043 	ADD_U_INT32(dptr, ruid);
1044 	ADD_U_INT32(dptr, rgid);
1045 	ADD_U_INT32(dptr, pid);
1046 	ADD_U_INT32(dptr, sid);
1047 	ADD_U_INT64(dptr, tid->port);
1048 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1049 
1050 	return (t);
1051 }
1052 
1053 token_t *
1054 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1055     pid_t pid, au_asid_t sid, au_tid_t *tid)
1056 {
1057 
1058 	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1059 	    tid));
1060 }
1061 
1062 /*
1063  * token ID                1 byte
1064  * audit ID                4 bytes
1065  * effective user ID       4 bytes
1066  * effective group ID      4 bytes
1067  * real user ID            4 bytes
1068  * real group ID           4 bytes
1069  * process ID              4 bytes
1070  * session ID              4 bytes
1071  * terminal ID
1072  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1073  *   address type/length   4 bytes
1074  *   machine address      16 bytes
1075  */
1076 token_t *
1077 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1078     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1079 {
1080 	token_t *t;
1081 	u_char *dptr = NULL;
1082 
1083 	if (tid->at_type == AU_IPv4)
1084 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1085 		    sizeof(u_int32_t));
1086 	else if (tid->at_type == AU_IPv6)
1087 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1088 		    sizeof(u_int32_t));
1089 	else {
1090 		errno = EINVAL;
1091 		return (NULL);
1092 	}
1093 	if (t == NULL)
1094 		return (NULL);
1095 
1096 	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1097 	ADD_U_INT32(dptr, auid);
1098 	ADD_U_INT32(dptr, euid);
1099 	ADD_U_INT32(dptr, egid);
1100 	ADD_U_INT32(dptr, ruid);
1101 	ADD_U_INT32(dptr, rgid);
1102 	ADD_U_INT32(dptr, pid);
1103 	ADD_U_INT32(dptr, sid);
1104 	ADD_U_INT32(dptr, tid->at_port);
1105 	ADD_U_INT32(dptr, tid->at_type);
1106 	if (tid->at_type == AU_IPv6)
1107 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1108 	else
1109 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1110 
1111 	return (t);
1112 }
1113 
1114 token_t *
1115 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1116     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1117 {
1118 	token_t *t;
1119 	u_char *dptr = NULL;
1120 
1121 	if (tid->at_type == AU_IPv4)
1122 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1123 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1124 		    2 * sizeof(u_int32_t));
1125 	else if (tid->at_type == AU_IPv6)
1126 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1127 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1128 		    5 * sizeof(u_int32_t));
1129 	else {
1130 		errno = EINVAL;
1131 		return (NULL);
1132 	}
1133 	if (t == NULL)
1134 		return (NULL);
1135 
1136 	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1137 	ADD_U_INT32(dptr, auid);
1138 	ADD_U_INT32(dptr, euid);
1139 	ADD_U_INT32(dptr, egid);
1140 	ADD_U_INT32(dptr, ruid);
1141 	ADD_U_INT32(dptr, rgid);
1142 	ADD_U_INT32(dptr, pid);
1143 	ADD_U_INT32(dptr, sid);
1144 	ADD_U_INT64(dptr, tid->at_port);
1145 	ADD_U_INT32(dptr, tid->at_type);
1146 	if (tid->at_type == AU_IPv6)
1147 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1148 	else
1149 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1150 
1151 	return (t);
1152 }
1153 
1154 token_t *
1155 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1156     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1157 {
1158 
1159 	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1160 	    tid));
1161 }
1162 
1163 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1164 /*
1165  * Collects audit information for the current process
1166  * and creates a subject token from it
1167  */
1168 token_t *
1169 au_to_me(void)
1170 {
1171 	auditinfo_t auinfo;
1172 
1173 	if (getaudit(&auinfo) != 0)
1174 		return (NULL);
1175 
1176 	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1177 	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1178 }
1179 #endif
1180 
1181 /*
1182  * token ID				1 byte
1183  * count				4 bytes
1184  * text					count null-terminated strings
1185  */
1186 token_t *
1187 au_to_exec_args(char **argv)
1188 {
1189 	token_t *t;
1190 	u_char *dptr = NULL;
1191 	const char *nextarg;
1192 	int i, count = 0;
1193 	size_t totlen = 0;
1194 
1195 	nextarg = *argv;
1196 
1197 	while (nextarg != NULL) {
1198 		int nextlen;
1199 
1200 		nextlen = strlen(nextarg);
1201 		totlen += nextlen + 1;
1202 		count++;
1203 		nextarg = *(argv + count);
1204 	}
1205 
1206 	totlen += count * sizeof(char);	/* nul terminations. */
1207 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1208 	if (t == NULL)
1209 		return (NULL);
1210 
1211 	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1212 	ADD_U_INT32(dptr, count);
1213 
1214 	for (i = 0; i < count; i++) {
1215 		nextarg = *(argv + i);
1216 		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1217 	}
1218 
1219 	return (t);
1220 }
1221 
1222 /*
1223  * token ID                1 byte
1224  * zonename length         2 bytes
1225  * zonename                N bytes + 1 terminating NULL byte
1226  */
1227 token_t *
1228 au_to_zonename(char *zonename)
1229 {
1230 	u_char *dptr = NULL;
1231 	u_int16_t textlen;
1232 	token_t *t;
1233 
1234 	textlen = strlen(zonename);
1235 	textlen += 1;
1236 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1237 	ADD_U_CHAR(dptr, AUT_ZONENAME);
1238 	ADD_U_INT16(dptr, textlen);
1239 	ADD_STRING(dptr, zonename, textlen);
1240 	return (t);
1241 }
1242 
1243 /*
1244  * token ID				1 byte
1245  * count				4 bytes
1246  * text					count null-terminated strings
1247  */
1248 token_t *
1249 au_to_exec_env(char **envp)
1250 {
1251 	token_t *t;
1252 	u_char *dptr = NULL;
1253 	int i, count = 0;
1254 	size_t totlen = 0;
1255 	const char *nextenv;
1256 
1257 	nextenv = *envp;
1258 
1259 	while (nextenv != NULL) {
1260 		int nextlen;
1261 
1262 		nextlen = strlen(nextenv);
1263 		totlen += nextlen + 1;
1264 		count++;
1265 		nextenv = *(envp + count);
1266 	}
1267 
1268 	totlen += sizeof(char) * count;
1269 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1270 	if (t == NULL)
1271 		return (NULL);
1272 
1273 	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1274 	ADD_U_INT32(dptr, count);
1275 
1276 	for (i = 0; i < count; i++) {
1277 		nextenv = *(envp + i);
1278 		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1279 	}
1280 
1281 	return (t);
1282 }
1283 
1284 /*
1285  * token ID                1 byte
1286  * record byte count       4 bytes
1287  * version #               1 byte    [2]
1288  * event type              2 bytes
1289  * event modifier          2 bytes
1290  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1291  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1292  */
1293 token_t *
1294 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1295     struct timeval tm)
1296 {
1297 	token_t *t;
1298 	u_char *dptr = NULL;
1299 	u_int32_t timems;
1300 
1301 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1302 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1303 	if (t == NULL)
1304 		return (NULL);
1305 
1306 	ADD_U_CHAR(dptr, AUT_HEADER32);
1307 	ADD_U_INT32(dptr, rec_size);
1308 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1309 	ADD_U_INT16(dptr, e_type);
1310 	ADD_U_INT16(dptr, e_mod);
1311 
1312 	timems = tm.tv_usec/1000;
1313 	/* Add the timestamp */
1314 	ADD_U_INT32(dptr, tm.tv_sec);
1315 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1316 
1317 	return (t);
1318 }
1319 
1320 token_t *
1321 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1322     struct timeval tm)
1323 {
1324 	token_t *t;
1325 	u_char *dptr = NULL;
1326 	u_int32_t timems;
1327 
1328 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1329 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1330 	if (t == NULL)
1331 		return (NULL);
1332 
1333 	ADD_U_CHAR(dptr, AUT_HEADER64);
1334 	ADD_U_INT32(dptr, rec_size);
1335 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1336 	ADD_U_INT16(dptr, e_type);
1337 	ADD_U_INT16(dptr, e_mod);
1338 
1339 	timems = tm.tv_usec/1000;
1340 	/* Add the timestamp */
1341 	ADD_U_INT64(dptr, tm.tv_sec);
1342 	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1343 
1344 	return (t);
1345 }
1346 
1347 #if !defined(KERNEL) && !defined(_KERNEL)
1348 token_t *
1349 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1350 {
1351 	struct timeval tm;
1352 
1353 	if (gettimeofday(&tm, NULL) == -1)
1354 		return (NULL);
1355 	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1356 }
1357 
1358 token_t *
1359 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1360     __unused au_emod_t e_mod)
1361 {
1362 	struct timeval tm;
1363 
1364 	if (gettimeofday(&tm, NULL) == -1)
1365 		return (NULL);
1366 	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1367 }
1368 
1369 token_t *
1370 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1371 {
1372 
1373 	return (au_to_header32(rec_size, e_type, e_mod));
1374 }
1375 #endif
1376 
1377 /*
1378  * token ID                1 byte
1379  * trailer magic number    2 bytes
1380  * record byte count       4 bytes
1381  */
1382 token_t *
1383 au_to_trailer(int rec_size)
1384 {
1385 	token_t *t;
1386 	u_char *dptr = NULL;
1387 	u_int16_t magic = TRAILER_PAD_MAGIC;
1388 
1389 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1390 	    sizeof(u_int32_t));
1391 	if (t == NULL)
1392 		return (NULL);
1393 
1394 	ADD_U_CHAR(dptr, AUT_TRAILER);
1395 	ADD_U_INT16(dptr, magic);
1396 	ADD_U_INT32(dptr, rec_size);
1397 
1398 	return (t);
1399 }
1400