]> git.saurik.com Git - apple/xnu.git/blob - bsd/kern/kern_bsm_audit.c
xnu-792.18.15.tar.gz
[apple/xnu.git] / bsd / kern / kern_bsm_audit.c
1 /*
2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. 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
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 #include <sys/types.h>
29 #include <sys/vnode_internal.h>
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>
36 #include <sys/user.h>
37
38 #include <sys/ipc.h>
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
45 #include <netinet/in_systm.h>
46 #include <netinet/in.h>
47 #include <netinet/ip.h>
48
49 #include <kern/lock.h>
50 #include <kern/kalloc.h>
51
52 /* The number of BSM records allocated. */
53 static 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 */
61 LIST_HEAD(, au_record) bsm_free_q;
62
63 /*
64 * Lock for serializing access to the list of audit records.
65 */
66 static mutex_t *bsm_audit_mutex;
67
68 static void audit_sys_auditon(struct audit_record *ar, struct au_record *rec);
69
70 /*
71 * Initialize the BSM auditing subsystem.
72 */
73 void
74 kau_init(void)
75 {
76 printf("BSM auditing present\n");
77 LIST_INIT(&bsm_free_q);
78 bsm_audit_mutex = mutex_alloc(0);
79 au_evclassmap_init();
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 */
90 struct au_record *
91 kau_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 */
117 rec = (struct au_record *)kalloc(sizeof(*rec));
118 if(rec == NULL) {
119 return NULL;
120 }
121 rec->data = (u_char *)kalloc(MAX_AUDIT_RECORD_SIZE * sizeof(u_char));
122 if((rec->data) == NULL) {
123 kfree(rec, sizeof(*rec));
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 */
143 int 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 */
165 int
166 kau_close(struct au_record *rec, struct timespec *ctime, short event)
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 }
196
197 return(retval);
198 }
199
200 /*
201 * Free a BSM audit record by releasing all the tokens and clearing the
202 * audit record information.
203 */
204 void 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);
211 kfree(tok, sizeof(*tok) + tok->len);
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
246 #define UPATH1_KPATH1_VNODE1_TOKENS \
247 do { \
248 if (ar->ar_valid_arg & ARG_UPATH1) { \
249 tok = au_to_path(ar->ar_arg_upath1); \
250 kau_write(rec, tok); \
251 } \
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 KPATH1_VNODE1_TOKENS \
263 do { \
264 if (ar->ar_valid_arg & ARG_KPATH1) { \
265 tok = au_to_path(ar->ar_arg_kpath1); \
266 kau_write(rec, tok); \
267 } \
268 if (ar->ar_valid_arg & ARG_VNODE1) { \
269 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
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) { \
281 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
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) { \
292 tok = kau_to_attr32(&ar->ar_arg_vnode1);\
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
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 */
322 static void
323 audit_sys_auditon(struct audit_record *ar, struct au_record *rec)
324 {
325 struct au_token *tok;
326
327 switch (ar->ar_arg_cmd) {
328 case A_SETPOLICY:
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;
337 case A_SETKMASK:
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;
345 case A_SETQCTRL:
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;
362 case A_SETUMASK:
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;
370 case A_SETSMASK:
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;
378 case A_SETCOND:
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;
387 case A_SETCLASS:
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;
395 case A_SETPMASK:
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;
403 case A_SETFSIZE:
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
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 */
422 int
423 kaudit_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;
429 int ctr;
430
431 *pau = NULL;
432 if (kar == NULL)
433 return (BSM_FAILURE);
434
435 ar = &kar->k_ar;
436
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:
488 tok = au_to_arg32(1,"domain", ar->ar_arg_sockinfo.so_domain);
489 kau_write(rec, tok);
490 tok = au_to_arg32(2,"type", ar->ar_arg_sockinfo.so_type);
491 kau_write(rec, tok);
492 tok = au_to_arg32(3,"protocol",ar->ar_arg_sockinfo.so_protocol);
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
502 case AUE_ACCT:
503 if (ar->ar_valid_arg & (ARG_KPATH1 | ARG_UPATH1)) {
504 UPATH1_KPATH1_VNODE1_TOKENS;
505 } else {
506 tok = au_to_arg32(1, "accounting off", 0);
507 kau_write(rec, tok);
508 }
509 break;
510
511 case AUE_SETAUID:
512 tok = au_to_arg32(2, "setauid", ar->ar_arg_auid);
513 kau_write(rec, tok);
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:
568 UPATH1_KPATH1_VNODE1_TOKENS;
569 break;
570
571 case AUE_ADJTIME:
572 case AUE_AUDIT:
573 case AUE_EXIT:
574 case AUE_GETAUDIT:
575 case AUE_GETAUDIT_ADDR:
576 case AUE_GETAUID:
577 case AUE_GETFSSTAT:
578 case AUE_PIPE:
579 case AUE_SETPGRP:
580 case AUE_SETRLIMIT:
581 case AUE_SETSID:
582 case AUE_SETTIMEOFDAY:
583 case AUE_NEWSYSTEMSHREG:
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:
607 UPATH1_KPATH1_VNODE1_TOKENS;
608 break;
609
610 case AUE_CHFLAGS:
611 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
612 kau_write(rec, tok);
613 UPATH1_KPATH1_VNODE1_TOKENS;
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);
619 UPATH1_KPATH1_VNODE1_TOKENS;
620 break;
621
622 case AUE_CHOWN:
623 case AUE_LCHOWN:
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);
628 UPATH1_KPATH1_VNODE1_TOKENS;
629 break;
630
631 case AUE_EXCHANGEDATA:
632 UPATH1_KPATH1_VNODE1_TOKENS;
633 KPATH2_VNODE2_TOKENS;
634 break;
635
636 case AUE_CLOSE:
637 tok = au_to_arg32(2, "fd", ar->ar_arg_fd);
638 kau_write(rec, tok);
639 UPATH1_KPATH1_VNODE1_TOKENS;
640 break;
641
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
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
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:
676 tok = au_to_arg32(2, "cmd", ar->ar_arg_cmd);
677 kau_write(rec, tok);
678 if (ar->ar_valid_arg & ARG_VNODE1) {
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
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);
731 UPATH1_KPATH1_VNODE1_TOKENS;
732 break;
733
734 case AUE_LINK:
735 case AUE_RENAME:
736 UPATH1_KPATH1_VNODE1_TOKENS;
737 UPATH2_TOKENS;
738 break;
739
740 case AUE_LOADSHFILE:
741 tok = au_to_arg32(4, "base addr", (u_int32_t)ar->ar_arg_addr);
742 kau_write(rec, tok);
743 UPATH1_KPATH1_VNODE1_TOKENS;
744 break;
745
746 case AUE_MKDIR:
747 tok = au_to_arg32(2, "mode", ar->ar_arg_mode);
748 kau_write(rec, tok);
749 UPATH1_KPATH1_VNODE1_TOKENS;
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);
757 UPATH1_KPATH1_VNODE1_TOKENS;
758 break;
759
760 case AUE_MMAP:
761 case AUE_MUNMAP:
762 case AUE_MPROTECT:
763 case AUE_MLOCK:
764 case AUE_MUNLOCK:
765 case AUE_MINHERIT:
766 tok = au_to_arg32(1, "addr", (u_int32_t)ar->ar_arg_addr); /* LP64todo */
767 kau_write(rec, tok);
768 tok = au_to_arg32(2, "len", ar->ar_arg_len); /* LP64todo */
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
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);
786 if (ar->ar_valid_arg & ARG_TEXT) {
787 tok = au_to_text(ar->ar_arg_text);
788 kau_write(rec, tok);
789 }
790 /* fall through */
791 case AUE_UNMOUNT:
792 UPATH1_KPATH1_VNODE1_TOKENS;
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
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
820 case AUE_OPEN_RC:
821 case AUE_OPEN_RTC:
822 case AUE_OPEN_RWC:
823 case AUE_OPEN_RWTC:
824 case AUE_OPEN_WC:
825 case AUE_OPEN_WTC:
826 tok = au_to_arg32(3, "mode", ar->ar_arg_mode);
827 kau_write(rec, tok);
828 /* fall thru */
829
830 case AUE_OPEN:
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:
836 case AUE_OPEN_WT:
837 tok = au_to_arg32(2, "flags", ar->ar_arg_fflags);
838 kau_write(rec, tok);
839 UPATH1_KPATH1_VNODE1_TOKENS;
840 break;
841
842 case AUE_PTRACE:
843 tok = au_to_arg32(1, "request", ar->ar_arg_cmd);
844 kau_write(rec, tok);
845 tok = au_to_arg32(3, "addr", (u_int32_t)ar->ar_arg_addr); /* LP64todo */
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
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);
857 UPATH1_KPATH1_VNODE1_TOKENS;
858 break;
859
860 case AUE_REBOOT:
861 tok = au_to_arg32(1, "howto", ar->ar_arg_cmd);
862 kau_write(rec, tok);
863 break;
864
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 {
902 tok = au_to_arg32(1, "setgroups", ar->ar_arg_groups.gidset[ctr]);
903 kau_write(rec, tok);
904 }
905 }
906 break;
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 */
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
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
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 }
1060 UPATH1_KPATH1_VNODE1_TOKENS;
1061 break;
1062
1063 case AUE_SYSCTL:
1064 case AUE_SYSCTL_NONADMIN:
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
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
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);
1119 UPATH1_KPATH1_VNODE1_TOKENS;
1120 break;
1121
1122 case AUE_SWAPOFF:
1123 UPATH1_KPATH1_VNODE1_TOKENS;
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
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 */
1155 int
1156 bsm_rec_verify(void* rec)
1157 {
1158 char c = *(char *)rec;
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 */
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) ) {
1170 return (0);
1171 }
1172 return (1);
1173 }