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