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