xref: /freebsd/contrib/openbsm/libbsm/bsm_token.c (revision f0a75d274af375d15b97b830966b99a02b7db911)
1 /*
2  * Copyright (c) 2004 Apple Computer, Inc.
3  * Copyright (c) 2005 SPARTA, Inc.
4  * All rights reserved.
5  *
6  * This code was developed in part by Robert N. M. Watson, Senior Principal
7  * Scientist, SPARTA, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1.  Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  * 2.  Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
18  *     its contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#52 $
34  */
35 
36 #include <sys/types.h>
37 
38 #include <config/config.h>
39 #ifdef HAVE_SYS_ENDIAN_H
40 #include <sys/endian.h>
41 #else /* !HAVE_SYS_ENDIAN_H */
42 #ifdef HAVE_MACHINE_ENDIAN_H
43 #include <machine/endian.h>
44 #else /* !HAVE_MACHINE_ENDIAN_H */
45 #ifdef HAVE_ENDIAN_H
46 #include <endian.h>
47 #else /* !HAVE_ENDIAN_H */
48 #error "No supported endian.h"
49 #endif /* !HAVE_ENDIAN_H */
50 #endif /* !HAVE_MACHINE_ENDIAN_H */
51 #include <compat/endian.h>
52 #endif /* !HAVE_SYS_ENDIAN_H */
53 #ifdef HAVE_FULL_QUEUE_H
54 #include <sys/queue.h>
55 #else /* !HAVE_FULL_QUEUE_H */
56 #include <compat/queue.h>
57 #endif /* !HAVE_FULL_QUEUE_H */
58 
59 #include <sys/socket.h>
60 #include <sys/time.h>
61 #include <sys/un.h>
62 
63 #include <sys/ipc.h>
64 
65 #include <netinet/in.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
68 
69 #include <assert.h>
70 #include <errno.h>
71 #include <string.h>
72 #include <stdlib.h>
73 #include <unistd.h>
74 
75 #include <bsm/audit_internal.h>
76 #include <bsm/libbsm.h>
77 
78 #define	GET_TOKEN_AREA(t, dptr, length) do {				\
79 	(t) = malloc(sizeof(token_t));					\
80 	if ((t) != NULL) {						\
81 		(t)->len = (length);					\
82 		(dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \
83 		if ((dptr) == NULL) {					\
84 			free(t);					\
85 			(t) = NULL;					\
86 		} else							\
87 			memset((dptr), 0, (length));			\
88 	} else								\
89 		(dptr) = NULL;						\
90 	assert(t == NULL || dptr != NULL);				\
91 } while (0)
92 
93 /*
94  * token ID                1 byte
95  * argument #              1 byte
96  * argument value          4 bytes/8 bytes (32-bit/64-bit value)
97  * text length             2 bytes
98  * text                    N bytes + 1 terminating NULL byte
99  */
100 token_t *
101 au_to_arg32(char n, char *text, u_int32_t v)
102 {
103 	token_t *t;
104 	u_char *dptr = NULL;
105 	u_int16_t textlen;
106 
107 	textlen = strlen(text);
108 	textlen += 1;
109 
110 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
111 	    sizeof(u_int16_t) + textlen);
112 	if (t == NULL)
113 		return (NULL);
114 
115 	ADD_U_CHAR(dptr, AUT_ARG32);
116 	ADD_U_CHAR(dptr, n);
117 	ADD_U_INT32(dptr, v);
118 	ADD_U_INT16(dptr, textlen);
119 	ADD_STRING(dptr, text, textlen);
120 
121 	return (t);
122 
123 }
124 
125 token_t *
126 au_to_arg64(char n, char *text, u_int64_t v)
127 {
128 	token_t *t;
129 	u_char *dptr = NULL;
130 	u_int16_t textlen;
131 
132 	textlen = strlen(text);
133 	textlen += 1;
134 
135 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
136 	    sizeof(u_int16_t) + textlen);
137 	if (t == NULL)
138 		return (NULL);
139 
140 	ADD_U_CHAR(dptr, AUT_ARG64);
141 	ADD_U_CHAR(dptr, n);
142 	ADD_U_INT64(dptr, v);
143 	ADD_U_INT16(dptr, textlen);
144 	ADD_STRING(dptr, text, textlen);
145 
146 	return (t);
147 
148 }
149 
150 token_t *
151 au_to_arg(char n, char *text, u_int32_t v)
152 {
153 
154 	return (au_to_arg32(n, text, v));
155 }
156 
157 #if defined(_KERNEL) || defined(KERNEL)
158 /*
159  * token ID                1 byte
160  * file access mode        4 bytes
161  * owner user ID           4 bytes
162  * owner group ID          4 bytes
163  * file system ID          4 bytes
164  * node ID                 8 bytes
165  * device                  4 bytes/8 bytes (32-bit/64-bit)
166  */
167 token_t *
168 au_to_attr32(struct vnode_au_info *vni)
169 {
170 	token_t *t;
171 	u_char *dptr = NULL;
172 	u_int16_t pad0_16 = 0;
173 	u_int16_t pad0_32 = 0;
174 
175 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
176 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
177 	if (t == NULL)
178 		return (NULL);
179 
180 	ADD_U_CHAR(dptr, AUT_ATTR32);
181 
182 	/*
183 	 * Darwin defines the size for the file mode
184 	 * as 2 bytes; BSM defines 4 so pad with 0
185 	 */
186 	ADD_U_INT16(dptr, pad0_16);
187 	ADD_U_INT16(dptr, vni->vn_mode);
188 
189 	ADD_U_INT32(dptr, vni->vn_uid);
190 	ADD_U_INT32(dptr, vni->vn_gid);
191 	ADD_U_INT32(dptr, vni->vn_fsid);
192 
193 	/*
194 	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
195 	 * Attempt to handle both, and let the compiler sort it out.  If we
196 	 * could pick this out at compile-time, it would be better, so as to
197 	 * avoid the else case below.
198 	 */
199 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
200 		ADD_U_INT32(dptr, pad0_32);
201 		ADD_U_INT32(dptr, vni->vn_fileid);
202 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
203 		ADD_U_INT64(dptr, vni->vn_fileid);
204 	else
205 		ADD_U_INT64(dptr, 0LL);
206 
207 	ADD_U_INT32(dptr, vni->vn_dev);
208 
209 	return (t);
210 }
211 
212 token_t *
213 au_to_attr64(struct vnode_au_info *vni)
214 {
215 
216 	errno = ENOTSUP;
217 	return (NULL);
218 }
219 
220 token_t *
221 au_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  */
235 token_t *
236 au_to_data(char unit_print, char unit_type, char unit_count, 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 		errno = EINVAL;
264  		return (NULL);
265 	}
266 
267 	totdata = datasize * unit_count;
268 
269 	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
270 	if (t == NULL)
271 		return (NULL);
272 
273 	ADD_U_CHAR(dptr, AUT_DATA);
274 	ADD_U_CHAR(dptr, unit_print);
275 	ADD_U_CHAR(dptr, unit_type);
276 	ADD_U_CHAR(dptr, unit_count);
277 	ADD_MEM(dptr, p, totdata);
278 
279 	return (t);
280 }
281 
282 
283 /*
284  * token ID                1 byte
285  * status		   4 bytes
286  * return value            4 bytes
287  */
288 token_t *
289 au_to_exit(int retval, int err)
290 {
291 	token_t *t;
292 	u_char *dptr = NULL;
293 
294 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
295 	if (t == NULL)
296 		return (NULL);
297 
298 	ADD_U_CHAR(dptr, AUT_EXIT);
299 	ADD_U_INT32(dptr, err);
300 	ADD_U_INT32(dptr, retval);
301 
302 	return (t);
303 }
304 
305 /*
306  */
307 token_t *
308 au_to_groups(int *groups)
309 {
310 
311 	return (au_to_newgroups(AUDIT_MAX_GROUPS, groups));
312 }
313 
314 /*
315  * token ID                1 byte
316  * number groups           2 bytes
317  * group list              count * 4 bytes
318  */
319 token_t *
320 au_to_newgroups(u_int16_t n, gid_t *groups)
321 {
322 	token_t *t;
323 	u_char *dptr = NULL;
324 	int i;
325 
326 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
327 	    n * sizeof(u_int32_t));
328 	if (t == NULL)
329 		return (NULL);
330 
331 	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
332 	ADD_U_INT16(dptr, n);
333 	for (i = 0; i < n; i++)
334 		ADD_U_INT32(dptr, groups[i]);
335 
336 	return (t);
337 }
338 
339 /*
340  * token ID                1 byte
341  * internet address        4 bytes
342  */
343 token_t *
344 au_to_in_addr(struct in_addr *internet_addr)
345 {
346 	token_t *t;
347 	u_char *dptr = NULL;
348 
349 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
350 	if (t == NULL)
351 		return (NULL);
352 
353 	ADD_U_CHAR(dptr, AUT_IN_ADDR);
354 	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
355 
356 	return (t);
357 }
358 
359 /*
360  * token ID                1 byte
361  * address type/length     4 bytes
362  * Address                16 bytes
363  */
364 token_t *
365 au_to_in_addr_ex(struct in6_addr *internet_addr)
366 {
367 	token_t *t;
368 	u_char *dptr = NULL;
369 	u_int32_t type = AF_INET6;
370 
371 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
372 	if (t == NULL)
373 		return (NULL);
374 
375 	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
376 	ADD_U_INT32(dptr, type);
377 	ADD_MEM(dptr, internet_addr, 5 * sizeof(uint32_t));
378 
379 	return (t);
380 }
381 
382 /*
383  * token ID                1 byte
384  * ip header		   20 bytes
385  */
386 token_t *
387 au_to_ip(struct ip *ip)
388 {
389 	token_t *t;
390 	u_char *dptr = NULL;
391 
392 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
393 	if (t == NULL)
394 		return (NULL);
395 
396 	ADD_U_CHAR(dptr, AUT_IP);
397 	/*
398 	 * XXXRW: Any byte order work needed on the IP header before writing?
399 	 */
400 	ADD_MEM(dptr, ip, sizeof(struct ip));
401 
402 	return (t);
403 }
404 
405 /*
406  * token ID                1 byte
407  * object ID type          1 byte
408  * object ID               4 bytes
409  */
410 token_t *
411 au_to_ipc(char type, int id)
412 {
413 	token_t *t;
414 	u_char *dptr = NULL;
415 
416 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
417 	if (t == NULL)
418 		return (NULL);
419 
420 	ADD_U_CHAR(dptr, AUT_IPC);
421 	ADD_U_CHAR(dptr, type);
422 	ADD_U_INT32(dptr, id);
423 
424 	return (t);
425 }
426 
427 /*
428  * token ID                1 byte
429  * owner user ID           4 bytes
430  * owner group ID          4 bytes
431  * creator user ID         4 bytes
432  * creator group ID        4 bytes
433  * access mode             4 bytes
434  * slot sequence #         4 bytes
435  * key                     4 bytes
436  */
437 token_t *
438 au_to_ipc_perm(struct ipc_perm *perm)
439 {
440 	token_t *t;
441 	u_char *dptr = NULL;
442 	u_int16_t pad0 = 0;
443 
444 	GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
445 	if (t == NULL)
446 		return (NULL);
447 
448 	ADD_U_CHAR(dptr, AUT_IPC_PERM);
449 
450 	/*
451 	 * Darwin defines the sizes for ipc_perm members
452 	 * as 2 bytes; BSM defines 4 so pad with 0
453 	 */
454 	ADD_U_INT16(dptr, pad0);
455 	ADD_U_INT16(dptr, perm->uid);
456 
457 	ADD_U_INT16(dptr, pad0);
458 	ADD_U_INT16(dptr, perm->gid);
459 
460 	ADD_U_INT16(dptr, pad0);
461 	ADD_U_INT16(dptr, perm->cuid);
462 
463 	ADD_U_INT16(dptr, pad0);
464 	ADD_U_INT16(dptr, perm->cgid);
465 
466 	ADD_U_INT16(dptr, pad0);
467 	ADD_U_INT16(dptr, perm->mode);
468 
469 	ADD_U_INT16(dptr, pad0);
470 
471 #ifdef HAVE_IPC_PERM___SEQ
472 	ADD_U_INT16(dptr, perm->__seq);
473 #else
474 	ADD_U_INT16(dptr, perm->seq);
475 #endif
476 
477 #ifdef HAVE_IPC_PERM___KEY
478 	ADD_U_INT32(dptr, perm->__key);
479 #else
480 	ADD_U_INT32(dptr, perm->key);
481 #endif
482 
483 	return (t);
484 }
485 
486 /*
487  * token ID                1 byte
488  * port IP address         2 bytes
489  */
490 token_t *
491 au_to_iport(u_int16_t iport)
492 {
493 	token_t *t;
494 	u_char *dptr = NULL;
495 
496 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
497 	if (t == NULL)
498 		return (NULL);
499 
500 	ADD_U_CHAR(dptr, AUT_IPORT);
501 	ADD_U_INT16(dptr, iport);
502 
503 	return (t);
504 }
505 
506 /*
507  * token ID                1 byte
508  * size                    2 bytes
509  * data                    size bytes
510  */
511 token_t *
512 au_to_opaque(char *data, u_int16_t bytes)
513 {
514 	token_t *t;
515 	u_char *dptr = NULL;
516 
517 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
518 	if (t == NULL)
519 		return (NULL);
520 
521 	ADD_U_CHAR(dptr, AUT_OPAQUE);
522 	ADD_U_INT16(dptr, bytes);
523 	ADD_MEM(dptr, data, bytes);
524 
525 	return (t);
526 }
527 
528 /*
529  * token ID                1 byte
530  * seconds of time         4 bytes
531  * milliseconds of time    4 bytes
532  * file name len           2 bytes
533  * file pathname           N bytes + 1 terminating NULL byte
534  */
535 token_t *
536 au_to_file(char *file, struct timeval tm)
537 {
538 	token_t *t;
539 	u_char *dptr = NULL;
540 	u_int16_t filelen;
541 	u_int32_t timems;
542 
543 	filelen = strlen(file);
544 	filelen += 1;
545 
546 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
547 	    sizeof(u_int16_t) + filelen);
548 	if (t == NULL)
549 		return (NULL);
550 
551 	timems = tm.tv_usec/1000;
552 
553 	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
554 	ADD_U_INT32(dptr, tm.tv_sec);
555 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
556 	ADD_U_INT16(dptr, filelen);
557 	ADD_STRING(dptr, file, filelen);
558 
559 	return (t);
560 }
561 
562 /*
563  * token ID                1 byte
564  * text length             2 bytes
565  * text                    N bytes + 1 terminating NULL byte
566  */
567 token_t *
568 au_to_text(char *text)
569 {
570 	token_t *t;
571 	u_char *dptr = NULL;
572 	u_int16_t textlen;
573 
574 	textlen = strlen(text);
575 	textlen += 1;
576 
577 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
578 	if (t == NULL)
579 		return (NULL);
580 
581 	ADD_U_CHAR(dptr, AUT_TEXT);
582 	ADD_U_INT16(dptr, textlen);
583 	ADD_STRING(dptr, text, textlen);
584 
585 	return (t);
586 }
587 
588 /*
589  * token ID                1 byte
590  * path length             2 bytes
591  * path                    N bytes + 1 terminating NULL byte
592  */
593 token_t *
594 au_to_path(char *text)
595 {
596 	token_t *t;
597 	u_char *dptr = NULL;
598 	u_int16_t textlen;
599 
600 	textlen = strlen(text);
601 	textlen += 1;
602 
603 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
604 	if (t == NULL)
605 		return (NULL);
606 
607 	ADD_U_CHAR(dptr, AUT_PATH);
608 	ADD_U_INT16(dptr, textlen);
609 	ADD_STRING(dptr, text, textlen);
610 
611 	return (t);
612 }
613 
614 /*
615  * token ID                1 byte
616  * audit ID                4 bytes
617  * effective user ID       4 bytes
618  * effective group ID      4 bytes
619  * real user ID            4 bytes
620  * real group ID           4 bytes
621  * process ID              4 bytes
622  * session ID              4 bytes
623  * terminal ID
624  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
625  *   machine address       4 bytes
626  */
627 token_t *
628 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
629     pid_t pid, au_asid_t sid, au_tid_t *tid)
630 {
631 	token_t *t;
632 	u_char *dptr = NULL;
633 
634 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
635 	if (t == NULL)
636 		return (NULL);
637 
638 	ADD_U_CHAR(dptr, AUT_PROCESS32);
639 	ADD_U_INT32(dptr, auid);
640 	ADD_U_INT32(dptr, euid);
641 	ADD_U_INT32(dptr, egid);
642 	ADD_U_INT32(dptr, ruid);
643 	ADD_U_INT32(dptr, rgid);
644 	ADD_U_INT32(dptr, pid);
645 	ADD_U_INT32(dptr, sid);
646 	ADD_U_INT32(dptr, tid->port);
647 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
648 
649 	return (t);
650 }
651 
652 token_t *
653 au_to_process64(__unused au_id_t auid, __unused uid_t euid,
654     __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
655     __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
656 {
657 
658 	errno = ENOTSUP;
659 	return (NULL);
660 }
661 
662 token_t *
663 au_to_process(__unused au_id_t auid, __unused uid_t euid,
664     __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid,
665     __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid)
666 {
667 
668 	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
669 	    tid));
670 }
671 
672 /*
673  * token ID                1 byte
674  * audit ID                4 bytes
675  * effective user ID       4 bytes
676  * effective group ID      4 bytes
677  * real user ID            4 bytes
678  * real group ID           4 bytes
679  * process ID              4 bytes
680  * session ID              4 bytes
681  * terminal ID
682  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
683  *   address type-len      4 bytes
684  *   machine address      16 bytes
685  */
686 token_t *
687 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
688     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
689 {
690 	token_t *t;
691 	u_char *dptr = NULL;
692 
693 	if (tid->at_type == AU_IPv4)
694 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
695 		    10 * sizeof(u_int32_t));
696 	else if (tid->at_type == AU_IPv6)
697 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
698 		    13 * sizeof(u_int32_t));
699 	else {
700 		errno = EINVAL;
701 		return (NULL);
702 	}
703 	if (t == NULL)
704 		return (NULL);
705 
706 	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
707 	ADD_U_INT32(dptr, auid);
708 	ADD_U_INT32(dptr, euid);
709 	ADD_U_INT32(dptr, egid);
710 	ADD_U_INT32(dptr, ruid);
711 	ADD_U_INT32(dptr, rgid);
712 	ADD_U_INT32(dptr, pid);
713 	ADD_U_INT32(dptr, sid);
714 	ADD_U_INT32(dptr, tid->at_port);
715 	ADD_U_INT32(dptr, tid->at_type);
716 	ADD_U_INT32(dptr, tid->at_addr[0]);
717 	if (tid->at_type == AU_IPv6) {
718 		ADD_U_INT32(dptr, tid->at_addr[1]);
719 		ADD_U_INT32(dptr, tid->at_addr[2]);
720 		ADD_U_INT32(dptr, tid->at_addr[3]);
721 	}
722 
723 	return (t);
724 }
725 
726 token_t *
727 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
728     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
729 {
730 
731 	errno = ENOTSUP;
732 	return (NULL);
733 }
734 
735 token_t *
736 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
737     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
738 {
739 
740 	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
741 	    tid));
742 }
743 
744 /*
745  * token ID                1 byte
746  * error status            1 byte
747  * return value            4 bytes/8 bytes (32-bit/64-bit value)
748  */
749 token_t *
750 au_to_return32(char status, u_int32_t ret)
751 {
752 	token_t *t;
753 	u_char *dptr = NULL;
754 
755 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
756 	if (t == NULL)
757 		return (NULL);
758 
759 	ADD_U_CHAR(dptr, AUT_RETURN32);
760 	ADD_U_CHAR(dptr, status);
761 	ADD_U_INT32(dptr, ret);
762 
763 	return (t);
764 }
765 
766 token_t *
767 au_to_return64(char status, u_int64_t ret)
768 {
769 	token_t *t;
770 	u_char *dptr = NULL;
771 
772 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
773 	if (t == NULL)
774 		return (NULL);
775 
776 	ADD_U_CHAR(dptr, AUT_RETURN64);
777 	ADD_U_CHAR(dptr, status);
778 	ADD_U_INT64(dptr, ret);
779 
780 	return (t);
781 }
782 
783 token_t *
784 au_to_return(char status, u_int32_t ret)
785 {
786 
787 	return (au_to_return32(status, ret));
788 }
789 
790 /*
791  * token ID                1 byte
792  * sequence number         4 bytes
793  */
794 token_t *
795 au_to_seq(long audit_count)
796 {
797 	token_t *t;
798 	u_char *dptr = NULL;
799 
800 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
801 	if (t == NULL)
802 		return (NULL);
803 
804 	ADD_U_CHAR(dptr, AUT_SEQ);
805 	ADD_U_INT32(dptr, audit_count);
806 
807 	return (t);
808 }
809 
810 /*
811  * token ID                1 byte
812  * socket family           2 bytes
813  * path                    104 bytes
814  */
815 token_t *
816 au_to_sock_unix(struct sockaddr_un *so)
817 {
818 	token_t *t;
819 	u_char *dptr;
820 
821 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
822 	if (t == NULL)
823 		return (NULL);
824 
825 	ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
826 	/* BSM token has two bytes for family */
827 	ADD_U_CHAR(dptr, 0);
828 	ADD_U_CHAR(dptr, so->sun_family);
829 	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
830 
831 	return (t);
832 }
833 
834 /*
835  * token ID                1 byte
836  * socket family           2 bytes
837  * local port              2 bytes
838  * socket address          4 bytes
839  */
840 token_t *
841 au_to_sock_inet32(struct sockaddr_in *so)
842 {
843 	token_t *t;
844 	u_char *dptr = NULL;
845 	uint16_t family;
846 
847 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
848 	    sizeof(uint32_t));
849 	if (t == NULL)
850 		return (NULL);
851 
852 	ADD_U_CHAR(dptr, AUT_SOCKINET32);
853 	/*
854 	 * BSM defines the family field as 16 bits, but many operating
855 	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
856 	 * writing into the token.  Assume that both the port and the address
857 	 * in the sockaddr_in are already in network byte order, but family
858 	 * is in local byte order.
859 	 *
860 	 * XXXRW: Should a name space conversion be taking place on the value
861 	 * of sin_family?
862  	 */
863 	family = so->sin_family;
864 	ADD_U_INT16(dptr, family);
865 	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
866 	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
867 
868 	return (t);
869 
870 }
871 
872 token_t *
873 au_to_sock_inet128(struct sockaddr_in6 *so)
874 {
875 	token_t *t;
876 	u_char *dptr = NULL;
877 
878 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
879 	    4 * sizeof(u_int32_t));
880 	if (t == NULL)
881 		return (NULL);
882 
883 	ADD_U_CHAR(dptr, AUT_SOCKINET128);
884 	/*
885 	 * In Darwin, sin6_family is one octet, but BSM defines the token
886  	 * to store two. So we copy in a 0 first.
887  	 */
888 	ADD_U_CHAR(dptr, 0);
889 	ADD_U_CHAR(dptr, so->sin6_family);
890 
891 	ADD_U_INT16(dptr, so->sin6_port);
892 	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
893 
894 	return (t);
895 
896 }
897 
898 token_t *
899 au_to_sock_inet(struct sockaddr_in *so)
900 {
901 
902 	return (au_to_sock_inet32(so));
903 }
904 
905 /*
906  * token ID                1 byte
907  * audit ID                4 bytes
908  * effective user ID       4 bytes
909  * effective group ID      4 bytes
910  * real user ID            4 bytes
911  * real group ID           4 bytes
912  * process ID              4 bytes
913  * session ID              4 bytes
914  * terminal ID
915  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
916  *   machine address       4 bytes
917  */
918 token_t *
919 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
920     pid_t pid, au_asid_t sid, au_tid_t *tid)
921 {
922 	token_t *t;
923 	u_char *dptr = NULL;
924 
925 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
926 	if (t == NULL)
927 		return (NULL);
928 
929 	ADD_U_CHAR(dptr, AUT_SUBJECT32);
930 	ADD_U_INT32(dptr, auid);
931 	ADD_U_INT32(dptr, euid);
932 	ADD_U_INT32(dptr, egid);
933 	ADD_U_INT32(dptr, ruid);
934 	ADD_U_INT32(dptr, rgid);
935 	ADD_U_INT32(dptr, pid);
936 	ADD_U_INT32(dptr, sid);
937 	ADD_U_INT32(dptr, tid->port);
938 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
939 
940 	return (t);
941 }
942 
943 token_t *
944 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
945     pid_t pid, au_asid_t sid, au_tid_t *tid)
946 {
947 
948 	errno = ENOTSUP;
949 	return (NULL);
950 }
951 
952 token_t *
953 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
954     pid_t pid, au_asid_t sid, au_tid_t *tid)
955 {
956 
957 	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
958 	    tid));
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  *   address type/length   4 bytes
973  *   machine address      16 bytes
974  */
975 token_t *
976 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
977     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
978 {
979 	token_t *t;
980 	u_char *dptr = NULL;
981 
982 	if (tid->at_type == AU_IPv4)
983 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
984 		    sizeof(u_int32_t));
985 	else if (tid->at_type == AU_IPv6)
986 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
987 		    sizeof(u_int32_t));
988 	else {
989 		errno = EINVAL;
990 		return (NULL);
991 	}
992 	if (t == NULL)
993 		return (NULL);
994 
995 	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
996 	ADD_U_INT32(dptr, auid);
997 	ADD_U_INT32(dptr, euid);
998 	ADD_U_INT32(dptr, egid);
999 	ADD_U_INT32(dptr, ruid);
1000 	ADD_U_INT32(dptr, rgid);
1001 	ADD_U_INT32(dptr, pid);
1002 	ADD_U_INT32(dptr, sid);
1003 	ADD_U_INT32(dptr, tid->at_port);
1004 	ADD_U_INT32(dptr, tid->at_type);
1005 	ADD_U_INT32(dptr, tid->at_addr[0]);
1006 	if (tid->at_type == AU_IPv6) {
1007 		ADD_U_INT32(dptr, tid->at_addr[1]);
1008 		ADD_U_INT32(dptr, tid->at_addr[2]);
1009 		ADD_U_INT32(dptr, tid->at_addr[3]);
1010 	}
1011 
1012 	return (t);
1013 }
1014 
1015 token_t *
1016 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1017     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1018 {
1019 
1020 	errno = ENOTSUP;
1021 	return (NULL);
1022 }
1023 
1024 token_t *
1025 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1026     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1027 {
1028 
1029 	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1030 	    tid));
1031 }
1032 
1033 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1034 /*
1035  * Collects audit information for the current process
1036  * and creates a subject token from it
1037  */
1038 token_t *
1039 au_to_me(void)
1040 {
1041 	auditinfo_t auinfo;
1042 
1043 	if (getaudit(&auinfo) != 0)
1044 		return (NULL);
1045 
1046 	return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1047 	    getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1048 }
1049 #endif
1050 
1051 /*
1052  * token ID				1 byte
1053  * count				4 bytes
1054  * text					count null-terminated strings
1055  */
1056 token_t *
1057 au_to_exec_args(char **argv)
1058 {
1059 	token_t *t;
1060 	u_char *dptr = NULL;
1061 	const char *nextarg;
1062 	int i, count = 0;
1063 	size_t totlen = 0;
1064 
1065 	nextarg = *argv;
1066 
1067 	while (nextarg != NULL) {
1068 		int nextlen;
1069 
1070 		nextlen = strlen(nextarg);
1071 		totlen += nextlen + 1;
1072 		count++;
1073 		nextarg = *(argv + count);
1074 	}
1075 
1076 	totlen += count * sizeof(char);	/* nul terminations. */
1077 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1078 	if (t == NULL)
1079 		return (NULL);
1080 
1081 	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1082 	ADD_U_INT32(dptr, count);
1083 
1084 	for (i = 0; i < count; i++) {
1085 		nextarg = *(argv + i);
1086 		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1087 	}
1088 
1089 	return (t);
1090 }
1091 
1092 /*
1093  * token ID				1 byte
1094  * count				4 bytes
1095  * text					count null-terminated strings
1096  */
1097 token_t *
1098 au_to_exec_env(char **envp)
1099 {
1100 	token_t *t;
1101 	u_char *dptr = NULL;
1102 	int i, count = 0;
1103 	size_t totlen = 0;
1104 	const char *nextenv;
1105 
1106 	nextenv = *envp;
1107 
1108 	while (nextenv != NULL) {
1109 		int nextlen;
1110 
1111 		nextlen = strlen(nextenv);
1112 		totlen += nextlen + 1;
1113 		count++;
1114 		nextenv = *(envp + count);
1115 	}
1116 
1117 	totlen += sizeof(char) * count;
1118 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1119 	if (t == NULL)
1120 		return (NULL);
1121 
1122 	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1123 	ADD_U_INT32(dptr, count);
1124 
1125 	for (i = 0; i < count; i++) {
1126 		nextenv = *(envp + i);
1127 		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1128 	}
1129 
1130 	return (t);
1131 }
1132 
1133 /*
1134  * token ID                1 byte
1135  * record byte count       4 bytes
1136  * version #               1 byte    [2]
1137  * event type              2 bytes
1138  * event modifier          2 bytes
1139  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1140  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1141  */
1142 token_t *
1143 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1144     struct timeval tm)
1145 {
1146 	token_t *t;
1147 	u_char *dptr = NULL;
1148 	u_int32_t timems;
1149 
1150 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1151 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1152 	if (t == NULL)
1153 		return (NULL);
1154 
1155 	ADD_U_CHAR(dptr, AUT_HEADER32);
1156 	ADD_U_INT32(dptr, rec_size);
1157 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1158 	ADD_U_INT16(dptr, e_type);
1159 	ADD_U_INT16(dptr, e_mod);
1160 
1161 	timems = tm.tv_usec/1000;
1162 	/* Add the timestamp */
1163 	ADD_U_INT32(dptr, tm.tv_sec);
1164 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1165 
1166 	return (t);
1167 }
1168 
1169 #if !defined(KERNEL) && !defined(_KERNEL)
1170 token_t *
1171 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1172 {
1173 	struct timeval tm;
1174 
1175 	if (gettimeofday(&tm, NULL) == -1)
1176 		return (NULL);
1177 	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1178 }
1179 
1180 token_t *
1181 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1182     __unused au_emod_t e_mod)
1183 {
1184 
1185 	errno = ENOTSUP;
1186 	return (NULL);
1187 }
1188 
1189 token_t *
1190 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1191 {
1192 
1193 	return (au_to_header32(rec_size, e_type, e_mod));
1194 }
1195 #endif
1196 
1197 /*
1198  * token ID                1 byte
1199  * trailer magic number    2 bytes
1200  * record byte count       4 bytes
1201  */
1202 token_t *
1203 au_to_trailer(int rec_size)
1204 {
1205 	token_t *t;
1206 	u_char *dptr = NULL;
1207 	u_int16_t magic = TRAILER_PAD_MAGIC;
1208 
1209 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1210 	    sizeof(u_int32_t));
1211 	if (t == NULL)
1212 		return (NULL);
1213 
1214 	ADD_U_CHAR(dptr, AUT_TRAILER);
1215 	ADD_U_INT16(dptr, magic);
1216 	ADD_U_INT32(dptr, rec_size);
1217 
1218 	return (t);
1219 }
1220