bsm_token.c revision 159259
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/audit3/sys/security/audit/audit_bsm_token.c#15 $
34 * $FreeBSD: head/sys/security/audit/audit_bsm_token.c 159259 2006-06-05 13:13:02Z rwatson $
35 */
36
37#include <sys/types.h>
38#include <sys/endian.h>
39#include <sys/queue.h>
40#include <sys/socket.h>
41#include <sys/time.h>
42
43#include <sys/ipc.h>
44#include <sys/libkern.h>
45#include <sys/malloc.h>
46#include <sys/un.h>
47
48#include <netinet/in.h>
49#include <netinet/in_systm.h>
50#include <netinet/ip.h>
51
52#include <sys/socketvar.h>
53
54#include <bsm/audit.h>
55#include <bsm/audit_internal.h>
56#include <bsm/audit_record.h>
57#include <security/audit/audit.h>
58#include <security/audit/audit_private.h>
59
60#define	GET_TOKEN_AREA(t, dptr, length) do {				\
61	t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK);		\
62	t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO);	\
63	t->len = length;						\
64	dptr = t->t_data;						\
65} while (0)
66
67/*
68 * token ID                1 byte
69 * argument #              1 byte
70 * argument value          4 bytes/8 bytes (32-bit/64-bit value)
71 * text length             2 bytes
72 * text                    N bytes + 1 terminating NULL byte
73 */
74token_t *
75au_to_arg32(char n, char *text, u_int32_t v)
76{
77	token_t *t;
78	u_char *dptr = NULL;
79	u_int16_t textlen;
80
81	textlen = strlen(text);
82	textlen += 1;
83
84	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
85	    sizeof(u_int16_t) + textlen);
86
87	ADD_U_CHAR(dptr, AUT_ARG32);
88	ADD_U_CHAR(dptr, n);
89	ADD_U_INT32(dptr, v);
90	ADD_U_INT16(dptr, textlen);
91	ADD_STRING(dptr, text, textlen);
92
93	return (t);
94
95}
96
97token_t *
98au_to_arg64(char n, char *text, u_int64_t v)
99{
100	token_t *t;
101	u_char *dptr = NULL;
102	u_int16_t textlen;
103
104	textlen = strlen(text);
105	textlen += 1;
106
107	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
108	    sizeof(u_int16_t) + textlen);
109
110	ADD_U_CHAR(dptr, AUT_ARG64);
111	ADD_U_CHAR(dptr, n);
112	ADD_U_INT64(dptr, v);
113	ADD_U_INT16(dptr, textlen);
114	ADD_STRING(dptr, text, textlen);
115
116	return (t);
117
118}
119
120token_t *
121au_to_arg(char n, char *text, u_int32_t v)
122{
123
124	return (au_to_arg32(n, text, v));
125}
126
127#if defined(_KERNEL) || defined(KERNEL)
128/*
129 * token ID                1 byte
130 * file access mode        4 bytes
131 * owner user ID           4 bytes
132 * owner group ID          4 bytes
133 * file system ID          4 bytes
134 * node ID                 8 bytes
135 * device                  4 bytes/8 bytes (32-bit/64-bit)
136 */
137token_t *
138au_to_attr32(struct vnode_au_info *vni)
139{
140	token_t *t;
141	u_char *dptr = NULL;
142	u_int16_t pad0_16 = 0;
143	u_int16_t pad0_32 = 0;
144
145	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
146	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
147
148	ADD_U_CHAR(dptr, AUT_ATTR32);
149
150	/*
151	 * Darwin defines the size for the file mode
152	 * as 2 bytes; BSM defines 4 so pad with 0
153	 */
154	ADD_U_INT16(dptr, pad0_16);
155	ADD_U_INT16(dptr, vni->vn_mode);
156
157	ADD_U_INT32(dptr, vni->vn_uid);
158	ADD_U_INT32(dptr, vni->vn_gid);
159	ADD_U_INT32(dptr, vni->vn_fsid);
160
161	/*
162	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
163	 * Attempt to handle both, and let the compiler sort it out.  If we
164	 * could pick this out at compile-time, it would be better, so as to
165	 * avoid the else case below.
166	 */
167	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
168		ADD_U_INT32(dptr, pad0_32);
169		ADD_U_INT32(dptr, vni->vn_fileid);
170	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
171		ADD_U_INT64(dptr, vni->vn_fileid);
172	else
173		ADD_U_INT64(dptr, 0LL);
174
175	ADD_U_INT32(dptr, vni->vn_dev);
176
177	return (t);
178}
179
180token_t *
181au_to_attr64(struct vnode_au_info *vni)
182{
183
184	return (NULL);
185}
186
187token_t *
188au_to_attr(struct vnode_au_info *vni)
189{
190
191	return (au_to_attr32(vni));
192}
193#endif /* !(defined(_KERNEL) || defined(KERNEL) */
194
195/*
196 * token ID                1 byte
197 * how to print            1 byte
198 * basic unit              1 byte
199 * unit count              1 byte
200 * data items              (depends on basic unit)
201 */
202token_t *
203au_to_data(char unit_print, char unit_type, char unit_count, char *p)
204{
205	token_t *t;
206	u_char *dptr = NULL;
207	size_t datasize, totdata;
208
209	/* Determine the size of the basic unit. */
210	switch (unit_type) {
211	case AUR_BYTE:
212	/* case AUR_CHAR: */
213		datasize = AUR_BYTE_SIZE;
214		break;
215
216	case AUR_SHORT:
217		datasize = AUR_SHORT_SIZE;
218		break;
219
220	case AUR_INT32:
221	/* case AUR_INT: */
222		datasize = AUR_INT32_SIZE;
223		break;
224
225	case AUR_INT64:
226		datasize = AUR_INT64_SIZE;
227		break;
228
229	default:
230 		return (NULL);
231	}
232
233	totdata = datasize * unit_count;
234
235	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
236
237	ADD_U_CHAR(dptr, AUT_DATA);
238	ADD_U_CHAR(dptr, unit_print);
239	ADD_U_CHAR(dptr, unit_type);
240	ADD_U_CHAR(dptr, unit_count);
241	ADD_MEM(dptr, p, totdata);
242
243	return (t);
244}
245
246
247/*
248 * token ID                1 byte
249 * status		   4 bytes
250 * return value            4 bytes
251 */
252token_t *
253au_to_exit(int retval, int err)
254{
255	token_t *t;
256	u_char *dptr = NULL;
257
258	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
259
260	ADD_U_CHAR(dptr, AUT_EXIT);
261	ADD_U_INT32(dptr, err);
262	ADD_U_INT32(dptr, retval);
263
264	return (t);
265}
266
267/*
268 */
269token_t *
270au_to_groups(int *groups)
271{
272
273	return (au_to_newgroups(BSM_MAX_GROUPS, groups));
274}
275
276/*
277 * token ID                1 byte
278 * number groups           2 bytes
279 * group list              count * 4 bytes
280 */
281token_t *
282au_to_newgroups(u_int16_t n, gid_t *groups)
283{
284	token_t *t;
285	u_char *dptr = NULL;
286	int i;
287
288	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
289	    n * sizeof(u_int32_t));
290
291	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
292	ADD_U_INT16(dptr, n);
293	for (i = 0; i < n; i++)
294		ADD_U_INT32(dptr, groups[i]);
295
296	return (t);
297}
298
299/*
300 * token ID                1 byte
301 * internet address        4 bytes
302 */
303token_t *
304au_to_in_addr(struct in_addr *internet_addr)
305{
306	token_t *t;
307	u_char *dptr = NULL;
308
309	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
310
311	ADD_U_CHAR(dptr, AUT_IN_ADDR);
312	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
313
314	return (t);
315}
316
317/*
318 * token ID                1 byte
319 * address type/length     4 bytes
320 * Address                16 bytes
321 */
322token_t *
323au_to_in_addr_ex(struct in6_addr *internet_addr)
324{
325	token_t *t;
326	u_char *dptr = NULL;
327	u_int32_t type = AF_INET6;
328
329	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
330
331	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
332	ADD_U_INT32(dptr, type);
333	ADD_MEM(dptr, internet_addr, 5 * sizeof(uint32_t));
334
335	return (t);
336}
337
338/*
339 * token ID                1 byte
340 * ip header		   20 bytes
341 */
342token_t *
343au_to_ip(struct ip *ip)
344{
345	token_t *t;
346	u_char *dptr = NULL;
347
348	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
349
350	ADD_U_CHAR(dptr, AUT_IP);
351	/*
352	 * XXXRW: Any byte order work needed on the IP header before writing?
353	 */
354	ADD_MEM(dptr, ip, sizeof(struct ip));
355
356	return (t);
357}
358
359/*
360 * token ID                1 byte
361 * object ID type          1 byte
362 * object ID               4 bytes
363 */
364token_t *
365au_to_ipc(char type, int id)
366{
367	token_t *t;
368	u_char *dptr = NULL;
369
370	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
371
372	ADD_U_CHAR(dptr, AUT_IPC);
373	ADD_U_CHAR(dptr, type);
374	ADD_U_INT32(dptr, id);
375
376	return (t);
377}
378
379/*
380 * token ID                1 byte
381 * owner user ID           4 bytes
382 * owner group ID          4 bytes
383 * creator user ID         4 bytes
384 * creator group ID        4 bytes
385 * access mode             4 bytes
386 * slot sequence #         4 bytes
387 * key                     4 bytes
388 */
389token_t *
390au_to_ipc_perm(struct ipc_perm *perm)
391{
392	token_t *t;
393	u_char *dptr = NULL;
394	u_int16_t pad0 = 0;
395
396	GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
397
398	ADD_U_CHAR(dptr, AUT_IPC_PERM);
399
400	/*
401	 * Darwin defines the sizes for ipc_perm members
402	 * as 2 bytes; BSM defines 4 so pad with 0
403	 */
404	ADD_U_INT16(dptr, pad0);
405	ADD_U_INT16(dptr, perm->uid);
406
407	ADD_U_INT16(dptr, pad0);
408	ADD_U_INT16(dptr, perm->gid);
409
410	ADD_U_INT16(dptr, pad0);
411	ADD_U_INT16(dptr, perm->cuid);
412
413	ADD_U_INT16(dptr, pad0);
414	ADD_U_INT16(dptr, perm->cgid);
415
416	ADD_U_INT16(dptr, pad0);
417	ADD_U_INT16(dptr, perm->mode);
418
419	ADD_U_INT16(dptr, pad0);
420	ADD_U_INT16(dptr, perm->seq);
421
422	ADD_U_INT32(dptr, perm->key);
423
424	return (t);
425}
426
427/*
428 * token ID                1 byte
429 * port IP address         2 bytes
430 */
431token_t *
432au_to_iport(u_int16_t iport)
433{
434	token_t *t;
435	u_char *dptr = NULL;
436
437	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
438
439	ADD_U_CHAR(dptr, AUT_IPORT);
440	ADD_U_INT16(dptr, iport);
441
442	return (t);
443}
444
445/*
446 * token ID                1 byte
447 * size                    2 bytes
448 * data                    size bytes
449 */
450token_t *
451au_to_opaque(char *data, u_int16_t bytes)
452{
453	token_t *t;
454	u_char *dptr = NULL;
455
456	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
457
458	ADD_U_CHAR(dptr, AUT_OPAQUE);
459	ADD_U_INT16(dptr, bytes);
460	ADD_MEM(dptr, data, bytes);
461
462	return (t);
463}
464
465/*
466 * token ID                1 byte
467 * seconds of time         4 bytes
468 * milliseconds of time    4 bytes
469 * file name len           2 bytes
470 * file pathname           N bytes + 1 terminating NULL byte
471 */
472token_t *
473au_to_file(char *file, struct timeval tm)
474{
475	token_t *t;
476	u_char *dptr = NULL;
477	u_int16_t filelen;
478	u_int32_t timems;
479
480	filelen = strlen(file);
481	filelen += 1;
482
483	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
484	    sizeof(u_int16_t) + filelen);
485
486	timems = tm.tv_usec/1000;
487
488	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
489	ADD_U_INT32(dptr, tm.tv_sec);
490	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
491	ADD_U_INT16(dptr, filelen);
492	ADD_STRING(dptr, file, filelen);
493
494	return (t);
495}
496
497/*
498 * token ID                1 byte
499 * text length             2 bytes
500 * text                    N bytes + 1 terminating NULL byte
501 */
502token_t *
503au_to_text(char *text)
504{
505	token_t *t;
506	u_char *dptr = NULL;
507	u_int16_t textlen;
508
509	textlen = strlen(text);
510	textlen += 1;
511
512	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
513
514	ADD_U_CHAR(dptr, AUT_TEXT);
515	ADD_U_INT16(dptr, textlen);
516	ADD_STRING(dptr, text, textlen);
517
518	return (t);
519}
520
521/*
522 * token ID                1 byte
523 * path length             2 bytes
524 * path                    N bytes + 1 terminating NULL byte
525 */
526token_t *
527au_to_path(char *text)
528{
529	token_t *t;
530	u_char *dptr = NULL;
531	u_int16_t textlen;
532
533	textlen = strlen(text);
534	textlen += 1;
535
536	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
537
538	ADD_U_CHAR(dptr, AUT_PATH);
539	ADD_U_INT16(dptr, textlen);
540	ADD_STRING(dptr, text, textlen);
541
542	return (t);
543}
544
545/*
546 * token ID                1 byte
547 * audit ID                4 bytes
548 * effective user ID       4 bytes
549 * effective group ID      4 bytes
550 * real user ID            4 bytes
551 * real group ID           4 bytes
552 * process ID              4 bytes
553 * session ID              4 bytes
554 * terminal ID
555 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
556 *   machine address       4 bytes
557 */
558token_t *
559au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
560    pid_t pid, au_asid_t sid, au_tid_t *tid)
561{
562	token_t *t;
563	u_char *dptr = NULL;
564
565	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
566
567	ADD_U_CHAR(dptr, AUT_PROCESS32);
568	ADD_U_INT32(dptr, auid);
569	ADD_U_INT32(dptr, euid);
570	ADD_U_INT32(dptr, egid);
571	ADD_U_INT32(dptr, ruid);
572	ADD_U_INT32(dptr, rgid);
573	ADD_U_INT32(dptr, pid);
574	ADD_U_INT32(dptr, sid);
575	ADD_U_INT32(dptr, tid->port);
576	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
577
578	return (t);
579}
580
581token_t *
582au_to_process64(__unused au_id_t auid, __unused uid_t euid,
583    __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
584    __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
585{
586
587	return (NULL);
588}
589
590token_t *
591au_to_process(__unused au_id_t auid, __unused uid_t euid,
592    __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
593    __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
594{
595
596	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
597	    tid));
598}
599
600/*
601 * token ID                1 byte
602 * audit ID                4 bytes
603 * effective user ID       4 bytes
604 * effective group ID      4 bytes
605 * real user ID            4 bytes
606 * real group ID           4 bytes
607 * process ID              4 bytes
608 * session ID              4 bytes
609 * terminal ID
610 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
611 *   address type-len      4 bytes
612 *   machine address      16 bytes
613 */
614token_t *
615au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
616    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
617{
618	token_t *t;
619	u_char *dptr = NULL;
620
621	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t));
622
623	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
624	ADD_U_INT32(dptr, auid);
625	ADD_U_INT32(dptr, euid);
626	ADD_U_INT32(dptr, egid);
627	ADD_U_INT32(dptr, ruid);
628	ADD_U_INT32(dptr, rgid);
629	ADD_U_INT32(dptr, pid);
630	ADD_U_INT32(dptr, sid);
631	ADD_U_INT32(dptr, tid->at_port);
632	ADD_U_INT32(dptr, tid->at_type);
633	ADD_U_INT32(dptr, tid->at_addr[0]);
634	ADD_U_INT32(dptr, tid->at_addr[1]);
635	ADD_U_INT32(dptr, tid->at_addr[2]);
636	ADD_U_INT32(dptr, tid->at_addr[3]);
637
638	return (t);
639}
640
641token_t *
642au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
643    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
644{
645
646	return (NULL);
647}
648
649token_t *
650au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
651    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
652{
653
654	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
655	    tid));
656}
657
658/*
659 * token ID                1 byte
660 * error status            1 byte
661 * return value            4 bytes/8 bytes (32-bit/64-bit value)
662 */
663token_t *
664au_to_return32(char status, u_int32_t ret)
665{
666	token_t *t;
667	u_char *dptr = NULL;
668
669	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
670
671	ADD_U_CHAR(dptr, AUT_RETURN32);
672	ADD_U_CHAR(dptr, status);
673	ADD_U_INT32(dptr, ret);
674
675	return (t);
676}
677
678token_t *
679au_to_return64(char status, u_int64_t ret)
680{
681	token_t *t;
682	u_char *dptr = NULL;
683
684	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
685
686	ADD_U_CHAR(dptr, AUT_RETURN64);
687	ADD_U_CHAR(dptr, status);
688	ADD_U_INT64(dptr, ret);
689
690	return (t);
691}
692
693token_t *
694au_to_return(char status, u_int32_t ret)
695{
696
697	return (au_to_return32(status, ret));
698}
699
700/*
701 * token ID                1 byte
702 * sequence number         4 bytes
703 */
704token_t *
705au_to_seq(long audit_count)
706{
707	token_t *t;
708	u_char *dptr = NULL;
709
710	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
711
712	ADD_U_CHAR(dptr, AUT_SEQ);
713	ADD_U_INT32(dptr, audit_count);
714
715	return (t);
716}
717
718/*
719 * token ID                1 byte
720 * socket type             2 bytes
721 * local port              2 bytes
722 * local Internet address  4 bytes
723 * remote port             2 bytes
724 * remote Internet address 4 bytes
725 */
726token_t *
727au_to_socket(struct socket *so)
728{
729
730	/* XXXRW ... */
731	return (NULL);
732}
733
734/*
735 * Kernel-specific version of the above function.
736 */
737#ifdef _KERNEL
738token_t *
739kau_to_socket(struct socket_au_info *soi)
740{
741	token_t *t;
742	u_char *dptr;
743	u_int16_t so_type;
744
745	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
746	    sizeof(u_int32_t) + sizeof(u_int16_t) + sizeof(u_int32_t));
747
748	ADD_U_CHAR(dptr, AU_SOCK_TOKEN);
749	/* Coerce the socket type into a short value */
750	so_type = soi->so_type;
751	ADD_U_INT16(dptr, so_type);
752	ADD_U_INT16(dptr, soi->so_lport);
753	ADD_U_INT32(dptr, soi->so_laddr);
754	ADD_U_INT16(dptr, soi->so_rport);
755	ADD_U_INT32(dptr, soi->so_raddr);
756
757	return (t);
758}
759#endif
760
761/*
762 * token ID                1 byte
763 * socket type             2 bytes
764 * local port              2 bytes
765 * address type/length     4 bytes
766 * local Internet address  4 bytes/16 bytes (IPv4/IPv6 address)
767 * remote port             4 bytes
768 * address type/length     4 bytes
769 * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address)
770 */
771token_t *
772au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
773    struct sockaddr *ra)
774{
775
776	return (NULL);
777}
778
779token_t *
780au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la,
781    struct sockaddr *ra)
782{
783
784	return (NULL);
785}
786
787/*
788 * token ID                1 byte
789 * socket family           2 bytes
790 * path                    104 bytes
791 */
792token_t *
793au_to_sock_unix(struct sockaddr_un *so)
794{
795	token_t *t;
796	u_char *dptr;
797
798	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
799
800	ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
801	/* BSM token has two bytes for family */
802	ADD_U_CHAR(dptr, 0);
803	ADD_U_CHAR(dptr, so->sun_family);
804	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
805
806	return (t);
807}
808
809/*
810 * token ID                1 byte
811 * socket family           2 bytes
812 * local port              2 bytes
813 * socket address          4 bytes
814 */
815token_t *
816au_to_sock_inet32(struct sockaddr_in *so)
817{
818	token_t *t;
819	u_char *dptr = NULL;
820	uint16_t family;
821
822	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
823	    sizeof(uint32_t));
824
825	ADD_U_CHAR(dptr, AUT_SOCKINET32);
826	/*
827	 * BSM defines the family field as 16 bits, but many operating
828	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
829	 * writing into the token.  Assume that both the port and the address
830	 * in the sockaddr_in are already in network byte order, but family
831	 * is in local byte order.
832	 *
833	 * XXXRW: Should a name space conversion be taking place on the value
834	 * of sin_family?
835 	 */
836	family = so->sin_family;
837	ADD_U_INT16(dptr, family);
838	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
839	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
840
841	return (t);
842
843}
844
845token_t *
846au_to_sock_inet128(struct sockaddr_in6 *so)
847{
848	token_t *t;
849	u_char *dptr = NULL;
850
851	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
852	    4 * sizeof(u_int32_t));
853
854	ADD_U_CHAR(dptr, AUT_SOCKINET128);
855	/*
856	 * In Darwin, sin6_family is one octet, but BSM defines the token
857 	 * to store two. So we copy in a 0 first.
858 	 */
859	ADD_U_CHAR(dptr, 0);
860	ADD_U_CHAR(dptr, so->sin6_family);
861
862	ADD_U_INT16(dptr, so->sin6_port);
863	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
864
865	return (t);
866
867}
868
869token_t *
870au_to_sock_inet(struct sockaddr_in *so)
871{
872
873	return (au_to_sock_inet32(so));
874}
875
876/*
877 * token ID                1 byte
878 * audit ID                4 bytes
879 * effective user ID       4 bytes
880 * effective group ID      4 bytes
881 * real user ID            4 bytes
882 * real group ID           4 bytes
883 * process ID              4 bytes
884 * session ID              4 bytes
885 * terminal ID
886 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
887 *   machine address       4 bytes
888 */
889token_t *
890au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
891    pid_t pid, au_asid_t sid, au_tid_t *tid)
892{
893	token_t *t;
894	u_char *dptr = NULL;
895
896	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
897
898	ADD_U_CHAR(dptr, AUT_SUBJECT32);
899	ADD_U_INT32(dptr, auid);
900	ADD_U_INT32(dptr, euid);
901	ADD_U_INT32(dptr, egid);
902	ADD_U_INT32(dptr, ruid);
903	ADD_U_INT32(dptr, rgid);
904	ADD_U_INT32(dptr, pid);
905	ADD_U_INT32(dptr, sid);
906	ADD_U_INT32(dptr, tid->port);
907	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
908
909	return (t);
910}
911
912token_t *
913au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
914    pid_t pid, au_asid_t sid, au_tid_t *tid)
915{
916
917	return (NULL);
918}
919
920token_t *
921au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
922    pid_t pid, au_asid_t sid, au_tid_t *tid)
923{
924
925	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
926	    tid));
927}
928
929/*
930 * token ID                1 byte
931 * audit ID                4 bytes
932 * effective user ID       4 bytes
933 * effective group ID      4 bytes
934 * real user ID            4 bytes
935 * real group ID           4 bytes
936 * process ID              4 bytes
937 * session ID              4 bytes
938 * terminal ID
939 *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
940 *   address type/length   4 bytes
941 *   machine address      16 bytes
942 */
943token_t *
944au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
945    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
946{
947	token_t *t;
948	u_char *dptr = NULL;
949
950	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t));
951
952	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
953	ADD_U_INT32(dptr, auid);
954	ADD_U_INT32(dptr, euid);
955	ADD_U_INT32(dptr, egid);
956	ADD_U_INT32(dptr, ruid);
957	ADD_U_INT32(dptr, rgid);
958	ADD_U_INT32(dptr, pid);
959	ADD_U_INT32(dptr, sid);
960	ADD_U_INT32(dptr, tid->at_port);
961	ADD_U_INT32(dptr, tid->at_type);
962	ADD_U_INT32(dptr, tid->at_addr[0]);
963	ADD_U_INT32(dptr, tid->at_addr[1]);
964	ADD_U_INT32(dptr, tid->at_addr[2]);
965	ADD_U_INT32(dptr, tid->at_addr[3]);
966
967	return (t);
968}
969
970token_t *
971au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
972    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
973{
974
975	return (NULL);
976}
977
978token_t *
979au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
980    gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
981{
982
983	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
984	    tid));
985}
986
987#if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
988/*
989 * Collects audit information for the current process
990 * and creates a subject token from it
991 */
992token_t *
993au_to_me(void)
994{
995	auditinfo_t auinfo;
996
997	if (getaudit(&auinfo) != 0)
998		return (NULL);
999
1000	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1001	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1002}
1003#endif
1004
1005/*
1006 * token ID				1 byte
1007 * count				4 bytes
1008 * text					count null-terminated strings
1009 */
1010token_t *
1011au_to_exec_args(const char **args)
1012{
1013	token_t *t;
1014	u_char *dptr = NULL;
1015	const char *nextarg;
1016	int i, count = 0;
1017	size_t totlen = 0;
1018
1019	nextarg = *args;
1020
1021	while (nextarg != NULL) {
1022		int nextlen;
1023
1024		nextlen = strlen(nextarg);
1025		totlen += nextlen + 1;
1026		count++;
1027		nextarg = *(args + count);
1028	}
1029
1030	totlen += count * sizeof(char);	/* nul terminations. */
1031	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1032
1033	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1034	ADD_U_INT32(dptr, count);
1035
1036	for (i = 0; i < count; i++) {
1037		nextarg = *(args + i);
1038		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1039	}
1040
1041	return (t);
1042}
1043
1044/*
1045 * token ID				1 byte
1046 * count				4 bytes
1047 * text					count null-terminated strings
1048 */
1049token_t *
1050au_to_exec_env(const char **env)
1051{
1052	token_t *t;
1053	u_char *dptr = NULL;
1054	int i, count = 0;
1055	size_t totlen = 0;
1056	const char *nextenv;
1057
1058	nextenv = *env;
1059
1060	while (nextenv != NULL) {
1061		int nextlen;
1062
1063		nextlen = strlen(nextenv);
1064		totlen += nextlen + 1;
1065		count++;
1066		nextenv = *(env + count);
1067	}
1068
1069	totlen += sizeof(char) * count;
1070	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1071
1072	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1073	ADD_U_INT32(dptr, count);
1074
1075	for (i = 0; i < count; i++) {
1076		nextenv = *(env + i);
1077		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1078	}
1079
1080	return (t);
1081}
1082
1083/*
1084 * token ID                1 byte
1085 * record byte count       4 bytes
1086 * version #               1 byte    [2]
1087 * event type              2 bytes
1088 * event modifier          2 bytes
1089 * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1090 * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1091 */
1092token_t *
1093au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1094    struct timeval tm)
1095{
1096	token_t *t;
1097	u_char *dptr = NULL;
1098	u_int32_t timems;
1099
1100	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1101	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1102
1103	ADD_U_CHAR(dptr, AUT_HEADER32);
1104	ADD_U_INT32(dptr, rec_size);
1105	ADD_U_CHAR(dptr, HEADER_VERSION);
1106	ADD_U_INT16(dptr, e_type);
1107	ADD_U_INT16(dptr, e_mod);
1108
1109	timems = tm.tv_usec/1000;
1110	/* Add the timestamp */
1111	ADD_U_INT32(dptr, tm.tv_sec);
1112	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1113
1114	return (t);
1115}
1116
1117/*
1118 * token ID                1 byte
1119 * trailer magic number    2 bytes
1120 * record byte count       4 bytes
1121 */
1122token_t *
1123au_to_trailer(int rec_size)
1124{
1125	token_t *t;
1126	u_char *dptr = NULL;
1127	u_int16_t magic = TRAILER_PAD_MAGIC;
1128
1129	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1130	    sizeof(u_int32_t));
1131
1132	ADD_U_CHAR(dptr, AUT_TRAILER);
1133	ADD_U_INT16(dptr, magic);
1134	ADD_U_INT32(dptr, rec_size);
1135
1136	return (t);
1137}
1138