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