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