2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/types.h>
24 #include <sys/vnode.h>
27 #include <sys/socketvar.h>
28 #include <sys/socket.h>
29 #include <sys/queue.h>
30 #include <sys/fcntl.h>
33 #include <bsm/audit.h>
34 #include <bsm/audit_record.h>
35 #include <bsm/audit_kernel.h>
36 #include <bsm/audit_kevents.h>
37 #include <bsm/audit_klib.h>
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
41 #include <netinet/ip.h>
43 #include <kern/lock.h>
45 /* The number of BSM records allocated. */
46 static int bsm_rec_count
= 0;
49 * Records that can be recycled are maintained in the list given below
50 * The maximum number of elements that can be present in this list is
51 * bounded by MAX_AUDIT_RECORDS. Memory allocated for these records are never
54 LIST_HEAD(, au_record
) bsm_free_q
;
57 * Lock for serializing access to the list of audit records.
59 static mutex_t
*bsm_audit_mutex
;
62 * Initialize the BSM auditing subsystem.
67 printf("BSM auditing present\n");
68 LIST_INIT(&bsm_free_q
);
69 bsm_audit_mutex
= mutex_alloc(ETAP_NO_TRACE
);
74 * This call reserves memory for the audit record.
75 * Memory must be guaranteed before any auditable event can be
77 * The au_record structure maintains a reference to the
78 * memory allocated above and also the list of tokens associated
84 struct au_record
*rec
= NULL
;
87 * Find an unused record, remove it from the free list, mark as used
89 mutex_lock(bsm_audit_mutex
);
90 if (!LIST_EMPTY(&bsm_free_q
)) {
91 rec
= LIST_FIRST(&bsm_free_q
);
92 LIST_REMOVE(rec
, au_rec_q
);
94 mutex_unlock(bsm_audit_mutex
);
97 mutex_lock(bsm_audit_mutex
);
98 if (bsm_rec_count
>= MAX_AUDIT_RECORDS
) {
99 /* XXX We need to increase size of MAX_AUDIT_RECORDS */
100 mutex_unlock(bsm_audit_mutex
);
103 mutex_unlock(bsm_audit_mutex
);
106 * Create a new BSM kernel record.
108 rec
= (struct au_record
*)kalloc(sizeof(*rec
));
112 rec
->data
= (u_char
*)kalloc(MAX_AUDIT_RECORD_SIZE
* sizeof(u_char
));
113 if((rec
->data
) == NULL
) {
114 kfree((vm_offset_t
)rec
, (vm_size_t
)sizeof(*rec
));
117 mutex_lock(bsm_audit_mutex
);
119 mutex_unlock(bsm_audit_mutex
);
121 memset(rec
->data
, 0, MAX_AUDIT_RECORD_SIZE
);
123 TAILQ_INIT(&rec
->token_q
);
131 * Store the token with the record descriptor
134 int kau_write(struct au_record
*rec
, struct au_token
*tok
)
137 return -1; /* Invalid Token */
140 /* Add the token to the tail */
142 * XXX Not locking here -- we should not be writing to
143 * XXX the same audit record from different threads
145 TAILQ_INSERT_TAIL(&rec
->token_q
, tok
, tokens
);
147 rec
->len
+= tok
->len
; /* grow record length by token size bytes */
153 * Close out the audit record by adding the header token, identifying
154 * any missing tokens. Write out the tokens to the record memory.
156 int kau_close(struct au_record
*rec
, struct timespec
*ctime
, short event
)
160 token_t
*cur
, *hdr
, *trail
;
163 tot_rec_size
= rec
->len
+ HEADER_SIZE
+ TRAILER_SIZE
;
164 if(tot_rec_size
<= MAX_AUDIT_RECORD_SIZE
) {
165 /* Create the header token */
166 hdr
= kau_to_header32(ctime
, tot_rec_size
, event
, 0);
169 /* Add to head of list */
170 TAILQ_INSERT_HEAD(&rec
->token_q
, hdr
, tokens
);
172 trail
= au_to_trailer(tot_rec_size
);
174 TAILQ_INSERT_TAIL(&rec
->token_q
, trail
, tokens
);
177 /* Serialize token data to the record */
179 rec
->len
= tot_rec_size
;
181 TAILQ_FOREACH(cur
, &rec
->token_q
, tokens
) {
182 memcpy(dptr
, cur
->t_data
, cur
->len
);
189 * Free a BSM audit record by releasing all the tokens and clearing the
190 * audit record information.
192 void kau_free(struct au_record
*rec
)
194 struct au_token
*tok
;
196 /* Free the token list */
197 while ((tok
= TAILQ_FIRST(&rec
->token_q
))) {
198 TAILQ_REMOVE(&rec
->token_q
, tok
, tokens
);
199 kfree((vm_offset_t
)tok
, sizeof(*tok
) + tok
->len
);
205 mutex_lock(bsm_audit_mutex
);
207 /* Add the record to the freelist */
208 LIST_INSERT_HEAD(&bsm_free_q
, rec
, au_rec_q
);
210 mutex_unlock(bsm_audit_mutex
);
215 * XXX May want turn some (or all) of these macros into functions in order
216 * to reduce the generated code sized.
218 #define UPATH1_TOKENS \
220 if (ar->ar_valid_arg & ARG_UPATH1) { \
221 tok = au_to_path(ar->ar_arg_upath1); \
222 kau_write(rec, tok); \
226 #define UPATH2_TOKENS \
228 if (ar->ar_valid_arg & ARG_UPATH2) { \
229 tok = au_to_path(ar->ar_arg_upath2); \
230 kau_write(rec, tok); \
234 #define UPATH1_KPATH1_VNODE1_TOKENS \
236 if (ar->ar_valid_arg & ARG_UPATH1) { \
237 tok = au_to_path(ar->ar_arg_upath1); \
238 kau_write(rec, tok); \
240 if (ar->ar_valid_arg & ARG_KPATH1) { \
241 tok = au_to_path(ar->ar_arg_kpath1); \
242 kau_write(rec, tok); \
244 if (ar->ar_valid_arg & ARG_VNODE1) { \
245 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
246 kau_write(rec, tok); \
250 #define KPATH1_VNODE1_TOKENS \
252 if (ar->ar_valid_arg & ARG_KPATH1) { \
253 tok = au_to_path(ar->ar_arg_kpath1); \
254 kau_write(rec, tok); \
256 if (ar->ar_valid_arg & ARG_VNODE1) { \
257 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
258 kau_write(rec, tok); \
262 #define KPATH2_VNODE2_TOKENS \
264 if (ar->ar_valid_arg & ARG_KPATH2) { \
265 tok = au_to_path(ar->ar_arg_kpath2); \
266 kau_write(rec, tok); \
268 if (ar->ar_valid_arg & ARG_VNODE2) { \
269 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
270 kau_write(rec, tok); \
274 #define FD_KPATH1_VNODE1_TOKENS \
276 if (ar->ar_valid_arg & ARG_KPATH1) { \
277 tok = au_to_path(ar->ar_arg_kpath1); \
278 kau_write(rec, tok); \
279 if (ar->ar_valid_arg & ARG_VNODE1) { \
280 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
281 kau_write(rec, tok); \
284 tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \
285 kau_write(rec, tok); \
289 #define PROCESS_PID_TOKENS(argn) \
291 if ((ar->ar_arg_pid > 0) /* Kill a single process */ \
292 && (ar->ar_valid_arg & ARG_PROCESS)) { \
293 tok = au_to_process(ar->ar_arg_auid, ar->ar_arg_euid, \
294 ar->ar_arg_egid, ar->ar_arg_ruid, \
295 ar->ar_arg_rgid, ar->ar_arg_pid, \
296 ar->ar_arg_asid, &ar->ar_arg_termid); \
297 kau_write(rec, tok); \
299 tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\
300 kau_write(rec, tok); \
305 * Implement auditing for the auditon() system call. The audit tokens
306 * that are generated depend on the command that was sent into the
307 * auditon() system call.
311 audit_sys_auditon(struct audit_record
*ar
, struct au_record
*rec
)
313 struct au_token
*tok
;
315 switch (ar
->ar_arg_cmd
) {
317 if (sizeof(ar
->ar_arg_auditon
.au_flags
) > 4)
318 tok
= au_to_arg64(1, "policy",
319 ar
->ar_arg_auditon
.au_flags
);
321 tok
= au_to_arg32(1, "policy",
322 ar
->ar_arg_auditon
.au_flags
);
326 tok
= au_to_arg32(2, "setkmask:as_success",
327 ar
->ar_arg_auditon
.au_mask
.am_success
);
329 tok
= au_to_arg32(2, "setkmask:as_failure",
330 ar
->ar_arg_auditon
.au_mask
.am_failure
);
334 tok
= au_to_arg32(3, "setqctrl:aq_hiwater",
335 ar
->ar_arg_auditon
.au_qctrl
.aq_hiwater
);
337 tok
= au_to_arg32(3, "setqctrl:aq_lowater",
338 ar
->ar_arg_auditon
.au_qctrl
.aq_lowater
);
340 tok
= au_to_arg32(3, "setqctrl:aq_bufsz",
341 ar
->ar_arg_auditon
.au_qctrl
.aq_bufsz
);
343 tok
= au_to_arg32(3, "setqctrl:aq_delay",
344 ar
->ar_arg_auditon
.au_qctrl
.aq_delay
);
346 tok
= au_to_arg32(3, "setqctrl:aq_minfree",
347 ar
->ar_arg_auditon
.au_qctrl
.aq_minfree
);
351 tok
= au_to_arg32(3, "setumask:as_success",
352 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_success
);
354 tok
= au_to_arg32(3, "setumask:as_failure",
355 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_failure
);
359 tok
= au_to_arg32(3, "setsmask:as_success",
360 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_success
);
362 tok
= au_to_arg32(3, "setsmask:as_failure",
363 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_failure
);
367 if (sizeof(ar
->ar_arg_auditon
.au_cond
) > 4)
368 tok
= au_to_arg64(3, "setcond",
369 ar
->ar_arg_auditon
.au_cond
);
371 tok
= au_to_arg32(3, "setcond",
372 ar
->ar_arg_auditon
.au_cond
);
376 tok
= au_to_arg32(2, "setclass:ec_event",
377 ar
->ar_arg_auditon
.au_evclass
.ec_number
);
379 tok
= au_to_arg32(3, "setclass:ec_class",
380 ar
->ar_arg_auditon
.au_evclass
.ec_class
);
384 tok
= au_to_arg32(2, "setpmask:as_success",
385 ar
->ar_arg_auditon
.au_aupinfo
.ap_mask
.am_success
);
387 tok
= au_to_arg32(2, "setpmask:as_failure",
388 ar
->ar_arg_auditon
.au_aupinfo
.ap_mask
.am_failure
);
392 tok
= au_to_arg32(2, "setfsize:filesize",
393 ar
->ar_arg_auditon
.au_fstat
.af_filesz
);
402 * Convert an internal kernel audit record to a BSM record and return
403 * a success/failure indicator. The BSM record is passed as an out
404 * parameter to this function.
406 * BSM_SUCCESS: The BSM record is valid
407 * BSM_FAILURE: Failure; the BSM record is NULL.
408 * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
411 kaudit_to_bsm(struct kaudit_record
*kar
, struct au_record
**pau
)
413 struct au_token
*tok
, *subj_tok
;
414 struct au_record
*rec
;
416 struct audit_record
*ar
;
421 return (BSM_FAILURE
);
427 return (BSM_FAILURE
);
429 /* Create the subject token */
430 tid
.port
= ar
->ar_subj_term
.port
;
431 tid
.machine
= ar
->ar_subj_term
.machine
;
432 subj_tok
= au_to_subject32(ar
->ar_subj_auid
, /* audit ID */
433 ar
->ar_subj_cred
.cr_uid
, /* eff uid */
434 ar
->ar_subj_egid
, /* eff group id */
435 ar
->ar_subj_ruid
, /* real uid */
436 ar
->ar_subj_rgid
, /* real group id */
437 ar
->ar_subj_pid
, /* process id */
438 ar
->ar_subj_asid
, /* session ID */
441 /* The logic inside each case fills in the tokens required for the
442 * event, except for the header, trailer, and return tokens. The
443 * header and trailer tokens are added by the kau_close() function.
444 * The return token is added outside of the switch statement.
446 switch(ar
->ar_event
) {
449 * Socket-related events.
458 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
460 if (ar
->ar_valid_arg
& ARG_SADDRINET
) {
461 tok
= au_to_sock_inet(
462 (struct sockaddr_in
*)&ar
->ar_arg_sockaddr
);
465 if (ar
->ar_valid_arg
& ARG_SADDRUNIX
) {
466 tok
= au_to_sock_unix(
467 (struct sockaddr_un
*)&ar
->ar_arg_sockaddr
);
471 /* XXX Need to handle ARG_SADDRINET6 */
476 tok
= au_to_arg32(1,"domain", ar
->ar_arg_sockinfo
.so_domain
);
478 tok
= au_to_arg32(2,"type", ar
->ar_arg_sockinfo
.so_type
);
480 tok
= au_to_arg32(3,"protocol",ar
->ar_arg_sockinfo
.so_protocol
);
486 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
491 if (ar
->ar_valid_arg
& (ARG_KPATH1
| ARG_UPATH1
)) {
492 UPATH1_KPATH1_VNODE1_TOKENS
;
494 tok
= au_to_arg32(1, "accounting off", 0);
500 tok
= au_to_arg32(2, "setauid", ar
->ar_arg_auid
);
505 if (ar
->ar_valid_arg
& ARG_AUID
) {
506 tok
= au_to_arg32(1, "setaudit:auid", ar
->ar_arg_auid
);
508 tok
= au_to_arg32(1, "setaudit:port",
509 ar
->ar_arg_termid
.port
);
511 tok
= au_to_arg32(1, "setaudit:machine",
512 ar
->ar_arg_termid
.machine
);
514 tok
= au_to_arg32(1, "setaudit:as_success",
515 ar
->ar_arg_amask
.am_success
);
517 tok
= au_to_arg32(1, "setaudit:as_failure",
518 ar
->ar_arg_amask
.am_failure
);
520 tok
= au_to_arg32(1, "setaudit:asid", ar
->ar_arg_asid
);
525 case AUE_SETAUDIT_ADDR
:
526 break; /* XXX need to add arguments */
529 /* For AUDITON commands without own event, audit the cmd */
530 tok
= au_to_arg32(1, "cmd", ar
->ar_arg_cmd
);
534 case AUE_AUDITON_GETCAR
:
535 case AUE_AUDITON_GETCLASS
:
536 case AUE_AUDITON_GETCOND
:
537 case AUE_AUDITON_GETCWD
:
538 case AUE_AUDITON_GETKMASK
:
539 case AUE_AUDITON_GETSTAT
:
540 case AUE_AUDITON_GPOLICY
:
541 case AUE_AUDITON_GQCTRL
:
542 case AUE_AUDITON_SETCLASS
:
543 case AUE_AUDITON_SETCOND
:
544 case AUE_AUDITON_SETKMASK
:
545 case AUE_AUDITON_SETSMASK
:
546 case AUE_AUDITON_SETSTAT
:
547 case AUE_AUDITON_SETUMASK
:
548 case AUE_AUDITON_SPOLICY
:
549 case AUE_AUDITON_SQCTRL
:
550 if (ar
->ar_valid_arg
& ARG_AUDITON
) {
551 audit_sys_auditon(ar
, rec
);
556 UPATH1_KPATH1_VNODE1_TOKENS
;
563 case AUE_GETAUDIT_ADDR
:
570 case AUE_SETTIMEOFDAY
:
571 case AUE_NEWSYSTEMSHREG
:
572 /* Header, subject, and return tokens added at end */
579 case AUE_GETATTRLIST
:
588 case AUE_SETATTRLIST
:
595 UPATH1_KPATH1_VNODE1_TOKENS
;
599 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
601 UPATH1_KPATH1_VNODE1_TOKENS
;
605 tok
= au_to_arg32(2, "new file mode", ar
->ar_arg_mode
);
607 UPATH1_KPATH1_VNODE1_TOKENS
;
611 tok
= au_to_arg32(2, "new file uid", ar
->ar_arg_uid
);
613 tok
= au_to_arg32(3, "new file gid", ar
->ar_arg_gid
);
615 UPATH1_KPATH1_VNODE1_TOKENS
;
618 case AUE_EXCHANGEDATA
:
619 UPATH1_KPATH1_VNODE1_TOKENS
;
620 KPATH2_VNODE2_TOKENS
;
624 tok
= au_to_arg32(2, "fd", ar
->ar_arg_fd
);
626 UPATH1_KPATH1_VNODE1_TOKENS
;
630 tok
= au_to_arg32(2, "new file mode", ar
->ar_arg_mode
);
632 FD_KPATH1_VNODE1_TOKENS
;
636 tok
= au_to_arg32(1, "request", ar
->ar_arg_cmd
);
638 if (ar
->ar_valid_arg
& (ARG_KPATH1
| ARG_UPATH1
)) {
639 UPATH1_KPATH1_VNODE1_TOKENS
;
645 case AUE_FSTAT
: /* XXX Need to handle sockets and shm */
649 case AUE_GETDIRENTRIES
:
650 case AUE_GETDIRENTRIESATTR
:
651 FD_KPATH1_VNODE1_TOKENS
;
655 tok
= au_to_arg32(2, "new file uid", ar
->ar_arg_uid
);
657 tok
= au_to_arg32(3, "new file gid", ar
->ar_arg_gid
);
659 FD_KPATH1_VNODE1_TOKENS
;
663 tok
= au_to_arg32(2, "cmd", ar
->ar_arg_cmd
);
665 if (ar
->ar_valid_arg
& ARG_VNODE1
) {
666 FD_KPATH1_VNODE1_TOKENS
;
671 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
673 FD_KPATH1_VNODE1_TOKENS
;
677 tok
= au_to_arg32(2, "operation", ar
->ar_arg_cmd
);
679 FD_KPATH1_VNODE1_TOKENS
;
684 tok
= au_to_arg32(0, "child PID", ar
->ar_arg_pid
);
689 tok
= au_to_arg32(2, "cmd", ar
->ar_arg_cmd
);
691 tok
= au_to_arg32(1, "arg", (u_int32_t
)ar
->ar_arg_addr
);
693 if (ar
->ar_valid_arg
& ARG_VNODE1
) {
694 FD_KPATH1_VNODE1_TOKENS
;
696 if (ar
->ar_valid_arg
& ARG_SOCKINFO
) {
697 tok
= kau_to_socket(&ar
->ar_arg_sockinfo
);
700 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
707 tok
= au_to_arg32(2, "signal", ar
->ar_arg_signum
);
709 PROCESS_PID_TOKENS(1);
713 tok
= au_to_arg32(2, "ops", ar
->ar_arg_cmd
);
715 tok
= au_to_arg32(3, "trpoints", ar
->ar_arg_value
);
717 PROCESS_PID_TOKENS(4);
718 UPATH1_KPATH1_VNODE1_TOKENS
;
723 UPATH1_KPATH1_VNODE1_TOKENS
;
728 tok
= au_to_arg32(4, "base addr", (u_int32_t
)ar
->ar_arg_addr
);
730 UPATH1_KPATH1_VNODE1_TOKENS
;
734 tok
= au_to_arg32(2, "mode", ar
->ar_arg_mode
);
736 UPATH1_KPATH1_VNODE1_TOKENS
;
740 tok
= au_to_arg32(2, "mode", ar
->ar_arg_mode
);
742 tok
= au_to_arg32(3, "dev", ar
->ar_arg_dev
);
744 UPATH1_KPATH1_VNODE1_TOKENS
;
753 tok
= au_to_arg32(1, "addr", (u_int32_t
)ar
->ar_arg_addr
);
755 tok
= au_to_arg32(2, "len", ar
->ar_arg_len
);
757 if (ar
->ar_event
== AUE_MMAP
)
758 FD_KPATH1_VNODE1_TOKENS
;
759 if (ar
->ar_event
== AUE_MPROTECT
) {
760 tok
= au_to_arg32(3, "protection", ar
->ar_arg_value
);
763 if (ar
->ar_event
== AUE_MINHERIT
) {
764 tok
= au_to_arg32(3, "inherit", ar
->ar_arg_value
);
770 /* XXX Need to handle NFS mounts */
771 tok
= au_to_arg32(3, "flags", ar
->ar_arg_fflags
);
773 if (ar
->ar_valid_arg
& ARG_TEXT
) {
774 tok
= au_to_text(ar
->ar_arg_text
);
779 UPATH1_KPATH1_VNODE1_TOKENS
;
783 ar
->ar_event
= msgctl_to_event(ar
->ar_arg_svipc_cmd
);
787 tok
= au_to_arg32(1, "msg ID", ar
->ar_arg_svipc_id
);
789 if (ar
->ar_errno
!= EINVAL
) {
790 tok
= au_to_ipc(AT_IPC_MSG
, ar
->ar_arg_svipc_id
);
796 if (ar
->ar_errno
== 0) {
797 tok
= au_to_ipc(AT_IPC_MSG
, ar
->ar_arg_svipc_id
);
802 case AUE_RESETSHFILE
:
803 tok
= au_to_arg32(1, "base addr", (u_int32_t
)ar
->ar_arg_addr
);
813 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
823 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
825 UPATH1_KPATH1_VNODE1_TOKENS
;
829 tok
= au_to_arg32(1, "request", ar
->ar_arg_cmd
);
831 tok
= au_to_arg32(3, "addr", (u_int32_t
)ar
->ar_arg_addr
);
833 tok
= au_to_arg32(4, "data", ar
->ar_arg_value
);
835 PROCESS_PID_TOKENS(2);
839 tok
= au_to_arg32(2, "command", ar
->ar_arg_cmd
);
841 tok
= au_to_arg32(3, "uid", ar
->ar_arg_uid
);
843 UPATH1_KPATH1_VNODE1_TOKENS
;
847 tok
= au_to_arg32(1, "howto", ar
->ar_arg_cmd
);
852 ar
->ar_event
= semctl_to_event(ar
->ar_arg_svipc_cmd
);
855 tok
= au_to_arg32(1, "sem ID", ar
->ar_arg_svipc_id
);
857 if (ar
->ar_errno
!= EINVAL
) {
858 tok
= au_to_ipc(AT_IPC_SEM
, ar
->ar_arg_svipc_id
);
863 if (ar
->ar_errno
== 0) {
864 tok
= au_to_ipc(AT_IPC_SEM
, ar
->ar_arg_svipc_id
);
869 tok
= au_to_arg32(1, "gid", ar
->ar_arg_egid
);
873 tok
= au_to_arg32(1, "uid", ar
->ar_arg_euid
);
877 tok
= au_to_arg32(1, "gid", ar
->ar_arg_gid
);
881 tok
= au_to_arg32(1, "uid", ar
->ar_arg_uid
);
885 if (ar
->ar_valid_arg
& ARG_GROUPSET
) {
886 for(ctr
= 0; ctr
< ar
->ar_arg_groups
.gidset_size
; ctr
++)
888 tok
= au_to_arg32(1, "setgroups", ar
->ar_arg_groups
.gidset
[ctr
]);
895 if (ar
->ar_valid_arg
& ARG_TEXT
) {
896 tok
= au_to_text(ar
->ar_arg_text
);
901 case AUE_SETPRIORITY
:
902 tok
= au_to_arg32(1, "which", ar
->ar_arg_cmd
);
904 tok
= au_to_arg32(2, "who", ar
->ar_arg_uid
);
906 tok
= au_to_arg32(2, "priority", ar
->ar_arg_value
);
910 case AUE_SETPRIVEXEC
:
911 tok
= au_to_arg32(1, "flag", ar
->ar_arg_value
);
915 /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
917 tok
= au_to_arg32(1, "shmid", ar
->ar_arg_svipc_id
);
919 tok
= au_to_arg32(2, "shmaddr", (int)ar
->ar_arg_svipc_addr
);
921 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
922 tok
= au_to_ipc(AT_IPC_SHM
, ar
->ar_arg_svipc_id
);
924 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
930 tok
= au_to_arg32(1, "shmid", ar
->ar_arg_svipc_id
);
932 switch (ar
->ar_arg_svipc_cmd
) {
934 ar
->ar_event
= AUE_SHMCTL_STAT
;
935 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
936 tok
= au_to_ipc(AT_IPC_SHM
,
937 ar
->ar_arg_svipc_id
);
942 ar
->ar_event
= AUE_SHMCTL_RMID
;
943 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
944 tok
= au_to_ipc(AT_IPC_SHM
,
945 ar
->ar_arg_svipc_id
);
950 ar
->ar_event
= AUE_SHMCTL_SET
;
951 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
952 tok
= au_to_ipc(AT_IPC_SHM
,
953 ar
->ar_arg_svipc_id
);
955 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
960 break; /* We will audit a bad command */
965 tok
= au_to_arg32(1, "shmaddr", (int)ar
->ar_arg_svipc_addr
);
970 /* This is unusual; the return value is in an argument token */
971 tok
= au_to_arg32(0, "shmid", ar
->ar_arg_svipc_id
);
973 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
974 tok
= au_to_ipc(AT_IPC_SHM
, ar
->ar_arg_svipc_id
);
976 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
981 /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
982 * and AUE_SEMUNLINK are Posix IPC */
984 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
986 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
989 if (ar
->ar_valid_arg
& ARG_TEXT
) {
990 tok
= au_to_text(ar
->ar_arg_text
);
993 if (ar
->ar_valid_arg
& ARG_POSIX_IPC_PERM
) {
994 /* Create an ipc_perm token */
995 struct ipc_perm perm
;
996 perm
.uid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
997 perm
.gid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
998 perm
.cuid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
999 perm
.cgid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1000 perm
.mode
= ar
->ar_arg_pipc_perm
.pipc_mode
;
1003 tok
= au_to_ipc_perm(&perm
);
1004 kau_write(rec
, tok
);
1009 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
1010 kau_write(rec
, tok
);
1011 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
1012 kau_write(rec
, tok
);
1013 tok
= au_to_arg32(4, "value", ar
->ar_arg_value
);
1014 kau_write(rec
, tok
);
1017 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1018 tok
= au_to_text(ar
->ar_arg_text
);
1019 kau_write(rec
, tok
);
1021 if (ar
->ar_valid_arg
& ARG_POSIX_IPC_PERM
) {
1022 /* Create an ipc_perm token */
1023 struct ipc_perm perm
;
1024 perm
.uid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1025 perm
.gid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1026 perm
.cuid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1027 perm
.cgid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1028 perm
.mode
= ar
->ar_arg_pipc_perm
.pipc_mode
;
1031 tok
= au_to_ipc_perm(&perm
);
1032 kau_write(rec
, tok
);
1037 tok
= au_to_arg32(1, "sem", ar
->ar_arg_fd
);
1038 kau_write(rec
, tok
);
1042 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1043 tok
= au_to_text(ar
->ar_arg_text
);
1044 kau_write(rec
, tok
);
1046 UPATH1_KPATH1_VNODE1_TOKENS
;
1050 if (ar
->ar_valid_arg
& (ARG_CTLNAME
| ARG_LEN
)) {
1051 for (ctr
= 0; ctr
< ar
->ar_arg_len
; ctr
++) {
1052 tok
= au_to_arg32(1, "name", ar
->ar_arg_ctlname
[ctr
]);
1053 kau_write(rec
, tok
);
1056 if (ar
->ar_valid_arg
& ARG_VALUE
) {
1057 tok
= au_to_arg32(5, "newval", ar
->ar_arg_value
);
1058 kau_write(rec
, tok
);
1060 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1061 tok
= au_to_text(ar
->ar_arg_text
);
1062 kau_write(rec
, tok
);
1067 tok
= au_to_arg32(1, "new mask", ar
->ar_arg_mask
);
1068 kau_write(rec
, tok
);
1069 tok
= au_to_arg32(0, "prev mask", ar
->ar_retval
);
1070 kau_write(rec
, tok
);
1073 /************************
1074 * Mach system calls *
1075 ************************/
1076 case AUE_INITPROCESS
:
1079 case AUE_PIDFORTASK
:
1080 tok
= au_to_arg32(1, "port", (u_int32_t
)ar
->ar_arg_mach_port1
);
1081 kau_write(rec
, tok
);
1082 if (ar
->ar_valid_arg
& ARG_PID
) {
1083 tok
= au_to_arg32(2, "pid", (u_int32_t
)ar
->ar_arg_pid
);
1084 kau_write(rec
, tok
);
1088 case AUE_TASKFORPID
:
1089 tok
= au_to_arg32(1, "target port",
1090 (u_int32_t
)ar
->ar_arg_mach_port1
);
1091 kau_write(rec
, tok
);
1092 if (ar
->ar_valid_arg
& ARG_MACHPORT2
) {
1093 tok
= au_to_arg32(3, "task port",
1094 (u_int32_t
)ar
->ar_arg_mach_port2
);
1095 kau_write(rec
, tok
);
1097 PROCESS_PID_TOKENS(2);
1101 tok
= au_to_arg32(4, "priority",
1102 (u_int32_t
)ar
->ar_arg_value
);
1103 kau_write(rec
, tok
);
1104 UPATH1_KPATH1_VNODE1_TOKENS
;
1108 UPATH1_KPATH1_VNODE1_TOKENS
;
1112 tok
= au_to_arg32(3, "va", (u_int32_t
)ar
->ar_arg_addr
);
1113 kau_write(rec
, tok
);
1114 FD_KPATH1_VNODE1_TOKENS
;
1117 default: /* We shouldn't fall through to here. */
1118 printf("BSM conversion requested for unknown event %d\n",
1124 kau_write(rec
, subj_tok
);
1125 tok
= au_to_return32((char)ar
->ar_errno
, ar
->ar_retval
);
1126 kau_write(rec
, tok
); /* Every record gets a return token */
1128 kau_close(rec
, &ar
->ar_endtime
, ar
->ar_event
);
1135 * Verify that a record is a valid BSM record. This verification is
1136 * simple now, but may be expanded on sometime in the future.
1137 * Return 1 if the record is good, 0 otherwise.
1141 bsm_rec_verify(void *rec
)
1143 char c
= *(char *)rec
;
1145 * Check the token ID of the first token; it has to be a header
1148 /* XXXAUDIT There needs to be a token structure to map a token.
1149 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1151 if ( (c
!= AU_HEADER_32_TOKEN
) &&
1152 (c
!= AU_HEADER_EX_32_TOKEN
) &&
1153 (c
!= AU_HEADER_64_TOKEN
) &&
1154 (c
!= AU_HEADER_EX_64_TOKEN
) ) {