xref: /freebsd/contrib/openbsm/libbsm/bsm_token.c (revision e0c4386e)
1 /*-
2  * Copyright (c) 2004-2009 Apple Inc.
3  * Copyright (c) 2005 SPARTA, Inc.
4  * All rights reserved.
5  *
6  * This code was developed in part by Robert N. M. Watson, Senior Principal
7  * Scientist, SPARTA, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1.  Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  * 2.  Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
18  *     its contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR
25  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/types.h>
35 
36 #include <config/config.h>
37 
38 #ifdef USE_ENDIAN_H
39 #include <endian.h>
40 #endif
41 #ifdef USE_SYS_ENDIAN_H
42 #include <sys/endian.h>
43 #endif
44 #ifdef USE_MACHINE_ENDIAN_H
45 #include <machine/endian.h>
46 #endif
47 #ifdef USE_COMPAT_ENDIAN_H
48 #include <compat/endian.h>
49 #endif
50 #ifdef USE_COMPAT_ENDIAN_ENC_H
51 #include <compat/endian_enc.h>
52 #endif
53 
54 #ifdef HAVE_FULL_QUEUE_H
55 #include <sys/queue.h>
56 #else /* !HAVE_FULL_QUEUE_H */
57 #include <compat/queue.h>
58 #endif /* !HAVE_FULL_QUEUE_H */
59 
60 #include <sys/socket.h>
61 #include <sys/time.h>
62 #include <sys/un.h>
63 
64 #include <sys/ipc.h>
65 
66 #include <netinet/in.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/ip.h>
69 
70 #include <assert.h>
71 #include <errno.h>
72 #include <string.h>
73 #include <stdlib.h>
74 #include <unistd.h>
75 
76 #include <bsm/audit_internal.h>
77 #include <bsm/libbsm.h>
78 
79 #define	GET_TOKEN_AREA(t, dptr, length) do {				\
80 	(t) = malloc(sizeof(token_t));					\
81 	if ((t) != NULL) {						\
82 		(t)->len = (length);					\
83 		(dptr) = (t->t_data) = calloc((length), sizeof(u_char)); \
84 		if ((dptr) == NULL) {					\
85 			free(t);					\
86 			(t) = NULL;					\
87 		}							\
88 	} else								\
89 		(dptr) = NULL;						\
90 	assert((t) == NULL || (dptr) != NULL);				\
91 } while (0)
92 
93 /*
94  * token ID                1 byte
95  * success/failure         1 byte
96  * privstrlen              2 bytes
97  * privstr                 N bytes + 1 (\0 byte)
98  */
99 token_t *
100 au_to_upriv(char sorf, char *priv)
101 {
102 	u_int16_t textlen;
103 	u_char *dptr;
104 	token_t *t;
105 
106 	textlen = strlen(priv) + 1;
107 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
108 	    sizeof(u_int16_t) + textlen);
109 	if (t == NULL)
110 		return (NULL);
111 	ADD_U_CHAR(dptr, AUT_UPRIV);
112 	ADD_U_CHAR(dptr, sorf);
113 	ADD_U_INT16(dptr, textlen);
114 	ADD_STRING(dptr, priv, textlen);
115 	return (t);
116 }
117 
118 /*
119  * token ID		1 byte
120  * privtstrlen		2 bytes
121  * privtstr		N bytes + 1
122  * privstrlen		2 bytes
123  * privstr		N bytes + 1
124  */
125 token_t *
126 au_to_privset(char *privtypestr, char *privstr)
127 {
128 	u_int16_t	 type_len, priv_len;
129 	u_char		*dptr;
130 	token_t		*t;
131 
132 	type_len = strlen(privtypestr) + 1;
133 	priv_len = strlen(privstr) + 1;
134 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
135 	    sizeof(u_int16_t) + type_len + priv_len);
136 	if (t == NULL)
137 		return (NULL);
138 	ADD_U_CHAR(dptr, AUT_PRIV);
139 	ADD_U_INT16(dptr, type_len);
140 	ADD_STRING(dptr, privtypestr, type_len);
141 	ADD_U_INT16(dptr, priv_len);
142 	ADD_STRING(dptr, privstr, priv_len);
143 	return (t);
144 }
145 
146 /*
147  * token ID                1 byte
148  * argument #              1 byte
149  * argument value          4 bytes/8 bytes (32-bit/64-bit value)
150  * text length             2 bytes
151  * text                    N bytes + 1 terminating NULL byte
152  */
153 token_t *
154 au_to_arg32(char n, const char *text, u_int32_t v)
155 {
156 	token_t *t;
157 	u_char *dptr = NULL;
158 	u_int16_t textlen;
159 
160 	textlen = strlen(text);
161 	textlen += 1;
162 
163 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
164 	    sizeof(u_int16_t) + textlen);
165 	if (t == NULL)
166 		return (NULL);
167 
168 	ADD_U_CHAR(dptr, AUT_ARG32);
169 	ADD_U_CHAR(dptr, n);
170 	ADD_U_INT32(dptr, v);
171 	ADD_U_INT16(dptr, textlen);
172 	ADD_STRING(dptr, text, textlen);
173 
174 	return (t);
175 }
176 
177 token_t *
178 au_to_arg64(char n, const char *text, u_int64_t v)
179 {
180 	token_t *t;
181 	u_char *dptr = NULL;
182 	u_int16_t textlen;
183 
184 	textlen = strlen(text);
185 	textlen += 1;
186 
187 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
188 	    sizeof(u_int16_t) + textlen);
189 	if (t == NULL)
190 		return (NULL);
191 
192 	ADD_U_CHAR(dptr, AUT_ARG64);
193 	ADD_U_CHAR(dptr, n);
194 	ADD_U_INT64(dptr, v);
195 	ADD_U_INT16(dptr, textlen);
196 	ADD_STRING(dptr, text, textlen);
197 
198 	return (t);
199 }
200 
201 token_t *
202 au_to_arg(char n, const char *text, u_int32_t v)
203 {
204 
205 	return (au_to_arg32(n, text, v));
206 }
207 
208 #if defined(_KERNEL) || defined(KERNEL)
209 /*
210  * token ID                1 byte
211  * file access mode        4 bytes
212  * owner user ID           4 bytes
213  * owner group ID          4 bytes
214  * file system ID          4 bytes
215  * node ID                 8 bytes
216  * device                  4 bytes/8 bytes (32-bit/64-bit)
217  */
218 token_t *
219 au_to_attr32(struct vnode_au_info *vni)
220 {
221 	token_t *t;
222 	u_char *dptr = NULL;
223 	u_int16_t pad0_16 = 0;
224 	u_int32_t pad0_32 = 0;
225 
226 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
227 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
228 	if (t == NULL)
229 		return (NULL);
230 
231 	ADD_U_CHAR(dptr, AUT_ATTR32);
232 
233 	/*
234 	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
235 	 * so pad with 0.
236 	 *
237 	 * XXXRW: Possibly should be conditionally compiled.
238 	 *
239 	 * XXXRW: Should any conversions take place on the mode?
240 	 */
241 	ADD_U_INT16(dptr, pad0_16);
242 	ADD_U_INT16(dptr, vni->vn_mode);
243 
244 	ADD_U_INT32(dptr, vni->vn_uid);
245 	ADD_U_INT32(dptr, vni->vn_gid);
246 	ADD_U_INT32(dptr, vni->vn_fsid);
247 
248 	/*
249 	 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
250 	 * Attempt to handle both, and let the compiler sort it out.  If we
251 	 * could pick this out at compile-time, it would be better, so as to
252 	 * avoid the else case below.
253 	 */
254 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
255 		ADD_U_INT32(dptr, pad0_32);
256 		ADD_U_INT32(dptr, vni->vn_fileid);
257 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
258 		ADD_U_INT64(dptr, vni->vn_fileid);
259 	else
260 		ADD_U_INT64(dptr, 0LL);
261 
262 	ADD_U_INT32(dptr, vni->vn_dev);
263 
264 	return (t);
265 }
266 
267 token_t *
268 au_to_attr64(struct vnode_au_info *vni)
269 {
270 	token_t *t;
271 	u_char *dptr = NULL;
272 	u_int16_t pad0_16 = 0;
273 	u_int32_t pad0_32 = 0;
274 
275 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
276 	    3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
277 	if (t == NULL)
278 		return (NULL);
279 
280 	ADD_U_CHAR(dptr, AUT_ATTR64);
281 
282 	/*
283 	 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
284 	 * so pad with 0.
285 	 *
286 	 * XXXRW: Possibly should be conditionally compiled.
287 	 *
288 	 * XXXRW: Should any conversions take place on the mode?
289 	 */
290 	ADD_U_INT16(dptr, pad0_16);
291 	ADD_U_INT16(dptr, vni->vn_mode);
292 
293 	ADD_U_INT32(dptr, vni->vn_uid);
294 	ADD_U_INT32(dptr, vni->vn_gid);
295 	ADD_U_INT32(dptr, vni->vn_fsid);
296 
297 	/*
298 	 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
299 	 * Attempt to handle both, and let the compiler sort it out.  If we
300 	 * could pick this out at compile-time, it would be better, so as to
301 	 * avoid the else case below.
302 	 */
303 	if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
304 		ADD_U_INT32(dptr, pad0_32);
305 		ADD_U_INT32(dptr, vni->vn_fileid);
306 	} else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
307 		ADD_U_INT64(dptr, vni->vn_fileid);
308 	else
309 		ADD_U_INT64(dptr, 0LL);
310 
311 	ADD_U_INT64(dptr, vni->vn_dev);
312 
313 	return (t);
314 }
315 
316 token_t *
317 au_to_attr(struct vnode_au_info *vni)
318 {
319 
320 	return (au_to_attr32(vni));
321 }
322 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
323 
324 /*
325  * token ID                1 byte
326  * how to print            1 byte
327  * basic unit              1 byte
328  * unit count              1 byte
329  * data items              (depends on basic unit)
330  */
331 token_t *
332 au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
333 {
334 	token_t *t;
335 	u_char *dptr = NULL;
336 	size_t datasize, totdata;
337 
338 	/* Determine the size of the basic unit. */
339 	switch (unit_type) {
340 	case AUR_BYTE:
341 	/* case AUR_CHAR: */
342 		datasize = AUR_BYTE_SIZE;
343 		break;
344 
345 	case AUR_SHORT:
346 		datasize = AUR_SHORT_SIZE;
347 		break;
348 
349 	case AUR_INT32:
350 	/* case AUR_INT: */
351 		datasize = AUR_INT32_SIZE;
352 		break;
353 
354 	case AUR_INT64:
355 		datasize = AUR_INT64_SIZE;
356 		break;
357 
358 	default:
359 		errno = EINVAL;
360 		return (NULL);
361 	}
362 
363 	totdata = datasize * unit_count;
364 
365 	GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
366 	if (t == NULL)
367 		return (NULL);
368 
369 	/*
370 	 * XXXRW: We should be byte-swapping each data item for multi-byte
371 	 * types.
372 	 */
373 	ADD_U_CHAR(dptr, AUT_DATA);
374 	ADD_U_CHAR(dptr, unit_print);
375 	ADD_U_CHAR(dptr, unit_type);
376 	ADD_U_CHAR(dptr, unit_count);
377 	ADD_MEM(dptr, p, totdata);
378 
379 	return (t);
380 }
381 
382 
383 /*
384  * token ID                1 byte
385  * status		   4 bytes
386  * return value            4 bytes
387  */
388 token_t *
389 au_to_exit(int retval, int err)
390 {
391 	token_t *t;
392 	u_char *dptr = NULL;
393 
394 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
395 	if (t == NULL)
396 		return (NULL);
397 
398 	ADD_U_CHAR(dptr, AUT_EXIT);
399 	ADD_U_INT32(dptr, err);
400 	ADD_U_INT32(dptr, retval);
401 
402 	return (t);
403 }
404 
405 /*
406  */
407 token_t *
408 au_to_groups(int *groups)
409 {
410 
411 	return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
412 }
413 
414 /*
415  * token ID                1 byte
416  * number groups           2 bytes
417  * group list              count * 4 bytes
418  */
419 token_t *
420 au_to_newgroups(u_int16_t n, gid_t *groups)
421 {
422 	token_t *t;
423 	u_char *dptr = NULL;
424 	int i;
425 
426 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
427 	    n * sizeof(u_int32_t));
428 	if (t == NULL)
429 		return (NULL);
430 
431 	ADD_U_CHAR(dptr, AUT_NEWGROUPS);
432 	ADD_U_INT16(dptr, n);
433 	for (i = 0; i < n; i++)
434 		ADD_U_INT32(dptr, groups[i]);
435 
436 	return (t);
437 }
438 
439 /*
440  * token ID                1 byte
441  * internet address        4 bytes
442  */
443 token_t *
444 au_to_in_addr(struct in_addr *internet_addr)
445 {
446 	token_t *t;
447 	u_char *dptr = NULL;
448 
449 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
450 	if (t == NULL)
451 		return (NULL);
452 
453 	ADD_U_CHAR(dptr, AUT_IN_ADDR);
454 	ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
455 
456 	return (t);
457 }
458 
459 /*
460  * token ID                1 byte
461  * address type/length     4 bytes
462  * address                16 bytes
463  */
464 token_t *
465 au_to_in_addr_ex(struct in6_addr *internet_addr)
466 {
467 	token_t *t;
468 	u_char *dptr = NULL;
469 	u_int32_t type = AU_IPv6;
470 
471 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
472 	if (t == NULL)
473 		return (NULL);
474 
475 	ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
476 	ADD_U_INT32(dptr, type);
477 	ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
478 
479 	return (t);
480 }
481 
482 /*
483  * token ID                1 byte
484  * ip header		   20 bytes
485  *
486  * The IP header should be submitted in network byte order.
487  */
488 token_t *
489 au_to_ip(struct ip *ip)
490 {
491 	token_t *t;
492 	u_char *dptr = NULL;
493 
494 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
495 	if (t == NULL)
496 		return (NULL);
497 
498 	ADD_U_CHAR(dptr, AUT_IP);
499 	ADD_MEM(dptr, ip, sizeof(struct ip));
500 
501 	return (t);
502 }
503 
504 /*
505  * token ID                1 byte
506  * object ID type          1 byte
507  * object ID               4 bytes
508  */
509 token_t *
510 au_to_ipc(char type, int id)
511 {
512 	token_t *t;
513 	u_char *dptr = NULL;
514 
515 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
516 	if (t == NULL)
517 		return (NULL);
518 
519 	ADD_U_CHAR(dptr, AUT_IPC);
520 	ADD_U_CHAR(dptr, type);
521 	ADD_U_INT32(dptr, id);
522 
523 	return (t);
524 }
525 
526 /*
527  * token ID                1 byte
528  * owner user ID           4 bytes
529  * owner group ID          4 bytes
530  * creator user ID         4 bytes
531  * creator group ID        4 bytes
532  * access mode             4 bytes
533  * slot sequence #         4 bytes
534  * key                     4 bytes
535  */
536 token_t *
537 au_to_ipc_perm(struct ipc_perm *perm)
538 {
539 	token_t *t;
540 	u_char *dptr = NULL;
541 	u_int16_t pad0 = 0;
542 
543 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
544 	    sizeof(u_int32_t));
545 	if (t == NULL)
546 		return (NULL);
547 
548 	ADD_U_CHAR(dptr, AUT_IPC_PERM);
549 
550 	/*
551 	 * Systems vary significantly in what types they use in struct
552 	 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
553 	 * allow for that, as BSM define 32-bit values here.
554 	 * Some systems define the sizes for ipc_perm members as 2 bytes;
555 	 * BSM defines 4 so pad with 0.
556 	 *
557 	 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
558 	 * need to be handled.
559 	 */
560 	if (sizeof(perm->uid) != sizeof(u_int32_t)) {
561 		ADD_U_INT16(dptr, pad0);
562 		ADD_U_INT16(dptr, perm->uid);
563 		ADD_U_INT16(dptr, pad0);
564 		ADD_U_INT16(dptr, perm->gid);
565 		ADD_U_INT16(dptr, pad0);
566 		ADD_U_INT16(dptr, perm->cuid);
567 		ADD_U_INT16(dptr, pad0);
568 		ADD_U_INT16(dptr, perm->cgid);
569 	} else {
570 		ADD_U_INT32(dptr, perm->uid);
571 		ADD_U_INT32(dptr, perm->gid);
572 		ADD_U_INT32(dptr, perm->cuid);
573 		ADD_U_INT32(dptr, perm->cgid);
574 	}
575 
576 	ADD_U_INT16(dptr, pad0);
577 	ADD_U_INT16(dptr, perm->mode);
578 
579 	ADD_U_INT16(dptr, pad0);
580 
581 #ifdef HAVE_IPC_PERM___SEQ
582 	ADD_U_INT16(dptr, perm->__seq);
583 #else	/* HAVE_IPC_PERM___SEQ */
584 #ifdef  HAVE_IPC_PERM__SEQ
585 	ADD_U_INT16(dptr, perm->_seq);
586 #else	/* HAVE_IPC_PERM__SEQ */
587 	ADD_U_INT16(dptr, perm->seq);
588 #endif	/* HAVE_IPC_PERM__SEQ */
589 #endif	/* HAVE_IPC_PERM___SEQ */
590 
591 #ifdef HAVE_IPC_PERM___KEY
592 	ADD_U_INT32(dptr, perm->__key);
593 #else	/* HAVE_IPC_PERM___KEY */
594 #ifdef  HAVE_IPC_PERM__KEY
595 	ADD_U_INT32(dptr, perm->_key);
596 #else	/* HAVE_IPC_PERM__KEY */
597 	ADD_U_INT32(dptr, perm->key);
598 #endif	/* HAVE_IPC_PERM__KEY */
599 #endif	/* HAVE_IPC_PERM___KEY */
600 
601 	return (t);
602 }
603 
604 /*
605  * token ID                1 byte
606  * port IP address         2 bytes
607  */
608 token_t *
609 au_to_iport(u_int16_t iport)
610 {
611 	token_t *t;
612 	u_char *dptr = NULL;
613 
614 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
615 	if (t == NULL)
616 		return (NULL);
617 
618 	ADD_U_CHAR(dptr, AUT_IPORT);
619 	ADD_U_INT16(dptr, iport);
620 
621 	return (t);
622 }
623 
624 /*
625  * token ID                1 byte
626  * size                    2 bytes
627  * data                    size bytes
628  */
629 token_t *
630 au_to_opaque(const char *data, u_int16_t bytes)
631 {
632 	token_t *t;
633 	u_char *dptr = NULL;
634 
635 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
636 	if (t == NULL)
637 		return (NULL);
638 
639 	ADD_U_CHAR(dptr, AUT_OPAQUE);
640 	ADD_U_INT16(dptr, bytes);
641 	ADD_MEM(dptr, data, bytes);
642 
643 	return (t);
644 }
645 
646 /*
647  * token ID                1 byte
648  * seconds of time         4 bytes
649  * milliseconds of time    4 bytes
650  * file name len           2 bytes
651  * file pathname           N bytes + 1 terminating NULL byte
652  */
653 token_t *
654 au_to_file(const char *file, struct timeval tm)
655 {
656 	token_t *t;
657 	u_char *dptr = NULL;
658 	u_int16_t filelen;
659 	u_int32_t timems;
660 
661 	filelen = strlen(file);
662 	filelen += 1;
663 
664 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
665 	    sizeof(u_int16_t) + filelen);
666 	if (t == NULL)
667 		return (NULL);
668 
669 	timems = tm.tv_usec/1000;
670 
671 	ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
672 	ADD_U_INT32(dptr, tm.tv_sec);
673 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
674 	ADD_U_INT16(dptr, filelen);
675 	ADD_STRING(dptr, file, filelen);
676 
677 	return (t);
678 }
679 
680 /*
681  * token ID                1 byte
682  * text length             2 bytes
683  * text                    N bytes + 1 terminating NULL byte
684  */
685 token_t *
686 au_to_text(const char *text)
687 {
688 	token_t *t;
689 	u_char *dptr = NULL;
690 	u_int16_t textlen;
691 
692 	textlen = strlen(text);
693 	textlen += 1;
694 
695 	/* XXXRW: Should validate length against token size limit. */
696 
697 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
698 	if (t == NULL)
699 		return (NULL);
700 
701 	ADD_U_CHAR(dptr, AUT_TEXT);
702 	ADD_U_INT16(dptr, textlen);
703 	ADD_STRING(dptr, text, textlen);
704 
705 	return (t);
706 }
707 
708 /*
709  * token ID                1 byte
710  * path length             2 bytes
711  * path                    N bytes + 1 terminating NULL byte
712  */
713 token_t *
714 au_to_path(const char *text)
715 {
716 	token_t *t;
717 	u_char *dptr = NULL;
718 	u_int16_t textlen;
719 
720 	textlen = strlen(text);
721 	textlen += 1;
722 
723 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
724 	if (t == NULL)
725 		return (NULL);
726 
727 	ADD_U_CHAR(dptr, AUT_PATH);
728 	ADD_U_INT16(dptr, textlen);
729 	ADD_STRING(dptr, text, textlen);
730 
731 	return (t);
732 }
733 
734 /*
735  * token ID                1 byte
736  * audit ID                4 bytes
737  * effective user ID       4 bytes
738  * effective group ID      4 bytes
739  * real user ID            4 bytes
740  * real group ID           4 bytes
741  * process ID              4 bytes
742  * session ID              4 bytes
743  * terminal ID
744  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
745  *   machine address       4 bytes
746  */
747 token_t *
748 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
749     pid_t pid, au_asid_t sid, au_tid_t *tid)
750 {
751 	token_t *t;
752 	u_char *dptr = NULL;
753 
754 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
755 	if (t == NULL)
756 		return (NULL);
757 
758 	ADD_U_CHAR(dptr, AUT_PROCESS32);
759 	ADD_U_INT32(dptr, auid);
760 	ADD_U_INT32(dptr, euid);
761 	ADD_U_INT32(dptr, egid);
762 	ADD_U_INT32(dptr, ruid);
763 	ADD_U_INT32(dptr, rgid);
764 	ADD_U_INT32(dptr, pid);
765 	ADD_U_INT32(dptr, sid);
766 	ADD_U_INT32(dptr, tid->port);
767 
768 	/*
769 	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
770 	 * address type and 16 bytes of address, but for IPv4 addresses it
771 	 * simply writes the 4-byte address directly.  We support only IPv4
772 	 * addresses for process32 tokens.
773 	 */
774 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
775 
776 	return (t);
777 }
778 
779 token_t *
780 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
781     pid_t pid, au_asid_t sid, au_tid_t *tid)
782 {
783 	token_t *t;
784 	u_char *dptr = NULL;
785 
786 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
787 	    sizeof(u_int64_t));
788 	if (t == NULL)
789 		return (NULL);
790 
791 	ADD_U_CHAR(dptr, AUT_PROCESS64);
792 	ADD_U_INT32(dptr, auid);
793 	ADD_U_INT32(dptr, euid);
794 	ADD_U_INT32(dptr, egid);
795 	ADD_U_INT32(dptr, ruid);
796 	ADD_U_INT32(dptr, rgid);
797 	ADD_U_INT32(dptr, pid);
798 	ADD_U_INT32(dptr, sid);
799 	ADD_U_INT64(dptr, tid->port);
800 
801 	/*
802 	 * Note: Solaris will write out IPv6 addresses here as a 32-bit
803 	 * address type and 16 bytes of address, but for IPv4 addresses it
804 	 * simply writes the 4-byte address directly.  We support only IPv4
805 	 * addresses for process64 tokens.
806 	 */
807 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
808 
809 	return (t);
810 }
811 
812 token_t *
813 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
814     pid_t pid, au_asid_t sid, au_tid_t *tid)
815 {
816 
817 	return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
818 	    tid));
819 }
820 
821 /*
822  * token ID                1 byte
823  * audit ID                4 bytes
824  * effective user ID       4 bytes
825  * effective group ID      4 bytes
826  * real user ID            4 bytes
827  * real group ID           4 bytes
828  * process ID              4 bytes
829  * session ID              4 bytes
830  * terminal ID
831  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
832  *   address type-len      4 bytes
833  *   machine address      16 bytes
834  */
835 token_t *
836 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
837     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
838 {
839 	token_t *t;
840 	u_char *dptr = NULL;
841 
842 	if (tid->at_type == AU_IPv4)
843 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
844 		    10 * sizeof(u_int32_t));
845 	else if (tid->at_type == AU_IPv6)
846 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
847 		    13 * sizeof(u_int32_t));
848 	else {
849 		errno = EINVAL;
850 		return (NULL);
851 	}
852 	if (t == NULL)
853 		return (NULL);
854 
855 	ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
856 	ADD_U_INT32(dptr, auid);
857 	ADD_U_INT32(dptr, euid);
858 	ADD_U_INT32(dptr, egid);
859 	ADD_U_INT32(dptr, ruid);
860 	ADD_U_INT32(dptr, rgid);
861 	ADD_U_INT32(dptr, pid);
862 	ADD_U_INT32(dptr, sid);
863 	ADD_U_INT32(dptr, tid->at_port);
864 	ADD_U_INT32(dptr, tid->at_type);
865 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
866 	if (tid->at_type == AU_IPv6) {
867 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
868 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
869 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
870 	}
871 
872 	return (t);
873 }
874 
875 token_t *
876 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
877     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
878 {
879 	token_t *t;
880 	u_char *dptr = NULL;
881 
882 	if (tid->at_type == AU_IPv4)
883 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
884 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
885 		    2 * sizeof(u_int32_t));
886 	else if (tid->at_type == AU_IPv6)
887 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
888 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
889 		    5 * sizeof(u_int32_t));
890 	else {
891 		errno = EINVAL;
892 		return (NULL);
893 	}
894 	if (t == NULL)
895 		return (NULL);
896 
897 	ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
898 	ADD_U_INT32(dptr, auid);
899 	ADD_U_INT32(dptr, euid);
900 	ADD_U_INT32(dptr, egid);
901 	ADD_U_INT32(dptr, ruid);
902 	ADD_U_INT32(dptr, rgid);
903 	ADD_U_INT32(dptr, pid);
904 	ADD_U_INT32(dptr, sid);
905 	ADD_U_INT64(dptr, tid->at_port);
906 	ADD_U_INT32(dptr, tid->at_type);
907 	ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
908 	if (tid->at_type == AU_IPv6) {
909 		ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
910 		ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
911 		ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
912 	}
913 
914 	return (t);
915 }
916 
917 token_t *
918 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
919     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
920 {
921 
922 	return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
923 	    tid));
924 }
925 
926 /*
927  * token ID                1 byte
928  * error status            1 byte
929  * return value            4 bytes/8 bytes (32-bit/64-bit value)
930  */
931 token_t *
932 au_to_return32(char status, u_int32_t ret)
933 {
934 	token_t *t;
935 	u_char *dptr = NULL;
936 
937 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
938 	if (t == NULL)
939 		return (NULL);
940 
941 	ADD_U_CHAR(dptr, AUT_RETURN32);
942 	ADD_U_CHAR(dptr, status);
943 	ADD_U_INT32(dptr, ret);
944 
945 	return (t);
946 }
947 
948 token_t *
949 au_to_return64(char status, u_int64_t ret)
950 {
951 	token_t *t;
952 	u_char *dptr = NULL;
953 
954 	GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
955 	if (t == NULL)
956 		return (NULL);
957 
958 	ADD_U_CHAR(dptr, AUT_RETURN64);
959 	ADD_U_CHAR(dptr, status);
960 	ADD_U_INT64(dptr, ret);
961 
962 	return (t);
963 }
964 
965 token_t *
966 au_to_return(char status, u_int32_t ret)
967 {
968 
969 	return (au_to_return32(status, ret));
970 }
971 
972 /*
973  * token ID                1 byte
974  * sequence number         4 bytes
975  */
976 token_t *
977 au_to_seq(long audit_count)
978 {
979 	token_t *t;
980 	u_char *dptr = NULL;
981 
982 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
983 	if (t == NULL)
984 		return (NULL);
985 
986 	ADD_U_CHAR(dptr, AUT_SEQ);
987 	ADD_U_INT32(dptr, audit_count);
988 
989 	return (t);
990 }
991 
992 /*
993  * token ID                1 byte
994  * socket domain           2 bytes
995  * socket type             2 bytes
996  * address type            2 byte
997  * local port              2 bytes
998  * local address           4 bytes/16 bytes (IPv4/IPv6 address)
999  * remote port             2 bytes
1000  * remote address          4 bytes/16 bytes (IPv4/IPv6 address)
1001  *
1002  * Domain and type arguments to this routine are assumed to already have been
1003  * converted to the BSM constant space, so we don't do that here.
1004  */
1005 token_t *
1006 au_to_socket_ex(u_short so_domain, u_short so_type,
1007     struct sockaddr *sa_local, struct sockaddr *sa_remote)
1008 {
1009 	token_t *t;
1010 	u_char *dptr = NULL;
1011 	struct sockaddr_in *sin;
1012 	struct sockaddr_in6 *sin6;
1013 
1014 	if (so_domain == AF_INET)
1015 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1016 		    5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1017 	else if (so_domain == AF_INET6)
1018 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1019 		    5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
1020 	else {
1021 		errno = EINVAL;
1022 		return (NULL);
1023 	}
1024 	if (t == NULL)
1025 		return (NULL);
1026 
1027 	ADD_U_CHAR(dptr, AUT_SOCKET_EX);
1028 	ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
1029 	ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
1030 	if (so_domain == AF_INET) {
1031 		ADD_U_INT16(dptr, AU_IPv4);
1032 		sin = (struct sockaddr_in *)sa_local;
1033 		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
1034 		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
1035 		sin = (struct sockaddr_in *)sa_remote;
1036 		ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
1037 		ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
1038 	} else {
1039 		ADD_U_INT16(dptr, AU_IPv6);
1040 		sin6 = (struct sockaddr_in6 *)sa_local;
1041 		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
1042 		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
1043 		sin6 = (struct sockaddr_in6 *)sa_remote;
1044 		ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
1045 		ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
1046 	}
1047 
1048 	return (t);
1049 }
1050 
1051 /*
1052  * token ID                1 byte
1053  * socket family           2 bytes
1054  * path                    (up to) 104 bytes + NULL  (NULL terminated string)
1055  */
1056 token_t *
1057 au_to_sock_unix(struct sockaddr_un *so)
1058 {
1059 	token_t *t;
1060 	u_char *dptr;
1061 
1062 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1063 	if (t == NULL)
1064 		return (NULL);
1065 
1066 	ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1067 	/* BSM token has two bytes for family */
1068 	ADD_U_CHAR(dptr, 0);
1069 	ADD_U_CHAR(dptr, so->sun_family);
1070 	ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1071 
1072 	return (t);
1073 }
1074 
1075 /*
1076  * token ID                1 byte
1077  * socket family           2 bytes
1078  * local port              2 bytes
1079  * socket address          4 bytes
1080  */
1081 token_t *
1082 au_to_sock_inet32(struct sockaddr_in *so)
1083 {
1084 	token_t *t;
1085 	u_char *dptr = NULL;
1086 	uint16_t family;
1087 
1088 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1089 	    sizeof(uint32_t));
1090 	if (t == NULL)
1091 		return (NULL);
1092 
1093 	ADD_U_CHAR(dptr, AUT_SOCKINET32);
1094 	/*
1095 	 * BSM defines the family field as 16 bits, but many operating
1096 	 * systems have an 8-bit sin_family field.  Extend to 16 bits before
1097 	 * writing into the token.  Assume that both the port and the address
1098 	 * in the sockaddr_in are already in network byte order, but family
1099 	 * is in local byte order.
1100 	 *
1101 	 * XXXRW: Should a name space conversion be taking place on the value
1102 	 * of sin_family?
1103 	 */
1104 	family = so->sin_family;
1105 	ADD_U_INT16(dptr, family);
1106 	ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1107 	ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1108 
1109 	return (t);
1110 }
1111 
1112 token_t *
1113 au_to_sock_inet128(struct sockaddr_in6 *so)
1114 {
1115 	token_t *t;
1116 	u_char *dptr = NULL;
1117 
1118 	GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1119 	    4 * sizeof(u_int32_t));
1120 	if (t == NULL)
1121 		return (NULL);
1122 
1123 	ADD_U_CHAR(dptr, AUT_SOCKINET128);
1124 	/*
1125 	 * In BSD, sin6_family is one octet, but BSM defines the token to
1126 	 * store two. So we copy in a 0 first.  XXXRW: Possibly should be
1127 	 * conditionally compiled.
1128 	 */
1129 	ADD_U_CHAR(dptr, 0);
1130 	ADD_U_CHAR(dptr, so->sin6_family);
1131 
1132 	ADD_U_INT16(dptr, so->sin6_port);
1133 	ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1134 
1135 	return (t);
1136 }
1137 
1138 token_t *
1139 au_to_sock_inet(struct sockaddr_in *so)
1140 {
1141 
1142 	return (au_to_sock_inet32(so));
1143 }
1144 
1145 /*
1146  * token ID                1 byte
1147  * audit ID                4 bytes
1148  * effective user ID       4 bytes
1149  * effective group ID      4 bytes
1150  * real user ID            4 bytes
1151  * real group ID           4 bytes
1152  * process ID              4 bytes
1153  * session ID              4 bytes
1154  * terminal ID
1155  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1156  *   machine address       4 bytes
1157  */
1158 token_t *
1159 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1160     pid_t pid, au_asid_t sid, au_tid_t *tid)
1161 {
1162 	token_t *t;
1163 	u_char *dptr = NULL;
1164 
1165 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1166 	if (t == NULL)
1167 		return (NULL);
1168 
1169 	ADD_U_CHAR(dptr, AUT_SUBJECT32);
1170 	ADD_U_INT32(dptr, auid);
1171 	ADD_U_INT32(dptr, euid);
1172 	ADD_U_INT32(dptr, egid);
1173 	ADD_U_INT32(dptr, ruid);
1174 	ADD_U_INT32(dptr, rgid);
1175 	ADD_U_INT32(dptr, pid);
1176 	ADD_U_INT32(dptr, sid);
1177 	ADD_U_INT32(dptr, tid->port);
1178 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1179 
1180 	return (t);
1181 }
1182 
1183 token_t *
1184 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1185     pid_t pid, au_asid_t sid, au_tid_t *tid)
1186 {
1187 	token_t *t;
1188 	u_char *dptr = NULL;
1189 
1190 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1191 	    sizeof(u_int64_t) + sizeof(u_int32_t));
1192 	if (t == NULL)
1193 		return (NULL);
1194 
1195 	ADD_U_CHAR(dptr, AUT_SUBJECT64);
1196 	ADD_U_INT32(dptr, auid);
1197 	ADD_U_INT32(dptr, euid);
1198 	ADD_U_INT32(dptr, egid);
1199 	ADD_U_INT32(dptr, ruid);
1200 	ADD_U_INT32(dptr, rgid);
1201 	ADD_U_INT32(dptr, pid);
1202 	ADD_U_INT32(dptr, sid);
1203 	ADD_U_INT64(dptr, tid->port);
1204 	ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1205 
1206 	return (t);
1207 }
1208 
1209 token_t *
1210 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1211     pid_t pid, au_asid_t sid, au_tid_t *tid)
1212 {
1213 
1214 	return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1215 	    tid));
1216 }
1217 
1218 /*
1219  * token ID                1 byte
1220  * audit ID                4 bytes
1221  * effective user ID       4 bytes
1222  * effective group ID      4 bytes
1223  * real user ID            4 bytes
1224  * real group ID           4 bytes
1225  * process ID              4 bytes
1226  * session ID              4 bytes
1227  * terminal ID
1228  *   port ID               4 bytes/8 bytes (32-bit/64-bit value)
1229  *   address type/length   4 bytes
1230  *   machine address      16 bytes
1231  */
1232 token_t *
1233 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1234     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1235 {
1236 	token_t *t;
1237 	u_char *dptr = NULL;
1238 
1239 	if (tid->at_type == AU_IPv4)
1240 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1241 		    sizeof(u_int32_t));
1242 	else if (tid->at_type == AU_IPv6)
1243 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1244 		    sizeof(u_int32_t));
1245 	else {
1246 		errno = EINVAL;
1247 		return (NULL);
1248 	}
1249 	if (t == NULL)
1250 		return (NULL);
1251 
1252 	ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1253 	ADD_U_INT32(dptr, auid);
1254 	ADD_U_INT32(dptr, euid);
1255 	ADD_U_INT32(dptr, egid);
1256 	ADD_U_INT32(dptr, ruid);
1257 	ADD_U_INT32(dptr, rgid);
1258 	ADD_U_INT32(dptr, pid);
1259 	ADD_U_INT32(dptr, sid);
1260 	ADD_U_INT32(dptr, tid->at_port);
1261 	ADD_U_INT32(dptr, tid->at_type);
1262 	if (tid->at_type == AU_IPv6)
1263 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1264 	else
1265 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1266 
1267 	return (t);
1268 }
1269 
1270 token_t *
1271 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1272     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1273 {
1274 	token_t *t;
1275 	u_char *dptr = NULL;
1276 
1277 	if (tid->at_type == AU_IPv4)
1278 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1279 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1280 		    2 * sizeof(u_int32_t));
1281 	else if (tid->at_type == AU_IPv6)
1282 		GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1283 		    7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1284 		    5 * sizeof(u_int32_t));
1285 	else {
1286 		errno = EINVAL;
1287 		return (NULL);
1288 	}
1289 	if (t == NULL)
1290 		return (NULL);
1291 
1292 	ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1293 	ADD_U_INT32(dptr, auid);
1294 	ADD_U_INT32(dptr, euid);
1295 	ADD_U_INT32(dptr, egid);
1296 	ADD_U_INT32(dptr, ruid);
1297 	ADD_U_INT32(dptr, rgid);
1298 	ADD_U_INT32(dptr, pid);
1299 	ADD_U_INT32(dptr, sid);
1300 	ADD_U_INT64(dptr, tid->at_port);
1301 	ADD_U_INT32(dptr, tid->at_type);
1302 	if (tid->at_type == AU_IPv6)
1303 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1304 	else
1305 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1306 
1307 	return (t);
1308 }
1309 
1310 token_t *
1311 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1312     gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1313 {
1314 
1315 	return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1316 	    tid));
1317 }
1318 
1319 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1320 /*
1321  * Collects audit information for the current process and creates a subject
1322  * token from it.
1323  */
1324 token_t *
1325 au_to_me(void)
1326 {
1327 	auditinfo_t auinfo;
1328 	auditinfo_addr_t aia;
1329 
1330 	/*
1331 	 * Try to use getaudit_addr(2) first.  If this kernel does not support
1332 	 * it, then fall back on to getaudit(2).
1333 	 */
1334 	if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1335 		if (errno == ENOSYS) {
1336 			if (getaudit(&auinfo) != 0)
1337 				return (NULL);
1338 			return (au_to_subject32(auinfo.ai_auid, geteuid(),
1339 				getegid(), getuid(), getgid(), getpid(),
1340 				auinfo.ai_asid, &auinfo.ai_termid));
1341 		} else {
1342 			/* getaudit_addr(2) failed for some other reason. */
1343 			return (NULL);
1344 		}
1345 	}
1346 
1347 	return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1348 		getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1349 }
1350 #endif
1351 
1352 /*
1353  * token ID				1 byte
1354  * count				4 bytes
1355  * text					count null-terminated strings
1356  */
1357 token_t *
1358 au_to_exec_args(char **argv)
1359 {
1360 	token_t *t;
1361 	u_char *dptr = NULL;
1362 	const char *nextarg;
1363 	int i, count = 0;
1364 	size_t totlen = 0;
1365 
1366 	nextarg = *argv;
1367 
1368 	while (nextarg != NULL) {
1369 		int nextlen;
1370 
1371 		nextlen = strlen(nextarg);
1372 		totlen += nextlen + 1;
1373 		count++;
1374 		nextarg = *(argv + count);
1375 	}
1376 
1377 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1378 	if (t == NULL)
1379 		return (NULL);
1380 
1381 	ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1382 	ADD_U_INT32(dptr, count);
1383 
1384 	for (i = 0; i < count; i++) {
1385 		nextarg = *(argv + i);
1386 		ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1387 	}
1388 
1389 	return (t);
1390 }
1391 
1392 /*
1393  * token ID				1 byte
1394  * count				4 bytes
1395  * text					count null-terminated strings
1396  */
1397 token_t *
1398 au_to_exec_env(char **envp)
1399 {
1400 	token_t *t;
1401 	u_char *dptr = NULL;
1402 	int i, count = 0;
1403 	size_t totlen = 0;
1404 	const char *nextenv;
1405 
1406 	nextenv = *envp;
1407 
1408 	while (nextenv != NULL) {
1409 		int nextlen;
1410 
1411 		nextlen = strlen(nextenv);
1412 		totlen += nextlen + 1;
1413 		count++;
1414 		nextenv = *(envp + count);
1415 	}
1416 
1417 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1418 	if (t == NULL)
1419 		return (NULL);
1420 
1421 	ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1422 	ADD_U_INT32(dptr, count);
1423 
1424 	for (i = 0; i < count; i++) {
1425 		nextenv = *(envp + i);
1426 		ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1427 	}
1428 
1429 	return (t);
1430 }
1431 
1432 /*
1433  * token ID                1 byte
1434  * zonename length         2 bytes
1435  * zonename                N bytes + 1 terminating NULL byte
1436  */
1437 token_t *
1438 au_to_zonename(const char *zonename)
1439 {
1440 	u_char *dptr = NULL;
1441 	u_int16_t textlen;
1442 	token_t *t;
1443 
1444 	textlen = strlen(zonename) + 1;
1445 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1446 	if (t == NULL)
1447 		return (NULL);
1448 
1449 	ADD_U_CHAR(dptr, AUT_ZONENAME);
1450 	ADD_U_INT16(dptr, textlen);
1451 	ADD_STRING(dptr, zonename, textlen);
1452 	return (t);
1453 }
1454 
1455 /*
1456  * token ID                1 byte
1457  * record byte count       4 bytes
1458  * version #               1 byte    [2]
1459  * event type              2 bytes
1460  * event modifier          2 bytes
1461  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1462  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1463  */
1464 token_t *
1465 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1466     struct timeval tm)
1467 {
1468 	token_t *t;
1469 	u_char *dptr = NULL;
1470 	u_int32_t timems;
1471 
1472 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1473 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1474 	if (t == NULL)
1475 		return (NULL);
1476 
1477 	ADD_U_CHAR(dptr, AUT_HEADER32);
1478 	ADD_U_INT32(dptr, rec_size);
1479 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1480 	ADD_U_INT16(dptr, e_type);
1481 	ADD_U_INT16(dptr, e_mod);
1482 
1483 	timems = tm.tv_usec/1000;
1484 	/* Add the timestamp */
1485 	ADD_U_INT32(dptr, tm.tv_sec);
1486 	ADD_U_INT32(dptr, timems);	/* We need time in ms. */
1487 
1488 	return (t);
1489 }
1490 
1491 /*
1492  * token ID                1 byte
1493  * record byte count       4 bytes
1494  * version #               1 byte    [2]
1495  * event type              2 bytes
1496  * event modifier          2 bytes
1497  * address type/length     4 bytes
1498  * machine address         4 bytes/16 bytes (IPv4/IPv6 address)
1499  * seconds of time         4 bytes/8 bytes (32-bit/64-bit value)
1500  * milliseconds of time    4 bytes/8 bytes (32-bit/64-bit value)
1501  */
1502 token_t *
1503 au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1504     struct timeval tm, struct auditinfo_addr *aia)
1505 {
1506 	token_t *t;
1507 	u_char *dptr = NULL;
1508 	u_int32_t timems;
1509 	au_tid_addr_t *tid;
1510 
1511 	tid = &aia->ai_termid;
1512 	if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6)
1513 		return (NULL);
1514 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1515 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1516 	    sizeof(u_int32_t) + tid->at_type);
1517 	if (t == NULL)
1518 		return (NULL);
1519 
1520 	ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1521 	ADD_U_INT32(dptr, rec_size);
1522 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1523 	ADD_U_INT16(dptr, e_type);
1524 	ADD_U_INT16(dptr, e_mod);
1525 
1526 	ADD_U_INT32(dptr, tid->at_type);
1527 	if (tid->at_type == AU_IPv6)
1528 		ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1529 	else
1530 		ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1531 	timems = tm.tv_usec/1000;
1532 	/* Add the timestamp */
1533 	ADD_U_INT32(dptr, tm.tv_sec);
1534 	ADD_U_INT32(dptr, timems);      /* We need time in ms. */
1535 
1536 	return (t);
1537 }
1538 
1539 token_t *
1540 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1541     struct timeval tm)
1542 {
1543 	token_t *t;
1544 	u_char *dptr = NULL;
1545 	u_int32_t timems;
1546 
1547 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1548 	    sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1549 	if (t == NULL)
1550 		return (NULL);
1551 
1552 	ADD_U_CHAR(dptr, AUT_HEADER64);
1553 	ADD_U_INT32(dptr, rec_size);
1554 	ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1555 	ADD_U_INT16(dptr, e_type);
1556 	ADD_U_INT16(dptr, e_mod);
1557 
1558 	timems = tm.tv_usec/1000;
1559 	/* Add the timestamp */
1560 	ADD_U_INT64(dptr, tm.tv_sec);
1561 	ADD_U_INT64(dptr, timems);	/* We need time in ms. */
1562 
1563 	return (t);
1564 }
1565 
1566 #if !defined(KERNEL) && !defined(_KERNEL)
1567 #ifdef HAVE_AUDIT_SYSCALLS
1568 token_t *
1569 au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1570 {
1571 	struct timeval tm;
1572 	struct auditinfo_addr aia;
1573 
1574 	if (gettimeofday(&tm, NULL) == -1)
1575 		return (NULL);
1576 	if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1577 		if (errno != ENOSYS)
1578 			return (NULL);
1579 		return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1580 	}
1581 	return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1582 }
1583 #endif /* HAVE_AUDIT_SYSCALLS */
1584 
1585 token_t *
1586 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1587 {
1588 	struct timeval tm;
1589 
1590 	if (gettimeofday(&tm, NULL) == -1)
1591 		return (NULL);
1592 	return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1593 }
1594 
1595 token_t *
1596 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1597     __unused au_emod_t e_mod)
1598 {
1599 	struct timeval tm;
1600 
1601 	if (gettimeofday(&tm, NULL) == -1)
1602 		return (NULL);
1603 	return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1604 }
1605 
1606 token_t *
1607 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1608 {
1609 
1610 	return (au_to_header32(rec_size, e_type, e_mod));
1611 }
1612 
1613 #ifdef HAVE_AUDIT_SYSCALLS
1614 token_t *
1615 au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1616 {
1617 
1618 	return (au_to_header32_ex(rec_size, e_type, e_mod));
1619 }
1620 #endif /* HAVE_AUDIT_SYSCALLS */
1621 #endif /* !defined(KERNEL) && !defined(_KERNEL) */
1622 
1623 /*
1624  * token ID                1 byte
1625  * trailer magic number    2 bytes
1626  * record byte count       4 bytes
1627  */
1628 token_t *
1629 au_to_trailer(int rec_size)
1630 {
1631 	token_t *t;
1632 	u_char *dptr = NULL;
1633 	u_int16_t magic = AUT_TRAILER_MAGIC;
1634 
1635 	GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1636 	    sizeof(u_int32_t));
1637 	if (t == NULL)
1638 		return (NULL);
1639 
1640 	ADD_U_CHAR(dptr, AUT_TRAILER);
1641 	ADD_U_INT16(dptr, magic);
1642 	ADD_U_INT32(dptr, rec_size);
1643 
1644 	return (t);
1645 }
1646