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#48 $ 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 /* case AUR_CHAR: */ 247 datasize = AUR_BYTE_SIZE; 248 break; 249 250 case AUR_SHORT: 251 datasize = AUR_SHORT_SIZE; 252 break; 253 254 case AUR_INT32: 255 /* case AUR_INT: */ 256 datasize = AUR_INT32_SIZE; 257 break; 258 259 case AUR_INT64: 260 datasize = AUR_INT64_SIZE; 261 break; 262 263 default: 264 errno = EINVAL; 265 return (NULL); 266 } 267 268 totdata = datasize * unit_count; 269 270 GET_TOKEN_AREA(t, dptr, 4 * sizeof(u_char) + totdata); 271 if (t == NULL) 272 return (NULL); 273 274 ADD_U_CHAR(dptr, AUT_DATA); 275 ADD_U_CHAR(dptr, unit_print); 276 ADD_U_CHAR(dptr, unit_type); 277 ADD_U_CHAR(dptr, unit_count); 278 ADD_MEM(dptr, p, totdata); 279 280 return (t); 281 } 282 283 284 /* 285 * token ID 1 byte 286 * status 4 bytes 287 * return value 4 bytes 288 */ 289 token_t * 290 au_to_exit(int retval, int err) 291 { 292 token_t *t; 293 u_char *dptr = NULL; 294 295 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t)); 296 if (t == NULL) 297 return (NULL); 298 299 ADD_U_CHAR(dptr, AUT_EXIT); 300 ADD_U_INT32(dptr, err); 301 ADD_U_INT32(dptr, retval); 302 303 return (t); 304 } 305 306 /* 307 */ 308 token_t * 309 au_to_groups(int *groups) 310 { 311 312 return (au_to_newgroups(BSM_MAX_GROUPS, groups)); 313 } 314 315 /* 316 * token ID 1 byte 317 * number groups 2 bytes 318 * group list count * 4 bytes 319 */ 320 token_t * 321 au_to_newgroups(u_int16_t n, gid_t *groups) 322 { 323 token_t *t; 324 u_char *dptr = NULL; 325 int i; 326 327 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 328 n * sizeof(u_int32_t)); 329 if (t == NULL) 330 return (NULL); 331 332 ADD_U_CHAR(dptr, AUT_NEWGROUPS); 333 ADD_U_INT16(dptr, n); 334 for (i = 0; i < n; i++) 335 ADD_U_INT32(dptr, groups[i]); 336 337 return (t); 338 } 339 340 /* 341 * token ID 1 byte 342 * internet address 4 bytes 343 */ 344 token_t * 345 au_to_in_addr(struct in_addr *internet_addr) 346 { 347 token_t *t; 348 u_char *dptr = NULL; 349 350 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(uint32_t)); 351 if (t == NULL) 352 return (NULL); 353 354 ADD_U_CHAR(dptr, AUT_IN_ADDR); 355 ADD_MEM(dptr, &internet_addr->s_addr, sizeof(uint32_t)); 356 357 return (t); 358 } 359 360 /* 361 * token ID 1 byte 362 * address type/length 4 bytes 363 * Address 16 bytes 364 */ 365 token_t * 366 au_to_in_addr_ex(struct in6_addr *internet_addr) 367 { 368 token_t *t; 369 u_char *dptr = NULL; 370 u_int32_t type = AF_INET6; 371 372 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 5 * sizeof(uint32_t)); 373 if (t == NULL) 374 return (NULL); 375 376 ADD_U_CHAR(dptr, AUT_IN_ADDR_EX); 377 ADD_U_INT32(dptr, type); 378 ADD_MEM(dptr, internet_addr, 5 * sizeof(uint32_t)); 379 380 return (t); 381 } 382 383 /* 384 * token ID 1 byte 385 * ip header 20 bytes 386 */ 387 token_t * 388 au_to_ip(struct ip *ip) 389 { 390 token_t *t; 391 u_char *dptr = NULL; 392 393 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(struct ip)); 394 if (t == NULL) 395 return (NULL); 396 397 ADD_U_CHAR(dptr, AUT_IP); 398 /* 399 * XXXRW: Any byte order work needed on the IP header before writing? 400 */ 401 ADD_MEM(dptr, ip, sizeof(struct ip)); 402 403 return (t); 404 } 405 406 /* 407 * token ID 1 byte 408 * object ID type 1 byte 409 * object ID 4 bytes 410 */ 411 token_t * 412 au_to_ipc(char type, int id) 413 { 414 token_t *t; 415 u_char *dptr = NULL; 416 417 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 418 if (t == NULL) 419 return (NULL); 420 421 ADD_U_CHAR(dptr, AUT_IPC); 422 ADD_U_CHAR(dptr, type); 423 ADD_U_INT32(dptr, id); 424 425 return (t); 426 } 427 428 /* 429 * token ID 1 byte 430 * owner user ID 4 bytes 431 * owner group ID 4 bytes 432 * creator user ID 4 bytes 433 * creator group ID 4 bytes 434 * access mode 4 bytes 435 * slot sequence # 4 bytes 436 * key 4 bytes 437 */ 438 token_t * 439 au_to_ipc_perm(struct ipc_perm *perm) 440 { 441 token_t *t; 442 u_char *dptr = NULL; 443 u_int16_t pad0 = 0; 444 445 GET_TOKEN_AREA(t, dptr, 12 * sizeof(u_int16_t) + sizeof(u_int32_t)); 446 if (t == NULL) 447 return (NULL); 448 449 ADD_U_CHAR(dptr, AUT_IPC_PERM); 450 451 /* 452 * Darwin defines the sizes for ipc_perm members 453 * as 2 bytes; BSM defines 4 so pad with 0 454 */ 455 ADD_U_INT16(dptr, pad0); 456 ADD_U_INT16(dptr, perm->uid); 457 458 ADD_U_INT16(dptr, pad0); 459 ADD_U_INT16(dptr, perm->gid); 460 461 ADD_U_INT16(dptr, pad0); 462 ADD_U_INT16(dptr, perm->cuid); 463 464 ADD_U_INT16(dptr, pad0); 465 ADD_U_INT16(dptr, perm->cgid); 466 467 ADD_U_INT16(dptr, pad0); 468 ADD_U_INT16(dptr, perm->mode); 469 470 ADD_U_INT16(dptr, pad0); 471 472 #ifdef HAVE_IPC_PERM___SEQ 473 ADD_U_INT16(dptr, perm->__seq); 474 #else 475 ADD_U_INT16(dptr, perm->seq); 476 #endif 477 478 #ifdef HAVE_IPC_PERM___KEY 479 ADD_U_INT32(dptr, perm->__key); 480 #else 481 ADD_U_INT32(dptr, perm->key); 482 #endif 483 484 return (t); 485 } 486 487 /* 488 * token ID 1 byte 489 * port IP address 2 bytes 490 */ 491 token_t * 492 au_to_iport(u_int16_t iport) 493 { 494 token_t *t; 495 u_char *dptr = NULL; 496 497 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t)); 498 if (t == NULL) 499 return (NULL); 500 501 ADD_U_CHAR(dptr, AUT_IPORT); 502 ADD_U_INT16(dptr, iport); 503 504 return (t); 505 } 506 507 /* 508 * token ID 1 byte 509 * size 2 bytes 510 * data size bytes 511 */ 512 token_t * 513 au_to_opaque(char *data, u_int16_t bytes) 514 { 515 token_t *t; 516 u_char *dptr = NULL; 517 518 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + bytes); 519 if (t == NULL) 520 return (NULL); 521 522 ADD_U_CHAR(dptr, AUT_OPAQUE); 523 ADD_U_INT16(dptr, bytes); 524 ADD_MEM(dptr, data, bytes); 525 526 return (t); 527 } 528 529 /* 530 * token ID 1 byte 531 * seconds of time 4 bytes 532 * milliseconds of time 4 bytes 533 * file name len 2 bytes 534 * file pathname N bytes + 1 terminating NULL byte 535 */ 536 token_t * 537 au_to_file(char *file, struct timeval tm) 538 { 539 token_t *t; 540 u_char *dptr = NULL; 541 u_int16_t filelen; 542 u_int32_t timems; 543 544 filelen = strlen(file); 545 filelen += 1; 546 547 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(u_int32_t) + 548 sizeof(u_int16_t) + filelen); 549 if (t == NULL) 550 return (NULL); 551 552 timems = tm.tv_usec/1000; 553 554 ADD_U_CHAR(dptr, AUT_OTHER_FILE32); 555 ADD_U_INT32(dptr, tm.tv_sec); 556 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 557 ADD_U_INT16(dptr, filelen); 558 ADD_STRING(dptr, file, filelen); 559 560 return (t); 561 } 562 563 /* 564 * token ID 1 byte 565 * text length 2 bytes 566 * text N bytes + 1 terminating NULL byte 567 */ 568 token_t * 569 au_to_text(char *text) 570 { 571 token_t *t; 572 u_char *dptr = NULL; 573 u_int16_t textlen; 574 575 textlen = strlen(text); 576 textlen += 1; 577 578 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 579 if (t == NULL) 580 return (NULL); 581 582 ADD_U_CHAR(dptr, AUT_TEXT); 583 ADD_U_INT16(dptr, textlen); 584 ADD_STRING(dptr, text, textlen); 585 586 return (t); 587 } 588 589 /* 590 * token ID 1 byte 591 * path length 2 bytes 592 * path N bytes + 1 terminating NULL byte 593 */ 594 token_t * 595 au_to_path(char *text) 596 { 597 token_t *t; 598 u_char *dptr = NULL; 599 u_int16_t textlen; 600 601 textlen = strlen(text); 602 textlen += 1; 603 604 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + textlen); 605 if (t == NULL) 606 return (NULL); 607 608 ADD_U_CHAR(dptr, AUT_PATH); 609 ADD_U_INT16(dptr, textlen); 610 ADD_STRING(dptr, text, textlen); 611 612 return (t); 613 } 614 615 /* 616 * token ID 1 byte 617 * audit ID 4 bytes 618 * effective user ID 4 bytes 619 * effective group ID 4 bytes 620 * real user ID 4 bytes 621 * real group ID 4 bytes 622 * process ID 4 bytes 623 * session ID 4 bytes 624 * terminal ID 625 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 626 * machine address 4 bytes 627 */ 628 token_t * 629 au_to_process32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 630 pid_t pid, au_asid_t sid, au_tid_t *tid) 631 { 632 token_t *t; 633 u_char *dptr = NULL; 634 635 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 636 if (t == NULL) 637 return (NULL); 638 639 ADD_U_CHAR(dptr, AUT_PROCESS32); 640 ADD_U_INT32(dptr, auid); 641 ADD_U_INT32(dptr, euid); 642 ADD_U_INT32(dptr, egid); 643 ADD_U_INT32(dptr, ruid); 644 ADD_U_INT32(dptr, rgid); 645 ADD_U_INT32(dptr, pid); 646 ADD_U_INT32(dptr, sid); 647 ADD_U_INT32(dptr, tid->port); 648 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 649 650 return (t); 651 } 652 653 token_t * 654 au_to_process64(__unused au_id_t auid, __unused uid_t euid, 655 __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, 656 __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) 657 { 658 659 errno = ENOTSUP; 660 return (NULL); 661 } 662 663 token_t * 664 au_to_process(__unused au_id_t auid, __unused uid_t euid, 665 __unused gid_t egid, __unused uid_t ruid, __unused gid_t rgid, 666 __unused pid_t pid, __unused au_asid_t sid, __unused au_tid_t *tid) 667 { 668 669 return (au_to_process32(auid, euid, egid, ruid, rgid, pid, sid, 670 tid)); 671 } 672 673 /* 674 * token ID 1 byte 675 * audit ID 4 bytes 676 * effective user ID 4 bytes 677 * effective group ID 4 bytes 678 * real user ID 4 bytes 679 * real group ID 4 bytes 680 * process ID 4 bytes 681 * session ID 4 bytes 682 * terminal ID 683 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 684 * address type-len 4 bytes 685 * machine address 16 bytes 686 */ 687 token_t * 688 au_to_process32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 689 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 690 { 691 token_t *t; 692 u_char *dptr = NULL; 693 694 if (tid->at_type == AU_IPv4) 695 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 696 10 * sizeof(u_int32_t)); 697 else if (tid->at_type == AU_IPv6) 698 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 699 13 * sizeof(u_int32_t)); 700 else { 701 errno = EINVAL; 702 return (NULL); 703 } 704 if (t == NULL) 705 return (NULL); 706 707 ADD_U_CHAR(dptr, AUT_PROCESS32_EX); 708 ADD_U_INT32(dptr, auid); 709 ADD_U_INT32(dptr, euid); 710 ADD_U_INT32(dptr, egid); 711 ADD_U_INT32(dptr, ruid); 712 ADD_U_INT32(dptr, rgid); 713 ADD_U_INT32(dptr, pid); 714 ADD_U_INT32(dptr, sid); 715 ADD_U_INT32(dptr, tid->at_port); 716 ADD_U_INT32(dptr, tid->at_type); 717 ADD_U_INT32(dptr, tid->at_addr[0]); 718 if (tid->at_type == AU_IPv6) { 719 ADD_U_INT32(dptr, tid->at_addr[1]); 720 ADD_U_INT32(dptr, tid->at_addr[2]); 721 ADD_U_INT32(dptr, tid->at_addr[3]); 722 } 723 724 return (t); 725 } 726 727 token_t * 728 au_to_process64_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 729 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 730 { 731 732 errno = ENOTSUP; 733 return (NULL); 734 } 735 736 token_t * 737 au_to_process_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 738 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 739 { 740 741 return (au_to_process32_ex(auid, euid, egid, ruid, rgid, pid, sid, 742 tid)); 743 } 744 745 /* 746 * token ID 1 byte 747 * error status 1 byte 748 * return value 4 bytes/8 bytes (32-bit/64-bit value) 749 */ 750 token_t * 751 au_to_return32(char status, u_int32_t ret) 752 { 753 token_t *t; 754 u_char *dptr = NULL; 755 756 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int32_t)); 757 if (t == NULL) 758 return (NULL); 759 760 ADD_U_CHAR(dptr, AUT_RETURN32); 761 ADD_U_CHAR(dptr, status); 762 ADD_U_INT32(dptr, ret); 763 764 return (t); 765 } 766 767 token_t * 768 au_to_return64(char status, u_int64_t ret) 769 { 770 token_t *t; 771 u_char *dptr = NULL; 772 773 GET_TOKEN_AREA(t, dptr, 2 * sizeof(u_char) + sizeof(u_int64_t)); 774 if (t == NULL) 775 return (NULL); 776 777 ADD_U_CHAR(dptr, AUT_RETURN64); 778 ADD_U_CHAR(dptr, status); 779 ADD_U_INT64(dptr, ret); 780 781 return (t); 782 } 783 784 token_t * 785 au_to_return(char status, u_int32_t ret) 786 { 787 788 return (au_to_return32(status, ret)); 789 } 790 791 /* 792 * token ID 1 byte 793 * sequence number 4 bytes 794 */ 795 token_t * 796 au_to_seq(long audit_count) 797 { 798 token_t *t; 799 u_char *dptr = NULL; 800 801 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t)); 802 if (t == NULL) 803 return (NULL); 804 805 ADD_U_CHAR(dptr, AUT_SEQ); 806 ADD_U_INT32(dptr, audit_count); 807 808 return (t); 809 } 810 811 /* 812 * token ID 1 byte 813 * socket family 2 bytes 814 * path 104 bytes 815 */ 816 token_t * 817 au_to_sock_unix(struct sockaddr_un *so) 818 { 819 token_t *t; 820 u_char *dptr; 821 822 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + strlen(so->sun_path) + 1); 823 if (t == NULL) 824 return (NULL); 825 826 ADD_U_CHAR(dptr, AU_SOCK_UNIX_TOKEN); 827 /* BSM token has two bytes for family */ 828 ADD_U_CHAR(dptr, 0); 829 ADD_U_CHAR(dptr, so->sun_family); 830 ADD_STRING(dptr, so->sun_path, strlen(so->sun_path) + 1); 831 832 return (t); 833 } 834 835 /* 836 * token ID 1 byte 837 * socket family 2 bytes 838 * local port 2 bytes 839 * socket address 4 bytes 840 */ 841 token_t * 842 au_to_sock_inet32(struct sockaddr_in *so) 843 { 844 token_t *t; 845 u_char *dptr = NULL; 846 uint16_t family; 847 848 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 2 * sizeof(uint16_t) + 849 sizeof(uint32_t)); 850 if (t == NULL) 851 return (NULL); 852 853 ADD_U_CHAR(dptr, AUT_SOCKINET32); 854 /* 855 * BSM defines the family field as 16 bits, but many operating 856 * systems have an 8-bit sin_family field. Extend to 16 bits before 857 * writing into the token. Assume that both the port and the address 858 * in the sockaddr_in are already in network byte order, but family 859 * is in local byte order. 860 * 861 * XXXRW: Should a name space conversion be taking place on the value 862 * of sin_family? 863 */ 864 family = so->sin_family; 865 ADD_U_INT16(dptr, family); 866 ADD_MEM(dptr, &so->sin_port, sizeof(uint16_t)); 867 ADD_MEM(dptr, &so->sin_addr.s_addr, sizeof(uint32_t)); 868 869 return (t); 870 871 } 872 873 token_t * 874 au_to_sock_inet128(struct sockaddr_in6 *so) 875 { 876 token_t *t; 877 u_char *dptr = NULL; 878 879 GET_TOKEN_AREA(t, dptr, 3 * sizeof(u_char) + sizeof(u_int16_t) + 880 4 * sizeof(u_int32_t)); 881 if (t == NULL) 882 return (NULL); 883 884 ADD_U_CHAR(dptr, AUT_SOCKINET128); 885 /* 886 * In Darwin, sin6_family is one octet, but BSM defines the token 887 * to store two. So we copy in a 0 first. 888 */ 889 ADD_U_CHAR(dptr, 0); 890 ADD_U_CHAR(dptr, so->sin6_family); 891 892 ADD_U_INT16(dptr, so->sin6_port); 893 ADD_MEM(dptr, &so->sin6_addr, 4 * sizeof(uint32_t)); 894 895 return (t); 896 897 } 898 899 token_t * 900 au_to_sock_inet(struct sockaddr_in *so) 901 { 902 903 return (au_to_sock_inet32(so)); 904 } 905 906 /* 907 * token ID 1 byte 908 * audit ID 4 bytes 909 * effective user ID 4 bytes 910 * effective group ID 4 bytes 911 * real user ID 4 bytes 912 * real group ID 4 bytes 913 * process ID 4 bytes 914 * session ID 4 bytes 915 * terminal ID 916 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 917 * machine address 4 bytes 918 */ 919 token_t * 920 au_to_subject32(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 921 pid_t pid, au_asid_t sid, au_tid_t *tid) 922 { 923 token_t *t; 924 u_char *dptr = NULL; 925 926 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 9 * sizeof(u_int32_t)); 927 if (t == NULL) 928 return (NULL); 929 930 ADD_U_CHAR(dptr, AUT_SUBJECT32); 931 ADD_U_INT32(dptr, auid); 932 ADD_U_INT32(dptr, euid); 933 ADD_U_INT32(dptr, egid); 934 ADD_U_INT32(dptr, ruid); 935 ADD_U_INT32(dptr, rgid); 936 ADD_U_INT32(dptr, pid); 937 ADD_U_INT32(dptr, sid); 938 ADD_U_INT32(dptr, tid->port); 939 ADD_MEM(dptr, &tid->machine, sizeof(u_int32_t)); 940 941 return (t); 942 } 943 944 token_t * 945 au_to_subject64(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 946 pid_t pid, au_asid_t sid, au_tid_t *tid) 947 { 948 949 errno = ENOTSUP; 950 return (NULL); 951 } 952 953 token_t * 954 au_to_subject(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, 955 pid_t pid, au_asid_t sid, au_tid_t *tid) 956 { 957 958 return (au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, 959 tid)); 960 } 961 962 /* 963 * token ID 1 byte 964 * audit ID 4 bytes 965 * effective user ID 4 bytes 966 * effective group ID 4 bytes 967 * real user ID 4 bytes 968 * real group ID 4 bytes 969 * process ID 4 bytes 970 * session ID 4 bytes 971 * terminal ID 972 * port ID 4 bytes/8 bytes (32-bit/64-bit value) 973 * address type/length 4 bytes 974 * machine address 16 bytes 975 */ 976 token_t * 977 au_to_subject32_ex(au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, 978 gid_t rgid, pid_t pid, au_asid_t sid, au_tid_addr_t *tid) 979 { 980 token_t *t; 981 u_char *dptr = NULL; 982 983 if (tid->at_type == AU_IPv4) 984 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 10 * 985 sizeof(u_int32_t)); 986 else if (tid->at_type == AU_IPv6) 987 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + 13 * 988 sizeof(u_int32_t)); 989 else { 990 errno = EINVAL; 991 return (NULL); 992 } 993 if (t == NULL) 994 return (NULL); 995 996 ADD_U_CHAR(dptr, AUT_SUBJECT32_EX); 997 ADD_U_INT32(dptr, auid); 998 ADD_U_INT32(dptr, euid); 999 ADD_U_INT32(dptr, egid); 1000 ADD_U_INT32(dptr, ruid); 1001 ADD_U_INT32(dptr, rgid); 1002 ADD_U_INT32(dptr, pid); 1003 ADD_U_INT32(dptr, sid); 1004 ADD_U_INT32(dptr, tid->at_port); 1005 ADD_U_INT32(dptr, tid->at_type); 1006 ADD_U_INT32(dptr, tid->at_addr[0]); 1007 if (tid->at_type == AU_IPv6) { 1008 ADD_U_INT32(dptr, tid->at_addr[1]); 1009 ADD_U_INT32(dptr, tid->at_addr[2]); 1010 ADD_U_INT32(dptr, tid->at_addr[3]); 1011 } 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) && defined(HAVE_AUDIT_SYSCALLS) 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 au_to_header32_tm(int rec_size, au_event_t e_type, au_emod_t e_mod, 1145 struct timeval tm) 1146 { 1147 token_t *t; 1148 u_char *dptr = NULL; 1149 u_int32_t timems; 1150 1151 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int32_t) + 1152 sizeof(u_char) + 2 * sizeof(u_int16_t) + 2 * sizeof(u_int32_t)); 1153 if (t == NULL) 1154 return (NULL); 1155 1156 ADD_U_CHAR(dptr, AUT_HEADER32); 1157 ADD_U_INT32(dptr, rec_size); 1158 ADD_U_CHAR(dptr, HEADER_VERSION); 1159 ADD_U_INT16(dptr, e_type); 1160 ADD_U_INT16(dptr, e_mod); 1161 1162 timems = tm.tv_usec/1000; 1163 /* Add the timestamp */ 1164 ADD_U_INT32(dptr, tm.tv_sec); 1165 ADD_U_INT32(dptr, timems); /* We need time in ms. */ 1166 1167 return (t); 1168 } 1169 1170 #if !defined(KERNEL) && !defined(_KERNEL) 1171 token_t * 1172 au_to_header32(int rec_size, au_event_t e_type, au_emod_t e_mod) 1173 { 1174 struct timeval tm; 1175 1176 if (gettimeofday(&tm, NULL) == -1) 1177 return (NULL); 1178 return (au_to_header32_tm(rec_size, e_type, e_mod, tm)); 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 #endif 1197 1198 /* 1199 * token ID 1 byte 1200 * trailer magic number 2 bytes 1201 * record byte count 4 bytes 1202 */ 1203 token_t * 1204 au_to_trailer(int rec_size) 1205 { 1206 token_t *t; 1207 u_char *dptr = NULL; 1208 u_int16_t magic = TRAILER_PAD_MAGIC; 1209 1210 GET_TOKEN_AREA(t, dptr, sizeof(u_char) + sizeof(u_int16_t) + 1211 sizeof(u_int32_t)); 1212 if (t == NULL) 1213 return (NULL); 1214 1215 ADD_U_CHAR(dptr, AUT_TRAILER); 1216 ADD_U_INT16(dptr, magic); 1217 ADD_U_INT32(dptr, rec_size); 1218 1219 return (t); 1220 } 1221