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