2 * Copyright (c) 2004-2009 Apple 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 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.
34 #include <sys/types.h>
36 #include <sys/event.h>
37 #include <sys/ucred.h>
38 #include <sys/systm.h>
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
46 #include <bsm/audit.h>
47 #include <bsm/audit_internal.h>
48 #include <bsm/audit_record.h>
49 #include <security/audit/audit.h>
50 #include <security/audit/audit_bsd.h>
51 #include <security/audit/audit_private.h>
53 #include <kern/host.h>
54 #include <kern/clock.h>
59 #define GET_TOKEN_AREA(t, dptr, length) do { \
60 t = malloc(sizeof(token_t), M_AUDITBSM, M_WAITOK); \
61 t->t_data = malloc(length, M_AUDITBSM, M_WAITOK | M_ZERO); \
69 * argument value 4 bytes/8 bytes (32-bit/64-bit value)
71 * text N bytes + 1 terminating NULL byte
74 au_to_arg32(char n
, const char *text
, u_int32_t v
)
80 textlen
= strlen(text
);
83 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int32_t
) +
84 sizeof(u_int16_t
) + textlen
);
86 ADD_U_CHAR(dptr
, AUT_ARG32
);
89 ADD_U_INT16(dptr
, textlen
);
90 ADD_STRING(dptr
, text
, textlen
);
96 au_to_arg64(char n
, const char *text
, u_int64_t v
)
102 textlen
= strlen(text
);
105 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int64_t
) +
106 sizeof(u_int16_t
) + textlen
);
108 ADD_U_CHAR(dptr
, AUT_ARG64
);
110 ADD_U_INT64(dptr
, v
);
111 ADD_U_INT16(dptr
, textlen
);
112 ADD_STRING(dptr
, text
, textlen
);
118 au_to_arg(char n
, const char *text
, u_int32_t v
)
120 return au_to_arg32(n
, text
, v
);
123 #if defined(_KERNEL) || defined(KERNEL)
126 * file access mode 4 bytes
127 * owner user ID 4 bytes
128 * owner group ID 4 bytes
129 * file system ID 4 bytes
131 * device 4 bytes/8 bytes (32-bit/64-bit)
134 au_to_attr32(struct vnode_au_info
*vni
)
138 u_int16_t pad0_16
= 0;
139 u_int32_t pad0_32
= 0;
141 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int16_t
) +
142 3 * sizeof(u_int32_t
) + sizeof(u_int64_t
) + sizeof(u_int32_t
));
144 ADD_U_CHAR(dptr
, AUT_ATTR32
);
147 * Darwin defines the size for the file mode
148 * as 2 bytes; BSM defines 4 so pad with 0
150 ADD_U_INT16(dptr
, pad0_16
);
151 ADD_U_INT16(dptr
, vni
->vn_mode
);
153 ADD_U_INT32(dptr
, vni
->vn_uid
);
154 ADD_U_INT32(dptr
, vni
->vn_gid
);
155 ADD_U_INT32(dptr
, vni
->vn_fsid
);
158 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
159 * Attempt to handle both, and let the compiler sort it out. If we
160 * could pick this out at compile-time, it would be better, so as to
161 * avoid the else case below.
163 if (sizeof(vni
->vn_fileid
) == sizeof(uint32_t)) {
164 ADD_U_INT32(dptr
, pad0_32
);
165 ADD_U_INT32(dptr
, vni
->vn_fileid
);
166 } else if (sizeof(vni
->vn_fileid
) == sizeof(uint64_t)) {
167 ADD_U_INT64(dptr
, vni
->vn_fileid
);
169 ADD_U_INT64(dptr
, 0LL);
172 ADD_U_INT32(dptr
, vni
->vn_dev
);
178 au_to_attr64(struct vnode_au_info
*vni
)
182 u_int16_t pad0_16
= 0;
183 u_int16_t pad0_32
= 0;
185 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int16_t
) +
186 3 * sizeof(u_int32_t
) + sizeof(u_int64_t
) * 2);
188 ADD_U_CHAR(dptr
, AUT_ATTR64
);
191 * Darwin defines the size for the file mode
192 * as 2 bytes; BSM defines 4 so pad with 0
194 ADD_U_INT16(dptr
, pad0_16
);
195 ADD_U_INT16(dptr
, vni
->vn_mode
);
197 ADD_U_INT32(dptr
, vni
->vn_uid
);
198 ADD_U_INT32(dptr
, vni
->vn_gid
);
199 ADD_U_INT32(dptr
, vni
->vn_fsid
);
202 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
203 * Attempt to handle both, and let the compiler sort it out. If we
204 * could pick this out at compile-time, it would be better, so as to
205 * avoid the else case below.
207 if (sizeof(vni
->vn_fileid
) == sizeof(uint32_t)) {
208 ADD_U_INT32(dptr
, pad0_32
);
209 ADD_U_INT32(dptr
, vni
->vn_fileid
);
210 } else if (sizeof(vni
->vn_fileid
) == sizeof(uint64_t)) {
211 ADD_U_INT64(dptr
, vni
->vn_fileid
);
213 ADD_U_INT64(dptr
, 0LL);
216 ADD_U_INT64(dptr
, vni
->vn_dev
);
222 au_to_attr(struct vnode_au_info
*vni
)
224 return au_to_attr32(vni
);
226 #endif /* defined(_KERNEL) || defined(KERNEL) */
230 * how to print 1 byte
233 * data items (depends on basic unit)
236 au_to_data(char unit_print
, char unit_type
, char unit_count
, const char *p
)
240 size_t datasize
, totdata
;
242 /* Determine the size of the basic unit. */
246 datasize
= AUR_BYTE_SIZE
;
250 datasize
= AUR_SHORT_SIZE
;
255 datasize
= AUR_INT32_SIZE
;
259 datasize
= AUR_INT64_SIZE
;
263 /* For unknown assume byte. */
264 datasize
= AUR_BYTE_SIZE
;
268 totdata
= datasize
* (size_t)unit_count
;
270 GET_TOKEN_AREA(t
, dptr
, 4 * sizeof(u_char
) + totdata
);
272 ADD_U_CHAR(dptr
, AUT_DATA
);
273 ADD_U_CHAR(dptr
, unit_print
);
274 ADD_U_CHAR(dptr
, unit_type
);
275 ADD_U_CHAR(dptr
, unit_count
);
276 ADD_MEM(dptr
, p
, totdata
);
284 * return value 4 bytes
287 au_to_exit(int retval
, int err
)
292 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int32_t
));
294 ADD_U_CHAR(dptr
, AUT_EXIT
);
295 ADD_U_INT32(dptr
, err
);
296 ADD_U_INT32(dptr
, retval
);
304 au_to_groups(int *groups
)
306 return au_to_newgroups(AUDIT_MAX_GROUPS
, (gid_t
*)groups
);
311 * number groups 2 bytes
312 * group list count * 4 bytes
315 au_to_newgroups(u_int16_t n
, gid_t
*groups
)
321 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) +
322 n
* sizeof(u_int32_t
));
324 ADD_U_CHAR(dptr
, AUT_NEWGROUPS
);
325 ADD_U_INT16(dptr
, n
);
326 for (i
= 0; i
< n
; i
++) {
327 ADD_U_INT32(dptr
, groups
[i
]);
335 * internet address 4 bytes
338 au_to_in_addr(struct in_addr
*internet_addr
)
343 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(uint32_t));
345 ADD_U_CHAR(dptr
, AUT_IN_ADDR
);
346 ADD_MEM(dptr
, &internet_addr
->s_addr
, sizeof(uint32_t));
353 * address type/length 4 bytes
357 au_to_in_addr_ex(struct in6_addr
*internet_addr
)
361 u_int32_t type
= AU_IPv6
;
363 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 5 * sizeof(uint32_t));
365 ADD_U_CHAR(dptr
, AUT_IN_ADDR_EX
);
366 ADD_U_INT32(dptr
, type
);
367 ADD_MEM(dptr
, internet_addr
, 4 * sizeof(uint32_t));
376 * The IP header should be submitted in network byte order.
379 au_to_ip(struct ip
*ip
)
384 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(struct ip
));
386 ADD_U_CHAR(dptr
, AUT_IP
);
387 ADD_MEM(dptr
, ip
, sizeof(struct ip
));
394 * object ID type 1 byte
398 au_to_ipc(char type
, int id
)
403 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int32_t
));
405 ADD_U_CHAR(dptr
, AUT_IPC
);
406 ADD_U_CHAR(dptr
, type
);
407 ADD_U_INT32(dptr
, id
);
414 * owner user ID 4 bytes
415 * owner group ID 4 bytes
416 * creator user ID 4 bytes
417 * creator group ID 4 bytes
418 * access mode 4 bytes
419 * slot sequence # 4 bytes
423 au_to_ipc_perm(struct ipc_perm
*perm
)
433 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 12 * sizeof(u_int16_t
) +
436 ADD_U_CHAR(dptr
, AUT_IPC_PERM
);
439 * Darwin defines the size for the file mode
440 * as 2 bytes; BSM defines 4 so pad with 0
442 ADD_U_INT32(dptr
, perm
->uid
);
443 ADD_U_INT32(dptr
, perm
->gid
);
444 ADD_U_INT32(dptr
, perm
->cuid
);
445 ADD_U_INT32(dptr
, perm
->cgid
);
447 ADD_U_INT16(dptr
, pad0
);
448 ADD_U_INT16(dptr
, perm
->mode
);
450 ADD_U_INT16(dptr
, pad0
);
451 ADD_U_INT16(dptr
, perm
->_seq
);
453 ADD_U_INT16(dptr
, pad0
);
454 ADD_U_INT16(dptr
, perm
->_key
);
461 * port IP address 2 bytes
464 au_to_iport(u_int16_t iport
)
469 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
));
471 ADD_U_CHAR(dptr
, AUT_IPORT
);
472 ADD_U_INT16(dptr
, iport
);
483 au_to_opaque(const char *data
, uint16_t bytes
)
488 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + bytes
);
490 ADD_U_CHAR(dptr
, AUT_OPAQUE
);
491 ADD_U_INT16(dptr
, bytes
);
492 ADD_MEM(dptr
, data
, bytes
);
499 * seconds of time 4 bytes
500 * milliseconds of time 4 bytes
501 * file name len 2 bytes
502 * file pathname N bytes + 1 terminating NULL byte
505 au_to_file(const char *file
, struct timeval tm
)
512 filelen
= strlen(file
);
515 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int32_t
) +
516 sizeof(u_int16_t
) + filelen
);
518 timems
= tm
.tv_usec
/ 1000;
520 ADD_U_CHAR(dptr
, AUT_OTHER_FILE32
);
521 ADD_U_INT32(dptr
, tm
.tv_sec
);
522 ADD_U_INT32(dptr
, timems
); /* We need time in ms. */
523 ADD_U_INT16(dptr
, filelen
);
524 ADD_STRING(dptr
, file
, filelen
);
531 * text length 2 bytes
532 * text N bytes + 1 terminating NULL byte
535 au_to_text(const char *text
)
541 textlen
= strlen(text
);
544 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + textlen
);
546 ADD_U_CHAR(dptr
, AUT_TEXT
);
547 ADD_U_INT16(dptr
, textlen
);
548 ADD_STRING(dptr
, text
, textlen
);
555 * path length 2 bytes
556 * path N bytes + 1 terminating NULL byte
559 au_to_path(const char *text
)
565 textlen
= strlen(text
);
568 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + textlen
);
570 ADD_U_CHAR(dptr
, AUT_PATH
);
571 ADD_U_INT16(dptr
, textlen
);
572 ADD_STRING(dptr
, text
, textlen
);
580 * effective user ID 4 bytes
581 * effective group ID 4 bytes
582 * real user ID 4 bytes
583 * real group ID 4 bytes
587 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
588 * machine address 4 bytes
591 au_to_process32(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
, gid_t rgid
,
592 pid_t pid
, au_asid_t sid
, au_tid_t
*tid
)
597 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 9 * sizeof(u_int32_t
));
599 ADD_U_CHAR(dptr
, AUT_PROCESS32
);
600 ADD_U_INT32(dptr
, auid
);
601 ADD_U_INT32(dptr
, euid
);
602 ADD_U_INT32(dptr
, egid
);
603 ADD_U_INT32(dptr
, ruid
);
604 ADD_U_INT32(dptr
, rgid
);
605 ADD_U_INT32(dptr
, pid
);
606 ADD_U_INT32(dptr
, sid
);
607 ADD_U_INT32(dptr
, tid
->port
);
608 ADD_MEM(dptr
, &tid
->machine
, sizeof(u_int32_t
));
614 au_to_process64(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
, gid_t rgid
,
615 pid_t pid
, au_asid_t sid
, au_tid_t
*tid
)
620 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 8 * sizeof(u_int32_t
) +
623 ADD_U_CHAR(dptr
, AUT_PROCESS64
);
624 ADD_U_INT32(dptr
, auid
);
625 ADD_U_INT32(dptr
, euid
);
626 ADD_U_INT32(dptr
, egid
);
627 ADD_U_INT32(dptr
, ruid
);
628 ADD_U_INT32(dptr
, rgid
);
629 ADD_U_INT32(dptr
, pid
);
630 ADD_U_INT32(dptr
, sid
);
631 ADD_U_INT64(dptr
, tid
->port
);
632 ADD_MEM(dptr
, &tid
->machine
, sizeof(u_int32_t
));
638 au_to_process(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
, gid_t rgid
,
639 pid_t pid
, au_asid_t sid
, au_tid_t
*tid
)
641 return au_to_process32(auid
, euid
, egid
, ruid
, rgid
, pid
, sid
,
648 * effective user ID 4 bytes
649 * effective group ID 4 bytes
650 * real user ID 4 bytes
651 * real group ID 4 bytes
655 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
656 * address type-len 4 bytes
657 * machine address 4/16 bytes
660 au_to_process32_ex(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
,
661 gid_t rgid
, pid_t pid
, au_asid_t sid
, au_tid_addr_t
*tid
)
666 KASSERT((tid
->at_type
== AU_IPv4
) || (tid
->at_type
== AU_IPv6
),
667 ("au_to_process32_ex: type %u", (unsigned int)tid
->at_type
));
668 if (tid
->at_type
== AU_IPv6
) {
669 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 13 *
672 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 10 *
676 ADD_U_CHAR(dptr
, AUT_PROCESS32_EX
);
677 ADD_U_INT32(dptr
, auid
);
678 ADD_U_INT32(dptr
, euid
);
679 ADD_U_INT32(dptr
, egid
);
680 ADD_U_INT32(dptr
, ruid
);
681 ADD_U_INT32(dptr
, rgid
);
682 ADD_U_INT32(dptr
, pid
);
683 ADD_U_INT32(dptr
, sid
);
684 ADD_U_INT32(dptr
, tid
->at_port
);
685 ADD_U_INT32(dptr
, tid
->at_type
);
686 if (tid
->at_type
== AU_IPv6
) {
687 ADD_MEM(dptr
, &tid
->at_addr
[0], 4 * sizeof(u_int32_t
));
689 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_t
));
696 au_to_process64_ex(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
,
697 gid_t rgid
, pid_t pid
, au_asid_t sid
, au_tid_addr_t
*tid
)
702 if (tid
->at_type
== AU_IPv4
) {
703 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) +
704 7 * sizeof(u_int32_t
) + sizeof(u_int64_t
) +
705 2 * sizeof(u_int32_t
));
706 } else if (tid
->at_type
== AU_IPv6
) {
707 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) +
708 7 * sizeof(u_int32_t
) + sizeof(u_int64_t
) +
709 5 * sizeof(u_int32_t
));
711 panic("au_to_process64_ex: invalidate at_type (%d)",
715 ADD_U_CHAR(dptr
, AUT_PROCESS64_EX
);
716 ADD_U_INT32(dptr
, auid
);
717 ADD_U_INT32(dptr
, euid
);
718 ADD_U_INT32(dptr
, egid
);
719 ADD_U_INT32(dptr
, ruid
);
720 ADD_U_INT32(dptr
, rgid
);
721 ADD_U_INT32(dptr
, pid
);
722 ADD_U_INT32(dptr
, sid
);
723 ADD_U_INT64(dptr
, tid
->at_port
);
724 ADD_U_INT32(dptr
, tid
->at_type
);
725 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_t
));
726 if (tid
->at_type
== AU_IPv6
) {
727 ADD_MEM(dptr
, &tid
->at_addr
[1], sizeof(u_int32_t
));
728 ADD_MEM(dptr
, &tid
->at_addr
[2], sizeof(u_int32_t
));
729 ADD_MEM(dptr
, &tid
->at_addr
[3], sizeof(u_int32_t
));
736 au_to_process_ex(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
,
737 gid_t rgid
, pid_t pid
, au_asid_t sid
, au_tid_addr_t
*tid
)
739 return au_to_process32_ex(auid
, euid
, egid
, ruid
, rgid
, pid
, sid
,
745 * error status 1 byte
746 * return value 4 bytes/8 bytes (32-bit/64-bit value)
749 au_to_return32(char status
, u_int32_t ret
)
754 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int32_t
));
756 ADD_U_CHAR(dptr
, AUT_RETURN32
);
757 ADD_U_CHAR(dptr
, status
);
758 ADD_U_INT32(dptr
, ret
);
764 au_to_return64(char status
, u_int64_t ret
)
769 GET_TOKEN_AREA(t
, dptr
, 2 * sizeof(u_char
) + sizeof(u_int64_t
));
771 ADD_U_CHAR(dptr
, AUT_RETURN64
);
772 ADD_U_CHAR(dptr
, status
);
773 ADD_U_INT64(dptr
, ret
);
779 au_to_return(char status
, u_int32_t ret
)
781 return au_to_return32(status
, ret
);
786 * sequence number 4 bytes
789 au_to_seq(long audit_count
)
794 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
));
796 ADD_U_CHAR(dptr
, AUT_SEQ
);
797 ADD_U_INT32(dptr
, (u_int32_t
) audit_count
);
804 * socket domain 2 bytes
805 * socket type 2 bytes
806 * address type 2 bytes
808 * local address 4 bytes/16 bytes (IPv4/IPv6 address)
809 * remote port 2 bytes
810 * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
813 au_to_socket_ex(u_short so_domain
, u_short so_type
,
814 struct sockaddr
*sa_local
, struct sockaddr
*sa_remote
)
818 struct sockaddr_in
*sin
;
819 struct sockaddr_in6
*sin6
;
821 if (so_domain
== AF_INET
) {
822 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) +
823 5 * sizeof(u_int16_t
) + 2 * sizeof(u_int32_t
));
824 } else if (so_domain
== AF_INET6
) {
825 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) +
826 5 * sizeof(u_int16_t
) + 8 * sizeof(u_int32_t
));
831 ADD_U_CHAR(dptr
, AUT_SOCKET_EX
);
832 ADD_U_INT16(dptr
, au_domain_to_bsm(so_domain
));
833 ADD_U_INT16(dptr
, au_socket_type_to_bsm(so_type
));
834 if (so_domain
== AF_INET
) {
835 ADD_U_INT16(dptr
, AU_IPv4
);
836 sin
= (struct sockaddr_in
*)sa_local
;
837 ADD_MEM(dptr
, &sin
->sin_port
, sizeof(uint16_t));
838 ADD_MEM(dptr
, &sin
->sin_addr
.s_addr
, sizeof(uint32_t));
839 sin
= (struct sockaddr_in
*)sa_remote
;
840 ADD_MEM(dptr
, &sin
->sin_port
, sizeof(uint16_t));
841 ADD_MEM(dptr
, &sin
->sin_addr
.s_addr
, sizeof(uint32_t));
842 } else { /* if (so_domain == AF_INET6) */
843 ADD_U_INT16(dptr
, AU_IPv6
);
844 sin6
= (struct sockaddr_in6
*)sa_local
;
845 ADD_MEM(dptr
, &sin6
->sin6_port
, sizeof(uint16_t));
846 ADD_MEM(dptr
, &sin6
->sin6_addr
, 4 * sizeof(uint32_t));
847 sin6
= (struct sockaddr_in6
*)sa_remote
;
848 ADD_MEM(dptr
, &sin6
->sin6_port
, sizeof(uint16_t));
849 ADD_MEM(dptr
, &sin6
->sin6_addr
, 4 * sizeof(uint32_t));
857 * socket family 2 bytes
858 * path (up to) 104 bytes + NULL
861 au_to_sock_unix(struct sockaddr_un
*so
)
868 * Please note that sun_len may not be correctly set and sun_path may
869 * not be NULL terminated.
871 if (so
->sun_len
>= offsetof(struct sockaddr_un
, sun_path
)) {
872 slen
= min(so
->sun_len
- offsetof(struct sockaddr_un
, sun_path
),
873 strnlen(so
->sun_path
, sizeof(so
->sun_path
)));
875 slen
= strnlen(so
->sun_path
, sizeof(so
->sun_path
));
878 GET_TOKEN_AREA(t
, dptr
, 3 * sizeof(u_char
) + slen
+ 1);
880 ADD_U_CHAR(dptr
, AUT_SOCKUNIX
);
881 /* BSM token has two bytes for family */
883 ADD_U_CHAR(dptr
, so
->sun_family
);
885 ADD_MEM(dptr
, so
->sun_path
, slen
);
887 ADD_U_CHAR(dptr
, '\0'); /* make the path a null-terminated string */
894 * socket family 2 bytes
896 * socket address 4 bytes
899 au_to_sock_inet32(struct sockaddr_in
*so
)
904 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(uint16_t) +
907 ADD_U_CHAR(dptr
, AUT_SOCKINET32
);
909 * Convert sin_family to the BSM value. Assume that both the port and
910 * the address in the sockaddr_in are already in network byte order,
911 * but family is in local byte order.
913 ADD_U_INT16(dptr
, au_domain_to_bsm(so
->sin_family
));
914 ADD_MEM(dptr
, &so
->sin_port
, sizeof(uint16_t));
915 ADD_MEM(dptr
, &so
->sin_addr
.s_addr
, sizeof(uint32_t));
922 * socket family 2 bytes
924 * socket address 16 bytes
927 au_to_sock_inet128(struct sockaddr_in6
*so
)
932 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 2 * sizeof(u_int16_t
) +
933 4 * sizeof(u_int32_t
));
935 ADD_U_CHAR(dptr
, AUT_SOCKINET128
);
936 ADD_U_INT16(dptr
, au_domain_to_bsm(so
->sin6_family
));
938 ADD_U_INT16(dptr
, so
->sin6_port
);
939 ADD_MEM(dptr
, &so
->sin6_addr
, 4 * sizeof(uint32_t));
945 au_to_sock_inet(struct sockaddr_in
*so
)
947 return au_to_sock_inet32(so
);
953 * effective user ID 4 bytes
954 * effective group ID 4 bytes
955 * real user ID 4 bytes
956 * real group ID 4 bytes
960 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
961 * machine address 4 bytes
964 au_to_subject32(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
, gid_t rgid
,
965 pid_t pid
, au_asid_t sid
, au_tid_t
*tid
)
970 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 9 * sizeof(u_int32_t
));
972 ADD_U_CHAR(dptr
, AUT_SUBJECT32
);
973 ADD_U_INT32(dptr
, auid
);
974 ADD_U_INT32(dptr
, euid
);
975 ADD_U_INT32(dptr
, egid
);
976 ADD_U_INT32(dptr
, ruid
);
977 ADD_U_INT32(dptr
, rgid
);
978 ADD_U_INT32(dptr
, pid
);
979 ADD_U_INT32(dptr
, sid
);
980 ADD_U_INT32(dptr
, tid
->port
);
981 ADD_MEM(dptr
, &tid
->machine
, sizeof(u_int32_t
));
987 au_to_subject64(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
, gid_t rgid
,
988 pid_t pid
, au_asid_t sid
, au_tid_t
*tid
)
993 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 7 * sizeof(u_int32_t
) +
994 sizeof(u_int64_t
) + sizeof(u_int32_t
));
996 ADD_U_CHAR(dptr
, AUT_SUBJECT64
);
997 ADD_U_INT32(dptr
, auid
);
998 ADD_U_INT32(dptr
, euid
);
999 ADD_U_INT32(dptr
, egid
);
1000 ADD_U_INT32(dptr
, ruid
);
1001 ADD_U_INT32(dptr
, rgid
);
1002 ADD_U_INT32(dptr
, pid
);
1003 ADD_U_INT32(dptr
, sid
);
1004 ADD_U_INT64(dptr
, tid
->port
);
1005 ADD_MEM(dptr
, &tid
->machine
, sizeof(u_int32_t
));
1011 au_to_subject(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
, gid_t rgid
,
1012 pid_t pid
, au_asid_t sid
, au_tid_t
*tid
)
1014 return au_to_subject32(auid
, euid
, egid
, ruid
, rgid
, pid
, sid
,
1021 * effective user ID 4 bytes
1022 * effective group ID 4 bytes
1023 * real user ID 4 bytes
1024 * real group ID 4 bytes
1025 * process ID 4 bytes
1026 * session ID 4 bytes
1028 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1029 * address type/length 4 bytes
1030 * machine address 4/16 bytes
1033 au_to_subject32_ex(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
,
1034 gid_t rgid
, pid_t pid
, au_asid_t sid
, au_tid_addr_t
*tid
)
1037 u_char
*dptr
= NULL
;
1039 KASSERT((tid
->at_type
== AU_IPv4
) || (tid
->at_type
== AU_IPv6
),
1040 ("au_to_subject32_ex: type %u", (unsigned int)tid
->at_type
));
1041 if (tid
->at_type
== AU_IPv6
) {
1042 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 13 *
1045 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + 10 *
1049 ADD_U_CHAR(dptr
, AUT_SUBJECT32_EX
);
1050 ADD_U_INT32(dptr
, auid
);
1051 ADD_U_INT32(dptr
, euid
);
1052 ADD_U_INT32(dptr
, egid
);
1053 ADD_U_INT32(dptr
, ruid
);
1054 ADD_U_INT32(dptr
, rgid
);
1055 ADD_U_INT32(dptr
, pid
);
1056 ADD_U_INT32(dptr
, sid
);
1057 ADD_U_INT32(dptr
, tid
->at_port
);
1058 ADD_U_INT32(dptr
, tid
->at_type
);
1059 if (tid
->at_type
== AU_IPv6
) {
1060 ADD_MEM(dptr
, &tid
->at_addr
[0], 4 * sizeof(u_int32_t
));
1062 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_t
));
1069 au_to_subject64_ex(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
,
1070 gid_t rgid
, pid_t pid
, au_asid_t sid
, au_tid_addr_t
*tid
)
1073 u_char
*dptr
= NULL
;
1075 if (tid
->at_type
== AU_IPv4
) {
1076 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) +
1077 7 * sizeof(u_int32_t
) + sizeof(u_int64_t
) +
1078 2 * sizeof(u_int32_t
));
1079 } else if (tid
->at_type
== AU_IPv6
) {
1080 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) +
1081 7 * sizeof(u_int32_t
) + sizeof(u_int64_t
) +
1082 5 * sizeof(u_int32_t
));
1084 panic("au_to_subject64_ex: invalid at_type (%d)",
1088 ADD_U_CHAR(dptr
, AUT_SUBJECT64_EX
);
1089 ADD_U_INT32(dptr
, auid
);
1090 ADD_U_INT32(dptr
, euid
);
1091 ADD_U_INT32(dptr
, egid
);
1092 ADD_U_INT32(dptr
, ruid
);
1093 ADD_U_INT32(dptr
, rgid
);
1094 ADD_U_INT32(dptr
, pid
);
1095 ADD_U_INT32(dptr
, sid
);
1096 ADD_U_INT64(dptr
, tid
->at_port
);
1097 ADD_U_INT32(dptr
, tid
->at_type
);
1098 if (tid
->at_type
== AU_IPv6
) {
1099 ADD_MEM(dptr
, &tid
->at_addr
[0], 4 * sizeof(u_int32_t
));
1101 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_t
));
1108 au_to_subject_ex(au_id_t auid
, uid_t euid
, gid_t egid
, uid_t ruid
,
1109 gid_t rgid
, pid_t pid
, au_asid_t sid
, au_tid_addr_t
*tid
)
1111 return au_to_subject32_ex(auid
, euid
, egid
, ruid
, rgid
, pid
, sid
,
1115 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1117 * Collects audit information for the current process
1118 * and creates a subject token from it
1125 if (getaudit(&auinfo
) != 0) {
1129 return au_to_subject32(auinfo
.ai_auid
, geteuid(), getegid(),
1130 getuid(), getgid(), getpid(), auinfo
.ai_asid
, &auinfo
.ai_termid
);
1134 #if defined(_KERNEL) || defined(KERNEL)
1136 au_to_exec_strings(const char *strs
, int count
, u_char type
)
1139 u_char
*dptr
= NULL
;
1148 totlen
+= strlen(p
) + 1;
1151 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) + totlen
);
1152 ADD_U_CHAR(dptr
, type
);
1153 ADD_U_INT32(dptr
, count
);
1154 ADD_STRING(dptr
, strs
, totlen
);
1162 * text count null-terminated strings
1165 au_to_exec_args(char *args
, int argc
)
1167 return au_to_exec_strings(args
, argc
, AUT_EXEC_ARGS
);
1173 * text count null-terminated strings
1176 au_to_exec_env(char *envs
, int envc
)
1178 return au_to_exec_strings(envs
, envc
, AUT_EXEC_ENV
);
1184 * text count null-terminated strings
1187 au_to_certificate_hash(char *hashes
, int hashc
)
1189 return au_to_exec_strings(hashes
, hashc
, AUT_CERT_HASH
);
1195 * text count null-terminated strings
1198 au_to_krb5_principal(char *principals
, int princ
)
1200 return au_to_exec_strings(principals
, princ
, AUT_KRB5_PRINCIPAL
);
1206 * text count null-terminated strings
1209 au_to_exec_args(char **argv
)
1212 u_char
*dptr
= NULL
;
1213 const char *nextarg
;
1219 while (nextarg
!= NULL
) {
1222 nextlen
= strlen(nextarg
);
1223 totlen
+= nextlen
+ 1;
1225 nextarg
= *(argv
+ count
);
1228 totlen
+= count
* sizeof(char); /* nul terminations. */
1229 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) + totlen
);
1231 ADD_U_CHAR(dptr
, AUT_EXEC_ARGS
);
1232 ADD_U_INT32(dptr
, count
);
1234 for (i
= 0; i
< count
; i
++) {
1235 nextarg
= *(argv
+ i
);
1236 ADD_MEM(dptr
, nextarg
, strlen(nextarg
) + 1);
1244 * zonename length 2 bytes
1245 * zonename N bytes + 1 terminating NULL byte
1248 au_to_zonename(char *zonename
)
1250 u_char
*dptr
= NULL
;
1254 textlen
= strlen(zonename
);
1256 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) + textlen
);
1257 ADD_U_CHAR(dptr
, AUT_ZONENAME
);
1258 ADD_U_INT16(dptr
, textlen
);
1259 ADD_STRING(dptr
, zonename
, textlen
);
1266 * text count null-terminated strings
1269 au_to_exec_env(char **envp
)
1272 u_char
*dptr
= NULL
;
1275 const char *nextenv
;
1279 while (nextenv
!= NULL
) {
1282 nextlen
= strlen(nextenv
);
1283 totlen
+= nextlen
+ 1;
1285 nextenv
= *(envp
+ count
);
1288 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) + totlen
);
1290 ADD_U_CHAR(dptr
, AUT_EXEC_ENV
);
1291 ADD_U_INT32(dptr
, count
);
1293 for (i
= 0; i
< count
; i
++) {
1294 nextenv
= *(envp
+ i
);
1295 ADD_MEM(dptr
, nextenv
, strlen(nextenv
) + 1);
1300 #endif /* !(defined(_KERNEL) || defined(KERNEL)) */
1304 * signer type 4 bytes
1305 * signer id length 2 bytes
1307 * signer id truncated 1 byte
1308 * team id length 2 bytes
1310 * team id truncated 1 byte
1311 * cdhash length 2 bytes
1315 au_to_identity(uint32_t signer_type
, const char* signing_id
,
1316 u_char signing_id_trunc
, const char* team_id
, u_char team_id_trunc
,
1317 uint8_t* cdhash
, uint16_t cdhash_len
)
1320 u_char
*dptr
= NULL
;
1321 size_t signing_id_len
= 0;
1322 size_t team_id_len
= 0;
1326 signing_id_len
= strlen(signing_id
);
1330 team_id_len
= strlen(team_id
);
1334 sizeof(u_char
) + // token id
1335 sizeof(uint32_t) + // signer type
1336 sizeof(uint16_t) + // singing id length
1337 signing_id_len
+ // length of signing id to copy
1338 sizeof(u_char
) + // null terminator for signing id
1339 sizeof(u_char
) + // if signing id truncated
1340 sizeof(uint16_t) + // team id length
1341 team_id_len
+ // length of team id to copy
1342 sizeof(u_char
) + // null terminator for team id
1343 sizeof(u_char
) + // if team id truncated
1344 sizeof(uint16_t) + // cdhash length
1345 cdhash_len
; // cdhash buffer
1347 GET_TOKEN_AREA(t
, dptr
, totlen
);
1349 ADD_U_CHAR(dptr
, AUT_IDENTITY
); // token id
1350 ADD_U_INT32(dptr
, signer_type
); // signer type
1351 ADD_U_INT16(dptr
, signing_id_len
+ 1); // signing id length+null
1352 ADD_STRING(dptr
, signing_id
, signing_id_len
); // truncated signing id
1353 ADD_U_CHAR(dptr
, 0); // null terminator byte
1354 ADD_U_CHAR(dptr
, signing_id_trunc
); // if signing id is trunc
1355 ADD_U_INT16(dptr
, team_id_len
+ 1); // team id length+null
1356 ADD_STRING(dptr
, team_id
, team_id_len
); // truncated team id
1357 ADD_U_CHAR(dptr
, 0); // null terminator byte
1358 ADD_U_CHAR(dptr
, team_id_trunc
); // if team id is trunc
1359 ADD_U_INT16(dptr
, cdhash_len
); // cdhash length
1360 ADD_MEM(dptr
, cdhash
, cdhash_len
); // cdhash
1367 * record byte count 4 bytes
1369 * event type 2 bytes
1370 * event modifier 2 bytes
1371 * address type/length 4 bytes
1372 * machine address 4 bytes/16 bytes (IPv4/IPv6 address)
1373 * seconds of time 4 bytes/8 bytes (32/64-bits)
1374 * milliseconds of time 4 bytes/8 bytes (32/64-bits)
1377 au_to_header32_ex_tm(int rec_size
, au_event_t e_type
, au_emod_t e_mod
,
1378 struct timeval tm
, struct auditinfo_addr
*aia
)
1381 u_char
*dptr
= NULL
;
1383 struct au_tid_addr
*tid
;
1385 tid
= &aia
->ai_termid
;
1386 KASSERT(tid
->at_type
== AU_IPv4
|| tid
->at_type
== AU_IPv6
,
1387 ("au_to_header32_ex_tm: invalid address family"));
1389 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) +
1390 sizeof(u_char
) + 2 * sizeof(u_int16_t
) + 3 * sizeof(u_int32_t
) +
1393 ADD_U_CHAR(dptr
, AUT_HEADER32_EX
);
1394 ADD_U_INT32(dptr
, rec_size
);
1395 ADD_U_CHAR(dptr
, AUDIT_HEADER_VERSION_OPENBSM
);
1396 ADD_U_INT16(dptr
, e_type
);
1397 ADD_U_INT16(dptr
, e_mod
);
1398 ADD_U_INT32(dptr
, tid
->at_type
);
1399 if (tid
->at_type
== AU_IPv6
) {
1400 ADD_MEM(dptr
, &tid
->at_addr
[0], 4 * sizeof(u_int32_t
));
1402 ADD_MEM(dptr
, &tid
->at_addr
[0], sizeof(u_int32_t
));
1404 timems
= tm
.tv_usec
/ 1000;
1405 /* Add the timestamp */
1406 ADD_U_INT32(dptr
, tm
.tv_sec
);
1407 ADD_U_INT32(dptr
, timems
); /* We need time in ms. */
1413 * record byte count 4 bytes
1414 * version # 1 byte [2]
1415 * event type 2 bytes
1416 * event modifier 2 bytes
1417 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1418 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1421 au_to_header32_tm(int rec_size
, au_event_t e_type
, au_emod_t e_mod
,
1425 u_char
*dptr
= NULL
;
1428 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) +
1429 sizeof(u_char
) + 2 * sizeof(u_int16_t
) + 2 * sizeof(u_int32_t
));
1431 ADD_U_CHAR(dptr
, AUT_HEADER32
);
1432 ADD_U_INT32(dptr
, rec_size
);
1433 ADD_U_CHAR(dptr
, AUDIT_HEADER_VERSION_OPENBSM
);
1434 ADD_U_INT16(dptr
, e_type
);
1435 ADD_U_INT16(dptr
, e_mod
);
1437 timems
= tm
.tv_usec
/ 1000;
1438 /* Add the timestamp */
1439 ADD_U_INT32(dptr
, tm
.tv_sec
);
1440 ADD_U_INT32(dptr
, timems
); /* We need time in ms. */
1446 au_to_header64_tm(int rec_size
, au_event_t e_type
, au_emod_t e_mod
,
1450 u_char
*dptr
= NULL
;
1453 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int32_t
) +
1454 sizeof(u_char
) + 2 * sizeof(u_int16_t
) + 2 * sizeof(u_int64_t
));
1456 ADD_U_CHAR(dptr
, AUT_HEADER64
);
1457 ADD_U_INT32(dptr
, rec_size
);
1458 ADD_U_CHAR(dptr
, AUDIT_HEADER_VERSION_OPENBSM
);
1459 ADD_U_INT16(dptr
, e_type
);
1460 ADD_U_INT16(dptr
, e_mod
);
1462 timems
= tm
.tv_usec
/ 1000;
1463 /* Add the timestamp */
1464 ADD_U_INT64(dptr
, tm
.tv_sec
);
1465 ADD_U_INT64(dptr
, timems
); /* We need time in ms. */
1472 * trailer magic number 2 bytes
1473 * record byte count 4 bytes
1476 au_to_trailer(int rec_size
)
1479 u_char
*dptr
= NULL
;
1480 u_int16_t magic
= AUT_TRAILER_MAGIC
;
1482 GET_TOKEN_AREA(t
, dptr
, sizeof(u_char
) + sizeof(u_int16_t
) +
1485 ADD_U_CHAR(dptr
, AUT_TRAILER
);
1486 ADD_U_INT16(dptr
, magic
);
1487 ADD_U_INT32(dptr
, rec_size
);
1491 #endif /* CONFIG_AUDIT */