2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
30 #include <sys/types.h>
31 #include <sys/vnode_internal.h>
34 #include <sys/socketvar.h>
35 #include <sys/socket.h>
36 #include <sys/queue.h>
37 #include <sys/fcntl.h>
41 #include <bsm/audit.h>
42 #include <bsm/audit_record.h>
43 #include <bsm/audit_kernel.h>
44 #include <bsm/audit_kevents.h>
45 #include <bsm/audit_klib.h>
47 #include <netinet/in_systm.h>
48 #include <netinet/in.h>
49 #include <netinet/ip.h>
51 #include <kern/lock.h>
52 #include <kern/kalloc.h>
54 /* The number of BSM records allocated. */
55 static int bsm_rec_count
= 0;
58 * Records that can be recycled are maintained in the list given below
59 * The maximum number of elements that can be present in this list is
60 * bounded by MAX_AUDIT_RECORDS. Memory allocated for these records are never
63 LIST_HEAD(, au_record
) bsm_free_q
;
66 * Lock for serializing access to the list of audit records.
68 static mutex_t
*bsm_audit_mutex
;
70 static void audit_sys_auditon(struct audit_record
*ar
, struct au_record
*rec
);
73 * Initialize the BSM auditing subsystem.
78 printf("BSM auditing present\n");
79 LIST_INIT(&bsm_free_q
);
80 bsm_audit_mutex
= mutex_alloc(0);
85 * This call reserves memory for the audit record.
86 * Memory must be guaranteed before any auditable event can be
88 * The au_record structure maintains a reference to the
89 * memory allocated above and also the list of tokens associated
95 struct au_record
*rec
= NULL
;
98 * Find an unused record, remove it from the free list, mark as used
100 mutex_lock(bsm_audit_mutex
);
101 if (!LIST_EMPTY(&bsm_free_q
)) {
102 rec
= LIST_FIRST(&bsm_free_q
);
103 LIST_REMOVE(rec
, au_rec_q
);
105 mutex_unlock(bsm_audit_mutex
);
108 mutex_lock(bsm_audit_mutex
);
109 if (bsm_rec_count
>= MAX_AUDIT_RECORDS
) {
110 /* XXX We need to increase size of MAX_AUDIT_RECORDS */
111 mutex_unlock(bsm_audit_mutex
);
114 mutex_unlock(bsm_audit_mutex
);
117 * Create a new BSM kernel record.
119 rec
= (struct au_record
*)kalloc(sizeof(*rec
));
123 rec
->data
= (u_char
*)kalloc(MAX_AUDIT_RECORD_SIZE
* sizeof(u_char
));
124 if((rec
->data
) == NULL
) {
125 kfree(rec
, sizeof(*rec
));
128 mutex_lock(bsm_audit_mutex
);
130 mutex_unlock(bsm_audit_mutex
);
132 memset(rec
->data
, 0, MAX_AUDIT_RECORD_SIZE
);
134 TAILQ_INIT(&rec
->token_q
);
142 * Store the token with the record descriptor
145 int kau_write(struct au_record
*rec
, struct au_token
*tok
)
148 return -1; /* Invalid Token */
151 /* Add the token to the tail */
153 * XXX Not locking here -- we should not be writing to
154 * XXX the same audit record from different threads
156 TAILQ_INSERT_TAIL(&rec
->token_q
, tok
, tokens
);
158 rec
->len
+= tok
->len
; /* grow record length by token size bytes */
164 * Close out the audit record by adding the header token, identifying
165 * any missing tokens. Write out the tokens to the record memory.
168 kau_close(struct au_record
*rec
, struct timespec
*ctime
, short event
)
172 token_t
*cur
, *hdr
, *trail
;
175 tot_rec_size
= rec
->len
+ HEADER_SIZE
+ TRAILER_SIZE
;
176 if(tot_rec_size
<= MAX_AUDIT_RECORD_SIZE
) {
177 /* Create the header token */
178 hdr
= kau_to_header32(ctime
, tot_rec_size
, event
, 0);
181 /* Add to head of list */
182 TAILQ_INSERT_HEAD(&rec
->token_q
, hdr
, tokens
);
184 trail
= au_to_trailer(tot_rec_size
);
186 TAILQ_INSERT_TAIL(&rec
->token_q
, trail
, tokens
);
189 /* Serialize token data to the record */
191 rec
->len
= tot_rec_size
;
193 TAILQ_FOREACH(cur
, &rec
->token_q
, tokens
) {
194 memcpy(dptr
, cur
->t_data
, cur
->len
);
203 * Free a BSM audit record by releasing all the tokens and clearing the
204 * audit record information.
206 void kau_free(struct au_record
*rec
)
208 struct au_token
*tok
;
210 /* Free the token list */
211 while ((tok
= TAILQ_FIRST(&rec
->token_q
))) {
212 TAILQ_REMOVE(&rec
->token_q
, tok
, tokens
);
213 kfree(tok
, sizeof(*tok
) + tok
->len
);
219 mutex_lock(bsm_audit_mutex
);
221 /* Add the record to the freelist */
222 LIST_INSERT_HEAD(&bsm_free_q
, rec
, au_rec_q
);
224 mutex_unlock(bsm_audit_mutex
);
229 * XXX May want turn some (or all) of these macros into functions in order
230 * to reduce the generated code sized.
232 #define UPATH1_TOKENS \
234 if (ar->ar_valid_arg & ARG_UPATH1) { \
235 tok = au_to_path(ar->ar_arg_upath1); \
236 kau_write(rec, tok); \
240 #define UPATH2_TOKENS \
242 if (ar->ar_valid_arg & ARG_UPATH2) { \
243 tok = au_to_path(ar->ar_arg_upath2); \
244 kau_write(rec, tok); \
248 #define UPATH1_KPATH1_VNODE1_TOKENS \
250 if (ar->ar_valid_arg & ARG_UPATH1) { \
251 tok = au_to_path(ar->ar_arg_upath1); \
252 kau_write(rec, tok); \
254 if (ar->ar_valid_arg & ARG_KPATH1) { \
255 tok = au_to_path(ar->ar_arg_kpath1); \
256 kau_write(rec, tok); \
258 if (ar->ar_valid_arg & ARG_VNODE1) { \
259 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
260 kau_write(rec, tok); \
264 #define KPATH1_VNODE1_TOKENS \
266 if (ar->ar_valid_arg & ARG_KPATH1) { \
267 tok = au_to_path(ar->ar_arg_kpath1); \
268 kau_write(rec, tok); \
270 if (ar->ar_valid_arg & ARG_VNODE1) { \
271 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
272 kau_write(rec, tok); \
276 #define KPATH2_VNODE2_TOKENS \
278 if (ar->ar_valid_arg & ARG_KPATH2) { \
279 tok = au_to_path(ar->ar_arg_kpath2); \
280 kau_write(rec, tok); \
282 if (ar->ar_valid_arg & ARG_VNODE2) { \
283 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
284 kau_write(rec, tok); \
288 #define FD_KPATH1_VNODE1_TOKENS \
290 if (ar->ar_valid_arg & ARG_KPATH1) { \
291 tok = au_to_path(ar->ar_arg_kpath1); \
292 kau_write(rec, tok); \
293 if (ar->ar_valid_arg & ARG_VNODE1) { \
294 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
295 kau_write(rec, tok); \
298 tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \
299 kau_write(rec, tok); \
303 #define PROCESS_PID_TOKENS(argn) \
305 if ((ar->ar_arg_pid > 0) /* Kill a single process */ \
306 && (ar->ar_valid_arg & ARG_PROCESS)) { \
307 tok = au_to_process(ar->ar_arg_auid, ar->ar_arg_euid, \
308 ar->ar_arg_egid, ar->ar_arg_ruid, \
309 ar->ar_arg_rgid, ar->ar_arg_pid, \
310 ar->ar_arg_asid, &ar->ar_arg_termid); \
311 kau_write(rec, tok); \
313 tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\
314 kau_write(rec, tok); \
319 * Implement auditing for the auditon() system call. The audit tokens
320 * that are generated depend on the command that was sent into the
321 * auditon() system call.
325 audit_sys_auditon(struct audit_record
*ar
, struct au_record
*rec
)
327 struct au_token
*tok
;
329 switch (ar
->ar_arg_cmd
) {
331 if (sizeof(ar
->ar_arg_auditon
.au_flags
) > 4)
332 tok
= au_to_arg64(1, "policy",
333 ar
->ar_arg_auditon
.au_flags
);
335 tok
= au_to_arg32(1, "policy",
336 ar
->ar_arg_auditon
.au_flags
);
340 tok
= au_to_arg32(2, "setkmask:as_success",
341 ar
->ar_arg_auditon
.au_mask
.am_success
);
343 tok
= au_to_arg32(2, "setkmask:as_failure",
344 ar
->ar_arg_auditon
.au_mask
.am_failure
);
348 tok
= au_to_arg32(3, "setqctrl:aq_hiwater",
349 ar
->ar_arg_auditon
.au_qctrl
.aq_hiwater
);
351 tok
= au_to_arg32(3, "setqctrl:aq_lowater",
352 ar
->ar_arg_auditon
.au_qctrl
.aq_lowater
);
354 tok
= au_to_arg32(3, "setqctrl:aq_bufsz",
355 ar
->ar_arg_auditon
.au_qctrl
.aq_bufsz
);
357 tok
= au_to_arg32(3, "setqctrl:aq_delay",
358 ar
->ar_arg_auditon
.au_qctrl
.aq_delay
);
360 tok
= au_to_arg32(3, "setqctrl:aq_minfree",
361 ar
->ar_arg_auditon
.au_qctrl
.aq_minfree
);
365 tok
= au_to_arg32(3, "setumask:as_success",
366 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_success
);
368 tok
= au_to_arg32(3, "setumask:as_failure",
369 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_failure
);
373 tok
= au_to_arg32(3, "setsmask:as_success",
374 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_success
);
376 tok
= au_to_arg32(3, "setsmask:as_failure",
377 ar
->ar_arg_auditon
.au_auinfo
.ai_mask
.am_failure
);
381 if (sizeof(ar
->ar_arg_auditon
.au_cond
) > 4)
382 tok
= au_to_arg64(3, "setcond",
383 ar
->ar_arg_auditon
.au_cond
);
385 tok
= au_to_arg32(3, "setcond",
386 ar
->ar_arg_auditon
.au_cond
);
390 tok
= au_to_arg32(2, "setclass:ec_event",
391 ar
->ar_arg_auditon
.au_evclass
.ec_number
);
393 tok
= au_to_arg32(3, "setclass:ec_class",
394 ar
->ar_arg_auditon
.au_evclass
.ec_class
);
398 tok
= au_to_arg32(2, "setpmask:as_success",
399 ar
->ar_arg_auditon
.au_aupinfo
.ap_mask
.am_success
);
401 tok
= au_to_arg32(2, "setpmask:as_failure",
402 ar
->ar_arg_auditon
.au_aupinfo
.ap_mask
.am_failure
);
406 tok
= au_to_arg32(2, "setfsize:filesize",
407 ar
->ar_arg_auditon
.au_fstat
.af_filesz
);
416 * Convert an internal kernel audit record to a BSM record and return
417 * a success/failure indicator. The BSM record is passed as an out
418 * parameter to this function.
420 * BSM_SUCCESS: The BSM record is valid
421 * BSM_FAILURE: Failure; the BSM record is NULL.
422 * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
425 kaudit_to_bsm(struct kaudit_record
*kar
, struct au_record
**pau
)
427 struct au_token
*tok
, *subj_tok
;
428 struct au_record
*rec
;
430 struct audit_record
*ar
;
435 return (BSM_FAILURE
);
441 return (BSM_FAILURE
);
443 /* Create the subject token */
444 tid
.port
= ar
->ar_subj_term
.port
;
445 tid
.machine
= ar
->ar_subj_term
.machine
;
446 subj_tok
= au_to_subject32(ar
->ar_subj_auid
, /* audit ID */
447 ar
->ar_subj_cred
.cr_uid
, /* eff uid */
448 ar
->ar_subj_egid
, /* eff group id */
449 ar
->ar_subj_ruid
, /* real uid */
450 ar
->ar_subj_rgid
, /* real group id */
451 ar
->ar_subj_pid
, /* process id */
452 ar
->ar_subj_asid
, /* session ID */
455 /* The logic inside each case fills in the tokens required for the
456 * event, except for the header, trailer, and return tokens. The
457 * header and trailer tokens are added by the kau_close() function.
458 * The return token is added outside of the switch statement.
460 switch(ar
->ar_event
) {
463 * Socket-related events.
472 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
474 if (ar
->ar_valid_arg
& ARG_SADDRINET
) {
475 tok
= au_to_sock_inet(
476 (struct sockaddr_in
*)&ar
->ar_arg_sockaddr
);
479 if (ar
->ar_valid_arg
& ARG_SADDRUNIX
) {
480 tok
= au_to_sock_unix(
481 (struct sockaddr_un
*)&ar
->ar_arg_sockaddr
);
485 /* XXX Need to handle ARG_SADDRINET6 */
490 tok
= au_to_arg32(1,"domain", ar
->ar_arg_sockinfo
.so_domain
);
492 tok
= au_to_arg32(2,"type", ar
->ar_arg_sockinfo
.so_type
);
494 tok
= au_to_arg32(3,"protocol",ar
->ar_arg_sockinfo
.so_protocol
);
500 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
505 if (ar
->ar_valid_arg
& (ARG_KPATH1
| ARG_UPATH1
)) {
506 UPATH1_KPATH1_VNODE1_TOKENS
;
508 tok
= au_to_arg32(1, "accounting off", 0);
514 tok
= au_to_arg32(2, "setauid", ar
->ar_arg_auid
);
519 if (ar
->ar_valid_arg
& ARG_AUID
) {
520 tok
= au_to_arg32(1, "setaudit:auid", ar
->ar_arg_auid
);
522 tok
= au_to_arg32(1, "setaudit:port",
523 ar
->ar_arg_termid
.port
);
525 tok
= au_to_arg32(1, "setaudit:machine",
526 ar
->ar_arg_termid
.machine
);
528 tok
= au_to_arg32(1, "setaudit:as_success",
529 ar
->ar_arg_amask
.am_success
);
531 tok
= au_to_arg32(1, "setaudit:as_failure",
532 ar
->ar_arg_amask
.am_failure
);
534 tok
= au_to_arg32(1, "setaudit:asid", ar
->ar_arg_asid
);
539 case AUE_SETAUDIT_ADDR
:
540 break; /* XXX need to add arguments */
543 /* For AUDITON commands without own event, audit the cmd */
544 tok
= au_to_arg32(1, "cmd", ar
->ar_arg_cmd
);
548 case AUE_AUDITON_GETCAR
:
549 case AUE_AUDITON_GETCLASS
:
550 case AUE_AUDITON_GETCOND
:
551 case AUE_AUDITON_GETCWD
:
552 case AUE_AUDITON_GETKMASK
:
553 case AUE_AUDITON_GETSTAT
:
554 case AUE_AUDITON_GPOLICY
:
555 case AUE_AUDITON_GQCTRL
:
556 case AUE_AUDITON_SETCLASS
:
557 case AUE_AUDITON_SETCOND
:
558 case AUE_AUDITON_SETKMASK
:
559 case AUE_AUDITON_SETSMASK
:
560 case AUE_AUDITON_SETSTAT
:
561 case AUE_AUDITON_SETUMASK
:
562 case AUE_AUDITON_SPOLICY
:
563 case AUE_AUDITON_SQCTRL
:
564 if (ar
->ar_valid_arg
& ARG_AUDITON
) {
565 audit_sys_auditon(ar
, rec
);
570 UPATH1_KPATH1_VNODE1_TOKENS
;
577 case AUE_GETAUDIT_ADDR
:
584 case AUE_SETTIMEOFDAY
:
585 case AUE_NEWSYSTEMSHREG
:
586 /* Header, subject, and return tokens added at end */
593 case AUE_GETATTRLIST
:
602 case AUE_SETATTRLIST
:
609 UPATH1_KPATH1_VNODE1_TOKENS
;
613 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
615 UPATH1_KPATH1_VNODE1_TOKENS
;
619 tok
= au_to_arg32(2, "new file mode", ar
->ar_arg_mode
);
621 UPATH1_KPATH1_VNODE1_TOKENS
;
626 tok
= au_to_arg32(2, "new file uid", ar
->ar_arg_uid
);
628 tok
= au_to_arg32(3, "new file gid", ar
->ar_arg_gid
);
630 UPATH1_KPATH1_VNODE1_TOKENS
;
633 case AUE_EXCHANGEDATA
:
634 UPATH1_KPATH1_VNODE1_TOKENS
;
635 KPATH2_VNODE2_TOKENS
;
639 tok
= au_to_arg32(2, "fd", ar
->ar_arg_fd
);
641 UPATH1_KPATH1_VNODE1_TOKENS
;
645 tok
= au_to_arg32(2, "new file mode", ar
->ar_arg_mode
);
647 FD_KPATH1_VNODE1_TOKENS
;
651 tok
= au_to_arg32(1, "request", ar
->ar_arg_cmd
);
653 if (ar
->ar_valid_arg
& (ARG_KPATH1
| ARG_UPATH1
)) {
654 UPATH1_KPATH1_VNODE1_TOKENS
;
660 case AUE_FSTAT
: /* XXX Need to handle sockets and shm */
664 case AUE_GETDIRENTRIES
:
665 case AUE_GETDIRENTRIESATTR
:
666 FD_KPATH1_VNODE1_TOKENS
;
670 tok
= au_to_arg32(2, "new file uid", ar
->ar_arg_uid
);
672 tok
= au_to_arg32(3, "new file gid", ar
->ar_arg_gid
);
674 FD_KPATH1_VNODE1_TOKENS
;
678 tok
= au_to_arg32(2, "cmd", ar
->ar_arg_cmd
);
680 if (ar
->ar_valid_arg
& ARG_VNODE1
) {
681 FD_KPATH1_VNODE1_TOKENS
;
686 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
688 FD_KPATH1_VNODE1_TOKENS
;
692 tok
= au_to_arg32(2, "operation", ar
->ar_arg_cmd
);
694 FD_KPATH1_VNODE1_TOKENS
;
699 tok
= au_to_arg32(0, "child PID", ar
->ar_arg_pid
);
704 tok
= au_to_arg32(2, "cmd", ar
->ar_arg_cmd
);
706 tok
= au_to_arg32(1, "arg", (u_int32_t
)ar
->ar_arg_addr
);
708 if (ar
->ar_valid_arg
& ARG_VNODE1
) {
709 FD_KPATH1_VNODE1_TOKENS
;
711 if (ar
->ar_valid_arg
& ARG_SOCKINFO
) {
712 tok
= kau_to_socket(&ar
->ar_arg_sockinfo
);
715 tok
= au_to_arg32(1, "fd", ar
->ar_arg_fd
);
722 tok
= au_to_arg32(2, "signal", ar
->ar_arg_signum
);
724 PROCESS_PID_TOKENS(1);
728 tok
= au_to_arg32(2, "ops", ar
->ar_arg_cmd
);
730 tok
= au_to_arg32(3, "trpoints", ar
->ar_arg_value
);
732 PROCESS_PID_TOKENS(4);
733 UPATH1_KPATH1_VNODE1_TOKENS
;
738 UPATH1_KPATH1_VNODE1_TOKENS
;
743 tok
= au_to_arg32(4, "base addr", (u_int32_t
)ar
->ar_arg_addr
);
745 UPATH1_KPATH1_VNODE1_TOKENS
;
749 tok
= au_to_arg32(2, "mode", ar
->ar_arg_mode
);
751 UPATH1_KPATH1_VNODE1_TOKENS
;
755 tok
= au_to_arg32(2, "mode", ar
->ar_arg_mode
);
757 tok
= au_to_arg32(3, "dev", ar
->ar_arg_dev
);
759 UPATH1_KPATH1_VNODE1_TOKENS
;
768 tok
= au_to_arg32(1, "addr", (u_int32_t
)ar
->ar_arg_addr
); /* LP64todo */
770 tok
= au_to_arg32(2, "len", ar
->ar_arg_len
); /* LP64todo */
772 if (ar
->ar_event
== AUE_MMAP
)
773 FD_KPATH1_VNODE1_TOKENS
;
774 if (ar
->ar_event
== AUE_MPROTECT
) {
775 tok
= au_to_arg32(3, "protection", ar
->ar_arg_value
);
778 if (ar
->ar_event
== AUE_MINHERIT
) {
779 tok
= au_to_arg32(3, "inherit", ar
->ar_arg_value
);
785 /* XXX Need to handle NFS mounts */
786 tok
= au_to_arg32(3, "flags", ar
->ar_arg_fflags
);
788 if (ar
->ar_valid_arg
& ARG_TEXT
) {
789 tok
= au_to_text(ar
->ar_arg_text
);
794 UPATH1_KPATH1_VNODE1_TOKENS
;
798 ar
->ar_event
= msgctl_to_event(ar
->ar_arg_svipc_cmd
);
802 tok
= au_to_arg32(1, "msg ID", ar
->ar_arg_svipc_id
);
804 if (ar
->ar_errno
!= EINVAL
) {
805 tok
= au_to_ipc(AT_IPC_MSG
, ar
->ar_arg_svipc_id
);
811 if (ar
->ar_errno
== 0) {
812 tok
= au_to_ipc(AT_IPC_MSG
, ar
->ar_arg_svipc_id
);
817 case AUE_RESETSHFILE
:
818 tok
= au_to_arg32(1, "base addr", (u_int32_t
)ar
->ar_arg_addr
);
828 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
839 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
841 UPATH1_KPATH1_VNODE1_TOKENS
;
845 tok
= au_to_arg32(1, "request", ar
->ar_arg_cmd
);
847 tok
= au_to_arg32(3, "addr", (u_int32_t
)ar
->ar_arg_addr
); /* LP64todo */
849 tok
= au_to_arg32(4, "data", ar
->ar_arg_value
);
851 PROCESS_PID_TOKENS(2);
855 tok
= au_to_arg32(2, "command", ar
->ar_arg_cmd
);
857 tok
= au_to_arg32(3, "uid", ar
->ar_arg_uid
);
859 UPATH1_KPATH1_VNODE1_TOKENS
;
863 tok
= au_to_arg32(1, "howto", ar
->ar_arg_cmd
);
868 ar
->ar_event
= semctl_to_event(ar
->ar_arg_svipc_cmd
);
871 tok
= au_to_arg32(1, "sem ID", ar
->ar_arg_svipc_id
);
873 if (ar
->ar_errno
!= EINVAL
) {
874 tok
= au_to_ipc(AT_IPC_SEM
, ar
->ar_arg_svipc_id
);
879 if (ar
->ar_errno
== 0) {
880 tok
= au_to_ipc(AT_IPC_SEM
, ar
->ar_arg_svipc_id
);
885 tok
= au_to_arg32(1, "gid", ar
->ar_arg_egid
);
889 tok
= au_to_arg32(1, "uid", ar
->ar_arg_euid
);
893 tok
= au_to_arg32(1, "gid", ar
->ar_arg_gid
);
897 tok
= au_to_arg32(1, "uid", ar
->ar_arg_uid
);
901 if (ar
->ar_valid_arg
& ARG_GROUPSET
) {
902 for(ctr
= 0; ctr
< ar
->ar_arg_groups
.gidset_size
; ctr
++)
904 tok
= au_to_arg32(1, "setgroups", ar
->ar_arg_groups
.gidset
[ctr
]);
911 if (ar
->ar_valid_arg
& ARG_TEXT
) {
912 tok
= au_to_text(ar
->ar_arg_text
);
917 case AUE_SETPRIORITY
:
918 tok
= au_to_arg32(1, "which", ar
->ar_arg_cmd
);
920 tok
= au_to_arg32(2, "who", ar
->ar_arg_uid
);
922 tok
= au_to_arg32(2, "priority", ar
->ar_arg_value
);
926 case AUE_SETPRIVEXEC
:
927 tok
= au_to_arg32(1, "flag", ar
->ar_arg_value
);
931 /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
933 tok
= au_to_arg32(1, "shmid", ar
->ar_arg_svipc_id
);
935 tok
= au_to_arg32(2, "shmaddr", (int)ar
->ar_arg_svipc_addr
);
937 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
938 tok
= au_to_ipc(AT_IPC_SHM
, ar
->ar_arg_svipc_id
);
940 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
946 tok
= au_to_arg32(1, "shmid", ar
->ar_arg_svipc_id
);
948 switch (ar
->ar_arg_svipc_cmd
) {
950 ar
->ar_event
= AUE_SHMCTL_STAT
;
951 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
952 tok
= au_to_ipc(AT_IPC_SHM
,
953 ar
->ar_arg_svipc_id
);
958 ar
->ar_event
= AUE_SHMCTL_RMID
;
959 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
960 tok
= au_to_ipc(AT_IPC_SHM
,
961 ar
->ar_arg_svipc_id
);
966 ar
->ar_event
= AUE_SHMCTL_SET
;
967 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
968 tok
= au_to_ipc(AT_IPC_SHM
,
969 ar
->ar_arg_svipc_id
);
971 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
976 break; /* We will audit a bad command */
981 tok
= au_to_arg32(1, "shmaddr", (int)ar
->ar_arg_svipc_addr
);
986 /* This is unusual; the return value is in an argument token */
987 tok
= au_to_arg32(0, "shmid", ar
->ar_arg_svipc_id
);
989 if (ar
->ar_valid_arg
& ARG_SVIPC_PERM
) {
990 tok
= au_to_ipc(AT_IPC_SHM
, ar
->ar_arg_svipc_id
);
992 tok
= au_to_ipc_perm(&ar
->ar_arg_svipc_perm
);
997 /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
998 * and AUE_SEMUNLINK are Posix IPC */
1000 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
1001 kau_write(rec
, tok
);
1002 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
1003 kau_write(rec
, tok
);
1005 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1006 tok
= au_to_text(ar
->ar_arg_text
);
1007 kau_write(rec
, tok
);
1009 if (ar
->ar_valid_arg
& ARG_POSIX_IPC_PERM
) {
1010 /* Create an ipc_perm token */
1011 struct ipc_perm perm
;
1012 perm
.uid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1013 perm
.gid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1014 perm
.cuid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1015 perm
.cgid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1016 perm
.mode
= ar
->ar_arg_pipc_perm
.pipc_mode
;
1019 tok
= au_to_ipc_perm(&perm
);
1020 kau_write(rec
, tok
);
1025 tok
= au_to_arg32(2, "flags", ar
->ar_arg_fflags
);
1026 kau_write(rec
, tok
);
1027 tok
= au_to_arg32(3, "mode", ar
->ar_arg_mode
);
1028 kau_write(rec
, tok
);
1029 tok
= au_to_arg32(4, "value", ar
->ar_arg_value
);
1030 kau_write(rec
, tok
);
1033 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1034 tok
= au_to_text(ar
->ar_arg_text
);
1035 kau_write(rec
, tok
);
1037 if (ar
->ar_valid_arg
& ARG_POSIX_IPC_PERM
) {
1038 /* Create an ipc_perm token */
1039 struct ipc_perm perm
;
1040 perm
.uid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1041 perm
.gid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1042 perm
.cuid
= ar
->ar_arg_pipc_perm
.pipc_uid
;
1043 perm
.cgid
= ar
->ar_arg_pipc_perm
.pipc_gid
;
1044 perm
.mode
= ar
->ar_arg_pipc_perm
.pipc_mode
;
1047 tok
= au_to_ipc_perm(&perm
);
1048 kau_write(rec
, tok
);
1053 tok
= au_to_arg32(1, "sem", ar
->ar_arg_fd
);
1054 kau_write(rec
, tok
);
1058 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1059 tok
= au_to_text(ar
->ar_arg_text
);
1060 kau_write(rec
, tok
);
1062 UPATH1_KPATH1_VNODE1_TOKENS
;
1066 case AUE_SYSCTL_NONADMIN
:
1067 if (ar
->ar_valid_arg
& (ARG_CTLNAME
| ARG_LEN
)) {
1068 for (ctr
= 0; ctr
< ar
->ar_arg_len
; ctr
++) {
1069 tok
= au_to_arg32(1, "name", ar
->ar_arg_ctlname
[ctr
]);
1070 kau_write(rec
, tok
);
1073 if (ar
->ar_valid_arg
& ARG_VALUE
) {
1074 tok
= au_to_arg32(5, "newval", ar
->ar_arg_value
);
1075 kau_write(rec
, tok
);
1077 if (ar
->ar_valid_arg
& ARG_TEXT
) {
1078 tok
= au_to_text(ar
->ar_arg_text
);
1079 kau_write(rec
, tok
);
1084 tok
= au_to_arg32(1, "new mask", ar
->ar_arg_mask
);
1085 kau_write(rec
, tok
);
1086 tok
= au_to_arg32(0, "prev mask", ar
->ar_retval
);
1087 kau_write(rec
, tok
);
1090 /************************
1091 * Mach system calls *
1092 ************************/
1093 case AUE_INITPROCESS
:
1096 case AUE_PIDFORTASK
:
1097 tok
= au_to_arg32(1, "port", (u_int32_t
)ar
->ar_arg_mach_port1
);
1098 kau_write(rec
, tok
);
1099 if (ar
->ar_valid_arg
& ARG_PID
) {
1100 tok
= au_to_arg32(2, "pid", (u_int32_t
)ar
->ar_arg_pid
);
1101 kau_write(rec
, tok
);
1105 case AUE_TASKFORPID
:
1106 tok
= au_to_arg32(1, "target port",
1107 (u_int32_t
)ar
->ar_arg_mach_port1
);
1108 kau_write(rec
, tok
);
1109 if (ar
->ar_valid_arg
& ARG_MACHPORT2
) {
1110 tok
= au_to_arg32(3, "task port",
1111 (u_int32_t
)ar
->ar_arg_mach_port2
);
1112 kau_write(rec
, tok
);
1114 PROCESS_PID_TOKENS(2);
1118 tok
= au_to_arg32(4, "priority",
1119 (u_int32_t
)ar
->ar_arg_value
);
1120 kau_write(rec
, tok
);
1121 UPATH1_KPATH1_VNODE1_TOKENS
;
1125 UPATH1_KPATH1_VNODE1_TOKENS
;
1129 tok
= au_to_arg32(3, "va", (u_int32_t
)ar
->ar_arg_addr
);
1130 kau_write(rec
, tok
);
1131 FD_KPATH1_VNODE1_TOKENS
;
1134 default: /* We shouldn't fall through to here. */
1135 printf("BSM conversion requested for unknown event %d\n",
1141 kau_write(rec
, subj_tok
);
1142 tok
= au_to_return32((char)ar
->ar_errno
, ar
->ar_retval
);
1143 kau_write(rec
, tok
); /* Every record gets a return token */
1145 kau_close(rec
, &ar
->ar_endtime
, ar
->ar_event
);
1152 * Verify that a record is a valid BSM record. This verification is
1153 * simple now, but may be expanded on sometime in the future.
1154 * Return 1 if the record is good, 0 otherwise.
1158 bsm_rec_verify(void* rec
)
1160 char c
= *(char *)rec
;
1162 * Check the token ID of the first token; it has to be a header
1165 /* XXXAUDIT There needs to be a token structure to map a token.
1166 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1168 if ( (c
!= AU_HEADER_32_TOKEN
) &&
1169 (c
!= AU_HEADER_EX_32_TOKEN
) &&
1170 (c
!= AU_HEADER_64_TOKEN
) &&
1171 (c
!= AU_HEADER_EX_64_TOKEN
) ) {