2 * Copyright (c) 2004 Apple Computer, Inc.
3 * Copyright (c) 2005 SPARTA, Inc.
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
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 */
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>
65 #include <netinet/in.h>
66 #include <netinet/in_systm.h>
67 #include <netinet/ip.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)); \
81 (t)->len = (length); \
82 (dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \
83 if ((dptr) == NULL) { \
87 memset((dptr), 0, (length)); \
90 assert(t == NULL || dptr != NULL); \
96 * argument value 4 bytes/8 bytes (32-bit/64-bit value)
98 * text N bytes + 1 terminating NULL byte
101 au_to_arg32(char n
, char *text
, u_int32_t v
)
107 textlen
= strlen(text
);
110 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int32_t
) +
111 sizeof(u_int16_t
) + textlen
);
115 ADD_U_CHAR(dptr
, AUT_ARG32
);
117 ADD_U_INT32(dptr
, v
);
118 ADD_U_INT16(dptr
, textlen
);
119 ADD_STRING(dptr
, text
, textlen
);
126 au_to_arg64(char n
, char *text
, u_int64_t v
)
132 textlen
= strlen(text
);
135 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int64_t
) +
136 sizeof(u_int16_t
) + textlen
);
140 ADD_U_CHAR(dptr
, AUT_ARG64
);
142 ADD_U_INT64(dptr
, v
);
143 ADD_U_INT16(dptr
, textlen
);
144 ADD_STRING(dptr
, text
, textlen
);
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)
160 * file access mode 4 bytes
161 * owner user ID 4 bytes
162 * owner group ID 4 bytes
163 * file system ID 4 bytes
165 * device 4 bytes/8 bytes (32-bit/64-bit)
168 au_to_attr32(struct vnode_au_info
*vni
)
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
));
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
);
205 ADD_U_INT64(dptr
, 0LL);
207 ADD_U_INT32(dptr
, vni
->vn_dev
);
213 au_to_attr64(struct vnode_au_info
*vni
)
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);
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
);
250 ADD_U_INT64(dptr
, 0LL);
252 ADD_U_INT64(dptr
, vni
->vn_dev
);
258 au_to_attr(struct vnode_au_info
*vni
)
261 return (au_to_attr32(vni
));
263 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
267 * how to print 1 byte
270 * data items (depends on basic unit)
273 au_to_data(char unit_print
, char unit_type
, char unit_count
, char *p
)
277 size_t datasize
, totdata
;
279 /* Determine the size of the basic unit. */
283 datasize
= AUR_BYTE_SIZE
;
287 datasize
= AUR_SHORT_SIZE
;
292 datasize
= AUR_INT32_SIZE
;
296 datasize
= AUR_INT64_SIZE
;
304 totdata
= datasize
* unit_count
;
306 GET_TOKEN_AREA(t
, dptr
, 4 * sizeof(u_char
) + totdata
);
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
);
323 * return value 4 bytes
326 au_to_exit(int retval
, int err
)
331 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int32_t
));
335 ADD_U_CHAR(dptr
, AUT_EXIT
);
336 ADD_U_INT32(dptr
, err
);
337 ADD_U_INT32(dptr
, retval
);
345 au_to_groups(int *groups
)
348 return (au_to_newgroups(AUDIT_MAX_GROUPS
, (gid_t
*)groups
));
353 * number groups 2 bytes
354 * group list count * 4 bytes
357 au_to_newgroups(u_int16_t n
, gid_t
*groups
)
363 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) +
364 n
* sizeof(u_int32_t
));
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
]);
378 * internet address 4 bytes
381 au_to_in_addr(struct in_addr
*internet_addr
)
386 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(uint32_t));
390 ADD_U_CHAR(dptr
, AUT_IN_ADDR
);
391 ADD_MEM(dptr
, &internet_addr
->s_addr
, sizeof(uint32_t));
398 * address type/length 4 bytes
402 au_to_in_addr_ex(struct in6_addr
*internet_addr
)
406 u_int32_t type
= AF_INET6
;
408 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 5 * sizeof(uint32_t));
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));
423 * The IP header should be submitted in network byte order.
426 au_to_ip(struct ip
*ip
)
431 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(struct ip
));
435 ADD_U_CHAR(dptr
, AUT_IP
);
436 ADD_MEM(dptr
, ip
, sizeof(struct ip
));
443 * object ID type 1 byte
447 au_to_ipc(char type
, int id
)
452 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int32_t
));
456 ADD_U_CHAR(dptr
, AUT_IPC
);
457 ADD_U_CHAR(dptr
, type
);
458 ADD_U_INT32(dptr
, id
);
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
474 au_to_ipc_perm(struct ipc_perm
*perm
)
480 GET_TOKEN_AREA(t
, dptr
, 12 * sizeof(u_int16_t
) + sizeof(u_int32_t
));
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
);
510 ADD_U_INT16(dptr
, perm
->seq
);
513 #ifdef HAVE_IPC_PERM___KEY
514 ADD_U_INT32(dptr
, perm
->__key
);
516 ADD_U_INT32(dptr
, perm
->key
);
524 * port IP address 2 bytes
527 au_to_iport(u_int16_t iport
)
532 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
));
536 ADD_U_CHAR(dptr
, AUT_IPORT
);
537 ADD_U_INT16(dptr
, iport
);
548 au_to_opaque(char *data
, u_int16_t bytes
)
553 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + bytes
);
557 ADD_U_CHAR(dptr
, AUT_OPAQUE
);
558 ADD_U_INT16(dptr
, bytes
);
559 ADD_MEM(dptr
, data
, bytes
);
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
572 au_to_file(char *file
, struct timeval tm
)
579 filelen
= strlen(file
);
582 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int32_t
) +
583 sizeof(u_int16_t
) + filelen
);
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
);
600 * text length 2 bytes
601 * text N bytes + 1 terminating NULL byte
604 au_to_text(char *text
)
610 textlen
= strlen(text
);
613 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + textlen
);
617 ADD_U_CHAR(dptr
, AUT_TEXT
);
618 ADD_U_INT16(dptr
, textlen
);
619 ADD_STRING(dptr
, text
, textlen
);
626 * path length 2 bytes
627 * path N bytes + 1 terminating NULL byte
630 au_to_path(char *text
)
636 textlen
= strlen(text
);
639 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + textlen
);
643 ADD_U_CHAR(dptr
, AUT_PATH
);
644 ADD_U_INT16(dptr
, textlen
);
645 ADD_STRING(dptr
, text
, textlen
);
653 * effective user ID 4 bytes
654 * effective group ID 4 bytes
655 * real user ID 4 bytes
656 * real group ID 4 bytes
660 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
661 * machine address 4 bytes
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
)
670 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 9 * sizeof(u_int32_t
));
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
));
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
)
695 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 8 * sizeof(u_int32_t
) +
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
));
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
,
726 * effective user ID 4 bytes
727 * effective group ID 4 bytes
728 * real user ID 4 bytes
729 * real group ID 4 bytes
733 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
734 * address type-len 4 bytes
735 * machine address 16 bytes
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
)
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
));
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
));
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
)
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
));
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
));
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
,
830 * error status 1 byte
831 * return value 4 bytes/8 bytes (32-bit/64-bit value)
834 au_to_return32(char status
, u_int32_t ret
)
839 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int32_t
));
843 ADD_U_CHAR(dptr
, AUT_RETURN32
);
844 ADD_U_CHAR(dptr
, status
);
845 ADD_U_INT32(dptr
, ret
);
851 au_to_return64(char status
, u_int64_t ret
)
856 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int64_t
));
860 ADD_U_CHAR(dptr
, AUT_RETURN64
);
861 ADD_U_CHAR(dptr
, status
);
862 ADD_U_INT64(dptr
, ret
);
868 au_to_return(char status
, u_int32_t ret
)
871 return (au_to_return32(status
, ret
));
876 * sequence number 4 bytes
879 au_to_seq(long audit_count
)
884 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
));
888 ADD_U_CHAR(dptr
, AUT_SEQ
);
889 ADD_U_INT32(dptr
, audit_count
);
896 * socket family 2 bytes
900 au_to_sock_unix(struct sockaddr_un
*so
)
905 GET_TOKEN_AREA(t
, dptr
, 3 * sizeof(u_char
) + strlen(so
->sun_path
) + 1);
909 ADD_U_CHAR(dptr
, AU_SOCK_UNIX_TOKEN
);
910 /* BSM token has two bytes for family */
912 ADD_U_CHAR(dptr
, so
->sun_family
);
913 ADD_STRING(dptr
, so
->sun_path
, strlen(so
->sun_path
) + 1);
920 * socket family 2 bytes
922 * socket address 4 bytes
925 au_to_sock_inet32(struct sockaddr_in
*so
)
931 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(uint16_t) +
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
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));
957 au_to_sock_inet128(struct sockaddr_in6
*so
)
962 GET_TOKEN_AREA(t
, dptr
, 3 * sizeof(u_char
) + sizeof(u_int16_t
) +
963 4 * sizeof(u_int32_t
));
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.
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));
983 au_to_sock_inet(struct sockaddr_in
*so
)
986 return (au_to_sock_inet32(so
));
992 * effective user ID 4 bytes
993 * effective group ID 4 bytes
994 * real user ID 4 bytes
995 * real group ID 4 bytes
999 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1000 * machine address 4 bytes
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
)
1007 u_char
*dptr
= NULL
;
1009 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 9 * sizeof(u_int32_t
));
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
));
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
)
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
));
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
));
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
,
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
1072 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1073 * address type/length 4 bytes
1074 * machine address 16 bytes
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
)
1081 u_char
*dptr
= NULL
;
1083 if (tid
->at_type
== AU_IPv4
)
1084 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 10 *
1086 else if (tid
->at_type
== AU_IPv6
)
1087 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 13 *
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
));
1109 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_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
)
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
));
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
));
1149 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_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
,
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
1173 if (getaudit(&auinfo
) != 0)
1176 return (au_to_subject32(auinfo
.ai_auid
, geteuid(), getegid(),
1177 getuid(), getgid(), getpid(), auinfo
.ai_asid
, &auinfo
.ai_termid
));
1184 * text count null-terminated strings
1187 au_to_exec_args(char **argv
)
1190 u_char
*dptr
= NULL
;
1191 const char *nextarg
;
1197 while (nextarg
!= NULL
) {
1200 nextlen
= strlen(nextarg
);
1201 totlen
+= nextlen
+ 1;
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
);
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);
1224 * zonename length 2 bytes
1225 * zonename N bytes + 1 terminating NULL byte
1228 au_to_zonename(char *zonename
)
1230 u_char
*dptr
= NULL
;
1234 textlen
= strlen(zonename
);
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
);
1246 * text count null-terminated strings
1249 au_to_exec_env(char **envp
)
1252 u_char
*dptr
= NULL
;
1255 const char *nextenv
;
1259 while (nextenv
!= NULL
) {
1262 nextlen
= strlen(nextenv
);
1263 totlen
+= nextlen
+ 1;
1265 nextenv
= *(envp
+ count
);
1268 totlen
+= sizeof(char) * count
;
1269 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) + totlen
);
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);
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)
1294 au_to_header32_tm(int rec_size
, au_event_t e_type
, au_emod_t e_mod
,
1298 u_char
*dptr
= NULL
;
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
));
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. */
1321 au_to_header64_tm(int rec_size
, au_event_t e_type
, au_emod_t e_mod
,
1325 u_char
*dptr
= NULL
;
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
));
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. */
1347 #if !defined(KERNEL) && !defined(_KERNEL)
1349 au_to_header32(int rec_size
, au_event_t e_type
, au_emod_t e_mod
)
1353 if (gettimeofday(&tm
, NULL
) == -1)
1355 return (au_to_header32_tm(rec_size
, e_type
, e_mod
, tm
));
1359 au_to_header64(__unused
int rec_size
, __unused au_event_t e_type
,
1360 __unused au_emod_t e_mod
)
1364 if (gettimeofday(&tm
, NULL
) == -1)
1366 return (au_to_header64_tm(rec_size
, e_type
, e_mod
, tm
));
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
));
1379 * trailer magic number 2 bytes
1380 * record byte count 4 bytes
1383 au_to_trailer(int rec_size
)
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
) +
1394 ADD_U_CHAR(dptr
, AUT_TRAILER
);
1395 ADD_U_INT16(dptr
, magic
);
1396 ADD_U_INT32(dptr
, rec_size
);