]> git.saurik.com Git - apple/xnu.git/blame - bsd/kern/kern_bsm_audit.c
xnu-792.18.15.tar.gz
[apple/xnu.git] / bsd / kern / kern_bsm_audit.c
CommitLineData
55e303ae 1/*
91447636 2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
55e303ae 3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
55e303ae 5 *
8f6c56a5
A
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 License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
55e303ae
A
27 */
28#include <sys/types.h>
91447636 29#include <sys/vnode_internal.h>
55e303ae
A
30#include <sys/ipc.h>
31#include <sys/sem.h>
32#include <sys/socketvar.h>
33#include <sys/socket.h>
34#include <sys/queue.h>
35#include <sys/fcntl.h>
55e303ae 36#include <sys/user.h>
e5568f75 37
91447636 38#include <sys/ipc.h>
e5568f75
A
39#include <bsm/audit.h>
40#include <bsm/audit_record.h>
41#include <bsm/audit_kernel.h>
42#include <bsm/audit_kevents.h>
43#include <bsm/audit_klib.h>
44
55e303ae
A
45#include <netinet/in_systm.h>
46#include <netinet/in.h>
47#include <netinet/ip.h>
48
49#include <kern/lock.h>
91447636 50#include <kern/kalloc.h>
55e303ae
A
51
52/* The number of BSM records allocated. */
53static int bsm_rec_count = 0;
54
55/*
56 * Records that can be recycled are maintained in the list given below
57 * The maximum number of elements that can be present in this list is
58 * bounded by MAX_AUDIT_RECORDS. Memory allocated for these records are never
59 * freed
60 */
61LIST_HEAD(, au_record) bsm_free_q;
62
63/*
64 * Lock for serializing access to the list of audit records.
65 */
66static mutex_t *bsm_audit_mutex;
67
91447636
A
68static void audit_sys_auditon(struct audit_record *ar, struct au_record *rec);
69
55e303ae
A
70/*
71 * Initialize the BSM auditing subsystem.
72 */
73void
74kau_init(void)
75{
76 printf("BSM auditing present\n");
77 LIST_INIT(&bsm_free_q);
91447636 78 bsm_audit_mutex = mutex_alloc(0);
e5568f75 79 au_evclassmap_init();
55e303ae
A
80}
81
82/*
83 * This call reserves memory for the audit record.
84 * Memory must be guaranteed before any auditable event can be
85 * generated.
86 * The au_record structure maintains a reference to the
87 * memory allocated above and also the list of tokens associated
88 * with this record
89 */
90struct au_record *
91kau_open(void)
92{
93 struct au_record *rec = NULL;
94
95 /*
96 * Find an unused record, remove it from the free list, mark as used
97 */
98 mutex_lock(bsm_audit_mutex);
99 if (!LIST_EMPTY(&bsm_free_q)) {
100 rec = LIST_FIRST(&bsm_free_q);
101 LIST_REMOVE(rec, au_rec_q);
102 }
103 mutex_unlock(bsm_audit_mutex);
104
105 if (rec == NULL) {
106 mutex_lock(bsm_audit_mutex);
107 if (bsm_rec_count >= MAX_AUDIT_RECORDS) {
108 /* XXX We need to increase size of MAX_AUDIT_RECORDS */
109 mutex_unlock(bsm_audit_mutex);
110 return NULL;
111 }
112 mutex_unlock(bsm_audit_mutex);
113
114 /*
115 * Create a new BSM kernel record.
116 */
e5568f75 117 rec = (struct au_record *)kalloc(sizeof(*rec));
55e303ae
A
118 if(rec == NULL) {
119 return NULL;
120 }
e5568f75 121 rec->data = (u_char *)kalloc(MAX_AUDIT_RECORD_SIZE * sizeof(u_char));
55e303ae 122 if((rec->data) == NULL) {
91447636 123 kfree(rec, sizeof(*rec));
55e303ae
A
124 return NULL;
125 }
126 mutex_lock(bsm_audit_mutex);
127 bsm_rec_count++;
128 mutex_unlock(bsm_audit_mutex);
129 }
130 memset(rec->data, 0, MAX_AUDIT_RECORD_SIZE);
131
132 TAILQ_INIT(&rec->token_q);
133 rec->len = 0;
134 rec->used = 1;
135
136 return rec;
137}
138
139/*
140 * Store the token with the record descriptor
141 *
142 */
143int kau_write(struct au_record *rec, struct au_token *tok)
144{
145 if(tok == NULL) {
146 return -1; /* Invalid Token */
147 }
148
149 /* Add the token to the tail */
150 /*
151 * XXX Not locking here -- we should not be writing to
152 * XXX the same audit record from different threads
153 */
154 TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
155
156 rec->len += tok->len; /* grow record length by token size bytes */
157
158 return 0;
159}
160
161/*
162 * Close out the audit record by adding the header token, identifying
163 * any missing tokens. Write out the tokens to the record memory.
164 */
91447636
A
165int
166kau_close(struct au_record *rec, struct timespec *ctime, short event)
55e303ae
A
167{
168 u_char *dptr;
169 size_t tot_rec_size;
170 token_t *cur, *hdr, *trail;
171 int retval = 0;
172
173 tot_rec_size = rec->len + HEADER_SIZE + TRAILER_SIZE;
174 if(tot_rec_size <= MAX_AUDIT_RECORD_SIZE) {
175 /* Create the header token */
176 hdr = kau_to_header32(ctime, tot_rec_size, event, 0);
177
178 if(hdr != NULL) {
179 /* Add to head of list */
180 TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
181
182 trail = au_to_trailer(tot_rec_size);
183 if(trail != NULL) {
184 TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
185 }
186 }
187 /* Serialize token data to the record */
188
189 rec->len = tot_rec_size;
190 dptr = rec->data;
191 TAILQ_FOREACH(cur, &rec->token_q, tokens) {
192 memcpy(dptr, cur->t_data, cur->len);
193 dptr += cur->len;
194 }
195 }
91447636
A
196
197 return(retval);
55e303ae
A
198}
199
200/*
201 * Free a BSM audit record by releasing all the tokens and clearing the
202 * audit record information.
203 */
204void kau_free(struct au_record *rec)
205{
206 struct au_token *tok;
207
208 /* Free the token list */
209 while ((tok = TAILQ_FIRST(&rec->token_q))) {
210 TAILQ_REMOVE(&rec->token_q, tok, tokens);
91447636 211 kfree(tok, sizeof(*tok) + tok->len);
55e303ae
A
212 }
213
214 rec->used = 0;
215 rec->len = 0;
216
217 mutex_lock(bsm_audit_mutex);
218
219 /* Add the record to the freelist */
220 LIST_INSERT_HEAD(&bsm_free_q, rec, au_rec_q);
221
222 mutex_unlock(bsm_audit_mutex);
223
224}
225
226/*
227 * XXX May want turn some (or all) of these macros into functions in order
228 * to reduce the generated code sized.
229 */
230#define UPATH1_TOKENS \
231 do { \
232 if (ar->ar_valid_arg & ARG_UPATH1) { \
233 tok = au_to_path(ar->ar_arg_upath1); \
234 kau_write(rec, tok); \
235 } \
236 } while (0)
237
238#define UPATH2_TOKENS \
239 do { \
240 if (ar->ar_valid_arg & ARG_UPATH2) { \
241 tok = au_to_path(ar->ar_arg_upath2); \
242 kau_write(rec, tok); \
243 } \
244 } while (0)
245
ccc36f2f 246#define UPATH1_KPATH1_VNODE1_TOKENS \
55e303ae 247 do { \
ccc36f2f
A
248 if (ar->ar_valid_arg & ARG_UPATH1) { \
249 tok = au_to_path(ar->ar_arg_upath1); \
250 kau_write(rec, tok); \
251 } \
55e303ae
A
252 if (ar->ar_valid_arg & ARG_KPATH1) { \
253 tok = au_to_path(ar->ar_arg_kpath1); \
254 kau_write(rec, tok); \
255 } \
256 if (ar->ar_valid_arg & ARG_VNODE1) { \
e5568f75 257 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
55e303ae
A
258 kau_write(rec, tok); \
259 } \
260 } while (0)
91447636 261
ccc36f2f 262#define KPATH1_VNODE1_TOKENS \
55e303ae
A
263 do { \
264 if (ar->ar_valid_arg & ARG_KPATH1) { \
265 tok = au_to_path(ar->ar_arg_kpath1); \
266 kau_write(rec, tok); \
55e303ae
A
267 } \
268 if (ar->ar_valid_arg & ARG_VNODE1) { \
e5568f75 269 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
55e303ae
A
270 kau_write(rec, tok); \
271 } \
272 } while (0)
273
274#define KPATH2_VNODE2_TOKENS \
275 do { \
276 if (ar->ar_valid_arg & ARG_KPATH2) { \
277 tok = au_to_path(ar->ar_arg_kpath2); \
278 kau_write(rec, tok); \
279 } \
280 if (ar->ar_valid_arg & ARG_VNODE2) { \
e5568f75 281 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
55e303ae
A
282 kau_write(rec, tok); \
283 } \
284 } while (0)
285
286#define FD_KPATH1_VNODE1_TOKENS \
287 do { \
288 if (ar->ar_valid_arg & ARG_KPATH1) { \
289 tok = au_to_path(ar->ar_arg_kpath1); \
290 kau_write(rec, tok); \
291 if (ar->ar_valid_arg & ARG_VNODE1) { \
e5568f75 292 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
55e303ae
A
293 kau_write(rec, tok); \
294 } \
295 } else { \
296 tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \
297 kau_write(rec, tok); \
298 } \
299 } while (0)
300
e5568f75
A
301#define PROCESS_PID_TOKENS(argn) \
302 do { \
303 if ((ar->ar_arg_pid > 0) /* Kill a single process */ \
304 && (ar->ar_valid_arg & ARG_PROCESS)) { \
305 tok = au_to_process(ar->ar_arg_auid, ar->ar_arg_euid, \
306 ar->ar_arg_egid, ar->ar_arg_ruid, \
307 ar->ar_arg_rgid, ar->ar_arg_pid, \
308 ar->ar_arg_asid, &ar->ar_arg_termid); \
309 kau_write(rec, tok); \
310 } else { \
311 tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\
312 kau_write(rec, tok); \
313 } \
314 } while (0) \
315
316/*
317 * Implement auditing for the auditon() system call. The audit tokens
318 * that are generated depend on the command that was sent into the
319 * auditon() system call.
320 *
321 */
91447636 322static void
e5568f75
A
323audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
324{
325 struct au_token *tok;
326
327 switch (ar->ar_arg_cmd) {
91447636 328 case A_SETPOLICY:
e5568f75
A
329 if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
330 tok = au_to_arg64(1, "policy",
331 ar->ar_arg_auditon.au_flags);
332 else
333 tok = au_to_arg32(1, "policy",
334 ar->ar_arg_auditon.au_flags);
335 kau_write(rec, tok);
336 break;
91447636 337 case A_SETKMASK:
e5568f75
A
338 tok = au_to_arg32(2, "setkmask:as_success",
339 ar->ar_arg_auditon.au_mask.am_success);
340 kau_write(rec, tok);
341 tok = au_to_arg32(2, "setkmask:as_failure",
342 ar->ar_arg_auditon.au_mask.am_failure);
343 kau_write(rec, tok);
344 break;
91447636 345 case A_SETQCTRL:
e5568f75
A
346 tok = au_to_arg32(3, "setqctrl:aq_hiwater",
347 ar->ar_arg_auditon.au_qctrl.aq_hiwater);
348 kau_write(rec, tok);
349 tok = au_to_arg32(3, "setqctrl:aq_lowater",
350 ar->ar_arg_auditon.au_qctrl.aq_lowater);
351 kau_write(rec, tok);
352 tok = au_to_arg32(3, "setqctrl:aq_bufsz",
353 ar->ar_arg_auditon.au_qctrl.aq_bufsz);
354 kau_write(rec, tok);
355 tok = au_to_arg32(3, "setqctrl:aq_delay",
356 ar->ar_arg_auditon.au_qctrl.aq_delay);
357 kau_write(rec, tok);
358 tok = au_to_arg32(3, "setqctrl:aq_minfree",
359 ar->ar_arg_auditon.au_qctrl.aq_minfree);
360 kau_write(rec, tok);
361 break;
91447636 362 case A_SETUMASK:
e5568f75
A
363 tok = au_to_arg32(3, "setumask:as_success",
364 ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
365 kau_write(rec, tok);
366 tok = au_to_arg32(3, "setumask:as_failure",
367 ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
368 kau_write(rec, tok);
369 break;
91447636 370 case A_SETSMASK:
e5568f75
A
371 tok = au_to_arg32(3, "setsmask:as_success",
372 ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
373 kau_write(rec, tok);
374 tok = au_to_arg32(3, "setsmask:as_failure",
375 ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
376 kau_write(rec, tok);
377 break;
91447636 378 case A_SETCOND:
e5568f75
A
379 if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
380 tok = au_to_arg64(3, "setcond",
381 ar->ar_arg_auditon.au_cond);
382 else
383 tok = au_to_arg32(3, "setcond",
384 ar->ar_arg_auditon.au_cond);
385 kau_write(rec, tok);
386 break;
91447636 387 case A_SETCLASS:
e5568f75
A
388 tok = au_to_arg32(2, "setclass:ec_event",
389 ar->ar_arg_auditon.au_evclass.ec_number);
390 kau_write(rec, tok);
391 tok = au_to_arg32(3, "setclass:ec_class",
392 ar->ar_arg_auditon.au_evclass.ec_class);
393 kau_write(rec, tok);
394 break;
91447636 395 case A_SETPMASK:
e5568f75
A
396 tok = au_to_arg32(2, "setpmask:as_success",
397 ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
398 kau_write(rec, tok);
399 tok = au_to_arg32(2, "setpmask:as_failure",
400 ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
401 kau_write(rec, tok);
402 break;
91447636 403 case A_SETFSIZE:
e5568f75
A
404 tok = au_to_arg32(2, "setfsize:filesize",
405 ar->ar_arg_auditon.au_fstat.af_filesz);
406 kau_write(rec, tok);
407 break;
408 default:
409 break;
410 }
411}
412
55e303ae
A
413/*
414 * Convert an internal kernel audit record to a BSM record and return
415 * a success/failure indicator. The BSM record is passed as an out
416 * parameter to this function.
417 * Return conditions:
418 * BSM_SUCCESS: The BSM record is valid
419 * BSM_FAILURE: Failure; the BSM record is NULL.
420 * BSM_NOAUDIT: The event is not auditable for BSM; the BSM record is NULL.
421 */
422int
423kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
424{
425 struct au_token *tok, *subj_tok;
426 struct au_record *rec;
427 au_tid_t tid;
428 struct audit_record *ar;
55e303ae
A
429 int ctr;
430
431 *pau = NULL;
432 if (kar == NULL)
433 return (BSM_FAILURE);
434
435 ar = &kar->k_ar;
436
55e303ae
A
437 rec = kau_open();
438 if (rec == NULL)
439 return (BSM_FAILURE);
440
441 /* Create the subject token */
442 tid.port = ar->ar_subj_term.port;
443 tid.machine = ar->ar_subj_term.machine;
444 subj_tok = au_to_subject32(ar->ar_subj_auid, /* audit ID */
445 ar->ar_subj_cred.cr_uid, /* eff uid */
446 ar->ar_subj_egid, /* eff group id */
447 ar->ar_subj_ruid, /* real uid */
448 ar->ar_subj_rgid, /* real group id */
449 ar->ar_subj_pid, /* process id */
450 ar->ar_subj_asid, /* session ID */
451 &tid);
452
453 /* The logic inside each case fills in the tokens required for the
454 * event, except for the header, trailer, and return tokens. The
455 * header and trailer tokens are added by the kau_close() function.
456 * The return token is added outside of the switch statement.
457 */
458 switch(ar->ar_event) {
459
460 /*
461 * Socket-related events.
462 */
463 case AUE_ACCEPT:
464 case AUE_BIND:
465 case AUE_CONNECT:
466 case AUE_RECVFROM:
467 case AUE_RECVMSG:
468 case AUE_SENDMSG:
469 case AUE_SENDTO:
470 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
471 kau_write(rec, tok);
472 if (ar->ar_valid_arg & ARG_SADDRINET) {
473 tok = au_to_sock_inet(
474 (struct sockaddr_in *)&ar->ar_arg_sockaddr);
475 kau_write(rec, tok);
476 }
477 if (ar->ar_valid_arg & ARG_SADDRUNIX) {
478 tok = au_to_sock_unix(
479 (struct sockaddr_un *)&ar->ar_arg_sockaddr);
480 kau_write(rec, tok);
481 UPATH1_TOKENS;
482 }
483 /* XXX Need to handle ARG_SADDRINET6 */
484 break;
485
486 case AUE_SOCKET:
487 case AUE_SOCKETPAIR:
e5568f75 488 tok = au_to_arg32(1,"domain", ar->ar_arg_sockinfo.so_domain);
55e303ae 489 kau_write(rec, tok);
e5568f75 490 tok = au_to_arg32(2,"type", ar->ar_arg_sockinfo.so_type);
55e303ae 491 kau_write(rec, tok);
e5568f75 492 tok = au_to_arg32(3,"protocol",ar->ar_arg_sockinfo.so_protocol);
55e303ae
A
493 kau_write(rec, tok);
494 break;
495
496 case AUE_SETSOCKOPT:
497 case AUE_SHUTDOWN:
498 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
499 kau_write(rec, tok);
500 break;
501
e5568f75
A
502 case AUE_ACCT:
503 if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
ccc36f2f 504 UPATH1_KPATH1_VNODE1_TOKENS;
e5568f75
A
505 } else {
506 tok = au_to_arg32(1, "accounting off", 0);
507 kau_write(rec, tok);
508 }
509 break;
510
55e303ae
A
511 case AUE_SETAUID:
512 tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
513 kau_write(rec, tok);
e5568f75
A
514 break;
515
516 case AUE_SETAUDIT:
517 if (ar->ar_valid_arg & ARG_AUID) {
518 tok = au_to_arg32(1, "setaudit:auid", ar->ar_arg_auid);
519 kau_write(rec, tok);
520 tok = au_to_arg32(1, "setaudit:port",
521 ar->ar_arg_termid.port);
522 kau_write(rec, tok);
523 tok = au_to_arg32(1, "setaudit:machine",
524 ar->ar_arg_termid.machine);
525 kau_write(rec, tok);
526 tok = au_to_arg32(1, "setaudit:as_success",
527 ar->ar_arg_amask.am_success);
528 kau_write(rec, tok);
529 tok = au_to_arg32(1, "setaudit:as_failure",
530 ar->ar_arg_amask.am_failure);
531 kau_write(rec, tok);
532 tok = au_to_arg32(1, "setaudit:asid", ar->ar_arg_asid);
533 kau_write(rec, tok);
534 }
535 break;
536
537 case AUE_SETAUDIT_ADDR:
538 break; /* XXX need to add arguments */
539
540 case AUE_AUDITON:
541 /* For AUDITON commands without own event, audit the cmd */
542 tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
543 kau_write(rec, tok);
544 /* fall thru */
545
546 case AUE_AUDITON_GETCAR:
547 case AUE_AUDITON_GETCLASS:
548 case AUE_AUDITON_GETCOND:
549 case AUE_AUDITON_GETCWD:
550 case AUE_AUDITON_GETKMASK:
551 case AUE_AUDITON_GETSTAT:
552 case AUE_AUDITON_GPOLICY:
553 case AUE_AUDITON_GQCTRL:
554 case AUE_AUDITON_SETCLASS:
555 case AUE_AUDITON_SETCOND:
556 case AUE_AUDITON_SETKMASK:
557 case AUE_AUDITON_SETSMASK:
558 case AUE_AUDITON_SETSTAT:
559 case AUE_AUDITON_SETUMASK:
560 case AUE_AUDITON_SPOLICY:
561 case AUE_AUDITON_SQCTRL:
562 if (ar->ar_valid_arg & ARG_AUDITON) {
563 audit_sys_auditon(ar, rec);
564 }
565 break;
566
567 case AUE_AUDITCTL:
ccc36f2f 568 UPATH1_KPATH1_VNODE1_TOKENS;
e5568f75
A
569 break;
570
55e303ae
A
571 case AUE_ADJTIME:
572 case AUE_AUDIT:
573 case AUE_EXIT:
e5568f75
A
574 case AUE_GETAUDIT:
575 case AUE_GETAUDIT_ADDR:
55e303ae
A
576 case AUE_GETAUID:
577 case AUE_GETFSSTAT:
578 case AUE_PIPE:
579 case AUE_SETPGRP:
580 case AUE_SETRLIMIT:
e5568f75
A
581 case AUE_SETSID:
582 case AUE_SETTIMEOFDAY:
583 case AUE_NEWSYSTEMSHREG:
55e303ae
A
584 /* Header, subject, and return tokens added at end */
585 break;
586
587 case AUE_ACCESS:
588 case AUE_CHDIR:
589 case AUE_CHROOT:
590 case AUE_EXECVE:
591 case AUE_GETATTRLIST:
592 case AUE_GETFH:
593 case AUE_LSTAT:
594 case AUE_MKFIFO:
595 case AUE_PATHCONF:
596 case AUE_READLINK:
597 case AUE_REVOKE:
598 case AUE_RMDIR:
599 case AUE_SEARCHFS:
600 case AUE_SETATTRLIST:
601 case AUE_STAT:
602 case AUE_STATFS:
603 case AUE_TRUNCATE:
604 case AUE_UNDELETE:
605 case AUE_UNLINK:
606 case AUE_UTIMES:
ccc36f2f 607 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
608 break;
609
610 case AUE_CHFLAGS:
611 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
612 kau_write(rec, tok);
ccc36f2f 613 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
614 break;
615
616 case AUE_CHMOD:
617 tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
618 kau_write(rec, tok);
ccc36f2f 619 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
620 break;
621
622 case AUE_CHOWN:
91447636 623 case AUE_LCHOWN:
55e303ae
A
624 tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
625 kau_write(rec, tok);
626 tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
627 kau_write(rec, tok);
ccc36f2f 628 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
629 break;
630
631 case AUE_EXCHANGEDATA:
ccc36f2f 632 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
633 KPATH2_VNODE2_TOKENS;
634 break;
635
55e303ae
A
636 case AUE_CLOSE:
637 tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
638 kau_write(rec, tok);
ccc36f2f 639 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae 640 break;
e5568f75 641
55e303ae
A
642 case AUE_FCHMOD:
643 tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
644 kau_write(rec, tok);
645 FD_KPATH1_VNODE1_TOKENS;
646 break;
647
ccc36f2f
A
648 case AUE_NFSSVC:
649 tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
650 kau_write(rec, tok);
651 if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
652 UPATH1_KPATH1_VNODE1_TOKENS;
653 }
654 break;
655
55e303ae
A
656 case AUE_FCHDIR:
657 case AUE_FPATHCONF:
658 case AUE_FSTAT: /* XXX Need to handle sockets and shm */
659 case AUE_FSTATFS:
660 case AUE_FTRUNCATE:
661 case AUE_FUTIMES:
662 case AUE_GETDIRENTRIES:
663 case AUE_GETDIRENTRIESATTR:
664 FD_KPATH1_VNODE1_TOKENS;
665 break;
666
667 case AUE_FCHOWN:
668 tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
669 kau_write(rec, tok);
670 tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
671 kau_write(rec, tok);
672 FD_KPATH1_VNODE1_TOKENS;
673 break;
674
675 case AUE_FCNTL:
ccc36f2f
A
676 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
677 kau_write(rec, tok);
678 if (ar->ar_valid_arg & ARG_VNODE1) {
55e303ae
A
679 FD_KPATH1_VNODE1_TOKENS;
680 }
681 break;
682
683 case AUE_FCHFLAGS:
684 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
685 kau_write(rec, tok);
686 FD_KPATH1_VNODE1_TOKENS;
687 break;
688
689 case AUE_FLOCK:
690 tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
691 kau_write(rec, tok);
692 FD_KPATH1_VNODE1_TOKENS;
693 break;
694
e5568f75
A
695 case AUE_FORK:
696 case AUE_VFORK:
697 tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
698 kau_write(rec, tok);
699 break;
700
701 case AUE_IOCTL:
702 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
703 kau_write(rec, tok);
704 tok = au_to_arg32(1, "arg", (u_int32_t)ar->ar_arg_addr);
705 kau_write(rec, tok);
706 if (ar->ar_valid_arg & ARG_VNODE1) {
707 FD_KPATH1_VNODE1_TOKENS;
708 } else {
709 if (ar->ar_valid_arg & ARG_SOCKINFO) {
710 tok = kau_to_socket(&ar->ar_arg_sockinfo);
711 kau_write(rec, tok);
712 } else {
713 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
714 kau_write(rec, tok);
715 }
716 }
717 break;
718
719 case AUE_KILL:
720 tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
721 kau_write(rec, tok);
722 PROCESS_PID_TOKENS(1);
723 break;
724
725 case AUE_KTRACE:
726 tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
727 kau_write(rec, tok);
728 tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
729 kau_write(rec, tok);
730 PROCESS_PID_TOKENS(4);
ccc36f2f 731 UPATH1_KPATH1_VNODE1_TOKENS;
e5568f75
A
732 break;
733
55e303ae
A
734 case AUE_LINK:
735 case AUE_RENAME:
ccc36f2f 736 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
737 UPATH2_TOKENS;
738 break;
739
e5568f75
A
740 case AUE_LOADSHFILE:
741 tok = au_to_arg32(4, "base addr", (u_int32_t)ar->ar_arg_addr);
742 kau_write(rec, tok);
ccc36f2f 743 UPATH1_KPATH1_VNODE1_TOKENS;
e5568f75 744 break;
91447636 745
55e303ae
A
746 case AUE_MKDIR:
747 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
748 kau_write(rec, tok);
ccc36f2f 749 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
750 break;
751
752 case AUE_MKNOD:
753 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
754 kau_write(rec, tok);
755 tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
756 kau_write(rec, tok);
ccc36f2f 757 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
758 break;
759
e5568f75
A
760 case AUE_MMAP:
761 case AUE_MUNMAP:
762 case AUE_MPROTECT:
763 case AUE_MLOCK:
764 case AUE_MUNLOCK:
765 case AUE_MINHERIT:
91447636 766 tok = au_to_arg32(1, "addr", (u_int32_t)ar->ar_arg_addr); /* LP64todo */
e5568f75 767 kau_write(rec, tok);
91447636 768 tok = au_to_arg32(2, "len", ar->ar_arg_len); /* LP64todo */
e5568f75
A
769 kau_write(rec, tok);
770 if (ar->ar_event == AUE_MMAP)
771 FD_KPATH1_VNODE1_TOKENS;
772 if (ar->ar_event == AUE_MPROTECT) {
773 tok = au_to_arg32(3, "protection", ar->ar_arg_value);
774 kau_write(rec, tok);
775 }
776 if (ar->ar_event == AUE_MINHERIT) {
777 tok = au_to_arg32(3, "inherit", ar->ar_arg_value);
778 kau_write(rec, tok);
779 }
780 break;
781
55e303ae
A
782 case AUE_MOUNT:
783 /* XXX Need to handle NFS mounts */
784 tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
785 kau_write(rec, tok);
e5568f75 786 if (ar->ar_valid_arg & ARG_TEXT) {
55e303ae
A
787 tok = au_to_text(ar->ar_arg_text);
788 kau_write(rec, tok);
789 }
790 /* fall through */
ccc36f2f
A
791 case AUE_UNMOUNT:
792 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
793 break;
794
795 case AUE_MSGCTL:
796 ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd);
797 /* Fall through */
798 case AUE_MSGRCV:
799 case AUE_MSGSND:
800 tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
801 kau_write(rec, tok);
802 if (ar->ar_errno != EINVAL) {
803 tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
804 kau_write(rec, tok);
805 }
806 break;
807
808 case AUE_MSGGET:
809 if (ar->ar_errno == 0) {
810 tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
811 kau_write(rec, tok);
812 }
813 break;
814
e5568f75
A
815 case AUE_RESETSHFILE:
816 tok = au_to_arg32(1, "base addr", (u_int32_t)ar->ar_arg_addr);
817 kau_write(rec, tok);
818 break;
819
55e303ae
A
820 case AUE_OPEN_RC:
821 case AUE_OPEN_RTC:
55e303ae
A
822 case AUE_OPEN_RWC:
823 case AUE_OPEN_RWTC:
55e303ae
A
824 case AUE_OPEN_WC:
825 case AUE_OPEN_WTC:
ccc36f2f
A
826 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
827 kau_write(rec, tok);
828 /* fall thru */
829
a3d08fcd 830 case AUE_OPEN:
ccc36f2f
A
831 case AUE_OPEN_R:
832 case AUE_OPEN_RT:
833 case AUE_OPEN_RW:
834 case AUE_OPEN_RWT:
835 case AUE_OPEN_W:
55e303ae 836 case AUE_OPEN_WT:
ccc36f2f
A
837 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
838 kau_write(rec, tok);
839 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
840 break;
841
e5568f75
A
842 case AUE_PTRACE:
843 tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
844 kau_write(rec, tok);
91447636 845 tok = au_to_arg32(3, "addr", (u_int32_t)ar->ar_arg_addr); /* LP64todo */
e5568f75
A
846 kau_write(rec, tok);
847 tok = au_to_arg32(4, "data", ar->ar_arg_value);
848 kau_write(rec, tok);
849 PROCESS_PID_TOKENS(2);
850 break;
851
55e303ae
A
852 case AUE_QUOTACTL:
853 tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
854 kau_write(rec, tok);
855 tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
856 kau_write(rec, tok);
ccc36f2f 857 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
858 break;
859
e5568f75
A
860 case AUE_REBOOT:
861 tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
862 kau_write(rec, tok);
863 break;
864
55e303ae
A
865 case AUE_SEMCTL:
866 ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd);
867 /* Fall through */
868 case AUE_SEMOP:
869 tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
870 kau_write(rec, tok);
871 if (ar->ar_errno != EINVAL) {
872 tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id);
873 kau_write(rec, tok);
874 }
875 break;
876 case AUE_SEMGET:
877 if (ar->ar_errno == 0) {
878 tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id);
879 kau_write(rec, tok);
880 }
881 break;
882 case AUE_SETEGID:
883 tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
884 kau_write(rec, tok);
885 break;
886 case AUE_SETEUID:
887 tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
888 kau_write(rec, tok);
889 break;
890 case AUE_SETGID:
891 tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
892 kau_write(rec, tok);
893 break;
894 case AUE_SETUID:
895 tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
896 kau_write(rec, tok);
897 break;
898 case AUE_SETGROUPS:
899 if (ar->ar_valid_arg & ARG_GROUPSET) {
900 for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
901 {
91447636 902 tok = au_to_arg32(1, "setgroups", ar->ar_arg_groups.gidset[ctr]);
55e303ae
A
903 kau_write(rec, tok);
904 }
905 }
906 break;
e5568f75
A
907
908 case AUE_SETLOGIN:
909 if (ar->ar_valid_arg & ARG_TEXT) {
910 tok = au_to_text(ar->ar_arg_text);
911 kau_write(rec, tok);
912 }
913 break;
914
915 case AUE_SETPRIORITY:
916 tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
917 kau_write(rec, tok);
918 tok = au_to_arg32(2, "who", ar->ar_arg_uid);
919 kau_write(rec, tok);
920 tok = au_to_arg32(2, "priority", ar->ar_arg_value);
921 kau_write(rec, tok);
922 break;
923
924 case AUE_SETPRIVEXEC:
925 tok = au_to_arg32(1, "flag", ar->ar_arg_value);
926 kau_write(rec, tok);
927 break;
928
929 /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
55e303ae
A
930 case AUE_SHMAT:
931 tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
932 kau_write(rec, tok);
933 tok = au_to_arg32(2, "shmaddr", (int)ar->ar_arg_svipc_addr);
934 kau_write(rec, tok);
935 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
936 tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
937 kau_write(rec, tok);
938 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
939 kau_write(rec, tok);
940 }
941 break;
942
943 case AUE_SHMCTL:
944 tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
945 kau_write(rec, tok);
946 switch (ar->ar_arg_svipc_cmd) {
947 case IPC_STAT:
948 ar->ar_event = AUE_SHMCTL_STAT;
949 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
950 tok = au_to_ipc(AT_IPC_SHM,
951 ar->ar_arg_svipc_id);
952 kau_write(rec, tok);
953 }
954 break;
955 case IPC_RMID:
956 ar->ar_event = AUE_SHMCTL_RMID;
957 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
958 tok = au_to_ipc(AT_IPC_SHM,
959 ar->ar_arg_svipc_id);
960 kau_write(rec, tok);
961 }
962 break;
963 case IPC_SET:
964 ar->ar_event = AUE_SHMCTL_SET;
965 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
966 tok = au_to_ipc(AT_IPC_SHM,
967 ar->ar_arg_svipc_id);
968 kau_write(rec, tok);
969 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
970 kau_write(rec, tok);
971 }
972 break;
973 default:
974 break; /* We will audit a bad command */
975 }
976 break;
977
978 case AUE_SHMDT:
979 tok = au_to_arg32(1, "shmaddr", (int)ar->ar_arg_svipc_addr);
980 kau_write(rec, tok);
981 break;
982
983 case AUE_SHMGET:
984 /* This is unusual; the return value is in an argument token */
985 tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
986 kau_write(rec, tok);
987 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
988 tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
989 kau_write(rec, tok);
990 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
991 kau_write(rec, tok);
992 }
993 break;
994
e5568f75
A
995 /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
996 * and AUE_SEMUNLINK are Posix IPC */
997 case AUE_SHMOPEN:
998 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
999 kau_write(rec, tok);
1000 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1001 kau_write(rec, tok);
1002 case AUE_SHMUNLINK:
1003 if (ar->ar_valid_arg & ARG_TEXT) {
1004 tok = au_to_text(ar->ar_arg_text);
1005 kau_write(rec, tok);
1006 }
1007 if (ar->ar_valid_arg & ARG_POSIX_IPC_PERM) {
1008 /* Create an ipc_perm token */
1009 struct ipc_perm perm;
1010 perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1011 perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1012 perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1013 perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1014 perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1015 perm.seq = 0;
1016 perm.key = 0;
1017 tok = au_to_ipc_perm(&perm);
1018 kau_write(rec, tok);
1019 }
1020 break;
1021
1022 case AUE_SEMOPEN:
1023 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
1024 kau_write(rec, tok);
1025 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
1026 kau_write(rec, tok);
1027 tok = au_to_arg32(4, "value", ar->ar_arg_value);
1028 kau_write(rec, tok);
1029 /* fall through */
1030 case AUE_SEMUNLINK:
1031 if (ar->ar_valid_arg & ARG_TEXT) {
1032 tok = au_to_text(ar->ar_arg_text);
1033 kau_write(rec, tok);
1034 }
1035 if (ar->ar_valid_arg & ARG_POSIX_IPC_PERM) {
1036 /* Create an ipc_perm token */
1037 struct ipc_perm perm;
1038 perm.uid = ar->ar_arg_pipc_perm.pipc_uid;
1039 perm.gid = ar->ar_arg_pipc_perm.pipc_gid;
1040 perm.cuid = ar->ar_arg_pipc_perm.pipc_uid;
1041 perm.cgid = ar->ar_arg_pipc_perm.pipc_gid;
1042 perm.mode = ar->ar_arg_pipc_perm.pipc_mode;
1043 perm.seq = 0;
1044 perm.key = 0;
1045 tok = au_to_ipc_perm(&perm);
1046 kau_write(rec, tok);
1047 }
1048 break;
1049
1050 case AUE_SEMCLOSE:
1051 tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1052 kau_write(rec, tok);
1053 break;
1054
55e303ae
A
1055 case AUE_SYMLINK:
1056 if (ar->ar_valid_arg & ARG_TEXT) {
1057 tok = au_to_text(ar->ar_arg_text);
1058 kau_write(rec, tok);
1059 }
ccc36f2f 1060 UPATH1_KPATH1_VNODE1_TOKENS;
55e303ae
A
1061 break;
1062
e5568f75 1063 case AUE_SYSCTL:
a3d08fcd 1064 case AUE_SYSCTL_NONADMIN:
e5568f75
A
1065 if (ar->ar_valid_arg & (ARG_CTLNAME | ARG_LEN)) {
1066 for (ctr = 0; ctr < ar->ar_arg_len; ctr++) {
1067 tok = au_to_arg32(1, "name", ar->ar_arg_ctlname[ctr]);
1068 kau_write(rec, tok);
1069 }
1070 }
1071 if (ar->ar_valid_arg & ARG_VALUE) {
1072 tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1073 kau_write(rec, tok);
1074 }
1075 if (ar->ar_valid_arg & ARG_TEXT) {
1076 tok = au_to_text(ar->ar_arg_text);
1077 kau_write(rec, tok);
1078 }
1079 break;
1080
55e303ae
A
1081 case AUE_UMASK:
1082 tok = au_to_arg32(1, "new mask", ar->ar_arg_mask);
1083 kau_write(rec, tok);
1084 tok = au_to_arg32(0, "prev mask", ar->ar_retval);
1085 kau_write(rec, tok);
1086 break;
1087
e5568f75
A
1088 /************************
1089 * Mach system calls *
1090 ************************/
1091 case AUE_INITPROCESS:
1092 break;
1093
1094 case AUE_PIDFORTASK:
1095 tok = au_to_arg32(1, "port", (u_int32_t)ar->ar_arg_mach_port1);
1096 kau_write(rec, tok);
1097 if (ar->ar_valid_arg & ARG_PID) {
1098 tok = au_to_arg32(2, "pid", (u_int32_t)ar->ar_arg_pid);
1099 kau_write(rec, tok);
1100 }
1101 break;
1102
1103 case AUE_TASKFORPID:
1104 tok = au_to_arg32(1, "target port",
1105 (u_int32_t)ar->ar_arg_mach_port1);
1106 kau_write(rec, tok);
1107 if (ar->ar_valid_arg & ARG_MACHPORT2) {
1108 tok = au_to_arg32(3, "task port",
1109 (u_int32_t)ar->ar_arg_mach_port2);
1110 kau_write(rec, tok);
1111 }
1112 PROCESS_PID_TOKENS(2);
1113 break;
1114
1115 case AUE_SWAPON:
1116 tok = au_to_arg32(4, "priority",
1117 (u_int32_t)ar->ar_arg_value);
1118 kau_write(rec, tok);
ccc36f2f 1119 UPATH1_KPATH1_VNODE1_TOKENS;
e5568f75
A
1120 break;
1121
1122 case AUE_SWAPOFF:
ccc36f2f 1123 UPATH1_KPATH1_VNODE1_TOKENS;
e5568f75
A
1124 break;
1125
1126 case AUE_MAPFD:
1127 tok = au_to_arg32(3, "va", (u_int32_t)ar->ar_arg_addr);
1128 kau_write(rec, tok);
1129 FD_KPATH1_VNODE1_TOKENS;
1130 break;
1131
55e303ae
A
1132 default: /* We shouldn't fall through to here. */
1133 printf("BSM conversion requested for unknown event %d\n",
1134 ar->ar_event);
1135 kau_free(rec);
1136 return BSM_NOAUDIT;
1137 }
1138
1139 kau_write(rec, subj_tok);
1140 tok = au_to_return32((char)ar->ar_errno, ar->ar_retval);
1141 kau_write(rec, tok); /* Every record gets a return token */
1142
1143 kau_close(rec, &ar->ar_endtime, ar->ar_event);
1144
1145 *pau = rec;
1146 return BSM_SUCCESS;
1147}
1148
1149/*
1150 * Verify that a record is a valid BSM record. This verification is
1151 * simple now, but may be expanded on sometime in the future.
1152 * Return 1 if the record is good, 0 otherwise.
1153 *
1154 */
1155int
91447636 1156bsm_rec_verify(void* rec)
55e303ae 1157{
e5568f75 1158 char c = *(char *)rec;
55e303ae
A
1159 /*
1160 * Check the token ID of the first token; it has to be a header
1161 * token.
1162 */
1163 /* XXXAUDIT There needs to be a token structure to map a token.
1164 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1165 */
e5568f75
A
1166 if ( (c != AU_HEADER_32_TOKEN) &&
1167 (c != AU_HEADER_EX_32_TOKEN) &&
1168 (c != AU_HEADER_64_TOKEN) &&
1169 (c != AU_HEADER_EX_64_TOKEN) ) {
55e303ae
A
1170 return (0);
1171 }
1172 return (1);
1173}