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