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