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.
33 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#99 $
36 #include <sys/types.h>
38 #include <config/config.h>
43 #ifdef USE_SYS_ENDIAN_H
44 #include <sys/endian.h>
46 #ifdef USE_MACHINE_ENDIAN_H
47 #include <machine/endian.h>
49 #ifdef USE_COMPAT_ENDIAN_H
50 #include <compat/endian.h>
52 #ifdef USE_COMPAT_ENDIAN_ENC_H
53 #include <compat/endian_enc.h>
56 #ifdef HAVE_FULL_QUEUE_H
57 #include <sys/queue.h>
58 #else /* !HAVE_FULL_QUEUE_H */
59 #include <compat/queue.h>
60 #endif /* !HAVE_FULL_QUEUE_H */
62 #include <sys/socket.h>
68 #include <netinet/in.h>
69 #include <netinet/in_systm.h>
70 #include <netinet/ip.h>
78 #include <bsm/audit_internal.h>
79 #include <bsm/libbsm.h>
81 #define GET_TOKEN_AREA(t, dptr, length) do { \
82 (t) = malloc(sizeof(token_t)); \
84 (t)->len = (length); \
85 (dptr) = (t->t_data) = calloc((length), sizeof(u_char)); \
86 if ((dptr) == NULL) { \
92 assert((t) == NULL || (dptr) != NULL); \
97 * success/failure 1 byte
99 * privstr N bytes + 1 (\0 byte)
102 au_to_upriv(char sorf, char *priv)
108 textlen = strlen(priv) + 1;
109 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_char) +
110 sizeof(u_int16_t) + textlen);
113 ADD_U_CHAR(dptr, AUT_UPRIV);
114 ADD_U_CHAR(dptr, sorf);
115 ADD_U_INT16(dptr, textlen);
116 ADD_STRING(dptr, priv, textlen);
122 * privtstrlen 2 bytes
123 * privtstr N bytes + 1
125 * privstr N bytes + 1
128 au_to_privset(char *privtypestr, char *privstr)
130 u_int16_t type_len, priv_len;
134 type_len = strlen(privtypestr) + 1;
135 priv_len = strlen(privstr) + 1;
136 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
137 sizeof(u_int16_t) + type_len + priv_len);
140 ADD_U_CHAR(dptr, AUT_PRIV);
141 ADD_U_INT16(dptr, type_len);
142 ADD_STRING(dptr, privtypestr, type_len);
143 ADD_U_INT16(dptr, priv_len);
144 ADD_STRING(dptr, privstr, priv_len);
151 * argument value 4 bytes/8 bytes (32-bit/64-bit value)
152 * text length 2 bytes
153 * text N bytes + 1 terminating NULL byte
156 au_to_arg32(char n, const char *text, u_int32_t v)
162 textlen = strlen(text);
165 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) +
166 sizeof(u_int16_t) + textlen);
170 ADD_U_CHAR(dptr, AUT_ARG32);
172 ADD_U_INT32(dptr, v);
173 ADD_U_INT16(dptr, textlen);
174 ADD_STRING(dptr, text, textlen);
180 au_to_arg64(char n, const char *text, u_int64_t v)
186 textlen = strlen(text);
189 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) +
190 sizeof(u_int16_t) + textlen);
194 ADD_U_CHAR(dptr, AUT_ARG64);
196 ADD_U_INT64(dptr, v);
197 ADD_U_INT16(dptr, textlen);
198 ADD_STRING(dptr, text, textlen);
204 au_to_arg(char n, const char *text, u_int32_t v)
207 return (au_to_arg32(n, text, v));
210 #if defined(_KERNEL) || defined(KERNEL)
213 * file access mode 4 bytes
214 * owner user ID 4 bytes
215 * owner group ID 4 bytes
216 * file system ID 4 bytes
218 * device 4 bytes/8 bytes (32-bit/64-bit)
221 au_to_attr32(struct vnode_au_info *vni)
225 u_int16_t pad0_16 = 0;
226 u_int32_t pad0_32 = 0;
228 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
229 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t));
233 ADD_U_CHAR(dptr, AUT_ATTR32);
236 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
239 * XXXRW: Possibly should be conditionally compiled.
241 * XXXRW: Should any conversions take place on the mode?
243 ADD_U_INT16(dptr, pad0_16);
244 ADD_U_INT16(dptr, vni->vn_mode);
246 ADD_U_INT32(dptr, vni->vn_uid);
247 ADD_U_INT32(dptr, vni->vn_gid);
248 ADD_U_INT32(dptr, vni->vn_fsid);
251 * Some systems use 32-bit file ID's, others use 64-bit file IDs.
252 * Attempt to handle both, and let the compiler sort it out. If we
253 * could pick this out at compile-time, it would be better, so as to
254 * avoid the else case below.
256 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
257 ADD_U_INT32(dptr, pad0_32);
258 ADD_U_INT32(dptr, vni->vn_fileid);
259 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
260 ADD_U_INT64(dptr, vni->vn_fileid);
262 ADD_U_INT64(dptr, 0LL);
264 ADD_U_INT32(dptr, vni->vn_dev);
270 au_to_attr64(struct vnode_au_info *vni)
274 u_int16_t pad0_16 = 0;
275 u_int32_t pad0_32 = 0;
277 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) +
278 3 * sizeof(u_int32_t) + sizeof(u_int64_t) * 2);
282 ADD_U_CHAR(dptr, AUT_ATTR64);
285 * BSD defines the size for the file mode as 2 bytes; BSM defines 4
288 * XXXRW: Possibly should be conditionally compiled.
290 * XXXRW: Should any conversions take place on the mode?
292 ADD_U_INT16(dptr, pad0_16);
293 ADD_U_INT16(dptr, vni->vn_mode);
295 ADD_U_INT32(dptr, vni->vn_uid);
296 ADD_U_INT32(dptr, vni->vn_gid);
297 ADD_U_INT32(dptr, vni->vn_fsid);
300 * Some systems use 32-bit file ID's, other's use 64-bit file IDs.
301 * Attempt to handle both, and let the compiler sort it out. If we
302 * could pick this out at compile-time, it would be better, so as to
303 * avoid the else case below.
305 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) {
306 ADD_U_INT32(dptr, pad0_32);
307 ADD_U_INT32(dptr, vni->vn_fileid);
308 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t))
309 ADD_U_INT64(dptr, vni->vn_fileid);
311 ADD_U_INT64(dptr, 0LL);
313 ADD_U_INT64(dptr, vni->vn_dev);
319 au_to_attr(struct vnode_au_info *vni)
322 return (au_to_attr32(vni));
324 #endif /* !(defined(_KERNEL) || defined(KERNEL) */
328 * how to print 1 byte
331 * data items (depends on basic unit)
334 au_to_data(char unit_print, char unit_type, char unit_count, const char *p)
338 size_t datasize, totdata;
340 /* Determine the size of the basic unit. */
344 datasize = AUR_BYTE_SIZE;
348 datasize = AUR_SHORT_SIZE;
353 datasize = AUR_INT32_SIZE;
357 datasize = AUR_INT64_SIZE;
365 totdata = datasize * unit_count;
367 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata);
372 * XXXRW: We should be byte-swapping each data item for multi-byte
375 ADD_U_CHAR(dptr, AUT_DATA);
376 ADD_U_CHAR(dptr, unit_print);
377 ADD_U_CHAR(dptr, unit_type);
378 ADD_U_CHAR(dptr, unit_count);
379 ADD_MEM(dptr, p, totdata);
388 * return value 4 bytes
391 au_to_exit(int retval, int err)
396 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t));
400 ADD_U_CHAR(dptr, AUT_EXIT);
401 ADD_U_INT32(dptr, err);
402 ADD_U_INT32(dptr, retval);
410 au_to_groups(int *groups)
413 return (au_to_newgroups(AUDIT_MAX_GROUPS, (gid_t *)groups));
418 * number groups 2 bytes
419 * group list count * 4 bytes
422 au_to_newgroups(u_int16_t n, gid_t *groups)
428 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
429 n * sizeof(u_int32_t));
433 ADD_U_CHAR(dptr, AUT_NEWGROUPS);
434 ADD_U_INT16(dptr, n);
435 for (i = 0; i < n; i++)
436 ADD_U_INT32(dptr, groups[i]);
443 * internet address 4 bytes
446 au_to_in_addr(struct in_addr *internet_addr)
451 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t));
455 ADD_U_CHAR(dptr, AUT_IN_ADDR);
456 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t));
463 * address type/length 4 bytes
467 au_to_in_addr_ex(struct in6_addr *internet_addr)
471 u_int32_t type = AU_IPv6;
473 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t));
477 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX);
478 ADD_U_INT32(dptr, type);
479 ADD_MEM(dptr, internet_addr, 4 * sizeof(uint32_t));
488 * The IP header should be submitted in network byte order.
491 au_to_ip(struct ip *ip)
496 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip));
500 ADD_U_CHAR(dptr, AUT_IP);
501 ADD_MEM(dptr, ip, sizeof(struct ip));
508 * object ID type 1 byte
512 au_to_ipc(char type, int id)
517 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
521 ADD_U_CHAR(dptr, AUT_IPC);
522 ADD_U_CHAR(dptr, type);
523 ADD_U_INT32(dptr, id);
530 * owner user ID 4 bytes
531 * owner group ID 4 bytes
532 * creator user ID 4 bytes
533 * creator group ID 4 bytes
534 * access mode 4 bytes
535 * slot sequence # 4 bytes
539 au_to_ipc_perm(struct ipc_perm *perm)
545 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 12 * sizeof(u_int16_t) +
550 ADD_U_CHAR(dptr, AUT_IPC_PERM);
553 * Systems vary significantly in what types they use in struct
554 * ipc_perm; at least a few still use 16-bit uid's and gid's, so
555 * allow for that, as BSM define 32-bit values here.
556 * Some systems define the sizes for ipc_perm members as 2 bytes;
557 * BSM defines 4 so pad with 0.
559 * XXXRW: Possibly shoulid be conditionally compiled, and more cases
560 * need to be handled.
562 if (sizeof(perm->uid) != sizeof(u_int32_t)) {
563 ADD_U_INT16(dptr, pad0);
564 ADD_U_INT16(dptr, perm->uid);
565 ADD_U_INT16(dptr, pad0);
566 ADD_U_INT16(dptr, perm->gid);
567 ADD_U_INT16(dptr, pad0);
568 ADD_U_INT16(dptr, perm->cuid);
569 ADD_U_INT16(dptr, pad0);
570 ADD_U_INT16(dptr, perm->cgid);
572 ADD_U_INT32(dptr, perm->uid);
573 ADD_U_INT32(dptr, perm->gid);
574 ADD_U_INT32(dptr, perm->cuid);
575 ADD_U_INT32(dptr, perm->cgid);
578 ADD_U_INT16(dptr, pad0);
579 ADD_U_INT16(dptr, perm->mode);
581 ADD_U_INT16(dptr, pad0);
583 #ifdef HAVE_IPC_PERM___SEQ
584 ADD_U_INT16(dptr, perm->__seq);
585 #else /* HAVE_IPC_PERM___SEQ */
586 #ifdef HAVE_IPC_PERM__SEQ
587 ADD_U_INT16(dptr, perm->_seq);
588 #else /* HAVE_IPC_PERM__SEQ */
589 ADD_U_INT16(dptr, perm->seq);
590 #endif /* HAVE_IPC_PERM__SEQ */
591 #endif /* HAVE_IPC_PERM___SEQ */
593 #ifdef HAVE_IPC_PERM___KEY
594 ADD_U_INT32(dptr, perm->__key);
595 #else /* HAVE_IPC_PERM___KEY */
596 #ifdef HAVE_IPC_PERM__KEY
597 ADD_U_INT32(dptr, perm->_key);
598 #else /* HAVE_IPC_PERM__KEY */
599 ADD_U_INT32(dptr, perm->key);
600 #endif /* HAVE_IPC_PERM__KEY */
601 #endif /* HAVE_IPC_PERM___KEY */
608 * port IP address 2 bytes
611 au_to_iport(u_int16_t iport)
616 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t));
620 ADD_U_CHAR(dptr, AUT_IPORT);
621 ADD_U_INT16(dptr, iport);
632 au_to_opaque(const char *data, u_int16_t bytes)
637 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes);
641 ADD_U_CHAR(dptr, AUT_OPAQUE);
642 ADD_U_INT16(dptr, bytes);
643 ADD_MEM(dptr, data, bytes);
650 * seconds of time 4 bytes
651 * milliseconds of time 4 bytes
652 * file name len 2 bytes
653 * file pathname N bytes + 1 terminating NULL byte
656 au_to_file(const char *file, struct timeval tm)
663 filelen = strlen(file);
666 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) +
667 sizeof(u_int16_t) + filelen);
671 timems = tm.tv_usec/1000;
673 ADD_U_CHAR(dptr, AUT_OTHER_FILE32);
674 ADD_U_INT32(dptr, tm.tv_sec);
675 ADD_U_INT32(dptr, timems); /* We need time in ms. */
676 ADD_U_INT16(dptr, filelen);
677 ADD_STRING(dptr, file, filelen);
684 * text length 2 bytes
685 * text N bytes + 1 terminating NULL byte
688 au_to_text(const char *text)
694 textlen = strlen(text);
697 /* XXXRW: Should validate length against token size limit. */
699 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
703 ADD_U_CHAR(dptr, AUT_TEXT);
704 ADD_U_INT16(dptr, textlen);
705 ADD_STRING(dptr, text, textlen);
712 * path length 2 bytes
713 * path N bytes + 1 terminating NULL byte
716 au_to_path(const char *text)
722 textlen = strlen(text);
725 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
729 ADD_U_CHAR(dptr, AUT_PATH);
730 ADD_U_INT16(dptr, textlen);
731 ADD_STRING(dptr, text, textlen);
739 * effective user ID 4 bytes
740 * effective group ID 4 bytes
741 * real user ID 4 bytes
742 * real group ID 4 bytes
746 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
747 * machine address 4 bytes
750 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
751 pid_t pid, au_asid_t sid, au_tid_t *tid)
756 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
760 ADD_U_CHAR(dptr, AUT_PROCESS32);
761 ADD_U_INT32(dptr, auid);
762 ADD_U_INT32(dptr, euid);
763 ADD_U_INT32(dptr, egid);
764 ADD_U_INT32(dptr, ruid);
765 ADD_U_INT32(dptr, rgid);
766 ADD_U_INT32(dptr, pid);
767 ADD_U_INT32(dptr, sid);
768 ADD_U_INT32(dptr, tid->port);
771 * Note: Solaris will write out IPv6 addresses here as a 32-bit
772 * address type and 16 bytes of address, but for IPv4 addresses it
773 * simply writes the 4-byte address directly. We support only IPv4
774 * addresses for process32 tokens.
776 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
782 au_to_process64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
783 pid_t pid, au_asid_t sid, au_tid_t *tid)
788 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 8 * sizeof(u_int32_t) +
793 ADD_U_CHAR(dptr, AUT_PROCESS64);
794 ADD_U_INT32(dptr, auid);
795 ADD_U_INT32(dptr, euid);
796 ADD_U_INT32(dptr, egid);
797 ADD_U_INT32(dptr, ruid);
798 ADD_U_INT32(dptr, rgid);
799 ADD_U_INT32(dptr, pid);
800 ADD_U_INT32(dptr, sid);
801 ADD_U_INT64(dptr, tid->port);
804 * Note: Solaris will write out IPv6 addresses here as a 32-bit
805 * address type and 16 bytes of address, but for IPv4 addresses it
806 * simply writes the 4-byte address directly. We support only IPv4
807 * addresses for process64 tokens.
809 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
815 au_to_process(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
816 pid_t pid, au_asid_t sid, au_tid_t *tid)
819 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid,
826 * effective user ID 4 bytes
827 * effective group ID 4 bytes
828 * real user ID 4 bytes
829 * real group ID 4 bytes
833 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
834 * address type-len 4 bytes
835 * machine address 16 bytes
838 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
839 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
844 if (tid->at_type == AU_IPv4)
845 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
846 10 * sizeof(u_int32_t));
847 else if (tid->at_type == AU_IPv6)
848 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
849 13 * sizeof(u_int32_t));
857 ADD_U_CHAR(dptr, AUT_PROCESS32_EX);
858 ADD_U_INT32(dptr, auid);
859 ADD_U_INT32(dptr, euid);
860 ADD_U_INT32(dptr, egid);
861 ADD_U_INT32(dptr, ruid);
862 ADD_U_INT32(dptr, rgid);
863 ADD_U_INT32(dptr, pid);
864 ADD_U_INT32(dptr, sid);
865 ADD_U_INT32(dptr, tid->at_port);
866 ADD_U_INT32(dptr, tid->at_type);
867 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
868 if (tid->at_type == AU_IPv6) {
869 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
870 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
871 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
878 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
879 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
884 if (tid->at_type == AU_IPv4)
885 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
886 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
887 2 * sizeof(u_int32_t));
888 else if (tid->at_type == AU_IPv6)
889 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
890 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
891 5 * sizeof(u_int32_t));
899 ADD_U_CHAR(dptr, AUT_PROCESS64_EX);
900 ADD_U_INT32(dptr, auid);
901 ADD_U_INT32(dptr, euid);
902 ADD_U_INT32(dptr, egid);
903 ADD_U_INT32(dptr, ruid);
904 ADD_U_INT32(dptr, rgid);
905 ADD_U_INT32(dptr, pid);
906 ADD_U_INT32(dptr, sid);
907 ADD_U_INT64(dptr, tid->at_port);
908 ADD_U_INT32(dptr, tid->at_type);
909 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
910 if (tid->at_type == AU_IPv6) {
911 ADD_MEM(dptr, &tid->at_addr[1], sizeof(u_int32_t));
912 ADD_MEM(dptr, &tid->at_addr[2], sizeof(u_int32_t));
913 ADD_MEM(dptr, &tid->at_addr[3], sizeof(u_int32_t));
920 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
921 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
924 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid,
930 * error status 1 byte
931 * return value 4 bytes/8 bytes (32-bit/64-bit value)
934 au_to_return32(char status, u_int32_t ret)
939 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t));
943 ADD_U_CHAR(dptr, AUT_RETURN32);
944 ADD_U_CHAR(dptr, status);
945 ADD_U_INT32(dptr, ret);
951 au_to_return64(char status, u_int64_t ret)
956 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t));
960 ADD_U_CHAR(dptr, AUT_RETURN64);
961 ADD_U_CHAR(dptr, status);
962 ADD_U_INT64(dptr, ret);
968 au_to_return(char status, u_int32_t ret)
971 return (au_to_return32(status, ret));
976 * sequence number 4 bytes
979 au_to_seq(long audit_count)
984 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t));
988 ADD_U_CHAR(dptr, AUT_SEQ);
989 ADD_U_INT32(dptr, audit_count);
996 * socket domain 2 bytes
997 * socket type 2 bytes
998 * address type 2 byte
1000 * local address 4 bytes/16 bytes (IPv4/IPv6 address)
1001 * remote port 2 bytes
1002 * remote address 4 bytes/16 bytes (IPv4/IPv6 address)
1004 * Domain and type arguments to this routine are assumed to already have been
1005 * converted to the BSM constant space, so we don't do that here.
1008 au_to_socket_ex(u_short so_domain, u_short so_type,
1009 struct sockaddr *sa_local, struct sockaddr *sa_remote)
1012 u_char *dptr = NULL;
1013 struct sockaddr_in *sin;
1014 struct sockaddr_in6 *sin6;
1016 if (so_domain == AF_INET)
1017 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1018 5 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1019 else if (so_domain == AF_INET6)
1020 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1021 5 * sizeof(u_int16_t) + 8 * sizeof(u_int32_t));
1029 ADD_U_CHAR(dptr, AUT_SOCKET_EX);
1030 ADD_U_INT16(dptr, au_domain_to_bsm(so_domain));
1031 ADD_U_INT16(dptr, au_socket_type_to_bsm(so_type));
1032 if (so_domain == AF_INET) {
1033 ADD_U_INT16(dptr, AU_IPv4);
1034 sin = (struct sockaddr_in *)sa_local;
1035 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
1036 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
1037 sin = (struct sockaddr_in *)sa_remote;
1038 ADD_MEM(dptr, &sin->sin_port, sizeof(uint16_t));
1039 ADD_MEM(dptr, &sin->sin_addr.s_addr, sizeof(uint32_t));
1041 ADD_U_INT16(dptr, AU_IPv6);
1042 sin6 = (struct sockaddr_in6 *)sa_local;
1043 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
1044 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
1045 sin6 = (struct sockaddr_in6 *)sa_remote;
1046 ADD_MEM(dptr, &sin6->sin6_port, sizeof(uint16_t));
1047 ADD_MEM(dptr, &sin6->sin6_addr, 4 * sizeof(uint32_t));
1055 * socket family 2 bytes
1056 * path (up to) 104 bytes + NULL (NULL terminated string)
1059 au_to_sock_unix(struct sockaddr_un *so)
1064 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1);
1068 ADD_U_CHAR(dptr, AUT_SOCKUNIX);
1069 /* BSM token has two bytes for family */
1070 ADD_U_CHAR(dptr, 0);
1071 ADD_U_CHAR(dptr, so->sun_family);
1072 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1);
1079 * socket family 2 bytes
1080 * local port 2 bytes
1081 * socket address 4 bytes
1084 au_to_sock_inet32(struct sockaddr_in *so)
1087 u_char *dptr = NULL;
1090 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) +
1095 ADD_U_CHAR(dptr, AUT_SOCKINET32);
1097 * BSM defines the family field as 16 bits, but many operating
1098 * systems have an 8-bit sin_family field. Extend to 16 bits before
1099 * writing into the token. Assume that both the port and the address
1100 * in the sockaddr_in are already in network byte order, but family
1101 * is in local byte order.
1103 * XXXRW: Should a name space conversion be taking place on the value
1106 family = so->sin_family;
1107 ADD_U_INT16(dptr, family);
1108 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t));
1109 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t));
1115 au_to_sock_inet128(struct sockaddr_in6 *so)
1118 u_char *dptr = NULL;
1120 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) +
1121 4 * sizeof(u_int32_t));
1125 ADD_U_CHAR(dptr, AUT_SOCKINET128);
1127 * In BSD, sin6_family is one octet, but BSM defines the token to
1128 * store two. So we copy in a 0 first. XXXRW: Possibly should be
1129 * conditionally compiled.
1131 ADD_U_CHAR(dptr, 0);
1132 ADD_U_CHAR(dptr, so->sin6_family);
1134 ADD_U_INT16(dptr, so->sin6_port);
1135 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t));
1141 au_to_sock_inet(struct sockaddr_in *so)
1144 return (au_to_sock_inet32(so));
1150 * effective user ID 4 bytes
1151 * effective group ID 4 bytes
1152 * real user ID 4 bytes
1153 * real group ID 4 bytes
1154 * process ID 4 bytes
1155 * session ID 4 bytes
1157 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1158 * machine address 4 bytes
1161 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1162 pid_t pid, au_asid_t sid, au_tid_t *tid)
1165 u_char *dptr = NULL;
1167 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t));
1171 ADD_U_CHAR(dptr, AUT_SUBJECT32);
1172 ADD_U_INT32(dptr, auid);
1173 ADD_U_INT32(dptr, euid);
1174 ADD_U_INT32(dptr, egid);
1175 ADD_U_INT32(dptr, ruid);
1176 ADD_U_INT32(dptr, rgid);
1177 ADD_U_INT32(dptr, pid);
1178 ADD_U_INT32(dptr, sid);
1179 ADD_U_INT32(dptr, tid->port);
1180 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1186 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1187 pid_t pid, au_asid_t sid, au_tid_t *tid)
1190 u_char *dptr = NULL;
1192 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 7 * sizeof(u_int32_t) +
1193 sizeof(u_int64_t) + sizeof(u_int32_t));
1197 ADD_U_CHAR(dptr, AUT_SUBJECT64);
1198 ADD_U_INT32(dptr, auid);
1199 ADD_U_INT32(dptr, euid);
1200 ADD_U_INT32(dptr, egid);
1201 ADD_U_INT32(dptr, ruid);
1202 ADD_U_INT32(dptr, rgid);
1203 ADD_U_INT32(dptr, pid);
1204 ADD_U_INT32(dptr, sid);
1205 ADD_U_INT64(dptr, tid->port);
1206 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t));
1212 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid,
1213 pid_t pid, au_asid_t sid, au_tid_t *tid)
1216 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid,
1223 * effective user ID 4 bytes
1224 * effective group ID 4 bytes
1225 * real user ID 4 bytes
1226 * real group ID 4 bytes
1227 * process ID 4 bytes
1228 * session ID 4 bytes
1230 * port ID 4 bytes/8 bytes (32-bit/64-bit value)
1231 * address type/length 4 bytes
1232 * machine address 16 bytes
1235 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1236 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1239 u_char *dptr = NULL;
1241 if (tid->at_type == AU_IPv4)
1242 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 *
1244 else if (tid->at_type == AU_IPv6)
1245 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 *
1254 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX);
1255 ADD_U_INT32(dptr, auid);
1256 ADD_U_INT32(dptr, euid);
1257 ADD_U_INT32(dptr, egid);
1258 ADD_U_INT32(dptr, ruid);
1259 ADD_U_INT32(dptr, rgid);
1260 ADD_U_INT32(dptr, pid);
1261 ADD_U_INT32(dptr, sid);
1262 ADD_U_INT32(dptr, tid->at_port);
1263 ADD_U_INT32(dptr, tid->at_type);
1264 if (tid->at_type == AU_IPv6)
1265 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1267 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1273 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1274 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1277 u_char *dptr = NULL;
1279 if (tid->at_type == AU_IPv4)
1280 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1281 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1282 2 * sizeof(u_int32_t));
1283 else if (tid->at_type == AU_IPv6)
1284 GET_TOKEN_AREA(t, dptr, sizeof(u_char) +
1285 7 * sizeof(u_int32_t) + sizeof(u_int64_t) +
1286 5 * sizeof(u_int32_t));
1294 ADD_U_CHAR(dptr, AUT_SUBJECT64_EX);
1295 ADD_U_INT32(dptr, auid);
1296 ADD_U_INT32(dptr, euid);
1297 ADD_U_INT32(dptr, egid);
1298 ADD_U_INT32(dptr, ruid);
1299 ADD_U_INT32(dptr, rgid);
1300 ADD_U_INT32(dptr, pid);
1301 ADD_U_INT32(dptr, sid);
1302 ADD_U_INT64(dptr, tid->at_port);
1303 ADD_U_INT32(dptr, tid->at_type);
1304 if (tid->at_type == AU_IPv6)
1305 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1307 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1313 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid,
1314 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid)
1317 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid,
1321 #if !defined(_KERNEL) && !defined(KERNEL) && defined(HAVE_AUDIT_SYSCALLS)
1323 * Collects audit information for the current process and creates a subject
1330 auditinfo_addr_t aia;
1333 * Try to use getaudit_addr(2) first. If this kernel does not support
1334 * it, then fall back on to getaudit(2).
1336 if (getaudit_addr(&aia, sizeof(aia)) != 0) {
1337 if (errno == ENOSYS) {
1338 if (getaudit(&auinfo) != 0)
1340 return (au_to_subject32(auinfo.ai_auid, geteuid(),
1341 getegid(), getuid(), getgid(), getpid(),
1342 auinfo.ai_asid, &auinfo.ai_termid));
1344 /* getaudit_addr(2) failed for some other reason. */
1349 return (au_to_subject32_ex(aia.ai_auid, geteuid(), getegid(), getuid(),
1350 getgid(), getpid(), aia.ai_asid, &aia.ai_termid));
1357 * text count null-terminated strings
1360 au_to_exec_args(char **argv)
1363 u_char *dptr = NULL;
1364 const char *nextarg;
1370 while (nextarg != NULL) {
1373 nextlen = strlen(nextarg);
1374 totlen += nextlen + 1;
1376 nextarg = *(argv + count);
1379 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1383 ADD_U_CHAR(dptr, AUT_EXEC_ARGS);
1384 ADD_U_INT32(dptr, count);
1386 for (i = 0; i < count; i++) {
1387 nextarg = *(argv + i);
1388 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1);
1397 * text count null-terminated strings
1400 au_to_exec_env(char **envp)
1403 u_char *dptr = NULL;
1406 const char *nextenv;
1410 while (nextenv != NULL) {
1413 nextlen = strlen(nextenv);
1414 totlen += nextlen + 1;
1416 nextenv = *(envp + count);
1419 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen);
1423 ADD_U_CHAR(dptr, AUT_EXEC_ENV);
1424 ADD_U_INT32(dptr, count);
1426 for (i = 0; i < count; i++) {
1427 nextenv = *(envp + i);
1428 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1);
1436 * zonename length 2 bytes
1437 * zonename N bytes + 1 terminating NULL byte
1440 au_to_zonename(const char *zonename)
1442 u_char *dptr = NULL;
1446 textlen = strlen(zonename) + 1;
1447 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen);
1451 ADD_U_CHAR(dptr, AUT_ZONENAME);
1452 ADD_U_INT16(dptr, textlen);
1453 ADD_STRING(dptr, zonename, textlen);
1459 * record byte count 4 bytes
1460 * version # 1 byte [2]
1461 * event type 2 bytes
1462 * event modifier 2 bytes
1463 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1464 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1467 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1471 u_char *dptr = NULL;
1474 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1475 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t));
1479 ADD_U_CHAR(dptr, AUT_HEADER32);
1480 ADD_U_INT32(dptr, rec_size);
1481 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1482 ADD_U_INT16(dptr, e_type);
1483 ADD_U_INT16(dptr, e_mod);
1485 timems = tm.tv_usec/1000;
1486 /* Add the timestamp */
1487 ADD_U_INT32(dptr, tm.tv_sec);
1488 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1495 * record byte count 4 bytes
1496 * version # 1 byte [2]
1497 * event type 2 bytes
1498 * event modifier 2 bytes
1499 * address type/length 4 bytes
1500 * machine address 4 bytes/16 bytes (IPv4/IPv6 address)
1501 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1502 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value)
1505 au_to_header32_ex_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1506 struct timeval tm, struct auditinfo_addr *aia)
1509 u_char *dptr = NULL;
1513 tid = &aia->ai_termid;
1514 if (tid->at_type != AU_IPv4 && tid->at_type != AU_IPv6)
1516 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1517 sizeof(u_char) + 2 * sizeof(u_int16_t) + 3 *
1518 sizeof(u_int32_t) + tid->at_type);
1522 ADD_U_CHAR(dptr, AUT_HEADER32_EX);
1523 ADD_U_INT32(dptr, rec_size);
1524 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1525 ADD_U_INT16(dptr, e_type);
1526 ADD_U_INT16(dptr, e_mod);
1528 ADD_U_INT32(dptr, tid->at_type);
1529 if (tid->at_type == AU_IPv6)
1530 ADD_MEM(dptr, &tid->at_addr[0], 4 * sizeof(u_int32_t));
1532 ADD_MEM(dptr, &tid->at_addr[0], sizeof(u_int32_t));
1533 timems = tm.tv_usec/1000;
1534 /* Add the timestamp */
1535 ADD_U_INT32(dptr, tm.tv_sec);
1536 ADD_U_INT32(dptr, timems); /* We need time in ms. */
1542 au_to_header64_tm(int rec_size, au_event_t e_type, au_emod_t e_mod,
1546 u_char *dptr = NULL;
1549 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) +
1550 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int64_t));
1554 ADD_U_CHAR(dptr, AUT_HEADER64);
1555 ADD_U_INT32(dptr, rec_size);
1556 ADD_U_CHAR(dptr, AUDIT_HEADER_VERSION_OPENBSM);
1557 ADD_U_INT16(dptr, e_type);
1558 ADD_U_INT16(dptr, e_mod);
1560 timems = tm.tv_usec/1000;
1561 /* Add the timestamp */
1562 ADD_U_INT64(dptr, tm.tv_sec);
1563 ADD_U_INT64(dptr, timems); /* We need time in ms. */
1568 #if !defined(KERNEL) && !defined(_KERNEL)
1569 #ifdef HAVE_AUDIT_SYSCALLS
1571 au_to_header32_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1574 struct auditinfo_addr aia;
1576 if (gettimeofday(&tm, NULL) == -1)
1578 if (audit_get_kaudit(&aia, sizeof(aia)) != 0) {
1579 if (errno != ENOSYS)
1581 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1583 return (au_to_header32_ex_tm(rec_size, e_type, e_mod, tm, &aia));
1585 #endif /* HAVE_AUDIT_SYSCALLS */
1588 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod)
1592 if (gettimeofday(&tm, NULL) == -1)
1594 return (au_to_header32_tm(rec_size, e_type, e_mod, tm));
1598 au_to_header64(__unused int rec_size, __unused au_event_t e_type,
1599 __unused au_emod_t e_mod)
1603 if (gettimeofday(&tm, NULL) == -1)
1605 return (au_to_header64_tm(rec_size, e_type, e_mod, tm));
1609 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod)
1612 return (au_to_header32(rec_size, e_type, e_mod));
1615 #ifdef HAVE_AUDIT_SYSCALLS
1617 au_to_header_ex(int rec_size, au_event_t e_type, au_emod_t e_mod)
1620 return (au_to_header32_ex(rec_size, e_type, e_mod));
1622 #endif /* HAVE_AUDIT_SYSCALLS */
1623 #endif /* !defined(KERNEL) && !defined(_KERNEL) */
1627 * trailer magic number 2 bytes
1628 * record byte count 4 bytes
1631 au_to_trailer(int rec_size)
1634 u_char *dptr = NULL;
1635 u_int16_t magic = AUT_TRAILER_MAGIC;
1637 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) +
1642 ADD_U_CHAR(dptr, AUT_TRAILER);
1643 ADD_U_INT16(dptr, magic);
1644 ADD_U_INT32(dptr, rec_size);