1 /* 2 * Copyright (c) 2004 Apple Computer, Inc. 3 * Copyright (c) 2005 SPARTA, Inc. 4 * All rights reserved. 5 * 6 * This code was developed in part by Robert N. M. Watson, Senior Principal 7 * Scientist, SPARTA, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 18 * its contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR 25 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $P4: //depot/projects/trustedbsd/openbsm/libbsm/bsm_token.c#34 $ 34 */ 35 36 #include <sys/types.h> 37 #ifdef __APPLE__ 38 #include <compat/endian.h> 39 #else /* !__APPLE__ */ 40 #include <sys/endian.h> 41 #endif /* __APPLE__*/ 42 #include <sys/socket.h> 43 #include <sys/time.h> 44 #include <sys/un.h> 45 46 #include <sys/ipc.h> 47 48 #include <netinet/in.h> 49 #include <netinet/in_systm.h> 50 #include <netinet/ip.h> 51 52 #include <assert.h> 53 #include <errno.h> 54 #include <string.h> 55 #include <stdlib.h> 56 #include <unistd.h> 57 #include <sys/socketvar.h> 58 59 #include <bsm/audit_internal.h> 60 #include <bsm/libbsm.h> 61 62 #define GET_TOKEN_AREA(t, dptr, length) do { \ 63 (t) = malloc(sizeof(token_t)); \ 64 if ((t) != NULL) { \ 65 (t)->len = (length); \ 66 (dptr) = (t->t_data) = malloc((length) * sizeof(u_char)); \ 67 if ((dptr) == NULL) { \ 68 free(t); \ 69 (t) = NULL; \ 70 } else \ 71 memset((dptr), 0, (length)); \ 72 } else \ 73 (dptr) = NULL; \ 74 assert(t == NULL || dptr != NULL); \ 75 } while (0) 76 77 /* 78 * token ID 1 byte 79 * argument # 1 byte 80 * argument value 4 bytes/8 bytes (32-bit/64-bit value) 81 * text length 2 bytes 82 * text N bytes + 1 terminating NULL byte 83 */ 84 token_t * 85 au_to_arg32(char n, char *text, u_int32_t v) 86 { 87 token_t *t; 88 u_char *dptr = NULL; 89 u_int16_t textlen; 90 91 textlen = strlen(text); 92 textlen += 1; 93 94 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t) + 95 sizeof(u_int16_t) + textlen); 96 if (t == NULL) 97 return (NULL); 98 99 ADD_U_CHAR(dptr, AUT_ARG32); 100 ADD_U_CHAR(dptr, n); 101 ADD_U_INT32(dptr, v); 102 ADD_U_INT16(dptr, textlen); 103 ADD_STRING(dptr, text, textlen); 104 105 return (t); 106 107 } 108 109 token_t * 110 au_to_arg64(char n, char *text, u_int64_t v) 111 { 112 token_t *t; 113 u_char *dptr = NULL; 114 u_int16_t textlen; 115 116 textlen = strlen(text); 117 textlen += 1; 118 119 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t) + 120 sizeof(u_int16_t) + textlen); 121 if (t == NULL) 122 return (NULL); 123 124 ADD_U_CHAR(dptr, AUT_ARG64); 125 ADD_U_CHAR(dptr, n); 126 ADD_U_INT64(dptr, v); 127 ADD_U_INT16(dptr, textlen); 128 ADD_STRING(dptr, text, textlen); 129 130 return (t); 131 132 } 133 134 token_t * 135 au_to_arg(char n, char *text, u_int32_t v) 136 { 137 138 return (au_to_arg32(n, text, v)); 139 } 140 141 #if defined(_KERNEL) || defined(KERNEL) 142 /* 143 * token ID 1 byte 144 * file access mode 4 bytes 145 * owner user ID 4 bytes 146 * owner group ID 4 bytes 147 * file system ID 4 bytes 148 * node ID 8 bytes 149 * device 4 bytes/8 bytes (32-bit/64-bit) 150 */ 151 token_t * 152 au_to_attr32(struct vnode_au_info *vni) 153 { 154 token_t *t; 155 u_char *dptr = NULL; 156 u_int16_t pad0_16 = 0; 157 u_int16_t pad0_32 = 0; 158 159 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int16_t) + 160 3 * sizeof(u_int32_t) + sizeof(u_int64_t) + sizeof(u_int32_t)); 161 if (t == NULL) 162 return (NULL); 163 164 ADD_U_CHAR(dptr, AUT_ATTR32); 165 166 /* 167 * Darwin defines the size for the file mode 168 * as 2 bytes; BSM defines 4 so pad with 0 169 */ 170 ADD_U_INT16(dptr, pad0_16); 171 ADD_U_INT16(dptr, vni->vn_mode); 172 173 ADD_U_INT32(dptr, vni->vn_uid); 174 ADD_U_INT32(dptr, vni->vn_gid); 175 ADD_U_INT32(dptr, vni->vn_fsid); 176 177 /* 178 * Some systems use 32-bit file ID's, other's use 64-bit file IDs. 179 * Attempt to handle both, and let the compiler sort it out. If we 180 * could pick this out at compile-time, it would be better, so as to 181 * avoid the else case below. 182 */ 183 if (sizeof(vni->vn_fileid) == sizeof(uint32_t)) { 184 ADD_U_INT32(dptr, pad0_32); 185 ADD_U_INT32(dptr, vni->vn_fileid); 186 } else if (sizeof(vni->vn_fileid) == sizeof(uint64_t)) 187 ADD_U_INT64(dptr, vni->vn_fileid); 188 else 189 ADD_U_INT64(dptr, 0LL); 190 191 ADD_U_INT32(dptr, vni->vn_dev); 192 193 return (t); 194 } 195 196 token_t * 197 au_to_attr64(struct vnode_au_info *vni) 198 { 199 200 errno = ENOTSUP; 201 return (NULL); 202 } 203 204 token_t * 205 au_to_attr(struct vnode_au_info *vni) 206 { 207 208 return (au_to_attr32(vni)); 209 } 210 #endif /* !(defined(_KERNEL) || defined(KERNEL) */ 211 212 /* 213 * token ID 1 byte 214 * how to print 1 byte 215 * basic unit 1 byte 216 * unit count 1 byte 217 * data items (depends on basic unit) 218 */ 219 token_t * 220 au_to_data(char unit_print, char unit_type, char unit_count, char *p) 221 { 222 token_t *t; 223 u_char *dptr = NULL; 224 size_t datasize, totdata; 225 226 /* Determine the size of the basic unit. */ 227 switch (unit_type) { 228 case AUR_BYTE: 229 datasize = AUR_BYTE_SIZE; 230 break; 231 232 case AUR_SHORT: 233 datasize = AUR_SHORT_SIZE; 234 break; 235 236 case AUR_LONG: 237 datasize = AUR_LONG_SIZE; 238 break; 239 240 default: 241 errno = EINVAL; 242 return (NULL); 243 } 244 245 totdata = datasize * unit_count; 246 247 GET_TOKEN_AREA(t, dptr, totdata + 4 * sizeof(u_char)); 248 if (t == NULL) 249 return (NULL); 250 251 ADD_U_CHAR(dptr, AUT_DATA); 252 ADD_U_CHAR(dptr, unit_print); 253 ADD_U_CHAR(dptr, unit_type); 254 ADD_U_CHAR(dptr, unit_count); 255 ADD_MEM(dptr, p, totdata); 256 257 return (t); 258 } 259 260 261 /* 262 * token ID 1 byte 263 * status 4 bytes 264 * return value 4 bytes 265 */ 266 token_t * 267 au_to_exit(int retval, int err) 268 { 269 token_t *t; 270 u_char *dptr = NULL; 271 272 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); 273 if (t == NULL) 274 return (NULL); 275 276 ADD_U_CHAR(dptr, AUT_EXIT); 277 ADD_U_INT32(dptr, err); 278 ADD_U_INT32(dptr, retval); 279 280 return (t); 281 } 282 283 /* 284 */ 285 token_t * 286 au_to_groups(int *groups) 287 { 288 289 return (au_to_newgroups(BSM_MAX_GROUPS, groups)); 290 } 291 292 /* 293 * token ID 1 byte 294 * number groups 2 bytes 295 * group list count * 4 bytes 296 */ 297 token_t * 298 au_to_newgroups(u_int16_t n, gid_t *groups) 299 { 300 token_t *t; 301 u_char *dptr = NULL; 302 int i; 303 304 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 305 n * sizeof(u_int32_t)); 306 if (t == NULL) 307 return (NULL); 308 309 ADD_U_CHAR(dptr, AUT_NEWGROUPS); 310 ADD_U_INT16(dptr, n); 311 for (i = 0; i < n; i++) 312 ADD_U_INT32(dptr, groups[i]); 313 314 return (t); 315 } 316 317 /* 318 * token ID 1 byte 319 * internet address 4 bytes 320 */ 321 token_t * 322 au_to_in_addr(struct in_addr *internet_addr) 323 { 324 token_t *t; 325 u_char *dptr = NULL; 326 327 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); 328 if (t == NULL) 329 return (NULL); 330 331 ADD_U_CHAR(dptr, AUT_IN_ADDR); 332 ADD_U_INT32(dptr, internet_addr->s_addr); 333 334 return (t); 335 } 336 337 /* 338 * token ID 1 byte 339 * address type/length 4 bytes 340 * Address 16 bytes 341 */ 342 token_t * 343 au_to_in_addr_ex(struct in6_addr *internet_addr) 344 { 345 token_t *t; 346 u_char *dptr = NULL; 347 u_int32_t type = AF_INET6; 348 349 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(u_int32_t)); 350 if (t == NULL) 351 return (NULL); 352 353 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); 354 ADD_U_INT32(dptr, type); 355 ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[0]); 356 ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[1]); 357 ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[2]); 358 ADD_U_INT32(dptr, internet_addr->__u6_addr.__u6_addr32[3]); 359 360 return (t); 361 } 362 363 /* 364 * token ID 1 byte 365 * ip header 20 bytes 366 */ 367 token_t * 368 au_to_ip(struct ip *ip) 369 { 370 token_t *t; 371 u_char *dptr = NULL; 372 373 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); 374 if (t == NULL) 375 return (NULL); 376 377 ADD_U_CHAR(dptr, AUT_IP); 378 /* 379 * XXXRW: Any byte order work needed on the IP header before writing? 380 */ 381 ADD_MEM(dptr, ip, sizeof(struct ip)); 382 383 return (t); 384 } 385 386 /* 387 * token ID 1 byte 388 * object ID type 1 byte 389 * object ID 4 bytes 390 */ 391 token_t * 392 au_to_ipc(char type, int id) 393 { 394 token_t *t; 395 u_char *dptr = NULL; 396 397 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 398 if (t == NULL) 399 return (NULL); 400 401 ADD_U_CHAR(dptr, AUT_IPC); 402 ADD_U_CHAR(dptr, type); 403 ADD_U_INT32(dptr, id); 404 405 return (t); 406 } 407 408 /* 409 * token ID 1 byte 410 * owner user ID 4 bytes 411 * owner group ID 4 bytes 412 * creator user ID 4 bytes 413 * creator group ID 4 bytes 414 * access mode 4 bytes 415 * slot sequence # 4 bytes 416 * key 4 bytes 417 */ 418 token_t * 419 au_to_ipc_perm(struct ipc_perm *perm) 420 { 421 token_t *t; 422 u_char *dptr = NULL; 423 u_int16_t pad0 = 0; 424 425 GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t)); 426 if (t == NULL) 427 return (NULL); 428 429 ADD_U_CHAR(dptr, AUT_IPC_PERM); 430 431 /* 432 * Darwin defines the sizes for ipc_perm members 433 * as 2 bytes; BSM defines 4 so pad with 0 434 */ 435 ADD_U_INT16(dptr, pad0); 436 ADD_U_INT16(dptr, perm->uid); 437 438 ADD_U_INT16(dptr, pad0); 439 ADD_U_INT16(dptr, perm->gid); 440 441 ADD_U_INT16(dptr, pad0); 442 ADD_U_INT16(dptr, perm->cuid); 443 444 ADD_U_INT16(dptr, pad0); 445 ADD_U_INT16(dptr, perm->cgid); 446 447 ADD_U_INT16(dptr, pad0); 448 ADD_U_INT16(dptr, perm->mode); 449 450 ADD_U_INT16(dptr, pad0); 451 ADD_U_INT16(dptr, perm->seq); 452 453 ADD_U_INT32(dptr, perm->key); 454 455 return (t); 456 } 457 458 /* 459 * token ID 1 byte 460 * port IP address 2 bytes 461 */ 462 token_t * 463 au_to_iport(u_int16_t iport) 464 { 465 token_t *t; 466 u_char *dptr = NULL; 467 468 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); 469 if (t == NULL) 470 return (NULL); 471 472 ADD_U_CHAR(dptr, AUT_IPORT); 473 ADD_U_INT16(dptr, iport); 474 475 return (t); 476 } 477 478 /* 479 * token ID 1 byte 480 * size 2 bytes 481 * data size bytes 482 */ 483 token_t * 484 au_to_opaque(char *data, u_int16_t bytes) 485 { 486 token_t *t; 487 u_char *dptr = NULL; 488 489 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); 490 if (t == NULL) 491 return (NULL); 492 493 ADD_U_CHAR(dptr, AUT_OPAQUE); 494 ADD_U_INT16(dptr, bytes); 495 ADD_MEM(dptr, data, bytes); 496 497 return (t); 498 } 499 500 /* 501 * token ID 1 byte 502 * seconds of time 4 bytes 503 * milliseconds of time 4 bytes 504 * file name len 2 bytes 505 * file pathname N bytes + 1 terminating NULL byte 506 */ 507 token_t * 508 #if defined(KERNEL) || defined(_KERNEL) 509 au_to_file(char *file, struct timeval tm) 510 #else 511 au_to_file(char *file) 512 #endif 513 { 514 token_t *t; 515 u_char *dptr = NULL; 516 u_int16_t filelen; 517 u_int32_t timems; 518 #if !defined(KERNEL) && !defined(_KERNEL) 519 struct timeval tm; 520 struct timezone tzp; 521 522 if (gettimeofday(&tm, &tzp) == -1) 523 return (NULL); 524 #endif 525 526 filelen = strlen(file); 527 filelen += 1; 528 529 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + 530 sizeof(u_int16_t) + filelen); 531 if (t == NULL) 532 return (NULL); 533 534 timems = tm.tv_usec/1000; 535 536 ADD_U_CHAR(dptr, AUT_OTHER_FILE32); 537 ADD_U_INT32(dptr, tm.tv_sec); 538 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 539 ADD_U_INT16(dptr, filelen); 540 ADD_STRING(dptr, file, filelen); 541 542 return (t); 543 } 544 545 /* 546 * token ID 1 byte 547 * text length 2 bytes 548 * text N bytes + 1 terminating NULL byte 549 */ 550 token_t * 551 au_to_text(char *text) 552 { 553 token_t *t; 554 u_char *dptr = NULL; 555 u_int16_t textlen; 556 557 textlen = strlen(text); 558 textlen += 1; 559 560 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 561 if (t == NULL) 562 return (NULL); 563 564 ADD_U_CHAR(dptr, AUT_TEXT); 565 ADD_U_INT16(dptr, textlen); 566 ADD_STRING(dptr, text, textlen); 567 568 return (t); 569 } 570 571 /* 572 * token ID 1 byte 573 * path length 2 bytes 574 * path N bytes + 1 terminating NULL byte 575 */ 576 token_t * 577 au_to_path(char *text) 578 { 579 token_t *t; 580 u_char *dptr = NULL; 581 u_int16_t textlen; 582 583 textlen = strlen(text); 584 textlen += 1; 585 586 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 587 if (t == NULL) 588 return (NULL); 589 590 ADD_U_CHAR(dptr, AUT_PATH); 591 ADD_U_INT16(dptr, textlen); 592 ADD_STRING(dptr, text, textlen); 593 594 return (t); 595 } 596 597 /* 598 * token ID 1 byte 599 * audit ID 4 bytes 600 * effective user ID 4 bytes 601 * effective group ID 4 bytes 602 * real user ID 4 bytes 603 * real group ID 4 bytes 604 * process ID 4 bytes 605 * session ID 4 bytes 606 * terminal ID 607 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 608 * machine address 4 bytes 609 */ 610 token_t * 611 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 612 pid_t pid, au_asid_t sid, au_tid_t *tid) 613 { 614 token_t *t; 615 u_char *dptr = NULL; 616 617 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 618 if (t == NULL) 619 return (NULL); 620 621 ADD_U_CHAR(dptr, AUT_PROCESS32); 622 ADD_U_INT32(dptr, auid); 623 ADD_U_INT32(dptr, euid); 624 ADD_U_INT32(dptr, egid); 625 ADD_U_INT32(dptr, ruid); 626 ADD_U_INT32(dptr, rgid); 627 ADD_U_INT32(dptr, pid); 628 ADD_U_INT32(dptr, sid); 629 ADD_U_INT32(dptr, tid->port); 630 ADD_U_INT32(dptr, tid->machine); 631 632 return (t); 633 } 634 635 token_t * 636 au_to_process64(__unused au_id_t auid, __unused uid_t euid, 637 __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, 638 __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) 639 { 640 641 errno = ENOTSUP; 642 return (NULL); 643 } 644 645 token_t * 646 au_to_process(__unused au_id_t auid, __unused uid_t euid, 647 __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, 648 __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) 649 { 650 651 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, 652 tid)); 653 } 654 655 /* 656 * token ID 1 byte 657 * audit ID 4 bytes 658 * effective user ID 4 bytes 659 * effective group ID 4 bytes 660 * real user ID 4 bytes 661 * real group ID 4 bytes 662 * process ID 4 bytes 663 * session ID 4 bytes 664 * terminal ID 665 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 666 * address type-len 4 bytes 667 * machine address 16 bytes 668 */ 669 token_t * 670 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 671 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 672 { 673 token_t *t; 674 u_char *dptr = NULL; 675 676 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t)); 677 if (t == NULL) 678 return (NULL); 679 680 ADD_U_CHAR(dptr, AUT_PROCESS32_EX); 681 ADD_U_INT32(dptr, auid); 682 ADD_U_INT32(dptr, euid); 683 ADD_U_INT32(dptr, egid); 684 ADD_U_INT32(dptr, ruid); 685 ADD_U_INT32(dptr, rgid); 686 ADD_U_INT32(dptr, pid); 687 ADD_U_INT32(dptr, sid); 688 ADD_U_INT32(dptr, tid->at_port); 689 ADD_U_INT32(dptr, tid->at_type); 690 ADD_U_INT32(dptr, tid->at_addr[0]); 691 ADD_U_INT32(dptr, tid->at_addr[1]); 692 ADD_U_INT32(dptr, tid->at_addr[2]); 693 ADD_U_INT32(dptr, tid->at_addr[3]); 694 695 return (t); 696 } 697 698 token_t * 699 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 700 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 701 { 702 703 errno = ENOTSUP; 704 return (NULL); 705 } 706 707 token_t * 708 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 709 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 710 { 711 712 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, 713 tid)); 714 } 715 716 /* 717 * token ID 1 byte 718 * error status 1 byte 719 * return value 4 bytes/8 bytes (32-bit/64-bit value) 720 */ 721 token_t * 722 au_to_return32(char status, u_int32_t ret) 723 { 724 token_t *t; 725 u_char *dptr = NULL; 726 727 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 728 if (t == NULL) 729 return (NULL); 730 731 ADD_U_CHAR(dptr, AUT_RETURN32); 732 ADD_U_CHAR(dptr, status); 733 ADD_U_INT32(dptr, ret); 734 735 return (t); 736 } 737 738 token_t * 739 au_to_return64(char status, u_int64_t ret) 740 { 741 token_t *t; 742 u_char *dptr = NULL; 743 744 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); 745 if (t == NULL) 746 return (NULL); 747 748 ADD_U_CHAR(dptr, AUT_RETURN64); 749 ADD_U_CHAR(dptr, status); 750 ADD_U_INT64(dptr, ret); 751 752 return (t); 753 } 754 755 token_t * 756 au_to_return(char status, u_int32_t ret) 757 { 758 759 return (au_to_return32(status, ret)); 760 } 761 762 /* 763 * token ID 1 byte 764 * sequence number 4 bytes 765 */ 766 token_t * 767 au_to_seq(long audit_count) 768 { 769 token_t *t; 770 u_char *dptr = NULL; 771 772 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); 773 if (t == NULL) 774 return (NULL); 775 776 ADD_U_CHAR(dptr, AUT_SEQ); 777 ADD_U_INT32(dptr, audit_count); 778 779 return (t); 780 } 781 782 /* 783 * token ID 1 byte 784 * socket type 2 bytes 785 * local port 2 bytes 786 * local Internet address 4 bytes 787 * remote port 2 bytes 788 * remote Internet address 4 bytes 789 */ 790 token_t * 791 au_to_socket(struct socket *so) 792 { 793 794 errno = ENOTSUP; 795 return (NULL); 796 } 797 798 /* 799 * token ID 1 byte 800 * socket type 2 bytes 801 * local port 2 bytes 802 * address type/length 4 bytes 803 * local Internet address 4 bytes/16 bytes (IPv4/IPv6 address) 804 * remote port 4 bytes 805 * address type/length 4 bytes 806 * remote Internet address 4 bytes/16 bytes (IPv4/IPv6 address) 807 */ 808 token_t * 809 au_to_socket_ex_32(u_int16_t lp, u_int16_t rp, struct sockaddr *la, 810 struct sockaddr *ra) 811 { 812 813 errno = ENOTSUP; 814 return (NULL); 815 } 816 817 token_t * 818 au_to_socket_ex_128(u_int16_t lp, u_int16_t rp, struct sockaddr *la, 819 struct sockaddr *ra) 820 { 821 822 errno = ENOTSUP; 823 return (NULL); 824 } 825 826 /* 827 * token ID 1 byte 828 * socket family 2 bytes 829 * path 104 bytes 830 */ 831 token_t * 832 au_to_sock_unix(struct sockaddr_un *so) 833 { 834 token_t *t; 835 u_char *dptr; 836 837 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); 838 if (t == NULL) 839 return (NULL); 840 841 ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN); 842 /* BSM token has two bytes for family */ 843 ADD_U_CHAR(dptr, 0); 844 ADD_U_CHAR(dptr, so->sun_family); 845 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); 846 847 return (t); 848 } 849 850 /* 851 * token ID 1 byte 852 * socket family 2 bytes 853 * local port 2 bytes 854 * socket address 4 bytes 855 */ 856 token_t * 857 au_to_sock_inet32(struct sockaddr_in *so) 858 { 859 token_t *t; 860 u_char *dptr = NULL; 861 862 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + 863 sizeof(u_int32_t)); 864 if (t == NULL) 865 return (NULL); 866 867 ADD_U_CHAR(dptr, AUT_SOCKINET32); 868 /* 869 * In Darwin, sin_family is one octet, but BSM defines the token 870 * to store two. So we copy in a 0 first. 871 */ 872 ADD_U_CHAR(dptr, 0); 873 ADD_U_CHAR(dptr, so->sin_family); 874 ADD_U_INT16(dptr, so->sin_port); 875 ADD_U_INT32(dptr, so->sin_addr.s_addr); 876 877 return (t); 878 879 } 880 881 token_t * 882 au_to_sock_inet128(struct sockaddr_in6 *so) 883 { 884 token_t *t; 885 u_char *dptr = NULL; 886 887 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + 888 4 * sizeof(u_int32_t)); 889 if (t == NULL) 890 return (NULL); 891 892 ADD_U_CHAR(dptr, AUT_SOCKINET128); 893 /* 894 * In Darwin, sin6_family is one octet, but BSM defines the token 895 * to store two. So we copy in a 0 first. 896 */ 897 ADD_U_CHAR(dptr, 0); 898 ADD_U_CHAR(dptr, so->sin6_family); 899 900 ADD_U_INT16(dptr, so->sin6_port); 901 ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[0]); 902 ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[1]); 903 ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[2]); 904 ADD_U_INT32(dptr, so->sin6_addr.__u6_addr.__u6_addr32[3]); 905 906 return (t); 907 908 } 909 910 token_t * 911 au_to_sock_inet(struct sockaddr_in *so) 912 { 913 914 return (au_to_sock_inet32(so)); 915 } 916 917 /* 918 * token ID 1 byte 919 * audit ID 4 bytes 920 * effective user ID 4 bytes 921 * effective group ID 4 bytes 922 * real user ID 4 bytes 923 * real group ID 4 bytes 924 * process ID 4 bytes 925 * session ID 4 bytes 926 * terminal ID 927 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 928 * machine address 4 bytes 929 */ 930 token_t * 931 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 932 pid_t pid, au_asid_t sid, au_tid_t *tid) 933 { 934 token_t *t; 935 u_char *dptr = NULL; 936 937 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 938 if (t == NULL) 939 return (NULL); 940 941 ADD_U_CHAR(dptr, AUT_SUBJECT32); 942 ADD_U_INT32(dptr, auid); 943 ADD_U_INT32(dptr, euid); 944 ADD_U_INT32(dptr, egid); 945 ADD_U_INT32(dptr, ruid); 946 ADD_U_INT32(dptr, rgid); 947 ADD_U_INT32(dptr, pid); 948 ADD_U_INT32(dptr, sid); 949 ADD_U_INT32(dptr, tid->port); 950 ADD_U_INT32(dptr, tid->machine); 951 952 return (t); 953 } 954 955 token_t * 956 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 957 pid_t pid, au_asid_t sid, au_tid_t *tid) 958 { 959 960 errno = ENOTSUP; 961 return (NULL); 962 } 963 964 token_t * 965 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 966 pid_t pid, au_asid_t sid, au_tid_t *tid) 967 { 968 969 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, 970 tid)); 971 } 972 973 /* 974 * token ID 1 byte 975 * audit ID 4 bytes 976 * effective user ID 4 bytes 977 * effective group ID 4 bytes 978 * real user ID 4 bytes 979 * real group ID 4 bytes 980 * process ID 4 bytes 981 * session ID 4 bytes 982 * terminal ID 983 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 984 * address type/length 4 bytes 985 * machine address 16 bytes 986 */ 987 token_t * 988 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 989 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 990 { 991 token_t *t; 992 u_char *dptr = NULL; 993 994 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * sizeof(u_int32_t)); 995 if (t == NULL) 996 return (NULL); 997 998 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); 999 ADD_U_INT32(dptr, auid); 1000 ADD_U_INT32(dptr, euid); 1001 ADD_U_INT32(dptr, egid); 1002 ADD_U_INT32(dptr, ruid); 1003 ADD_U_INT32(dptr, rgid); 1004 ADD_U_INT32(dptr, pid); 1005 ADD_U_INT32(dptr, sid); 1006 ADD_U_INT32(dptr, tid->at_port); 1007 ADD_U_INT32(dptr, tid->at_type); 1008 ADD_U_INT32(dptr, tid->at_addr[0]); 1009 ADD_U_INT32(dptr, tid->at_addr[1]); 1010 ADD_U_INT32(dptr, tid->at_addr[2]); 1011 ADD_U_INT32(dptr, tid->at_addr[3]); 1012 1013 return (t); 1014 } 1015 1016 token_t * 1017 au_to_subject64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1018 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1019 { 1020 1021 errno = ENOTSUP; 1022 return (NULL); 1023 } 1024 1025 token_t * 1026 au_to_subject_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 1027 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 1028 { 1029 1030 return (au_to_subject32_ex(auid, euid, egid, ruid, rgid, pid, sid, 1031 tid)); 1032 } 1033 1034 #if !defined(_KERNEL) && !defined(KERNEL) 1035 /* 1036 * Collects audit information for the current process 1037 * and creates a subject token from it 1038 */ 1039 token_t * 1040 au_to_me(void) 1041 { 1042 auditinfo_t auinfo; 1043 1044 if (getaudit(&auinfo) != 0) 1045 return (NULL); 1046 1047 return (au_to_subject32(auinfo.ai_auid, geteuid(), getegid(), 1048 getuid(), getgid(), getpid(), auinfo.ai_asid, &auinfo.ai_termid)); 1049 } 1050 #endif 1051 1052 /* 1053 * token ID 1 byte 1054 * count 4 bytes 1055 * text count null-terminated strings 1056 */ 1057 token_t * 1058 au_to_exec_args(const char **args) 1059 { 1060 token_t *t; 1061 u_char *dptr = NULL; 1062 const char *nextarg; 1063 int i, count = 0; 1064 size_t totlen = 0; 1065 1066 nextarg = *args; 1067 1068 while (nextarg != NULL) { 1069 int nextlen; 1070 1071 nextlen = strlen(nextarg); 1072 totlen += nextlen + 1; 1073 count++; 1074 nextarg = *(args + count); 1075 } 1076 1077 totlen += count * sizeof(char); /* nul terminations. */ 1078 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1079 if (t == NULL) 1080 return (NULL); 1081 1082 ADD_U_CHAR(dptr, AUT_EXEC_ARGS); 1083 ADD_U_INT32(dptr, count); 1084 1085 for (i = 0; i < count; i++) { 1086 nextarg = *(args + i); 1087 ADD_MEM(dptr, nextarg, strlen(nextarg) + 1); 1088 } 1089 1090 return (t); 1091 } 1092 1093 /* 1094 * token ID 1 byte 1095 * count 4 bytes 1096 * text count null-terminated strings 1097 */ 1098 token_t * 1099 au_to_exec_env(const char **env) 1100 { 1101 token_t *t; 1102 u_char *dptr = NULL; 1103 int i, count = 0; 1104 size_t totlen = 0; 1105 const char *nextenv; 1106 1107 nextenv = *env; 1108 1109 while (nextenv != NULL) { 1110 int nextlen; 1111 1112 nextlen = strlen(nextenv); 1113 totlen += nextlen + 1; 1114 count++; 1115 nextenv = *(env + count); 1116 } 1117 1118 totlen += sizeof(char) * count; 1119 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + totlen); 1120 if (t == NULL) 1121 return (NULL); 1122 1123 ADD_U_CHAR(dptr, AUT_EXEC_ENV); 1124 ADD_U_INT32(dptr, count); 1125 1126 for (i = 0; i < count; i++) { 1127 nextenv = *(env + i); 1128 ADD_MEM(dptr, nextenv, strlen(nextenv) + 1); 1129 } 1130 1131 return (t); 1132 } 1133 1134 /* 1135 * token ID 1 byte 1136 * record byte count 4 bytes 1137 * version # 1 byte [2] 1138 * event type 2 bytes 1139 * event modifier 2 bytes 1140 * seconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1141 * milliseconds of time 4 bytes/8 bytes (32-bit/64-bit value) 1142 */ 1143 token_t * 1144 #if defined(KERNEL) || defined(_KERNEL) 1145 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod, 1146 struct timeval tm) 1147 #else 1148 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) 1149 #endif 1150 { 1151 token_t *t; 1152 u_char *dptr = NULL; 1153 u_int32_t timems; 1154 #if !defined(KERNEL) && !defined(_KERNEL) 1155 struct timeval tm; 1156 struct timezone tzp; 1157 1158 if (gettimeofday(&tm, &tzp) == -1) 1159 return (NULL); 1160 #endif 1161 1162 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1163 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); 1164 if (t == NULL) 1165 return (NULL); 1166 1167 ADD_U_CHAR(dptr, AUT_HEADER32); 1168 ADD_U_INT32(dptr, rec_size); 1169 ADD_U_CHAR(dptr, HEADER_VERSION); 1170 ADD_U_INT16(dptr, e_type); 1171 ADD_U_INT16(dptr, e_mod); 1172 1173 timems = tm.tv_usec/1000; 1174 /* Add the timestamp */ 1175 ADD_U_INT32(dptr, tm.tv_sec); 1176 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 1177 1178 return (t); 1179 } 1180 1181 token_t * 1182 au_to_header64(__unused int rec_size, __unused au_event_t e_type, 1183 __unused au_emod_t e_mod) 1184 { 1185 1186 errno = ENOTSUP; 1187 return (NULL); 1188 } 1189 1190 token_t * 1191 au_to_header(int rec_size, au_event_t e_type, au_emod_t e_mod) 1192 { 1193 1194 return (au_to_header32(rec_size, e_type, e_mod)); 1195 } 1196 1197 /* 1198 * token ID 1 byte 1199 * trailer magic number 2 bytes 1200 * record byte count 4 bytes 1201 */ 1202 token_t * 1203 au_to_trailer(int rec_size) 1204 { 1205 token_t *t; 1206 u_char *dptr = NULL; 1207 u_int16_t magic = TRAILER_PAD_MAGIC; 1208 1209 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 1210 sizeof(u_int32_t)); 1211 if (t == NULL) 1212 return (NULL); 1213 1214 ADD_U_CHAR(dptr, AUT_TRAILER); 1215 ADD_U_INT16(dptr, magic); 1216 ADD_U_INT32(dptr, rec_size); 1217 1218 return (t); 1219 } 1220