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