Ignore machine-check MSRs
[freebsd-src/fkvm-freebsd.git] / contrib / openbsm / libbsm / bsm_token.c
blobc6608954abb8e7f01dd11f445cb3175168cb85c5
1 /*
2 * Copyright (c) 2004 Apple Computer, Inc.
3 * Copyright (c) 2005 SPARTA, Inc.
4 * All rights reserved.
6 * This code was developed in part by Robert N. M. Watson, Senior Principal
7 * Scientist, SPARTA, Inc.
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.
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.
33 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#63 $
36 #include <sys/types.h>
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 */
59 #include <sys/socket.h>
60 #include <sys/time.h>
61 #include <sys/un.h>
63 #include <sys/ipc.h>
65 #include <netinet/in.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.h>
69 #include <assert.h>
70 #include <errno.h>
71 #include <string.h>
72 #include <stdlib.h>
73 #include <unistd.h>
75 #include <bsm/audit_internal.h>
76 #include <bsm/libbsm.h>
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)
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
100 token_t *
101 au_to_arg32(char n, char *text, u_int32_t v)
103 token_t *t;
104 u_char *dptr = NULL;
105 u_int16_t textlen;
107 textlen = strlen(text);
108 textlen += 1;
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);
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);
121 return (t);
125 token_t *
126 au_to_arg64(char n, char *text, u_int64_t v)
128 token_t *t;
129 u_char *dptr = NULL;
130 u_int16_t textlen;
132 textlen = strlen(text);
133 textlen += 1;
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);
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);
146 return (t);
150 token_t *
151 au_to_arg(char n, char *text, u_int32_t v)
154 return (au_to_arg32(n, text, v));
157 #if defined(_KERNEL) || defined(KERNEL)
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)
167 token_t *
168 au_to_attr32(struct vnode_au_info *vni)
170 token_t *t;
171 u_char *dptr = NULL;
172 u_int16_t pad0_16 = 0;
173 u_int16_t pad0_32 = 0;
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);
180 ADD_U_CHAR(dptr, AUT_ATTR32);
183 * Darwin defines the size for the file mode
184 * as 2 bytes; BSM defines 4 so pad with 0
186 ADD_U_INT16(dptr, pad0_16);
187 ADD_U_INT16(dptr, vni->vn_mode);
189 ADD_U_INT32(dptr, vni->vn_uid);
190 ADD_U_INT32(dptr, vni->vn_gid);
191 ADD_U_INT32(dptr, vni->vn_fsid);
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.
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);
207 ADD_U_INT32(dptr, vni->vn_dev);
209 return (t);
212 token_t *
213 au_to_attr64(struct vnode_au_info *vni)
215 token_t *t;
216 u_char *dptr = NULL;
217 u_int16_t pad0_16 = 0;
218 u_int16_t pad0_32 = 0;
220 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
221 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
222 if (t == NULL)
223 return (NULL);
225 ADD_U_CHAR(dptr, AUT_ATTR64);
228 * Darwin defines the size for the file mode
229 * as 2 bytes; BSM defines 4 so pad with 0
231 ADD_U_INT16(dptr, pad0_16);
232 ADD_U_INT16(dptr, vni->vn_mode);
234 ADD_U_INT32(dptr, vni->vn_uid);
235 ADD_U_INT32(dptr, vni->vn_gid);
236 ADD_U_INT32(dptr, vni->vn_fsid);
239 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
240 * Attempt to handle both, and let the compiler sort it out. If we
241 * could pick this out at compile-time, it would be better, so as to
242 * avoid the else case below.
244 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
245 ADD_U_INT32(dptr, pad0_32);
246 ADD_U_INT32(dptr, vni->vn_fileid);
247 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
248 ADD_U_INT64(dptr, vni->vn_fileid);
249 else
250 ADD_U_INT64(dptr, 0LL);
252 ADD_U_INT64(dptr, vni->vn_dev);
254 return (t);
257 token_t *
258 au_to_attr(struct vnode_au_info *vni)
261 return (au_to_attr32(vni));
263 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
266 * token ID 1 byte
267 * how to print 1 byte
268 * basic unit 1 byte
269 * unit count 1 byte
270 * data items (depends on basic unit)
272 token_t *
273 au_to_data(char unit_print, char unit_type, char unit_count, char *p)
275 token_t *t;
276 u_char *dptr = NULL;
277 size_t datasize, totdata;
279 /* Determine the size of the basic unit. */
280 switch (unit_type) {
281 case AUR_BYTE:
282 /* case AUR_CHAR: */
283 datasize = AUR_BYTE_SIZE;
284 break;
286 case AUR_SHORT:
287 datasize = AUR_SHORT_SIZE;
288 break;
290 case AUR_INT32:
291 /* case AUR_INT: */
292 datasize = AUR_INT32_SIZE;
293 break;
295 case AUR_INT64:
296 datasize = AUR_INT64_SIZE;
297 break;
299 default:
300 errno = EINVAL;
301 return (NULL);
304 totdata = datasize * unit_count;
306 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
307 if (t == NULL)
308 return (NULL);
310 ADD_U_CHAR(dptr, AUT_DATA);
311 ADD_U_CHAR(dptr, unit_print);
312 ADD_U_CHAR(dptr, unit_type);
313 ADD_U_CHAR(dptr, unit_count);
314 ADD_MEM(dptr, p, totdata);
316 return (t);
321 * token ID 1 byte
322 * status 4 bytes
323 * return value 4 bytes
325 token_t *
326 au_to_exit(int retval, int err)
328 token_t *t;
329 u_char *dptr = NULL;
331 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
332 if (t == NULL)
333 return (NULL);
335 ADD_U_CHAR(dptr, AUT_EXIT);
336 ADD_U_INT32(dptr, err);
337 ADD_U_INT32(dptr, retval);
339 return (t);
344 token_t *
345 au_to_groups(int *groups)
348 return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t*)groups));
352 * token ID 1 byte
353 * number groups 2 bytes
354 * group list count * 4 bytes
356 token_t *
357 au_to_newgroups(u_int16_t n, gid_t *groups)
359 token_t *t;
360 u_char *dptr = NULL;
361 int i;
363 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
364 n * sizeof(u_int32_t));
365 if (t == NULL)
366 return (NULL);
368 ADD_U_CHAR(dptr, AUT_NEWGROUPS);
369 ADD_U_INT16(dptr, n);
370 for (i = 0; i < n; i++)
371 ADD_U_INT32(dptr, groups[i]);
373 return (t);
377 * token ID 1 byte
378 * internet address 4 bytes
380 token_t *
381 au_to_in_addr(struct in_addr *internet_addr)
383 token_t *t;
384 u_char *dptr = NULL;
386 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
387 if (t == NULL)
388 return (NULL);
390 ADD_U_CHAR(dptr, AUT_IN_ADDR);
391 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
393 return (t);
397 * token ID 1 byte
398 * address type/length 4 bytes
399 * Address 16 bytes
401 token_t *
402 au_to_in_addr_ex(struct in6_addr *internet_addr)
404 token_t *t;
405 u_char *dptr = NULL;
406 u_int32_t type = AF_INET6;
408 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
409 if (t == NULL)
410 return (NULL);
412 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
413 ADD_U_INT32(dptr, type);
414 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
416 return (t);
420 * token ID 1 byte
421 * ip header 20 bytes
423 * The IP header should be submitted in network byte order.
425 token_t *
426 au_to_ip(struct ip *ip)
428 token_t *t;
429 u_char *dptr = NULL;
431 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
432 if (t == NULL)
433 return (NULL);
435 ADD_U_CHAR(dptr, AUT_IP);
436 ADD_MEM(dptr, ip, sizeof(struct ip));
438 return (t);
442 * token ID 1 byte
443 * object ID type 1 byte
444 * object ID 4 bytes
446 token_t *
447 au_to_ipc(char type, int id)
449 token_t *t;
450 u_char *dptr = NULL;
452 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
453 if (t == NULL)
454 return (NULL);
456 ADD_U_CHAR(dptr, AUT_IPC);
457 ADD_U_CHAR(dptr, type);
458 ADD_U_INT32(dptr, id);
460 return (t);
464 * token ID 1 byte
465 * owner user ID 4 bytes
466 * owner group ID 4 bytes
467 * creator user ID 4 bytes
468 * creator group ID 4 bytes
469 * access mode 4 bytes
470 * slot sequence # 4 bytes
471 * key 4 bytes
473 token_t *
474 au_to_ipc_perm(struct ipc_perm *perm)
476 token_t *t;
477 u_char *dptr = NULL;
478 u_int16_t pad0 = 0;
480 GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t));
481 if (t == NULL)
482 return (NULL);
484 ADD_U_CHAR(dptr, AUT_IPC_PERM);
487 * Darwin defines the sizes for ipc_perm members
488 * as 2 bytes; BSM defines 4 so pad with 0
490 ADD_U_INT16(dptr, pad0);
491 ADD_U_INT16(dptr, perm->uid);
493 ADD_U_INT16(dptr, pad0);
494 ADD_U_INT16(dptr, perm->gid);
496 ADD_U_INT16(dptr, pad0);
497 ADD_U_INT16(dptr, perm->cuid);
499 ADD_U_INT16(dptr, pad0);
500 ADD_U_INT16(dptr, perm->cgid);
502 ADD_U_INT16(dptr, pad0);
503 ADD_U_INT16(dptr, perm->mode);
505 ADD_U_INT16(dptr, pad0);
507 #ifdef HAVE_IPC_PERM___SEQ
508 ADD_U_INT16(dptr, perm->__seq);
509 #else
510 ADD_U_INT16(dptr, perm->seq);
511 #endif
513 #ifdef HAVE_IPC_PERM___KEY
514 ADD_U_INT32(dptr, perm->__key);
515 #else
516 ADD_U_INT32(dptr, perm->key);
517 #endif
519 return (t);
523 * token ID 1 byte
524 * port IP address 2 bytes
526 token_t *
527 au_to_iport(u_int16_t iport)
529 token_t *t;
530 u_char *dptr = NULL;
532 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
533 if (t == NULL)
534 return (NULL);
536 ADD_U_CHAR(dptr, AUT_IPORT);
537 ADD_U_INT16(dptr, iport);
539 return (t);
543 * token ID 1 byte
544 * size 2 bytes
545 * data size bytes
547 token_t *
548 au_to_opaque(char *data, u_int16_t bytes)
550 token_t *t;
551 u_char *dptr = NULL;
553 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
554 if (t == NULL)
555 return (NULL);
557 ADD_U_CHAR(dptr, AUT_OPAQUE);
558 ADD_U_INT16(dptr, bytes);
559 ADD_MEM(dptr, data, bytes);
561 return (t);
565 * token ID 1 byte
566 * seconds of time 4 bytes
567 * milliseconds of time 4 bytes
568 * file name len 2 bytes
569 * file pathname N bytes + 1 terminating NULL byte
571 token_t *
572 au_to_file(char *file, struct timeval tm)
574 token_t *t;
575 u_char *dptr = NULL;
576 u_int16_t filelen;
577 u_int32_t timems;
579 filelen = strlen(file);
580 filelen += 1;
582 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
583 sizeof(u_int16_t) + filelen);
584 if (t == NULL)
585 return (NULL);
587 timems = tm.tv_usec/1000;
589 ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
590 ADD_U_INT32(dptr, tm.tv_sec);
591 ADD_U_INT32(dptr, timems); /* We need time in ms. */
592 ADD_U_INT16(dptr, filelen);
593 ADD_STRING(dptr, file, filelen);
595 return (t);
599 * token ID 1 byte
600 * text length 2 bytes
601 * text N bytes + 1 terminating NULL byte
603 token_t *
604 au_to_text(char *text)
606 token_t *t;
607 u_char *dptr = NULL;
608 u_int16_t textlen;
610 textlen = strlen(text);
611 textlen += 1;
613 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
614 if (t == NULL)
615 return (NULL);
617 ADD_U_CHAR(dptr, AUT_TEXT);
618 ADD_U_INT16(dptr, textlen);
619 ADD_STRING(dptr, text, textlen);
621 return (t);
625 * token ID 1 byte
626 * path length 2 bytes
627 * path N bytes + 1 terminating NULL byte
629 token_t *
630 au_to_path(char *text)
632 token_t *t;
633 u_char *dptr = NULL;
634 u_int16_t textlen;
636 textlen = strlen(text);
637 textlen += 1;
639 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
640 if (t == NULL)
641 return (NULL);
643 ADD_U_CHAR(dptr, AUT_PATH);
644 ADD_U_INT16(dptr, textlen);
645 ADD_STRING(dptr, text, textlen);
647 return (t);
651 * token ID 1 byte
652 * audit ID 4 bytes
653 * effective user ID 4 bytes
654 * effective group ID 4 bytes
655 * real user ID 4 bytes
656 * real group ID 4 bytes
657 * process ID 4 bytes
658 * session ID 4 bytes
659 * terminal ID
660 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
661 * machine address 4 bytes
663 token_t *
664 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
665 pid_t pid, au_asid_t sid, au_tid_t *tid)
667 token_t *t;
668 u_char *dptr = NULL;
670 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
671 if (t == NULL)
672 return (NULL);
674 ADD_U_CHAR(dptr, AUT_PROCESS32);
675 ADD_U_INT32(dptr, auid);
676 ADD_U_INT32(dptr, euid);
677 ADD_U_INT32(dptr, egid);
678 ADD_U_INT32(dptr, ruid);
679 ADD_U_INT32(dptr, rgid);
680 ADD_U_INT32(dptr, pid);
681 ADD_U_INT32(dptr, sid);
682 ADD_U_INT32(dptr, tid->port);
683 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
685 return (t);
688 token_t *
689 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
690 pid_t pid, au_asid_t sid, au_tid_t *tid)
692 token_t *t;
693 u_char *dptr = NULL;
695 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
696 sizeof(u_int64_t));
697 if (t == NULL)
698 return (NULL);
700 ADD_U_CHAR(dptr, AUT_PROCESS64);
701 ADD_U_INT32(dptr, auid);
702 ADD_U_INT32(dptr, euid);
703 ADD_U_INT32(dptr, egid);
704 ADD_U_INT32(dptr, ruid);
705 ADD_U_INT32(dptr, rgid);
706 ADD_U_INT32(dptr, pid);
707 ADD_U_INT32(dptr, sid);
708 ADD_U_INT64(dptr, tid->port);
709 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
711 return (t);
714 token_t *
715 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
716 pid_t pid, au_asid_t sid, au_tid_t *tid)
719 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
720 tid));
724 * token ID 1 byte
725 * audit ID 4 bytes
726 * effective user ID 4 bytes
727 * effective group ID 4 bytes
728 * real user ID 4 bytes
729 * real group ID 4 bytes
730 * process ID 4 bytes
731 * session ID 4 bytes
732 * terminal ID
733 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
734 * address type-len 4 bytes
735 * machine address 16 bytes
737 token_t *
738 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
739 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
741 token_t *t;
742 u_char *dptr = NULL;
744 if (tid->at_type == AU_IPv4)
745 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
746 10 * sizeof(u_int32_t));
747 else if (tid->at_type == AU_IPv6)
748 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
749 13 * sizeof(u_int32_t));
750 else {
751 errno = EINVAL;
752 return (NULL);
754 if (t == NULL)
755 return (NULL);
757 ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
758 ADD_U_INT32(dptr, auid);
759 ADD_U_INT32(dptr, euid);
760 ADD_U_INT32(dptr, egid);
761 ADD_U_INT32(dptr, ruid);
762 ADD_U_INT32(dptr, rgid);
763 ADD_U_INT32(dptr, pid);
764 ADD_U_INT32(dptr, sid);
765 ADD_U_INT32(dptr, tid->at_port);
766 ADD_U_INT32(dptr, tid->at_type);
767 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
768 if (tid->at_type == AU_IPv6) {
769 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
770 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
771 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
774 return (t);
777 token_t *
778 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
779 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
781 token_t *t;
782 u_char *dptr = NULL;
784 if (tid->at_type == AU_IPv4)
785 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
786 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
787 2 * sizeof(u_int32_t));
788 else if (tid->at_type == AU_IPv6)
789 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
790 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
791 5 * sizeof(u_int32_t));
792 else {
793 errno = EINVAL;
794 return (NULL);
796 if (t == NULL)
797 return (NULL);
799 ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
800 ADD_U_INT32(dptr, auid);
801 ADD_U_INT32(dptr, euid);
802 ADD_U_INT32(dptr, egid);
803 ADD_U_INT32(dptr, ruid);
804 ADD_U_INT32(dptr, rgid);
805 ADD_U_INT32(dptr, pid);
806 ADD_U_INT32(dptr, sid);
807 ADD_U_INT64(dptr, tid->at_port);
808 ADD_U_INT32(dptr, tid->at_type);
809 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
810 if (tid->at_type == AU_IPv6) {
811 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
812 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
813 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
816 return (t);
819 token_t *
820 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
821 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
824 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
825 tid));
829 * token ID 1 byte
830 * error status 1 byte
831 * return value 4 bytes/8 bytes (32-bit/64-bit value)
833 token_t *
834 au_to_return32(char status, u_int32_t ret)
836 token_t *t;
837 u_char *dptr = NULL;
839 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
840 if (t == NULL)
841 return (NULL);
843 ADD_U_CHAR(dptr, AUT_RETURN32);
844 ADD_U_CHAR(dptr, status);
845 ADD_U_INT32(dptr, ret);
847 return (t);
850 token_t *
851 au_to_return64(char status, u_int64_t ret)
853 token_t *t;
854 u_char *dptr = NULL;
856 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
857 if (t == NULL)
858 return (NULL);
860 ADD_U_CHAR(dptr, AUT_RETURN64);
861 ADD_U_CHAR(dptr, status);
862 ADD_U_INT64(dptr, ret);
864 return (t);
867 token_t *
868 au_to_return(char status, u_int32_t ret)
871 return (au_to_return32(status, ret));
875 * token ID 1 byte
876 * sequence number 4 bytes
878 token_t *
879 au_to_seq(long audit_count)
881 token_t *t;
882 u_char *dptr = NULL;
884 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
885 if (t == NULL)
886 return (NULL);
888 ADD_U_CHAR(dptr, AUT_SEQ);
889 ADD_U_INT32(dptr, audit_count);
891 return (t);
895 * token ID 1 byte
896 * socket family 2 bytes
897 * path 104 bytes
899 token_t *
900 au_to_sock_unix(struct sockaddr_un *so)
902 token_t *t;
903 u_char *dptr;
905 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
906 if (t == NULL)
907 return (NULL);
909 ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN);
910 /* BSM token has two bytes for family */
911 ADD_U_CHAR(dptr, 0);
912 ADD_U_CHAR(dptr, so->sun_family);
913 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
915 return (t);
919 * token ID 1 byte
920 * socket family 2 bytes
921 * local port 2 bytes
922 * socket address 4 bytes
924 token_t *
925 au_to_sock_inet32(struct sockaddr_in *so)
927 token_t *t;
928 u_char *dptr = NULL;
929 uint16_t family;
931 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
932 sizeof(uint32_t));
933 if (t == NULL)
934 return (NULL);
936 ADD_U_CHAR(dptr, AUT_SOCKINET32);
938 * BSM defines the family field as 16 bits, but many operating
939 * systems have an 8-bit sin_family field. Extend to 16 bits before
940 * writing into the token. Assume that both the port and the address
941 * in the sockaddr_in are already in network byte order, but family
942 * is in local byte order.
944 * XXXRW: Should a name space conversion be taking place on the value
945 * of sin_family?
947 family = so->sin_family;
948 ADD_U_INT16(dptr, family);
949 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
950 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
952 return (t);
956 token_t *
957 au_to_sock_inet128(struct sockaddr_in6 *so)
959 token_t *t;
960 u_char *dptr = NULL;
962 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
963 4 * sizeof(u_int32_t));
964 if (t == NULL)
965 return (NULL);
967 ADD_U_CHAR(dptr, AUT_SOCKINET128);
969 * In Darwin, sin6_family is one octet, but BSM defines the token
970 * to store two. So we copy in a 0 first.
972 ADD_U_CHAR(dptr, 0);
973 ADD_U_CHAR(dptr, so->sin6_family);
975 ADD_U_INT16(dptr, so->sin6_port);
976 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
978 return (t);
982 token_t *
983 au_to_sock_inet(struct sockaddr_in *so)
986 return (au_to_sock_inet32(so));
990 * token ID 1 byte
991 * audit ID 4 bytes
992 * effective user ID 4 bytes
993 * effective group ID 4 bytes
994 * real user ID 4 bytes
995 * real group ID 4 bytes
996 * process ID 4 bytes
997 * session ID 4 bytes
998 * terminal ID
999 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1000 * machine address 4 bytes
1002 token_t *
1003 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1004 pid_t pid, au_asid_t sid, au_tid_t *tid)
1006 token_t *t;
1007 u_char *dptr = NULL;
1009 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1010 if (t == NULL)
1011 return (NULL);
1013 ADD_U_CHAR(dptr, AUT_SUBJECT32);
1014 ADD_U_INT32(dptr, auid);
1015 ADD_U_INT32(dptr, euid);
1016 ADD_U_INT32(dptr, egid);
1017 ADD_U_INT32(dptr, ruid);
1018 ADD_U_INT32(dptr, rgid);
1019 ADD_U_INT32(dptr, pid);
1020 ADD_U_INT32(dptr, sid);
1021 ADD_U_INT32(dptr, tid->port);
1022 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1024 return (t);
1027 token_t *
1028 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1029 pid_t pid, au_asid_t sid, au_tid_t *tid)
1031 token_t *t;
1032 u_char *dptr = NULL;
1034 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1035 sizeof(u_int64_t) + sizeof(u_int32_t));
1036 if (t == NULL)
1037 return (NULL);
1039 ADD_U_CHAR(dptr, AUT_SUBJECT64);
1040 ADD_U_INT32(dptr, auid);
1041 ADD_U_INT32(dptr, euid);
1042 ADD_U_INT32(dptr, egid);
1043 ADD_U_INT32(dptr, ruid);
1044 ADD_U_INT32(dptr, rgid);
1045 ADD_U_INT32(dptr, pid);
1046 ADD_U_INT32(dptr, sid);
1047 ADD_U_INT64(dptr, tid->port);
1048 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1050 return (t);
1053 token_t *
1054 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1055 pid_t pid, au_asid_t sid, au_tid_t *tid)
1058 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1059 tid));
1063 * token ID 1 byte
1064 * audit ID 4 bytes
1065 * effective user ID 4 bytes
1066 * effective group ID 4 bytes
1067 * real user ID 4 bytes
1068 * real group ID 4 bytes
1069 * process ID 4 bytes
1070 * session ID 4 bytes
1071 * terminal ID
1072 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1073 * address type/length 4 bytes
1074 * machine address 16 bytes
1076 token_t *
1077 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1078 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1080 token_t *t;
1081 u_char *dptr = NULL;
1083 if (tid->at_type == AU_IPv4)
1084 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1085 sizeof(u_int32_t));
1086 else if (tid->at_type == AU_IPv6)
1087 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1088 sizeof(u_int32_t));
1089 else {
1090 errno = EINVAL;
1091 return (NULL);
1093 if (t == NULL)
1094 return (NULL);
1096 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1097 ADD_U_INT32(dptr, auid);
1098 ADD_U_INT32(dptr, euid);
1099 ADD_U_INT32(dptr, egid);
1100 ADD_U_INT32(dptr, ruid);
1101 ADD_U_INT32(dptr, rgid);
1102 ADD_U_INT32(dptr, pid);
1103 ADD_U_INT32(dptr, sid);
1104 ADD_U_INT32(dptr, tid->at_port);
1105 ADD_U_INT32(dptr, tid->at_type);
1106 if (tid->at_type == AU_IPv6)
1107 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1108 else
1109 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1111 return (t);
1114 token_t *
1115 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1116 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1118 token_t *t;
1119 u_char *dptr = NULL;
1121 if (tid->at_type == AU_IPv4)
1122 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1123 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1124 2 * sizeof(u_int32_t));
1125 else if (tid->at_type == AU_IPv6)
1126 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1127 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1128 5 * sizeof(u_int32_t));
1129 else {
1130 errno = EINVAL;
1131 return (NULL);
1133 if (t == NULL)
1134 return (NULL);
1136 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1137 ADD_U_INT32(dptr, auid);
1138 ADD_U_INT32(dptr, euid);
1139 ADD_U_INT32(dptr, egid);
1140 ADD_U_INT32(dptr, ruid);
1141 ADD_U_INT32(dptr, rgid);
1142 ADD_U_INT32(dptr, pid);
1143 ADD_U_INT32(dptr, sid);
1144 ADD_U_INT64(dptr, tid->at_port);
1145 ADD_U_INT32(dptr, tid->at_type);
1146 if (tid->at_type == AU_IPv6)
1147 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1148 else
1149 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1151 return (t);
1154 token_t *
1155 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1156 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1159 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1160 tid));
1163 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1165 * Collects audit information for the current process
1166 * and creates a subject token from it
1168 token_t *
1169 au_to_me(void)
1171 auditinfo_t auinfo;
1173 if (getaudit(&auinfo) != 0)
1174 return (NULL);
1176 return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
1177 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid));
1179 #endif
1182 * token ID 1 byte
1183 * count 4 bytes
1184 * text count null-terminated strings
1186 token_t *
1187 au_to_exec_args(char **argv)
1189 token_t *t;
1190 u_char *dptr = NULL;
1191 const char *nextarg;
1192 int i, count = 0;
1193 size_t totlen = 0;
1195 nextarg = *argv;
1197 while (nextarg != NULL) {
1198 int nextlen;
1200 nextlen = strlen(nextarg);
1201 totlen += nextlen + 1;
1202 count++;
1203 nextarg = *(argv + count);
1206 totlen += count * sizeof(char); /* nul terminations. */
1207 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1208 if (t == NULL)
1209 return (NULL);
1211 ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1212 ADD_U_INT32(dptr, count);
1214 for (i = 0; i < count; i++) {
1215 nextarg = *(argv + i);
1216 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1219 return (t);
1223 * token ID 1 byte
1224 * zonename length 2 bytes
1225 * zonename N bytes + 1 terminating NULL byte
1227 token_t *
1228 au_to_zonename(char *zonename)
1230 u_char *dptr = NULL;
1231 u_int16_t textlen;
1232 token_t *t;
1234 textlen = strlen(zonename);
1235 textlen += 1;
1236 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1237 ADD_U_CHAR(dptr, AUT_ZONENAME);
1238 ADD_U_INT16(dptr, textlen);
1239 ADD_STRING(dptr, zonename, textlen);
1240 return (t);
1244 * token ID 1 byte
1245 * count 4 bytes
1246 * text count null-terminated strings
1248 token_t *
1249 au_to_exec_env(char **envp)
1251 token_t *t;
1252 u_char *dptr = NULL;
1253 int i, count = 0;
1254 size_t totlen = 0;
1255 const char *nextenv;
1257 nextenv = *envp;
1259 while (nextenv != NULL) {
1260 int nextlen;
1262 nextlen = strlen(nextenv);
1263 totlen += nextlen + 1;
1264 count++;
1265 nextenv = *(envp + count);
1268 totlen += sizeof(char) * count;
1269 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1270 if (t == NULL)
1271 return (NULL);
1273 ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1274 ADD_U_INT32(dptr, count);
1276 for (i = 0; i < count; i++) {
1277 nextenv = *(envp + i);
1278 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1281 return (t);
1285 * token ID 1 byte
1286 * record byte count 4 bytes
1287 * version # 1 byte [2]
1288 * event type 2 bytes
1289 * event modifier 2 bytes
1290 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1291 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1293 token_t *
1294 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1295 struct timeval tm)
1297 token_t *t;
1298 u_char *dptr = NULL;
1299 u_int32_t timems;
1301 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1302 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1303 if (t == NULL)
1304 return (NULL);
1306 ADD_U_CHAR(dptr, AUT_HEADER32);
1307 ADD_U_INT32(dptr, rec_size);
1308 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1309 ADD_U_INT16(dptr, e_type);
1310 ADD_U_INT16(dptr, e_mod);
1312 timems = tm.tv_usec/1000;
1313 /* Add the timestamp */
1314 ADD_U_INT32(dptr, tm.tv_sec);
1315 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1317 return (t);
1320 token_t *
1321 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1322 struct timeval tm)
1324 token_t *t;
1325 u_char *dptr = NULL;
1326 u_int32_t timems;
1328 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1329 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1330 if (t == NULL)
1331 return (NULL);
1333 ADD_U_CHAR(dptr, AUT_HEADER64);
1334 ADD_U_INT32(dptr, rec_size);
1335 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1336 ADD_U_INT16(dptr, e_type);
1337 ADD_U_INT16(dptr, e_mod);
1339 timems = tm.tv_usec/1000;
1340 /* Add the timestamp */
1341 ADD_U_INT64(dptr, tm.tv_sec);
1342 ADD_U_INT64(dptr, timems); /* We need time in ms. */
1344 return (t);
1347 #if !defined(KERNEL) && !defined(_KERNEL)
1348 token_t *
1349 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1351 struct timeval tm;
1353 if (gettimeofday(&tm, NULL) == -1)
1354 return (NULL);
1355 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1358 token_t *
1359 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1360 __unused au_emod_t e_mod)
1362 struct timeval tm;
1364 if (gettimeofday(&tm, NULL) == -1)
1365 return (NULL);
1366 return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1369 token_t *
1370 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1373 return (au_to_header32(rec_size, e_type, e_mod));
1375 #endif
1378 * token ID 1 byte
1379 * trailer magic number 2 bytes
1380 * record byte count 4 bytes
1382 token_t *
1383 au_to_trailer(int rec_size)
1385 token_t *t;
1386 u_char *dptr = NULL;
1387 u_int16_t magic = TRAILER_PAD_MAGIC;
1389 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1390 sizeof(u_int32_t));
1391 if (t == NULL)
1392 return (NULL);
1394 ADD_U_CHAR(dptr, AUT_TRAILER);
1395 ADD_U_INT16(dptr, magic);
1396 ADD_U_INT32(dptr, rec_size);
1398 return (t);