1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Token processing for sysupd; each token function does one 30 * or more operations. All of them bump the buffer pointer 31 * to the next token; some of them extract one or more data 32 * from the token. 33 */ 34 35 #define DEBUG 0 36 #if DEBUG 37 #define DPRINT(x) {fprintf x; } 38 #else 39 #define DPRINT(x) 40 #endif 41 42 #include <locale.h> 43 #include <stdlib.h> 44 #include <stdio.h> 45 #include <string.h> 46 #include <sys/types.h> 47 #include <bsm/libbsm.h> 48 #include <sys/tsol/label.h> 49 #include "toktable.h" /* ../praudit */ 50 #include "sysplugin.h" 51 #include "systoken.h" 52 #include <audit_plugin.h> 53 54 #if DEBUG 55 static FILE *dbfp; /* debug file */ 56 #endif 57 58 static void anchor_path(char *); 59 static size_t collapse_path(char *, size_t); 60 static void get_bytes_to_string(parse_context_t *, size_t *, char **, 61 size_t); 62 static void skip_bytes(parse_context_t *); 63 static void skip_string(parse_context_t *); 64 static int xgeneric(parse_context_t *); 65 66 /* 67 * Process a token in a record to (1) extract data of interest if any 68 * and (2) point to the next token. 69 * 70 * returns 0 if ok. + or - values are of debug value: 71 * 72 * returns -1 if the parsing of the token failed. 73 * 74 * returns +<previous id> if the token is not found. This value 75 * is used to help determine where in the record the problem 76 * occurred. The common failure case is that the parsing of 77 * token M is incorrect and the buffer pointer ends up pointing 78 * to garbage. The positive error value of M *may* be the id of 79 * the incorrectly parsed token. 80 */ 81 82 int 83 parse_token(parse_context_t *ctx) 84 { 85 char tokenid; 86 static char prev_tokenid = -1; 87 int rc; 88 89 #if DEBUG 90 static boolean_t first = 1; 91 92 if (first) { 93 dbfp = __auditd_debug_file_open(); 94 first = 0; 95 } 96 #endif 97 98 adrm_char(&(ctx->adr), &tokenid, 1); 99 100 if ((tokenid > 0) && (tokentable[tokenid].func != NOFUNC)) { 101 rc = (*tokentable[tokenid].func)(ctx); 102 prev_tokenid = tokenid; 103 return (rc); 104 } 105 /* here if token id is not in table */ 106 return (prev_tokenid); 107 } 108 109 /* There should not be any file tokens in the middle of a record */ 110 111 /* ARGSUSED */ 112 int 113 file_token(parse_context_t *ctx) 114 { 115 116 return (-1); 117 } 118 119 /* ARGSUSED */ 120 int 121 file64_token(parse_context_t *ctx) 122 { 123 return (-1); 124 } 125 126 static void 127 common_header(parse_context_t *ctx) 128 { 129 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_reclen), 1); 130 ctx->adr.adr_now += sizeof (char); /* version number */ 131 adrm_short(&(ctx->adr), &(ctx->out.sf_eventid), 1); 132 ctx->adr.adr_now += sizeof (short); /* modifier */ 133 } 134 135 /* 136 * 32bit header 137 */ 138 int 139 header_token(parse_context_t *ctx) 140 { 141 common_header(ctx); 142 ctx->adr.adr_now += 2 * sizeof (int32_t); /* time */ 143 144 return (0); 145 } 146 147 148 int 149 header32_ex_token(parse_context_t *ctx) 150 { 151 int32_t type; 152 153 common_header(ctx); 154 155 adrm_int32(&(ctx->adr), &type, 1); /* tid type */ 156 ctx->adr.adr_now += type * sizeof (char); /* ip address */ 157 158 ctx->adr.adr_now += 2 * sizeof (int32_t); /* time */ 159 160 return (0); 161 } 162 163 164 int 165 header64_ex_token(parse_context_t *ctx) 166 { 167 int32_t type; 168 169 common_header(ctx); 170 171 adrm_int32(&(ctx->adr), &type, 1); /* tid type */ 172 ctx->adr.adr_now += type * sizeof (char); /* ip address */ 173 174 ctx->adr.adr_now += 2 * sizeof (int64_t); /* time */ 175 176 return (0); 177 } 178 179 180 int 181 header64_token(parse_context_t *ctx) 182 { 183 common_header(ctx); 184 185 ctx->adr.adr_now += 2 * sizeof (int64_t); /* time */ 186 187 return (0); 188 } 189 190 191 /* 192 * ====================================================== 193 * The following token processing routines return 194 * 0: if parsed ok 195 * -1: can't parse and can't determine location of next token 196 * ====================================================== 197 */ 198 199 int 200 trailer_token(parse_context_t *ctx) 201 { 202 short magic_number; 203 uint32_t bytes; 204 205 adrm_u_short(&(ctx->adr), (ushort_t *)&magic_number, 1); 206 if (magic_number != AUT_TRAILER_MAGIC) 207 return (-1); 208 209 adrm_u_int32(&(ctx->adr), &bytes, 1); 210 211 return (0); 212 } 213 214 215 /* 216 * Format of arbitrary data token: 217 * arbitrary data token id &(ctx->adr) char 218 * how to print adr_char 219 * basic unit adr_char 220 * unit count adr_char, specifying number of units of 221 * data items depends on basic unit 222 * 223 */ 224 int 225 arbitrary_data_token(parse_context_t *ctx) 226 { 227 char basic_unit, unit_count; 228 229 ctx->adr.adr_now += sizeof (char); /* how to print */ 230 231 adrm_char(&(ctx->adr), &basic_unit, 1); 232 adrm_char(&(ctx->adr), &unit_count, 1); 233 234 switch (basic_unit) { 235 case AUR_CHAR: /* same as AUR_BYTE */ 236 ctx->adr.adr_now += unit_count * sizeof (char); 237 break; 238 case AUR_SHORT: 239 ctx->adr.adr_now += unit_count * sizeof (short); 240 break; 241 case AUR_INT32: /* same as AUR_INT */ 242 ctx->adr.adr_now += unit_count * sizeof (int32_t); 243 break; 244 case AUR_INT64: 245 ctx->adr.adr_now += unit_count * sizeof (int64_t); 246 break; 247 default: 248 return (-1); 249 break; 250 } 251 return (0); 252 } 253 254 255 /* 256 * Format of opaque token: 257 * opaque token id adr_char 258 * size adr_short 259 * data adr_char, size times 260 * 261 */ 262 int 263 opaque_token(parse_context_t *ctx) 264 { 265 skip_bytes(ctx); 266 return (0); 267 } 268 269 270 /* 271 * Format of return32 value token: 272 * return value token id adr_char 273 * error number adr_char 274 * return value adr_u_int32 275 * 276 */ 277 int 278 return_value32_token(parse_context_t *ctx) 279 { 280 char errnum; 281 282 adrm_char(&(ctx->adr), &errnum, 1); /* pass / fail */ 283 ctx->adr.adr_now += sizeof (int32_t); /* error code */ 284 285 ctx->out.sf_pass = (errnum == 0) ? 1 : -1; 286 287 return (0); 288 } 289 290 /* 291 * Format of return64 value token: 292 * return value token id adr_char 293 * error number adr_char 294 * return value adr_u_int64 295 * 296 */ 297 int 298 return_value64_token(parse_context_t *ctx) 299 { 300 char errnum; 301 302 adrm_char(&(ctx->adr), &errnum, 1); /* pass / fail */ 303 ctx->adr.adr_now += sizeof (int64_t); /* error code */ 304 305 ctx->out.sf_pass = (errnum == 0) ? 1 : -1; 306 307 return (0); 308 } 309 310 311 /* 312 * Format of sequence token: 313 * sequence token id adr_char 314 * audit_count int32_t 315 * 316 */ 317 int 318 sequence_token(parse_context_t *ctx) 319 { 320 adrm_int32(&(ctx->adr), &(ctx->out.sf_sequence), 1); 321 return (0); 322 } 323 324 325 /* 326 * Format of text token: 327 * text token id adr_char 328 * text adr_string 329 */ 330 int 331 text_token(parse_context_t *ctx) 332 { 333 ushort_t len; 334 size_t separator_sz = 0; 335 char *bp; /* pointer to output string */ 336 337 adrm_u_short(&(ctx->adr), &len, 1); 338 339 if (ctx->out.sf_textlen > 0) 340 separator_sz = sizeof (AU_TEXT_NAME) - 1; 341 342 DPRINT((dbfp, "text_token: start length=%d, add length=%d+%d\n", 343 ctx->out.sf_textlen, (size_t)len, separator_sz)); 344 345 ctx->out.sf_text = realloc(ctx->out.sf_text, 346 ctx->out.sf_textlen + (size_t)len + separator_sz); 347 348 if (ctx->out.sf_text == NULL) 349 return (-1); 350 351 bp = ctx->out.sf_text; 352 353 if (ctx->out.sf_textlen != 0) { /* concatenation? */ 354 bp += ctx->out.sf_textlen; 355 bp += strlcpy(bp, AU_TEXT_NAME, separator_sz + 1); 356 ctx->out.sf_textlen += separator_sz; 357 DPRINT((dbfp, "text_token: l is %d\n%s\n", ctx->out.sf_textlen, 358 ctx->out.sf_text)); 359 } 360 adrm_char(&(ctx->adr), bp, len); 361 len--; /* includes EOS */ 362 *(bp + len) = '\0'; 363 364 ctx->out.sf_textlen += len; 365 DPRINT((dbfp, "text_token: l=%d\n%s\n", ctx->out.sf_textlen, 366 ctx->out.sf_text)); 367 368 return (0); 369 } 370 371 /* 372 * Format of tid token: 373 * ip token id adr_char 374 * terminal type adr_char 375 * terminal type = AU_IPADR: 376 * remote port: ushort 377 * local port: ushort 378 * IP type: int32 -- AU_IPv4 or AU_IPv6 379 * address: int32 if IPv4, else 4 * int32 380 */ 381 int 382 tid_token(parse_context_t *ctx) 383 { 384 uchar_t type; 385 int32_t ip_length; 386 387 adrm_char(&(ctx->adr), (char *)&type, 1); 388 389 switch (type) { 390 default: 391 return (-1); /* other than IP type is not implemented */ 392 case AU_IPADR: 393 ctx->adr.adr_now += 2 * sizeof (ushort_t); 394 adrm_int32(&(ctx->adr), &ip_length, 1); 395 ctx->adr.adr_now += ip_length; 396 break; 397 } 398 return (0); 399 } 400 401 /* 402 * Format of ip_addr token: 403 * ip token id adr_char 404 * address adr_int32 405 * 406 */ 407 int 408 ip_addr_token(parse_context_t *ctx) 409 { 410 ctx->adr.adr_now += sizeof (int32_t); 411 412 return (0); 413 } 414 415 /* 416 * Format of ip_addr_ex token: 417 * ip token id adr_char 418 * ip type adr_int32 419 * address 4*adr_int32 420 * 421 */ 422 int 423 ip_addr_ex_token(parse_context_t *ctx) 424 { 425 ctx->adr.adr_now += 5 * sizeof (int32_t); 426 427 return (0); 428 } 429 430 /* 431 * Format of ip token: 432 * ip header token id adr_char 433 * version adr_char 434 * type of service adr_char 435 * length adr_short 436 * id adr_u_short 437 * offset adr_u_short 438 * ttl adr_char 439 * protocol adr_char 440 * checksum adr_u_short 441 * source address adr_int32 442 * destination address adr_int32 443 * 444 */ 445 int 446 ip_token(parse_context_t *ctx) 447 { 448 ctx->adr.adr_now += (2 * sizeof (char)) + 449 (3 * sizeof (short)) + 450 (2 * sizeof (char)) + 451 sizeof (short) + 452 (2 * sizeof (int32_t)); 453 return (0); 454 } 455 456 457 /* 458 * Format of iport token: 459 * ip port address token id adr_char 460 * port address adr_short 461 * 462 */ 463 int 464 iport_token(parse_context_t *ctx) 465 { 466 ctx->adr.adr_now += sizeof (short); 467 468 return (0); 469 } 470 471 472 /* 473 * Format of groups token: 474 * group token id adr_char 475 * group list adr_int32, 16 times 476 * 477 */ 478 int 479 group_token(parse_context_t *ctx) 480 { 481 ctx->adr.adr_now += 16 * sizeof (int32_t); 482 483 return (0); 484 } 485 486 /* 487 * Format of newgroups token: 488 * group token id adr_char 489 * number of groups adr_short 490 * group list adr_int32, "number" times 491 * 492 */ 493 int 494 newgroup_token(parse_context_t *ctx) 495 { 496 short int number; 497 498 adrm_short(&(ctx->adr), &number, 1); 499 500 ctx->adr.adr_now += number * sizeof (int32_t); 501 502 return (0); 503 } 504 505 /* 506 * Format of argument32 token: 507 * argument token id adr_char 508 * argument number adr_char 509 * argument value adr_int32 510 * argument description adr_string 511 * 512 */ 513 int 514 argument32_token(parse_context_t *ctx) 515 { 516 ctx->adr.adr_now += sizeof (char) + sizeof (int32_t); 517 skip_bytes(ctx); 518 519 return (0); 520 } 521 522 /* 523 * Format of argument64 token: 524 * argument token id adr_char 525 * argument number adr_char 526 * argument value adr_int64 527 * argument description adr_string 528 * 529 */ 530 int 531 argument64_token(parse_context_t *ctx) 532 { 533 ctx->adr.adr_now += sizeof (char) + sizeof (int64_t); 534 skip_bytes(ctx); 535 536 return (0); 537 } 538 539 int 540 acl_token(parse_context_t *ctx) 541 { 542 ctx->adr.adr_now += 3 * sizeof (int32_t); 543 544 return (0); 545 } 546 547 /* 548 * Format of attribute token: (old pre SunOS 5.7 format) 549 * attribute token id adr_char 550 * mode adr_int32 (printed in octal) 551 * uid adr_int32 552 * gid adr_int32 553 * file system id adr_int32 554 * node id adr_int32 555 * device adr_int32 556 * 557 */ 558 int 559 attribute_token(parse_context_t *ctx) 560 { 561 ctx->adr.adr_now += 6 * sizeof (int32_t); 562 563 return (0); 564 } 565 566 /* 567 * Format of attribute32 token: 568 * attribute token id adr_char 569 * mode adr_int32 (printed in octal) 570 * uid adr_int32 571 * gid adr_int32 572 * file system id adr_int32 573 * node id adr_int64 574 * device adr_int32 575 * 576 */ 577 int 578 attribute32_token(parse_context_t *ctx) 579 { 580 ctx->adr.adr_now += (5 * sizeof (int32_t)) + sizeof (int64_t); 581 582 return (0); 583 } 584 585 /* 586 * Format of attribute64 token: 587 * attribute token id adr_char 588 * mode adr_int32 (printed in octal) 589 * uid adr_int32 590 * gid adr_int32 591 * file system id adr_int32 592 * node id adr_int64 593 * device adr_int64 594 * 595 */ 596 int 597 attribute64_token(parse_context_t *ctx) 598 { 599 ctx->adr.adr_now += (4 * sizeof (int32_t)) + (2 * sizeof (int64_t)); 600 601 return (0); 602 } 603 604 605 /* 606 * Format of command token: 607 * attribute token id adr_char 608 * argc adr_short 609 * argv len adr_short variable amount of argv len 610 * argv text argv len and text 611 * . 612 * . 613 * . 614 * envp count adr_short variable amount of envp len 615 * envp len adr_short and text 616 * envp text envp len 617 * . 618 * . 619 * . 620 * 621 */ 622 int 623 cmd_token(parse_context_t *ctx) 624 { 625 short cnt; 626 short i; 627 628 adrm_short(&(ctx->adr), &cnt, 1); 629 630 for (i = 0; i < cnt; i++) 631 skip_bytes(ctx); 632 633 adrm_short(&(ctx->adr), &cnt, 1); 634 635 for (i = 0; i < cnt; i++) 636 skip_bytes(ctx); 637 638 return (0); 639 } 640 641 642 /* 643 * Format of exit token: 644 * attribute token id adr_char 645 * return value adr_int32 646 * errno adr_int32 647 * 648 */ 649 int 650 exit_token(parse_context_t *ctx) 651 { 652 int32_t retval; 653 654 adrm_int32(&(ctx->adr), &retval, 1); 655 ctx->adr.adr_now += sizeof (int32_t); 656 657 ctx->out.sf_pass = (retval == 0) ? 1 : -1; 658 return (0); 659 } 660 661 /* 662 * Format of exec_args token: 663 * attribute token id adr_char 664 * count value adr_int32 665 * strings null terminated strings 666 * 667 */ 668 int 669 exec_args_token(parse_context_t *ctx) 670 { 671 int count, i; 672 673 adrm_int32(&(ctx->adr), (int32_t *)&count, 1); 674 for (i = 1; i <= count; i++) { 675 skip_string(ctx); 676 } 677 678 return (0); 679 } 680 681 /* 682 * Format of exec_env token: 683 * attribute token id adr_char 684 * count value adr_int32 685 * strings null terminated strings 686 * 687 */ 688 int 689 exec_env_token(parse_context_t *ctx) 690 { 691 int count, i; 692 693 adrm_int32(&(ctx->adr), (int32_t *)&count, 1); 694 for (i = 1; i <= count; i++) 695 skip_string(ctx); 696 697 return (0); 698 } 699 700 /* 701 * Format of liaison token: 702 */ 703 int 704 liaison_token(parse_context_t *ctx) 705 { 706 ctx->adr.adr_now += sizeof (int32_t); 707 708 return (0); 709 } 710 711 712 /* 713 * Format of path token: 714 * path adr_string 715 */ 716 int 717 path_token(parse_context_t *ctx) 718 { 719 get_bytes_to_string(ctx, &(ctx->out.sf_pathlen), &(ctx->out.sf_path), 720 0); 721 if (ctx->out.sf_path == NULL) 722 return (-1); 723 /* 724 * anchor the path because collapse_path needs it 725 */ 726 if (*(ctx->out.sf_path) != '/') { 727 anchor_path(ctx->out.sf_path); 728 ctx->out.sf_pathlen++; 729 } 730 ctx->out.sf_pathlen = collapse_path(ctx->out.sf_path, 731 ctx->out.sf_pathlen); 732 733 return (0); 734 } 735 736 /* 737 * path attr token / AUT_XATPATH 738 * 739 * Format of path attr token: 740 * token id adr_char 741 * string count adr_int32 742 * strings adr_string 743 * 744 * the sequence of strings is converted to a single string with 745 * a blank separator replacing the EOS for all but the last 746 * string. 747 */ 748 int 749 path_attr_token(parse_context_t *ctx) 750 { 751 int count, i; 752 int last_len; 753 size_t offset; 754 char *p; 755 756 adrm_int32(&(ctx->adr), &count, 1); 757 758 offset = ctx->out.sf_atpathlen; 759 p = ctx->adr.adr_now; 760 for (i = 0; i <= count; i++) { 761 last_len = strlen(p); 762 ctx->out.sf_atpathlen += last_len + 1; 763 p += last_len + 1; 764 } 765 ctx->out.sf_atpath = realloc(ctx->out.sf_atpath, ctx->out.sf_atpathlen); 766 ctx->out.sf_atpath += offset; 767 p = ctx->out.sf_atpath; /* save for fix up, below */ 768 (void) memcpy(ctx->out.sf_atpath, ctx->adr.adr_now, 769 ctx->out.sf_atpathlen - offset); 770 ctx->out.sf_atpathlen--; 771 772 /* fix up: replace each eos except the last with ' ' */ 773 774 for (i = 0; i < count; i++) { 775 while (*p++ != '\0'); 776 *(p - 1) = ' '; 777 } 778 return (0); 779 } 780 781 782 /* 783 * Format of System V IPC permission token: 784 * System V IPC permission token id adr_char 785 * uid adr_int32 786 * gid adr_int32 787 * cuid adr_int32 788 * cgid adr_int32 789 * mode adr_int32 790 * seq adr_int32 791 * key adr_int32 792 */ 793 int 794 s5_IPC_perm_token(parse_context_t *ctx) 795 { 796 ctx->adr.adr_now += (7 * sizeof (int32_t)); 797 return (0); 798 } 799 800 static void 801 common_process(parse_context_t *ctx) 802 { 803 int32_t ruid, rgid, egid, pid; 804 uint32_t asid; 805 806 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_pauid), 1); 807 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_peuid), 1); 808 adrm_int32(&(ctx->adr), &egid, 1); 809 adrm_int32(&(ctx->adr), &ruid, 1); 810 adrm_int32(&(ctx->adr), &rgid, 1); 811 adrm_int32(&(ctx->adr), &pid, 1); 812 adrm_u_int32(&(ctx->adr), &asid, 1); 813 } 814 815 /* 816 * Format of process32 token: 817 * process token id adr_char 818 * auid adr_int32 819 * euid adr_int32 820 * egid adr_int32 821 * ruid adr_int32 822 * rgid adr_int32 823 * pid adr_int32 824 * sid adr_int32 825 * termid adr_int32*2 826 * 827 */ 828 int 829 process32_token(parse_context_t *ctx) 830 { 831 int32_t port, machine; 832 833 common_process(ctx); 834 835 adrm_int32(&(ctx->adr), &port, 1); 836 adrm_int32(&(ctx->adr), &machine, 1); 837 838 return (0); 839 } 840 841 /* 842 * Format of process32_ex token: 843 * process token id adr_char 844 * auid adr_int32 845 * euid adr_int32 846 * egid adr_int32 847 * ruid adr_int32 848 * rgid adr_int32 849 * pid adr_int32 850 * sid adr_int32 851 * termid adr_int32*6 852 * 853 */ 854 int 855 process32_ex_token(parse_context_t *ctx) 856 { 857 int32_t port, type, addr[4]; 858 859 common_process(ctx); 860 861 adrm_int32(&(ctx->adr), &port, 1); 862 adrm_int32(&(ctx->adr), &type, 1); 863 adrm_int32(&(ctx->adr), &addr[0], 4); 864 865 return (0); 866 } 867 868 /* 869 * Format of process64 token: 870 * process token id adr_char 871 * auid adr_int32 872 * euid adr_int32 873 * egid adr_int32 874 * ruid adr_int32 875 * rgid adr_int32 876 * pid adr_int32 877 * sid adr_int32 878 * termid adr_int64+adr_int32 879 * 880 */ 881 int 882 process64_token(parse_context_t *ctx) 883 { 884 int64_t port; 885 int32_t machine; 886 887 common_process(ctx); 888 889 adrm_int64(&(ctx->adr), &port, 1); 890 adrm_int32(&(ctx->adr), &machine, 1); 891 892 return (0); 893 } 894 895 /* 896 * Format of process64 token: 897 * process token id adr_char 898 * auid adr_int32 899 * euid adr_int32 900 * egid adr_int32 901 * ruid adr_int32 902 * rgid adr_int32 903 * pid adr_int32 904 * sid adr_int32 905 * termid adr_int64+5*adr_int32 906 * 907 */ 908 int 909 process64_ex_token(parse_context_t *ctx) 910 { 911 int64_t port; 912 int32_t type, addr[4]; 913 914 common_process(ctx); 915 916 adrm_int64(&(ctx->adr), &port, 1); 917 adrm_int32(&(ctx->adr), &type, 1); 918 adrm_int32(&(ctx->adr), &addr[0], 4); 919 920 return (0); 921 } 922 923 /* 924 * Format of System V IPC token: 925 * System V IPC token id adr_char 926 * System V IPC type adr_char 927 * object id adr_int32 928 * 929 */ 930 int 931 s5_IPC_token(parse_context_t *ctx) 932 { 933 ctx->adr.adr_now += sizeof (char); 934 ctx->adr.adr_now += sizeof (int32_t); 935 936 return (0); 937 } 938 939 940 /* 941 * Format of socket token: 942 * socket_type adrm_short 943 * remote_port adrm_short 944 * remote_inaddr adrm_int32 945 * 946 */ 947 int 948 socket_token(parse_context_t *ctx) 949 { 950 ctx->adr.adr_now += (2 * sizeof (short)) + sizeof (int32_t); 951 952 return (0); 953 } 954 955 956 /* 957 * Format of socket token: 958 * 959 */ 960 int 961 socket_ex_token(parse_context_t *ctx) 962 { 963 short ip_size; 964 965 ctx->adr.adr_now += (2 * sizeof (short)); 966 adrm_short(&(ctx->adr), &ip_size, 1); 967 968 ctx->adr.adr_now += sizeof (short) + 969 (ip_size * sizeof (char)) + 970 sizeof (short) + 971 (ip_size * sizeof (char)); 972 return (0); 973 } 974 975 976 static void 977 common_subject(parse_context_t *ctx) 978 { 979 int32_t ruid, rgid, pid; 980 981 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_auid), 1); 982 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_euid), 1); 983 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_egid), 1); 984 adrm_int32(&(ctx->adr), &ruid, 1); 985 adrm_int32(&(ctx->adr), &rgid, 1); 986 adrm_int32(&(ctx->adr), &pid, 1); 987 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_asid), 1); 988 } 989 990 /* 991 * Format of subject32 token: 992 * subject token id adr_char 993 * auid adr_int32 994 * euid adr_int32 995 * egid adr_int32 996 * ruid adr_int32 997 * rgid adr_int32 998 * pid adr_int32 999 * sid adr_int32 1000 * termid adr_int32*2 1001 * 1002 */ 1003 int 1004 subject32_token(parse_context_t *ctx) 1005 { 1006 int32_t port; /* not used in output */ 1007 1008 common_subject(ctx); 1009 1010 adrm_int32(&(ctx->adr), &port, 1); 1011 ctx->out.sf_tid.at_type = AU_IPv4; 1012 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_addr[0]), 1); 1013 1014 return (0); 1015 } 1016 1017 /* 1018 * Format of subject32_ex token: 1019 * subject token id adr_char 1020 * auid adr_int32 1021 * euid adr_int32 1022 * egid adr_int32 1023 * ruid adr_int32 1024 * rgid adr_int32 1025 * pid adr_int32 1026 * sid adr_int32 1027 * termid_addr adr_int32*6 1028 * 1029 */ 1030 int 1031 subject32_ex_token(parse_context_t *ctx) 1032 { 1033 int32_t port; /* not used in output */ 1034 1035 common_subject(ctx); 1036 1037 adrm_int32(&(ctx->adr), &port, 1); 1038 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1); 1039 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_addr[0]), 4); 1040 1041 return (0); 1042 } 1043 1044 /* 1045 * Format of subject64 token: 1046 * subject token id adr_char 1047 * auid adr_int32 1048 * euid adr_int32 1049 * egid adr_int32 1050 * ruid adr_int32 1051 * rgid adr_int32 1052 * pid adr_int32 1053 * sid adr_int32 1054 * termid adr_int64+adr_int32 1055 * 1056 */ 1057 int 1058 subject64_token(parse_context_t *ctx) 1059 { 1060 int64_t port; 1061 1062 common_subject(ctx); 1063 1064 adrm_int64(&(ctx->adr), &port, 1); 1065 ctx->out.sf_tid.at_type = AU_IPv4; 1066 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_addr[0]), 1); 1067 1068 return (0); 1069 } 1070 1071 /* 1072 * Format of subject64 token: 1073 * subject token id adr_char 1074 * auid adr_int32 1075 * euid adr_int32 1076 * egid adr_int32 1077 * ruid adr_int32 1078 * rgid adr_int32 1079 * pid adr_int32 1080 * sid adr_int32 1081 * termid adr_int64+5*adr_int32 1082 * 1083 */ 1084 int 1085 subject64_ex_token(parse_context_t *ctx) 1086 { 1087 int64_t port; 1088 1089 common_subject(ctx); 1090 1091 adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_asid), 1); 1092 adrm_int64(&(ctx->adr), &port, 1); 1093 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1); 1094 adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_addr[0]), 4); 1095 1096 return (0); 1097 } 1098 1099 1100 int 1101 xatom_token(parse_context_t *ctx) 1102 { 1103 skip_bytes(ctx); 1104 1105 return (0); 1106 } 1107 1108 1109 int 1110 xselect_token(parse_context_t *ctx) 1111 { 1112 skip_bytes(ctx); 1113 skip_bytes(ctx); 1114 skip_bytes(ctx); 1115 1116 return (0); 1117 } 1118 1119 /* 1120 * anchor a path name with a slash 1121 * assume we have enough space 1122 */ 1123 static void 1124 anchor_path(char *path) 1125 { 1126 1127 (void) memmove((void *)(path + 1), (void *)path, strlen(path) + 1); 1128 *path = '/'; 1129 } 1130 1131 1132 /* 1133 * copy path to collapsed path. 1134 * collapsed path does not contain: 1135 * successive slashes 1136 * instances of dot-slash 1137 * instances of dot-dot-slash 1138 * passed path must be anchored with a '/' 1139 */ 1140 static size_t 1141 collapse_path(char *s, size_t ls) 1142 { 1143 int id; /* index of where we are in destination string */ 1144 int is; /* index of where we are in source string */ 1145 int slashseen; /* have we seen a slash */ 1146 1147 ls++; /* source length including '\0' */ 1148 1149 slashseen = 0; 1150 for (is = 0, id = 0; is < ls; is++) { 1151 if (s[is] == '\0') { 1152 if (id > 1 && s[id-1] == '/') { 1153 --id; 1154 } 1155 s[id++] = '\0'; 1156 break; 1157 } 1158 /* previous character was a / */ 1159 if (slashseen) { 1160 if (s[is] == '/') 1161 continue; /* another slash, ignore it */ 1162 } else if (s[is] == '/') { 1163 /* we see a /, just copy it and try again */ 1164 slashseen = 1; 1165 s[id++] = '/'; 1166 continue; 1167 } 1168 /* /./ seen */ 1169 if (s[is] == '.' && s[is+1] == '/') { 1170 is += 1; 1171 continue; 1172 } 1173 /* XXX/. seen */ 1174 if (s[is] == '.' && s[is+1] == '\0') { 1175 if (id > 1) 1176 id--; 1177 continue; 1178 } 1179 /* XXX/.. seen */ 1180 if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') { 1181 is += 1; 1182 if (id > 0) 1183 id--; 1184 while (id > 0 && s[--id] != '/'); 1185 id++; 1186 continue; 1187 } 1188 /* XXX/../ seen */ 1189 if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') { 1190 is += 2; 1191 if (id > 0) 1192 id--; 1193 while (id > 0 && s[--id] != '/'); 1194 id++; 1195 continue; 1196 } 1197 while (is < ls && (s[id++] = s[is++]) != '/'); 1198 is--; 1199 } 1200 return ((size_t)id - 1); 1201 } 1202 1203 /* 1204 * for tokens with sub-fields that include a length, this 1205 * skips the sub-field. 1206 */ 1207 1208 static void 1209 skip_bytes(parse_context_t *ctx) 1210 { 1211 ushort_t c; 1212 1213 adrm_u_short(&(ctx->adr), &c, 1); 1214 ctx->adr.adr_now += c; 1215 } 1216 1217 static void 1218 skip_string(parse_context_t *ctx) 1219 { 1220 char c; 1221 1222 do { 1223 adrm_char(&(ctx->adr), &c, 1); 1224 } while (c != (char)0); 1225 } 1226 1227 /* 1228 * add a byte to specified length so there can be a prefix of 1229 * '/' added (if needed for paths). Another is added for '\0' 1230 * 1231 * if offset is zero, new data overwrites old, if any. Otherwise 1232 * new data is appended to the end. 1233 */ 1234 1235 static void 1236 get_bytes_to_string(parse_context_t *ctx, size_t *l, char **p, 1237 size_t offset) 1238 { 1239 ushort_t len; 1240 char *bp; 1241 1242 adrm_u_short(&(ctx->adr), &len, 1); 1243 1244 len++; /* in case need to add '/' prefix */ 1245 *p = realloc(*p, 1 + (size_t)len + offset); 1246 if (*p == NULL) { 1247 perror("audit_sysudp.so"); 1248 return; 1249 } 1250 if (offset > 0) 1251 offset--; /* overwrite end of string */ 1252 1253 *l = (size_t)len - 2 + offset; 1254 1255 bp = *p + offset; 1256 adrm_char(&(ctx->adr), bp, len - 1); 1257 *(bp + len - 1) = '\0'; 1258 } 1259 1260 1261 /* 1262 * Format of host token: 1263 * host adr_uint32 1264 */ 1265 int 1266 host_token(parse_context_t *ctx) 1267 { 1268 ctx->adr.adr_now += sizeof (int32_t); 1269 1270 return (0); 1271 } 1272 1273 /* 1274 * Format of useofauth token: 1275 * uauth token id adr_char 1276 * uauth adr_string 1277 * 1278 */ 1279 int 1280 useofauth_token(parse_context_t *ctx) 1281 { 1282 get_bytes_to_string(ctx, &(ctx->out.sf_uauthlen), 1283 &(ctx->out.sf_uauth), 0); 1284 1285 return (0); 1286 } 1287 1288 /* 1289 * Format of zonename token: 1290 * zonename token id adr_char 1291 * zonename adr_string 1292 * 1293 */ 1294 int 1295 zonename_token(parse_context_t *ctx) 1296 { 1297 get_bytes_to_string(ctx, 1298 &(ctx->out.sf_zonelen), 1299 &(ctx->out.sf_zonename), 1300 0); 1301 1302 return (0); 1303 } 1304 1305 /* 1306 * Format of fmri token: 1307 * fmri token id adr_char 1308 * fmri adr_string 1309 */ 1310 int 1311 fmri_token(parse_context_t *ctx) 1312 { 1313 skip_bytes(ctx); 1314 1315 return (0); 1316 } 1317 1318 int 1319 xcolormap_token(parse_context_t *ctx) 1320 { 1321 return (xgeneric(ctx)); 1322 } 1323 1324 int 1325 xcursor_token(parse_context_t *ctx) 1326 { 1327 return (xgeneric(ctx)); 1328 } 1329 1330 int 1331 xfont_token(parse_context_t *ctx) 1332 { 1333 return (xgeneric(ctx)); 1334 } 1335 1336 int 1337 xgc_token(parse_context_t *ctx) 1338 { 1339 return (xgeneric(ctx)); 1340 } 1341 1342 int 1343 xpixmap_token(parse_context_t *ctx) 1344 { 1345 return (xgeneric(ctx)); 1346 } 1347 1348 int 1349 xwindow_token(parse_context_t *ctx) 1350 { 1351 return (xgeneric(ctx)); 1352 } 1353 /* 1354 * Format of xgeneric token: 1355 * XID adr_int32 1356 * creator UID adr_int32 1357 * 1358 * Includes: xcolormap, xcursor, xfont, xgc, xpixmap, and xwindow 1359 */ 1360 static int 1361 xgeneric(parse_context_t *ctx) 1362 { 1363 ctx->adr.adr_now += 2 * sizeof (int32_t); 1364 1365 return (0); 1366 } 1367 /* 1368 * Format of xproperty token: 1369 * XID adr_int32 1370 * creator UID adr_int32 1371 * atom string adr_string 1372 */ 1373 int 1374 xproperty_token(parse_context_t *ctx) 1375 { 1376 ctx->adr.adr_now += 2 * sizeof (int32_t); 1377 1378 return (0); 1379 } 1380 /* 1381 * Format of xclient token: 1382 * xclient id adr_int32 1383 */ 1384 int 1385 xclient_token(parse_context_t *ctx) 1386 { 1387 ctx->adr.adr_now += sizeof (int32_t); 1388 1389 return (0); 1390 } 1391 1392 /* 1393 * ----------------------------------------------------------------------- 1394 * privilege_token() : Process privilege token and display contents 1395 * 1396 * Format of privilege token: 1397 * privilege token id adr_char 1398 * privilege type adr_string 1399 * privilege adr_string 1400 * ----------------------------------------------------------------------- 1401 */ 1402 1403 int 1404 privilege_token(parse_context_t *ctx) 1405 { 1406 skip_bytes(ctx); 1407 skip_bytes(ctx); 1408 1409 return (0); 1410 } 1411 1412 1413 /* 1414 * Format of label token: 1415 * label ID 1 byte 1416 * compartment length 1 byte 1417 * classification 2 bytes 1418 * compartment words <compartment length> * 4 bytes 1419 */ 1420 int 1421 label_token(parse_context_t *ctx) 1422 { 1423 char c; 1424 1425 ctx->adr.adr_now += sizeof (char); /* label ID */ 1426 adrm_char(&(ctx->adr), &c, 1); 1427 1428 ctx->adr.adr_now += sizeof (ushort_t); /* classification */ 1429 ctx->adr.adr_now += 4 * c; /* compartments */ 1430 1431 return (0); 1432 } 1433 1434 /* 1435 * Format of useofpriv token: 1436 * priv_type adr_char 1437 * priv_set_t adr_short 1438 * priv_set adr_char*(sizeof (priv_set_t)) 1439 */ 1440 int 1441 useofpriv_token(parse_context_t *ctx) 1442 { 1443 ctx->adr.adr_now += sizeof (char); /* success / fail */ 1444 skip_bytes(ctx); 1445 1446 return (0); 1447 } 1448