]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_bsm_audit.c
ae667ba9354b19e3d5c19462ff91ea06b62ab856
[apple/xnu.git] / bsd / kern / kern_bsm_audit.c
1 /*
2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 #include <sys/types.h>
24 #include <sys/vnode.h>
25 #include <sys/ipc.h>
26 #include <sys/sem.h>
27 #include <sys/socketvar.h>
28 #include <sys/socket.h>
29 #include <sys/queue.h>
30 #include <sys/fcntl.h>
31 #include <sys/user.h>
32
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>
38
39 #include <netinet/in_systm.h>
40 #include <netinet/in.h>
41 #include <netinet/ip.h>
42
43 #include <kern/lock.h>
44
45 /* The number of BSM records allocated. */
46 static int bsm_rec_count = 0;
47
48 /*
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
52 * freed
53 */
54 LIST_HEAD(, au_record) bsm_free_q;
55
56 /*
57 * Lock for serializing access to the list of audit records.
58 */
59 static mutex_t *bsm_audit_mutex;
60
61 /*
62 * Initialize the BSM auditing subsystem.
63 */
64 void
65 kau_init(void)
66 {
67 printf("BSM auditing present\n");
68 LIST_INIT(&bsm_free_q);
69 bsm_audit_mutex = mutex_alloc(ETAP_NO_TRACE);
70 au_evclassmap_init();
71 }
72
73 /*
74 * This call reserves memory for the audit record.
75 * Memory must be guaranteed before any auditable event can be
76 * generated.
77 * The au_record structure maintains a reference to the
78 * memory allocated above and also the list of tokens associated
79 * with this record
80 */
81 struct au_record *
82 kau_open(void)
83 {
84 struct au_record *rec = NULL;
85
86 /*
87 * Find an unused record, remove it from the free list, mark as used
88 */
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);
93 }
94 mutex_unlock(bsm_audit_mutex);
95
96 if (rec == NULL) {
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);
101 return NULL;
102 }
103 mutex_unlock(bsm_audit_mutex);
104
105 /*
106 * Create a new BSM kernel record.
107 */
108 rec = (struct au_record *)kalloc(sizeof(*rec));
109 if(rec == NULL) {
110 return NULL;
111 }
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));
115 return NULL;
116 }
117 mutex_lock(bsm_audit_mutex);
118 bsm_rec_count++;
119 mutex_unlock(bsm_audit_mutex);
120 }
121 memset(rec->data, 0, MAX_AUDIT_RECORD_SIZE);
122
123 TAILQ_INIT(&rec->token_q);
124 rec->len = 0;
125 rec->used = 1;
126
127 return rec;
128 }
129
130 /*
131 * Store the token with the record descriptor
132 *
133 */
134 int kau_write(struct au_record *rec, struct au_token *tok)
135 {
136 if(tok == NULL) {
137 return -1; /* Invalid Token */
138 }
139
140 /* Add the token to the tail */
141 /*
142 * XXX Not locking here -- we should not be writing to
143 * XXX the same audit record from different threads
144 */
145 TAILQ_INSERT_TAIL(&rec->token_q, tok, tokens);
146
147 rec->len += tok->len; /* grow record length by token size bytes */
148
149 return 0;
150 }
151
152 /*
153 * Close out the audit record by adding the header token, identifying
154 * any missing tokens. Write out the tokens to the record memory.
155 */
156 int kau_close(struct au_record *rec, struct timespec *ctime, short event)
157 {
158 u_char *dptr;
159 size_t tot_rec_size;
160 token_t *cur, *hdr, *trail;
161 int retval = 0;
162
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);
167
168 if(hdr != NULL) {
169 /* Add to head of list */
170 TAILQ_INSERT_HEAD(&rec->token_q, hdr, tokens);
171
172 trail = au_to_trailer(tot_rec_size);
173 if(trail != NULL) {
174 TAILQ_INSERT_TAIL(&rec->token_q, trail, tokens);
175 }
176 }
177 /* Serialize token data to the record */
178
179 rec->len = tot_rec_size;
180 dptr = rec->data;
181 TAILQ_FOREACH(cur, &rec->token_q, tokens) {
182 memcpy(dptr, cur->t_data, cur->len);
183 dptr += cur->len;
184 }
185 }
186 }
187
188 /*
189 * Free a BSM audit record by releasing all the tokens and clearing the
190 * audit record information.
191 */
192 void kau_free(struct au_record *rec)
193 {
194 struct au_token *tok;
195
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);
200 }
201
202 rec->used = 0;
203 rec->len = 0;
204
205 mutex_lock(bsm_audit_mutex);
206
207 /* Add the record to the freelist */
208 LIST_INSERT_HEAD(&bsm_free_q, rec, au_rec_q);
209
210 mutex_unlock(bsm_audit_mutex);
211
212 }
213
214 /*
215 * XXX May want turn some (or all) of these macros into functions in order
216 * to reduce the generated code sized.
217 */
218 #define UPATH1_TOKENS \
219 do { \
220 if (ar->ar_valid_arg & ARG_UPATH1) { \
221 tok = au_to_path(ar->ar_arg_upath1); \
222 kau_write(rec, tok); \
223 } \
224 } while (0)
225
226 #define UPATH2_TOKENS \
227 do { \
228 if (ar->ar_valid_arg & ARG_UPATH2) { \
229 tok = au_to_path(ar->ar_arg_upath2); \
230 kau_write(rec, tok); \
231 } \
232 } while (0)
233
234 #define UPATH1_KPATH1_VNODE1_TOKENS \
235 do { \
236 if (ar->ar_valid_arg & ARG_UPATH1) { \
237 tok = au_to_path(ar->ar_arg_upath1); \
238 kau_write(rec, tok); \
239 } \
240 if (ar->ar_valid_arg & ARG_KPATH1) { \
241 tok = au_to_path(ar->ar_arg_kpath1); \
242 kau_write(rec, tok); \
243 } \
244 if (ar->ar_valid_arg & ARG_VNODE1) { \
245 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
246 kau_write(rec, tok); \
247 } \
248 } while (0)
249
250 #define KPATH1_VNODE1_TOKENS \
251 do { \
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) { \
257 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
258 kau_write(rec, tok); \
259 } \
260 } while (0)
261
262 #define KPATH2_VNODE2_TOKENS \
263 do { \
264 if (ar->ar_valid_arg & ARG_KPATH2) { \
265 tok = au_to_path(ar->ar_arg_kpath2); \
266 kau_write(rec, tok); \
267 } \
268 if (ar->ar_valid_arg & ARG_VNODE2) { \
269 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
270 kau_write(rec, tok); \
271 } \
272 } while (0)
273
274 #define FD_KPATH1_VNODE1_TOKENS \
275 do { \
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); \
282 } \
283 } else { \
284 tok = au_to_arg32(1, "no path: fd", ar->ar_arg_fd); \
285 kau_write(rec, tok); \
286 } \
287 } while (0)
288
289 #define PROCESS_PID_TOKENS(argn) \
290 do { \
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); \
298 } else { \
299 tok = au_to_arg32(argn, "process", ar->ar_arg_pid);\
300 kau_write(rec, tok); \
301 } \
302 } while (0) \
303
304 /*
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.
308 *
309 */
310 void
311 audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
312 {
313 struct au_token *tok;
314
315 switch (ar->ar_arg_cmd) {
316 case A_SETPOLICY:
317 if (sizeof(ar->ar_arg_auditon.au_flags) > 4)
318 tok = au_to_arg64(1, "policy",
319 ar->ar_arg_auditon.au_flags);
320 else
321 tok = au_to_arg32(1, "policy",
322 ar->ar_arg_auditon.au_flags);
323 kau_write(rec, tok);
324 break;
325 case A_SETKMASK:
326 tok = au_to_arg32(2, "setkmask:as_success",
327 ar->ar_arg_auditon.au_mask.am_success);
328 kau_write(rec, tok);
329 tok = au_to_arg32(2, "setkmask:as_failure",
330 ar->ar_arg_auditon.au_mask.am_failure);
331 kau_write(rec, tok);
332 break;
333 case A_SETQCTRL:
334 tok = au_to_arg32(3, "setqctrl:aq_hiwater",
335 ar->ar_arg_auditon.au_qctrl.aq_hiwater);
336 kau_write(rec, tok);
337 tok = au_to_arg32(3, "setqctrl:aq_lowater",
338 ar->ar_arg_auditon.au_qctrl.aq_lowater);
339 kau_write(rec, tok);
340 tok = au_to_arg32(3, "setqctrl:aq_bufsz",
341 ar->ar_arg_auditon.au_qctrl.aq_bufsz);
342 kau_write(rec, tok);
343 tok = au_to_arg32(3, "setqctrl:aq_delay",
344 ar->ar_arg_auditon.au_qctrl.aq_delay);
345 kau_write(rec, tok);
346 tok = au_to_arg32(3, "setqctrl:aq_minfree",
347 ar->ar_arg_auditon.au_qctrl.aq_minfree);
348 kau_write(rec, tok);
349 break;
350 case A_SETUMASK:
351 tok = au_to_arg32(3, "setumask:as_success",
352 ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
353 kau_write(rec, tok);
354 tok = au_to_arg32(3, "setumask:as_failure",
355 ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
356 kau_write(rec, tok);
357 break;
358 case A_SETSMASK:
359 tok = au_to_arg32(3, "setsmask:as_success",
360 ar->ar_arg_auditon.au_auinfo.ai_mask.am_success);
361 kau_write(rec, tok);
362 tok = au_to_arg32(3, "setsmask:as_failure",
363 ar->ar_arg_auditon.au_auinfo.ai_mask.am_failure);
364 kau_write(rec, tok);
365 break;
366 case A_SETCOND:
367 if (sizeof(ar->ar_arg_auditon.au_cond) > 4)
368 tok = au_to_arg64(3, "setcond",
369 ar->ar_arg_auditon.au_cond);
370 else
371 tok = au_to_arg32(3, "setcond",
372 ar->ar_arg_auditon.au_cond);
373 kau_write(rec, tok);
374 break;
375 case A_SETCLASS:
376 tok = au_to_arg32(2, "setclass:ec_event",
377 ar->ar_arg_auditon.au_evclass.ec_number);
378 kau_write(rec, tok);
379 tok = au_to_arg32(3, "setclass:ec_class",
380 ar->ar_arg_auditon.au_evclass.ec_class);
381 kau_write(rec, tok);
382 break;
383 case A_SETPMASK:
384 tok = au_to_arg32(2, "setpmask:as_success",
385 ar->ar_arg_auditon.au_aupinfo.ap_mask.am_success);
386 kau_write(rec, tok);
387 tok = au_to_arg32(2, "setpmask:as_failure",
388 ar->ar_arg_auditon.au_aupinfo.ap_mask.am_failure);
389 kau_write(rec, tok);
390 break;
391 case A_SETFSIZE:
392 tok = au_to_arg32(2, "setfsize:filesize",
393 ar->ar_arg_auditon.au_fstat.af_filesz);
394 kau_write(rec, tok);
395 break;
396 default:
397 break;
398 }
399 }
400
401 /*
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.
405 * Return conditions:
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.
409 */
410 int
411 kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
412 {
413 struct au_token *tok, *subj_tok;
414 struct au_record *rec;
415 au_tid_t tid;
416 struct audit_record *ar;
417 int ctr;
418
419 *pau = NULL;
420 if (kar == NULL)
421 return (BSM_FAILURE);
422
423 ar = &kar->k_ar;
424
425 rec = kau_open();
426 if (rec == NULL)
427 return (BSM_FAILURE);
428
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 */
439 &tid);
440
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.
445 */
446 switch(ar->ar_event) {
447
448 /*
449 * Socket-related events.
450 */
451 case AUE_ACCEPT:
452 case AUE_BIND:
453 case AUE_CONNECT:
454 case AUE_RECVFROM:
455 case AUE_RECVMSG:
456 case AUE_SENDMSG:
457 case AUE_SENDTO:
458 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
459 kau_write(rec, tok);
460 if (ar->ar_valid_arg & ARG_SADDRINET) {
461 tok = au_to_sock_inet(
462 (struct sockaddr_in *)&ar->ar_arg_sockaddr);
463 kau_write(rec, tok);
464 }
465 if (ar->ar_valid_arg & ARG_SADDRUNIX) {
466 tok = au_to_sock_unix(
467 (struct sockaddr_un *)&ar->ar_arg_sockaddr);
468 kau_write(rec, tok);
469 UPATH1_TOKENS;
470 }
471 /* XXX Need to handle ARG_SADDRINET6 */
472 break;
473
474 case AUE_SOCKET:
475 case AUE_SOCKETPAIR:
476 tok = au_to_arg32(1,"domain", ar->ar_arg_sockinfo.so_domain);
477 kau_write(rec, tok);
478 tok = au_to_arg32(2,"type", ar->ar_arg_sockinfo.so_type);
479 kau_write(rec, tok);
480 tok = au_to_arg32(3,"protocol",ar->ar_arg_sockinfo.so_protocol);
481 kau_write(rec, tok);
482 break;
483
484 case AUE_SETSOCKOPT:
485 case AUE_SHUTDOWN:
486 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
487 kau_write(rec, tok);
488 break;
489
490 case AUE_ACCT:
491 if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
492 UPATH1_KPATH1_VNODE1_TOKENS;
493 } else {
494 tok = au_to_arg32(1, "accounting off", 0);
495 kau_write(rec, tok);
496 }
497 break;
498
499 case AUE_SETAUID:
500 tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
501 kau_write(rec, tok);
502 break;
503
504 case AUE_SETAUDIT:
505 if (ar->ar_valid_arg & ARG_AUID) {
506 tok = au_to_arg32(1, "setaudit:auid", ar->ar_arg_auid);
507 kau_write(rec, tok);
508 tok = au_to_arg32(1, "setaudit:port",
509 ar->ar_arg_termid.port);
510 kau_write(rec, tok);
511 tok = au_to_arg32(1, "setaudit:machine",
512 ar->ar_arg_termid.machine);
513 kau_write(rec, tok);
514 tok = au_to_arg32(1, "setaudit:as_success",
515 ar->ar_arg_amask.am_success);
516 kau_write(rec, tok);
517 tok = au_to_arg32(1, "setaudit:as_failure",
518 ar->ar_arg_amask.am_failure);
519 kau_write(rec, tok);
520 tok = au_to_arg32(1, "setaudit:asid", ar->ar_arg_asid);
521 kau_write(rec, tok);
522 }
523 break;
524
525 case AUE_SETAUDIT_ADDR:
526 break; /* XXX need to add arguments */
527
528 case AUE_AUDITON:
529 /* For AUDITON commands without own event, audit the cmd */
530 tok = au_to_arg32(1, "cmd", ar->ar_arg_cmd);
531 kau_write(rec, tok);
532 /* fall thru */
533
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);
552 }
553 break;
554
555 case AUE_AUDITCTL:
556 UPATH1_KPATH1_VNODE1_TOKENS;
557 break;
558
559 case AUE_ADJTIME:
560 case AUE_AUDIT:
561 case AUE_EXIT:
562 case AUE_GETAUDIT:
563 case AUE_GETAUDIT_ADDR:
564 case AUE_GETAUID:
565 case AUE_GETFSSTAT:
566 case AUE_PIPE:
567 case AUE_SETPGRP:
568 case AUE_SETRLIMIT:
569 case AUE_SETSID:
570 case AUE_SETTIMEOFDAY:
571 case AUE_NEWSYSTEMSHREG:
572 /* Header, subject, and return tokens added at end */
573 break;
574
575 case AUE_ACCESS:
576 case AUE_CHDIR:
577 case AUE_CHROOT:
578 case AUE_EXECVE:
579 case AUE_GETATTRLIST:
580 case AUE_GETFH:
581 case AUE_LSTAT:
582 case AUE_MKFIFO:
583 case AUE_PATHCONF:
584 case AUE_READLINK:
585 case AUE_REVOKE:
586 case AUE_RMDIR:
587 case AUE_SEARCHFS:
588 case AUE_SETATTRLIST:
589 case AUE_STAT:
590 case AUE_STATFS:
591 case AUE_TRUNCATE:
592 case AUE_UNDELETE:
593 case AUE_UNLINK:
594 case AUE_UTIMES:
595 UPATH1_KPATH1_VNODE1_TOKENS;
596 break;
597
598 case AUE_CHFLAGS:
599 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
600 kau_write(rec, tok);
601 UPATH1_KPATH1_VNODE1_TOKENS;
602 break;
603
604 case AUE_CHMOD:
605 tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
606 kau_write(rec, tok);
607 UPATH1_KPATH1_VNODE1_TOKENS;
608 break;
609
610 case AUE_CHOWN:
611 tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
612 kau_write(rec, tok);
613 tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
614 kau_write(rec, tok);
615 UPATH1_KPATH1_VNODE1_TOKENS;
616 break;
617
618 case AUE_EXCHANGEDATA:
619 UPATH1_KPATH1_VNODE1_TOKENS;
620 KPATH2_VNODE2_TOKENS;
621 break;
622
623 case AUE_CLOSE:
624 tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
625 kau_write(rec, tok);
626 UPATH1_KPATH1_VNODE1_TOKENS;
627 break;
628
629 case AUE_FCHMOD:
630 tok = au_to_arg32(2, "new file mode", ar->ar_arg_mode);
631 kau_write(rec, tok);
632 FD_KPATH1_VNODE1_TOKENS;
633 break;
634
635 case AUE_NFSSVC:
636 tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
637 kau_write(rec, tok);
638 if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
639 UPATH1_KPATH1_VNODE1_TOKENS;
640 }
641 break;
642
643 case AUE_FCHDIR:
644 case AUE_FPATHCONF:
645 case AUE_FSTAT: /* XXX Need to handle sockets and shm */
646 case AUE_FSTATFS:
647 case AUE_FTRUNCATE:
648 case AUE_FUTIMES:
649 case AUE_GETDIRENTRIES:
650 case AUE_GETDIRENTRIESATTR:
651 FD_KPATH1_VNODE1_TOKENS;
652 break;
653
654 case AUE_FCHOWN:
655 tok = au_to_arg32(2, "new file uid", ar->ar_arg_uid);
656 kau_write(rec, tok);
657 tok = au_to_arg32(3, "new file gid", ar->ar_arg_gid);
658 kau_write(rec, tok);
659 FD_KPATH1_VNODE1_TOKENS;
660 break;
661
662 case AUE_FCNTL:
663 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
664 kau_write(rec, tok);
665 if (ar->ar_valid_arg & ARG_VNODE1) {
666 FD_KPATH1_VNODE1_TOKENS;
667 }
668 break;
669
670 case AUE_FCHFLAGS:
671 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
672 kau_write(rec, tok);
673 FD_KPATH1_VNODE1_TOKENS;
674 break;
675
676 case AUE_FLOCK:
677 tok = au_to_arg32(2, "operation", ar->ar_arg_cmd);
678 kau_write(rec, tok);
679 FD_KPATH1_VNODE1_TOKENS;
680 break;
681
682 case AUE_FORK:
683 case AUE_VFORK:
684 tok = au_to_arg32(0, "child PID", ar->ar_arg_pid);
685 kau_write(rec, tok);
686 break;
687
688 case AUE_IOCTL:
689 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
690 kau_write(rec, tok);
691 tok = au_to_arg32(1, "arg", (u_int32_t)ar->ar_arg_addr);
692 kau_write(rec, tok);
693 if (ar->ar_valid_arg & ARG_VNODE1) {
694 FD_KPATH1_VNODE1_TOKENS;
695 } else {
696 if (ar->ar_valid_arg & ARG_SOCKINFO) {
697 tok = kau_to_socket(&ar->ar_arg_sockinfo);
698 kau_write(rec, tok);
699 } else {
700 tok = au_to_arg32(1, "fd", ar->ar_arg_fd);
701 kau_write(rec, tok);
702 }
703 }
704 break;
705
706 case AUE_KILL:
707 tok = au_to_arg32(2, "signal", ar->ar_arg_signum);
708 kau_write(rec, tok);
709 PROCESS_PID_TOKENS(1);
710 break;
711
712 case AUE_KTRACE:
713 tok = au_to_arg32(2, "ops", ar->ar_arg_cmd);
714 kau_write(rec, tok);
715 tok = au_to_arg32(3, "trpoints", ar->ar_arg_value);
716 kau_write(rec, tok);
717 PROCESS_PID_TOKENS(4);
718 UPATH1_KPATH1_VNODE1_TOKENS;
719 break;
720
721 case AUE_LINK:
722 case AUE_RENAME:
723 UPATH1_KPATH1_VNODE1_TOKENS;
724 UPATH2_TOKENS;
725 break;
726
727 case AUE_LOADSHFILE:
728 tok = au_to_arg32(4, "base addr", (u_int32_t)ar->ar_arg_addr);
729 kau_write(rec, tok);
730 UPATH1_KPATH1_VNODE1_TOKENS;
731 break;
732
733 case AUE_MKDIR:
734 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
735 kau_write(rec, tok);
736 UPATH1_KPATH1_VNODE1_TOKENS;
737 break;
738
739 case AUE_MKNOD:
740 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
741 kau_write(rec, tok);
742 tok = au_to_arg32(3, "dev", ar->ar_arg_dev);
743 kau_write(rec, tok);
744 UPATH1_KPATH1_VNODE1_TOKENS;
745 break;
746
747 case AUE_MMAP:
748 case AUE_MUNMAP:
749 case AUE_MPROTECT:
750 case AUE_MLOCK:
751 case AUE_MUNLOCK:
752 case AUE_MINHERIT:
753 tok = au_to_arg32(1, "addr", (u_int32_t)ar->ar_arg_addr);
754 kau_write(rec, tok);
755 tok = au_to_arg32(2, "len", ar->ar_arg_len);
756 kau_write(rec, tok);
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);
761 kau_write(rec, tok);
762 }
763 if (ar->ar_event == AUE_MINHERIT) {
764 tok = au_to_arg32(3, "inherit", ar->ar_arg_value);
765 kau_write(rec, tok);
766 }
767 break;
768
769 case AUE_MOUNT:
770 /* XXX Need to handle NFS mounts */
771 tok = au_to_arg32(3, "flags", ar->ar_arg_fflags);
772 kau_write(rec, tok);
773 if (ar->ar_valid_arg & ARG_TEXT) {
774 tok = au_to_text(ar->ar_arg_text);
775 kau_write(rec, tok);
776 }
777 /* fall through */
778 case AUE_UNMOUNT:
779 UPATH1_KPATH1_VNODE1_TOKENS;
780 break;
781
782 case AUE_MSGCTL:
783 ar->ar_event = msgctl_to_event(ar->ar_arg_svipc_cmd);
784 /* Fall through */
785 case AUE_MSGRCV:
786 case AUE_MSGSND:
787 tok = au_to_arg32(1, "msg ID", ar->ar_arg_svipc_id);
788 kau_write(rec, tok);
789 if (ar->ar_errno != EINVAL) {
790 tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
791 kau_write(rec, tok);
792 }
793 break;
794
795 case AUE_MSGGET:
796 if (ar->ar_errno == 0) {
797 tok = au_to_ipc(AT_IPC_MSG, ar->ar_arg_svipc_id);
798 kau_write(rec, tok);
799 }
800 break;
801
802 case AUE_RESETSHFILE:
803 tok = au_to_arg32(1, "base addr", (u_int32_t)ar->ar_arg_addr);
804 kau_write(rec, tok);
805 break;
806
807 case AUE_OPEN_RC:
808 case AUE_OPEN_RTC:
809 case AUE_OPEN_RWC:
810 case AUE_OPEN_RWTC:
811 case AUE_OPEN_WC:
812 case AUE_OPEN_WTC:
813 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
814 kau_write(rec, tok);
815 /* fall thru */
816
817 case AUE_OPEN_R:
818 case AUE_OPEN_RT:
819 case AUE_OPEN_RW:
820 case AUE_OPEN_RWT:
821 case AUE_OPEN_W:
822 case AUE_OPEN_WT:
823 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
824 kau_write(rec, tok);
825 UPATH1_KPATH1_VNODE1_TOKENS;
826 break;
827
828 case AUE_PTRACE:
829 tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
830 kau_write(rec, tok);
831 tok = au_to_arg32(3, "addr", (u_int32_t)ar->ar_arg_addr);
832 kau_write(rec, tok);
833 tok = au_to_arg32(4, "data", ar->ar_arg_value);
834 kau_write(rec, tok);
835 PROCESS_PID_TOKENS(2);
836 break;
837
838 case AUE_QUOTACTL:
839 tok = au_to_arg32(2, "command", ar->ar_arg_cmd);
840 kau_write(rec, tok);
841 tok = au_to_arg32(3, "uid", ar->ar_arg_uid);
842 kau_write(rec, tok);
843 UPATH1_KPATH1_VNODE1_TOKENS;
844 break;
845
846 case AUE_REBOOT:
847 tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
848 kau_write(rec, tok);
849 break;
850
851 case AUE_SEMCTL:
852 ar->ar_event = semctl_to_event(ar->ar_arg_svipc_cmd);
853 /* Fall through */
854 case AUE_SEMOP:
855 tok = au_to_arg32(1, "sem ID", ar->ar_arg_svipc_id);
856 kau_write(rec, tok);
857 if (ar->ar_errno != EINVAL) {
858 tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id);
859 kau_write(rec, tok);
860 }
861 break;
862 case AUE_SEMGET:
863 if (ar->ar_errno == 0) {
864 tok = au_to_ipc(AT_IPC_SEM, ar->ar_arg_svipc_id);
865 kau_write(rec, tok);
866 }
867 break;
868 case AUE_SETEGID:
869 tok = au_to_arg32(1, "gid", ar->ar_arg_egid);
870 kau_write(rec, tok);
871 break;
872 case AUE_SETEUID:
873 tok = au_to_arg32(1, "uid", ar->ar_arg_euid);
874 kau_write(rec, tok);
875 break;
876 case AUE_SETGID:
877 tok = au_to_arg32(1, "gid", ar->ar_arg_gid);
878 kau_write(rec, tok);
879 break;
880 case AUE_SETUID:
881 tok = au_to_arg32(1, "uid", ar->ar_arg_uid);
882 kau_write(rec, tok);
883 break;
884 case AUE_SETGROUPS:
885 if (ar->ar_valid_arg & ARG_GROUPSET) {
886 for(ctr = 0; ctr < ar->ar_arg_groups.gidset_size; ctr++)
887 {
888 tok = au_to_arg32(1, "setgroups", ar->ar_arg_groups.gidset[ctr]);
889 kau_write(rec, tok);
890 }
891 }
892 break;
893
894 case AUE_SETLOGIN:
895 if (ar->ar_valid_arg & ARG_TEXT) {
896 tok = au_to_text(ar->ar_arg_text);
897 kau_write(rec, tok);
898 }
899 break;
900
901 case AUE_SETPRIORITY:
902 tok = au_to_arg32(1, "which", ar->ar_arg_cmd);
903 kau_write(rec, tok);
904 tok = au_to_arg32(2, "who", ar->ar_arg_uid);
905 kau_write(rec, tok);
906 tok = au_to_arg32(2, "priority", ar->ar_arg_value);
907 kau_write(rec, tok);
908 break;
909
910 case AUE_SETPRIVEXEC:
911 tok = au_to_arg32(1, "flag", ar->ar_arg_value);
912 kau_write(rec, tok);
913 break;
914
915 /* AUE_SHMAT, AUE_SHMCTL, AUE_SHMDT and AUE_SHMGET are SysV IPC */
916 case AUE_SHMAT:
917 tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
918 kau_write(rec, tok);
919 tok = au_to_arg32(2, "shmaddr", (int)ar->ar_arg_svipc_addr);
920 kau_write(rec, tok);
921 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
922 tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
923 kau_write(rec, tok);
924 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
925 kau_write(rec, tok);
926 }
927 break;
928
929 case AUE_SHMCTL:
930 tok = au_to_arg32(1, "shmid", ar->ar_arg_svipc_id);
931 kau_write(rec, tok);
932 switch (ar->ar_arg_svipc_cmd) {
933 case IPC_STAT:
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);
938 kau_write(rec, tok);
939 }
940 break;
941 case IPC_RMID:
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);
946 kau_write(rec, tok);
947 }
948 break;
949 case IPC_SET:
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);
954 kau_write(rec, tok);
955 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
956 kau_write(rec, tok);
957 }
958 break;
959 default:
960 break; /* We will audit a bad command */
961 }
962 break;
963
964 case AUE_SHMDT:
965 tok = au_to_arg32(1, "shmaddr", (int)ar->ar_arg_svipc_addr);
966 kau_write(rec, tok);
967 break;
968
969 case AUE_SHMGET:
970 /* This is unusual; the return value is in an argument token */
971 tok = au_to_arg32(0, "shmid", ar->ar_arg_svipc_id);
972 kau_write(rec, tok);
973 if (ar->ar_valid_arg & ARG_SVIPC_PERM) {
974 tok = au_to_ipc(AT_IPC_SHM, ar->ar_arg_svipc_id);
975 kau_write(rec, tok);
976 tok = au_to_ipc_perm(&ar->ar_arg_svipc_perm);
977 kau_write(rec, tok);
978 }
979 break;
980
981 /* AUE_SHMOPEN, AUE_SHMUNLINK, AUE_SEMOPEN, AUE_SEMCLOSE
982 * and AUE_SEMUNLINK are Posix IPC */
983 case AUE_SHMOPEN:
984 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
985 kau_write(rec, tok);
986 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
987 kau_write(rec, tok);
988 case AUE_SHMUNLINK:
989 if (ar->ar_valid_arg & ARG_TEXT) {
990 tok = au_to_text(ar->ar_arg_text);
991 kau_write(rec, tok);
992 }
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;
1001 perm.seq = 0;
1002 perm.key = 0;
1003 tok = au_to_ipc_perm(&perm);
1004 kau_write(rec, tok);
1005 }
1006 break;
1007
1008 case AUE_SEMOPEN:
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);
1015 /* fall through */
1016 case AUE_SEMUNLINK:
1017 if (ar->ar_valid_arg & ARG_TEXT) {
1018 tok = au_to_text(ar->ar_arg_text);
1019 kau_write(rec, tok);
1020 }
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;
1029 perm.seq = 0;
1030 perm.key = 0;
1031 tok = au_to_ipc_perm(&perm);
1032 kau_write(rec, tok);
1033 }
1034 break;
1035
1036 case AUE_SEMCLOSE:
1037 tok = au_to_arg32(1, "sem", ar->ar_arg_fd);
1038 kau_write(rec, tok);
1039 break;
1040
1041 case AUE_SYMLINK:
1042 if (ar->ar_valid_arg & ARG_TEXT) {
1043 tok = au_to_text(ar->ar_arg_text);
1044 kau_write(rec, tok);
1045 }
1046 UPATH1_KPATH1_VNODE1_TOKENS;
1047 break;
1048
1049 case AUE_SYSCTL:
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);
1054 }
1055 }
1056 if (ar->ar_valid_arg & ARG_VALUE) {
1057 tok = au_to_arg32(5, "newval", ar->ar_arg_value);
1058 kau_write(rec, tok);
1059 }
1060 if (ar->ar_valid_arg & ARG_TEXT) {
1061 tok = au_to_text(ar->ar_arg_text);
1062 kau_write(rec, tok);
1063 }
1064 break;
1065
1066 case AUE_UMASK:
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);
1071 break;
1072
1073 /************************
1074 * Mach system calls *
1075 ************************/
1076 case AUE_INITPROCESS:
1077 break;
1078
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);
1085 }
1086 break;
1087
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);
1096 }
1097 PROCESS_PID_TOKENS(2);
1098 break;
1099
1100 case AUE_SWAPON:
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;
1105 break;
1106
1107 case AUE_SWAPOFF:
1108 UPATH1_KPATH1_VNODE1_TOKENS;
1109 break;
1110
1111 case AUE_MAPFD:
1112 tok = au_to_arg32(3, "va", (u_int32_t)ar->ar_arg_addr);
1113 kau_write(rec, tok);
1114 FD_KPATH1_VNODE1_TOKENS;
1115 break;
1116
1117 default: /* We shouldn't fall through to here. */
1118 printf("BSM conversion requested for unknown event %d\n",
1119 ar->ar_event);
1120 kau_free(rec);
1121 return BSM_NOAUDIT;
1122 }
1123
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 */
1127
1128 kau_close(rec, &ar->ar_endtime, ar->ar_event);
1129
1130 *pau = rec;
1131 return BSM_SUCCESS;
1132 }
1133
1134 /*
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.
1138 *
1139 */
1140 int
1141 bsm_rec_verify(void *rec)
1142 {
1143 char c = *(char *)rec;
1144 /*
1145 * Check the token ID of the first token; it has to be a header
1146 * token.
1147 */
1148 /* XXXAUDIT There needs to be a token structure to map a token.
1149 * XXXAUDIT 'Shouldn't be simply looking at the first char.
1150 */
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) ) {
1155 return (0);
1156 }
1157 return (1);
1158 }