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