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 2010 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  * Copyright 2012 Milan Jurik. All rights reserved.
  25  */
  26 
  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) { (void) 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_u_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         }
 250         return (0);
 251 }
 252 
 253 
 254 /*
 255  * Format of opaque token:
 256  *      opaque token id         adr_char
 257  *      size                    adr_short
 258  *      data                    adr_char, size times
 259  *
 260  */
 261 int
 262 opaque_token(parse_context_t *ctx)
 263 {
 264         skip_bytes(ctx);
 265         return (0);
 266 }
 267 
 268 
 269 /*
 270  * Format of return32 value token:
 271  *      return value token id   adr_char
 272  *      error number            adr_char
 273  *      return value            adr_u_int32
 274  *
 275  */
 276 int
 277 return_value32_token(parse_context_t *ctx)
 278 {
 279         char            errnum;
 280 
 281         adrm_char(&(ctx->adr), &errnum, 1);  /* pass / fail */
 282         ctx->adr.adr_now += sizeof (int32_t);        /* error code */
 283 
 284         ctx->out.sf_pass = (errnum == 0) ? 1 : -1;
 285 
 286         return (0);
 287 }
 288 
 289 /*
 290  * Format of return64 value token:
 291  *      return value token id   adr_char
 292  *      error number            adr_char
 293  *      return value            adr_u_int64
 294  *
 295  */
 296 int
 297 return_value64_token(parse_context_t *ctx)
 298 {
 299         char            errnum;
 300 
 301         adrm_char(&(ctx->adr), &errnum, 1);  /* pass / fail */
 302         ctx->adr.adr_now += sizeof (int64_t);        /* error code */
 303 
 304         ctx->out.sf_pass = (errnum == 0) ? 1 : -1;
 305 
 306         return (0);
 307 }
 308 
 309 
 310 /*
 311  * Format of sequence token:
 312  *      sequence token id       adr_char
 313  *      audit_count             int32_t
 314  *
 315  */
 316 int
 317 sequence_token(parse_context_t *ctx)
 318 {
 319         adrm_int32(&(ctx->adr), &(ctx->out.sf_sequence), 1);
 320         return (0);
 321 }
 322 
 323 
 324 /*
 325  * Format of text token:
 326  *      text token id           adr_char
 327  *      text                    adr_string
 328  */
 329 int
 330 text_token(parse_context_t *ctx)
 331 {
 332         ushort_t        len;
 333         size_t          separator_sz = 0;
 334         char            *bp;    /* pointer to output string */
 335 
 336         adrm_u_short(&(ctx->adr), &len, 1);
 337 
 338         if (ctx->out.sf_textlen > 0)
 339                 separator_sz = sizeof (AU_TEXT_NAME) - 1;
 340 
 341         DPRINT((dbfp, "text_token: start length=%d, add length=%d+%d\n",
 342             ctx->out.sf_textlen, (size_t)len, separator_sz));
 343 
 344         ctx->out.sf_text = realloc(ctx->out.sf_text,
 345             ctx->out.sf_textlen + (size_t)len + separator_sz);
 346 
 347         if (ctx->out.sf_text == NULL)
 348                 return (-1);
 349 
 350         bp = ctx->out.sf_text;
 351 
 352         if (ctx->out.sf_textlen != 0) {      /* concatenation? */
 353                 bp += ctx->out.sf_textlen;
 354                 bp += strlcpy(bp, AU_TEXT_NAME, separator_sz + 1);
 355                 ctx->out.sf_textlen += separator_sz;
 356                 DPRINT((dbfp, "text_token: l is %d\n%s\n", ctx->out.sf_textlen,
 357                     ctx->out.sf_text));
 358         }
 359         adrm_char(&(ctx->adr), bp, len);
 360         len--;          /* includes EOS */
 361         *(bp + len) = '\0';
 362 
 363         ctx->out.sf_textlen += len;
 364         DPRINT((dbfp, "text_token: l=%d\n%s\n", ctx->out.sf_textlen,
 365             ctx->out.sf_text));
 366 
 367         return (0);
 368 }
 369 
 370 /*
 371  * Format of tid token:
 372  *      ip token id     adr_char
 373  *      terminal type   adr_char
 374  *  terminal type = AU_IPADR:
 375  *      remote port:    ushort
 376  *      local port:     ushort
 377  *      IP type:        int32 -- AU_IPv4 or AU_IPv6
 378  *      address:        int32 if IPv4, else 4 * int32
 379  */
 380 int
 381 tid_token(parse_context_t *ctx)
 382 {
 383         uchar_t         type;
 384         int32_t         ip_length;
 385 
 386         adrm_char(&(ctx->adr), (char *)&type, 1);
 387 
 388         switch (type) {
 389         default:
 390                 return (-1);    /* other than IP type is not implemented */
 391         case AU_IPADR:
 392                 ctx->adr.adr_now += 2 * sizeof (ushort_t);
 393                 adrm_int32(&(ctx->adr), &ip_length, 1);
 394                 ctx->adr.adr_now += ip_length;
 395                 break;
 396         }
 397         return (0);
 398 }
 399 
 400 /*
 401  * Format of ip_addr token:
 402  *      ip token id     adr_char
 403  *      address         adr_int32
 404  *
 405  */
 406 int
 407 ip_addr_token(parse_context_t *ctx)
 408 {
 409         ctx->adr.adr_now += sizeof (int32_t);
 410 
 411         return (0);
 412 }
 413 
 414 /*
 415  * Format of ip_addr_ex token:
 416  *      ip token id     adr_char
 417  *      ip type         adr_int32
 418  *      ip address      adr_u_char*type
 419  *
 420  */
 421 int
 422 ip_addr_ex_token(parse_context_t *ctx)
 423 {
 424         int32_t type;
 425 
 426         adrm_int32(&(ctx->adr), &type, 1);           /* ip type */
 427         ctx->adr.adr_now += type * sizeof (uchar_t); /* ip address */
 428 
 429         return (0);
 430 }
 431 
 432 /*
 433  * Format of ip token:
 434  *      ip header token id      adr_char
 435  *      version                 adr_char
 436  *      type of service         adr_char
 437  *      length                  adr_short
 438  *      id                      adr_u_short
 439  *      offset                  adr_u_short
 440  *      ttl                     adr_char
 441  *      protocol                adr_char
 442  *      checksum                adr_u_short
 443  *      source address          adr_int32
 444  *      destination address     adr_int32
 445  *
 446  */
 447 int
 448 ip_token(parse_context_t *ctx)
 449 {
 450         ctx->adr.adr_now += (2 * sizeof (char)) + (3 * sizeof (short)) +
 451             (2 * sizeof (char)) + sizeof (short) + (2 * sizeof (int32_t));
 452         return (0);
 453 }
 454 
 455 
 456 /*
 457  * Format of iport token:
 458  *      ip port address token id        adr_char
 459  *      port address                    adr_short
 460  *
 461  */
 462 int
 463 iport_token(parse_context_t *ctx)
 464 {
 465         ctx->adr.adr_now += sizeof (short);
 466 
 467         return (0);
 468 }
 469 
 470 
 471 /*
 472  * Format of groups token:
 473  *      group token id          adr_char
 474  *      group list              adr_int32, 16 times
 475  *
 476  */
 477 int
 478 group_token(parse_context_t *ctx)
 479 {
 480         ctx->adr.adr_now += 16 * sizeof (int32_t);
 481 
 482         return (0);
 483 }
 484 
 485 /*
 486  * Format of newgroups token:
 487  *      group token id          adr_char
 488  *      number of groups        adr_short
 489  *      group list              adr_int32, "number" times
 490  *
 491  */
 492 int
 493 newgroup_token(parse_context_t *ctx)
 494 {
 495         short int   number;
 496 
 497         adrm_short(&(ctx->adr), &number, 1);
 498 
 499         ctx->adr.adr_now += number * sizeof (int32_t);
 500 
 501         return (0);
 502 }
 503 
 504 /*
 505  * Format of argument32 token:
 506  *      argument token id       adr_char
 507  *      argument number         adr_char
 508  *      argument value          adr_int32
 509  *      argument description    adr_string
 510  *
 511  */
 512 int
 513 argument32_token(parse_context_t *ctx)
 514 {
 515         ctx->adr.adr_now += sizeof (char) + sizeof (int32_t);
 516         skip_bytes(ctx);
 517 
 518         return (0);
 519 }
 520 
 521 /*
 522  * Format of argument64 token:
 523  *      argument token id       adr_char
 524  *      argument number         adr_char
 525  *      argument value          adr_int64
 526  *      argument description    adr_string
 527  *
 528  */
 529 int
 530 argument64_token(parse_context_t *ctx)
 531 {
 532         ctx->adr.adr_now += sizeof (char) + sizeof (int64_t);
 533         skip_bytes(ctx);
 534 
 535         return (0);
 536 }
 537 
 538 /*
 539  * Format of acl token:
 540  *      acl token id            adr_char
 541  *      type                    adr_u_int32
 542  *      value                   adr_u_int32
 543  *      mode                    adr_u_int32
 544  */
 545 int
 546 acl_token(parse_context_t *ctx)
 547 {
 548         ctx->adr.adr_now += 3 * sizeof (uint32_t);
 549 
 550         return (0);
 551 }
 552 
 553 /*
 554  * Format of ace token:
 555  *      ace token id            adr_char
 556  *      id                      adr_u_int32
 557  *      access_mask             adr_u_int32
 558  *      flags                   adr_u_short
 559  *      type                    adr_u_short
 560  */
 561 int
 562 ace_token(parse_context_t *ctx)
 563 {
 564         ctx->adr.adr_now += 2 * sizeof (uint32_t) + 2 * sizeof (ushort_t);
 565 
 566         return (0);
 567 }
 568 
 569 /*
 570  * Format of attribute token: (old pre SunOS 5.7 format)
 571  *      attribute token id      adr_char
 572  *      mode                    adr_int32 (printed in octal)
 573  *      uid                     adr_int32
 574  *      gid                     adr_int32
 575  *      file system id          adr_int32
 576  *      node id                 adr_int32
 577  *      device                  adr_int32
 578  *
 579  */
 580 int
 581 attribute_token(parse_context_t *ctx)
 582 {
 583         ctx->adr.adr_now += 6 * sizeof (int32_t);
 584 
 585         return (0);
 586 }
 587 
 588 /*
 589  * Format of attribute32 token:
 590  *      attribute token id      adr_char
 591  *      mode                    adr_int32 (printed in octal)
 592  *      uid                     adr_int32
 593  *      gid                     adr_int32
 594  *      file system id          adr_int32
 595  *      node id                 adr_int64
 596  *      device                  adr_int32
 597  *
 598  */
 599 int
 600 attribute32_token(parse_context_t *ctx)
 601 {
 602         ctx->adr.adr_now += (5 * sizeof (int32_t)) + sizeof (int64_t);
 603 
 604         return (0);
 605 }
 606 
 607 /*
 608  * Format of attribute64 token:
 609  *      attribute token id      adr_char
 610  *      mode                    adr_int32 (printed in octal)
 611  *      uid                     adr_int32
 612  *      gid                     adr_int32
 613  *      file system id          adr_int32
 614  *      node id                 adr_int64
 615  *      device                  adr_int64
 616  *
 617  */
 618 int
 619 attribute64_token(parse_context_t *ctx)
 620 {
 621         ctx->adr.adr_now += (4 * sizeof (int32_t)) + (2 * sizeof (int64_t));
 622 
 623         return (0);
 624 }
 625 
 626 
 627 /*
 628  * Format of command token:
 629  *      attribute token id      adr_char
 630  *      argc                    adr_short
 631  *      argv len                adr_short       variable amount of argv len
 632  *      argv text               argv len        and text
 633  *      .
 634  *      .
 635  *      .
 636  *      envp count              adr_short       variable amount of envp len
 637  *      envp len                adr_short       and text
 638  *      envp text               envp            len
 639  *      .
 640  *      .
 641  *      .
 642  *
 643  */
 644 int
 645 cmd_token(parse_context_t *ctx)
 646 {
 647         short   cnt;
 648         short   i;
 649 
 650         adrm_short(&(ctx->adr), &cnt, 1);
 651 
 652         for (i = 0; i < cnt; i++)
 653                 skip_bytes(ctx);
 654 
 655         adrm_short(&(ctx->adr), &cnt, 1);
 656 
 657         for (i = 0; i < cnt; i++)
 658                 skip_bytes(ctx);
 659 
 660         return (0);
 661 }
 662 
 663 
 664 /*
 665  * Format of exit token:
 666  *      attribute token id      adr_char
 667  *      return value            adr_int32
 668  *      errno                   adr_int32
 669  *
 670  */
 671 int
 672 exit_token(parse_context_t *ctx)
 673 {
 674         int32_t retval;
 675 
 676         adrm_int32(&(ctx->adr), &retval, 1);
 677         ctx->adr.adr_now += sizeof (int32_t);
 678 
 679         ctx->out.sf_pass = (retval == 0) ? 1 : -1;
 680         return (0);
 681 }
 682 
 683 /*
 684  * Format of exec_args token:
 685  *      attribute token id      adr_char
 686  *      count value             adr_int32
 687  *      strings                 null terminated strings
 688  *
 689  */
 690 int
 691 exec_args_token(parse_context_t *ctx)
 692 {
 693         int count, i;
 694 
 695         adrm_int32(&(ctx->adr), (int32_t *)&count, 1);
 696         for (i = 1; i <= count; i++) {
 697                 skip_string(ctx);
 698         }
 699 
 700         return (0);
 701 }
 702 
 703 /*
 704  * Format of exec_env token:
 705  *      attribute token id      adr_char
 706  *      count value             adr_int32
 707  *      strings                 null terminated strings
 708  *
 709  */
 710 int
 711 exec_env_token(parse_context_t *ctx)
 712 {
 713         int count, i;
 714 
 715         adrm_int32(&(ctx->adr), (int32_t *)&count, 1);
 716         for (i = 1; i <= count; i++)
 717                 skip_string(ctx);
 718 
 719         return (0);
 720 }
 721 
 722 /*
 723  * Format of liaison token:
 724  */
 725 int
 726 liaison_token(parse_context_t *ctx)
 727 {
 728         ctx->adr.adr_now += sizeof (int32_t);
 729 
 730         return (0);
 731 }
 732 
 733 
 734 /*
 735  * Format of path token:
 736  *      path                            adr_string
 737  */
 738 int
 739 path_token(parse_context_t *ctx)
 740 {
 741         get_bytes_to_string(ctx, &(ctx->out.sf_pathlen), &(ctx->out.sf_path),
 742             0);
 743         if (ctx->out.sf_path == NULL)
 744                 return (-1);
 745         /*
 746          * anchor the path because collapse_path needs it
 747          */
 748         if (*(ctx->out.sf_path) != '/') {
 749                 anchor_path(ctx->out.sf_path);
 750                 ctx->out.sf_pathlen++;
 751         }
 752         ctx->out.sf_pathlen = collapse_path(ctx->out.sf_path,
 753             ctx->out.sf_pathlen);
 754 
 755         return (0);
 756 }
 757 
 758 /*
 759  * path attr token / AUT_XATPATH
 760  *
 761  * Format of path attr token:
 762  *      token id                adr_char
 763  *      string count            adr_int32
 764  *      strings                 adr_string
 765  *
 766  * the sequence of strings is converted to a single string with
 767  * a blank separator replacing the EOS for all but the last
 768  * string.
 769  */
 770 int
 771 path_attr_token(parse_context_t *ctx)
 772 {
 773         int     count, i;
 774         int     last_len;
 775         size_t  offset;
 776         char    *p;
 777 
 778         adrm_int32(&(ctx->adr), &count, 1);
 779 
 780         offset = ctx->out.sf_atpathlen;
 781         p = ctx->adr.adr_now;
 782         for (i = 0; i <= count; i++) {
 783                 last_len = strlen(p);
 784                 ctx->out.sf_atpathlen += last_len + 1;
 785                 p += last_len + 1;
 786         }
 787         ctx->out.sf_atpath = realloc(ctx->out.sf_atpath, ctx->out.sf_atpathlen);
 788         ctx->out.sf_atpath += offset;
 789         p = ctx->out.sf_atpath;              /* save for fix up, below */
 790         (void) memcpy(ctx->out.sf_atpath, ctx->adr.adr_now,
 791             ctx->out.sf_atpathlen - offset);
 792         ctx->out.sf_atpathlen--;
 793 
 794         /* fix up: replace each eos except the last with ' ' */
 795 
 796         for (i = 0; i < count; i++) {
 797                 while (*p++ != '\0')
 798                         ;
 799                 *(p - 1) = ' ';
 800         }
 801         return (0);
 802 }
 803 
 804 
 805 /*
 806  * Format of System V IPC permission token:
 807  *      System V IPC permission token id        adr_char
 808  *      uid                                     adr_int32
 809  *      gid                                     adr_int32
 810  *      cuid                                    adr_int32
 811  *      cgid                                    adr_int32
 812  *      mode                                    adr_int32
 813  *      seq                                     adr_int32
 814  *      key                                     adr_int32
 815  */
 816 int
 817 s5_IPC_perm_token(parse_context_t *ctx)
 818 {
 819         ctx->adr.adr_now += (7 * sizeof (int32_t));
 820         return (0);
 821 }
 822 
 823 static void
 824 common_process(parse_context_t *ctx)
 825 {
 826         int32_t ruid, rgid, egid, pid;
 827         uint32_t asid;
 828 
 829         adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_pauid), 1);
 830         adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_peuid), 1);
 831         adrm_int32(&(ctx->adr), &egid, 1);
 832         adrm_int32(&(ctx->adr), &ruid, 1);
 833         adrm_int32(&(ctx->adr), &rgid, 1);
 834         adrm_int32(&(ctx->adr), &pid, 1);
 835         adrm_u_int32(&(ctx->adr), &asid, 1);
 836 }
 837 
 838 /*
 839  * Format of process32 token:
 840  *      process token id        adr_char
 841  *      auid                    adr_int32
 842  *      euid                    adr_int32
 843  *      egid                    adr_int32
 844  *      ruid                    adr_int32
 845  *      rgid                    adr_int32
 846  *      pid                     adr_int32
 847  *      sid                     adr_int32
 848  *      termid                  adr_int32*2
 849  *
 850  */
 851 int
 852 process32_token(parse_context_t *ctx)
 853 {
 854         int32_t port, machine;
 855 
 856         common_process(ctx);
 857 
 858         adrm_int32(&(ctx->adr), &port, 1);
 859         adrm_int32(&(ctx->adr), &machine, 1);
 860 
 861         return (0);
 862 }
 863 
 864 /*
 865  * Format of process32_ex token:
 866  *      process token id        adr_char
 867  *      auid                    adr_int32
 868  *      euid                    adr_int32
 869  *      egid                    adr_int32
 870  *      ruid                    adr_int32
 871  *      rgid                    adr_int32
 872  *      pid                     adr_int32
 873  *      sid                     adr_int32
 874  *      termid
 875  *              port            adr_int32
 876  *              type            adr_int32
 877  *              ip address      adr_u_char*type
 878  *
 879  */
 880 int
 881 process32_ex_token(parse_context_t *ctx)
 882 {
 883         int32_t port, type;
 884         uchar_t addr[16];
 885 
 886         common_process(ctx);
 887 
 888         adrm_int32(&(ctx->adr), &port, 1);
 889         adrm_int32(&(ctx->adr), &type, 1);
 890         adrm_u_char(&(ctx->adr), addr, type);
 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+adr_int32
 906  *
 907  */
 908 int
 909 process64_token(parse_context_t *ctx)
 910 {
 911         int64_t port;
 912         int32_t machine;
 913 
 914         common_process(ctx);
 915 
 916         adrm_int64(&(ctx->adr), &port, 1);
 917         adrm_int32(&(ctx->adr), &machine, 1);
 918 
 919         return (0);
 920 }
 921 
 922 /*
 923  * Format of process64_ex token:
 924  *      process token id        adr_char
 925  *      auid                    adr_int32
 926  *      euid                    adr_int32
 927  *      egid                    adr_int32
 928  *      ruid                    adr_int32
 929  *      rgid                    adr_int32
 930  *      pid                     adr_int32
 931  *      sid                     adr_int32
 932  *      termid
 933  *              port            adr_int64
 934  *              type            adr_int32
 935  *              ip address      adr_u_char*type
 936  *
 937  */
 938 int
 939 process64_ex_token(parse_context_t *ctx)
 940 {
 941         int64_t port;
 942         int32_t type;
 943         uchar_t addr[16];
 944 
 945         common_process(ctx);
 946 
 947         adrm_int64(&(ctx->adr), &port, 1);
 948         adrm_int32(&(ctx->adr), &type, 1);
 949         adrm_u_char(&(ctx->adr), addr, type);
 950 
 951         return (0);
 952 }
 953 
 954 /*
 955  * Format of System V IPC token:
 956  *      System V IPC token id   adr_char
 957  *      System V IPC type       adr_char
 958  *      object id               adr_int32
 959  *
 960  */
 961 int
 962 s5_IPC_token(parse_context_t *ctx)
 963 {
 964         ctx->adr.adr_now += sizeof (char);
 965         ctx->adr.adr_now += sizeof (int32_t);
 966 
 967         return (0);
 968 }
 969 
 970 
 971 /*
 972  * Format of socket token:
 973  *      socket_type             adrm_short
 974  *      remote_port             adrm_short
 975  *      remote_inaddr           adrm_int32
 976  *
 977  */
 978 int
 979 socket_token(parse_context_t *ctx)
 980 {
 981         ctx->adr.adr_now += (2 * sizeof (short)) + sizeof (int32_t);
 982 
 983         return (0);
 984 }
 985 
 986 
 987 /*
 988  * Format of socket_ex token:
 989  *      socket_domain           adrm_short
 990  *      socket_type             adrm_short
 991  *      address_type            adrm_short
 992  *      local_port              adrm_short
 993  *      local_inaddr            adrm_u_char*address_type
 994  *      remote_port             adrm_short
 995  *      remote_inaddr           adrm_u_char*address_type
 996  *
 997  */
 998 int
 999 socket_ex_token(parse_context_t *ctx)
1000 {
1001         short   ip_size;
1002 
1003         ctx->adr.adr_now += (2 * sizeof (short));
1004         adrm_short(&(ctx->adr), &ip_size, 1);
1005 
1006         ctx->adr.adr_now += sizeof (short) + (ip_size * sizeof (char)) +
1007             sizeof (short) + (ip_size * sizeof (char));
1008         return (0);
1009 }
1010 
1011 
1012 static void
1013 common_subject(parse_context_t *ctx)
1014 {
1015         int32_t ruid, rgid, pid;
1016 
1017         adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_auid), 1);
1018         adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_euid), 1);
1019         adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_egid), 1);
1020         adrm_int32(&(ctx->adr), &ruid, 1);
1021         adrm_int32(&(ctx->adr), &rgid, 1);
1022         adrm_int32(&(ctx->adr), &pid, 1);
1023         adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_asid), 1);
1024 }
1025 
1026 /*
1027  * Format of subject32 token:
1028  *      subject token id        adr_char
1029  *      auid                    adr_int32
1030  *      euid                    adr_int32
1031  *      egid                    adr_int32
1032  *      ruid                    adr_int32
1033  *      rgid                    adr_int32
1034  *      pid                     adr_int32
1035  *      sid                     adr_int32
1036  *      termid                  adr_int32*2
1037  *
1038  */
1039 int
1040 subject32_token(parse_context_t *ctx)
1041 {
1042         int32_t port;   /* not used in output */
1043 
1044         common_subject(ctx);
1045 
1046         adrm_int32(&(ctx->adr), &port, 1);
1047         ctx->out.sf_tid.at_type = AU_IPv4;
1048         adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 4);
1049 
1050         return (0);
1051 }
1052 
1053 /*
1054  * Format of subject32_ex token:
1055  *      subject token id        adr_char
1056  *      auid                    adr_int32
1057  *      euid                    adr_int32
1058  *      egid                    adr_int32
1059  *      ruid                    adr_int32
1060  *      rgid                    adr_int32
1061  *      pid                     adr_int32
1062  *      sid                     adr_int32
1063  *      termid
1064  *              port            adr_int32
1065  *              type            adr_int32
1066  *              ip address      adr_u_char*type
1067  *
1068  */
1069 int
1070 subject32_ex_token(parse_context_t *ctx)
1071 {
1072         int32_t port;   /* not used in output */
1073 
1074         common_subject(ctx);
1075 
1076         adrm_int32(&(ctx->adr), &port, 1);
1077         adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1);
1078         adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]),
1079             ctx->out.sf_tid.at_type);
1080 
1081         return (0);
1082 }
1083 
1084 /*
1085  * Format of subject64 token:
1086  *      subject token id        adr_char
1087  *      auid                    adr_int32
1088  *      euid                    adr_int32
1089  *      egid                    adr_int32
1090  *      ruid                    adr_int32
1091  *      rgid                    adr_int32
1092  *      pid                     adr_int32
1093  *      sid                     adr_int32
1094  *      termid                  adr_int64+adr_int32
1095  *
1096  */
1097 int
1098 subject64_token(parse_context_t *ctx)
1099 {
1100         int64_t port;
1101 
1102         common_subject(ctx);
1103 
1104         adrm_int64(&(ctx->adr), &port, 1);
1105         ctx->out.sf_tid.at_type = AU_IPv4;
1106         adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 4);
1107 
1108         return (0);
1109 }
1110 
1111 /*
1112  * Format of subject64_ex token:
1113  *      subject token id        adr_char
1114  *      auid                    adr_int32
1115  *      euid                    adr_int32
1116  *      egid                    adr_int32
1117  *      ruid                    adr_int32
1118  *      rgid                    adr_int32
1119  *      pid                     adr_int32
1120  *      sid                     adr_int32
1121  *      termid
1122  *              port            adr_int64
1123  *              type            adr_int32
1124  *              ip address      adr_u_char*type
1125  *
1126  */
1127 int
1128 subject64_ex_token(parse_context_t *ctx)
1129 {
1130         int64_t port;
1131 
1132         common_subject(ctx);
1133 
1134         adrm_int64(&(ctx->adr), &port, 1);
1135         adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1);
1136         adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]),
1137             ctx->out.sf_tid.at_type);
1138 
1139         return (0);
1140 }
1141 
1142 
1143 int
1144 xatom_token(parse_context_t *ctx)
1145 {
1146         skip_bytes(ctx);
1147 
1148         return (0);
1149 }
1150 
1151 
1152 int
1153 xselect_token(parse_context_t *ctx)
1154 {
1155         skip_bytes(ctx);
1156         skip_bytes(ctx);
1157         skip_bytes(ctx);
1158 
1159         return (0);
1160 }
1161 
1162 /*
1163  * anchor a path name with a slash
1164  * assume we have enough space
1165  */
1166 static void
1167 anchor_path(char *path)
1168 {
1169 
1170         (void) memmove((void *)(path + 1), (void *)path, strlen(path) + 1);
1171         *path = '/';
1172 }
1173 
1174 
1175 /*
1176  * copy path to collapsed path.
1177  * collapsed path does not contain:
1178  *      successive slashes
1179  *      instances of dot-slash
1180  *      instances of dot-dot-slash
1181  * passed path must be anchored with a '/'
1182  */
1183 static size_t
1184 collapse_path(char *s, size_t ls)
1185 {
1186         int     id;     /* index of where we are in destination string */
1187         int     is;     /* index of where we are in source string */
1188         int     slashseen;      /* have we seen a slash */
1189 
1190         ls++; /* source length including '\0' */
1191 
1192         slashseen = 0;
1193         for (is = 0, id = 0; is < ls; is++) {
1194                 if (s[is] == '\0') {
1195                         if (id > 1 && s[id-1] == '/') {
1196                                 --id;
1197                         }
1198                         s[id++] = '\0';
1199                         break;
1200                 }
1201                 /* previous character was a / */
1202                 if (slashseen) {
1203                         if (s[is] == '/')
1204                                 continue;       /* another slash, ignore it */
1205                 } else if (s[is] == '/') {
1206                         /* we see a /, just copy it and try again */
1207                         slashseen = 1;
1208                         s[id++] = '/';
1209                         continue;
1210                 }
1211                 /* /./ seen */
1212                 if (s[is] == '.' && s[is+1] == '/') {
1213                         is += 1;
1214                         continue;
1215                 }
1216                 /* XXX/. seen */
1217                 if (s[is] == '.' && s[is+1] == '\0') {
1218                         if (id > 1)
1219                                 id--;
1220                         continue;
1221                 }
1222                 /* XXX/.. seen */
1223                 if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') {
1224                         is += 1;
1225                         if (id > 0)
1226                                 id--;
1227                         while (id > 0 && s[--id] != '/')
1228                                 ;
1229                         id++;
1230                         continue;
1231                 }
1232                 /* XXX/../ seen */
1233                 if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
1234                         is += 2;
1235                         if (id > 0)
1236                                 id--;
1237                         while (id > 0 && s[--id] != '/')
1238                                 ;
1239                         id++;
1240                         continue;
1241                 }
1242                 while (is < ls && (s[id++] = s[is++]) != '/')
1243                         ;
1244                 is--;
1245         }
1246         return ((size_t)id - 1);
1247 }
1248 
1249 /*
1250  * for tokens with sub-fields that include a length, this
1251  * skips the sub-field.
1252  */
1253 
1254 static void
1255 skip_bytes(parse_context_t *ctx)
1256 {
1257         ushort_t        c;
1258 
1259         adrm_u_short(&(ctx->adr), &c, 1);
1260         ctx->adr.adr_now += c;
1261 }
1262 
1263 static void
1264 skip_string(parse_context_t *ctx)
1265 {
1266         char    c;
1267 
1268         do {
1269                 adrm_char(&(ctx->adr), &c, 1);
1270         } while (c != (char)0);
1271 }
1272 
1273 /*
1274  * add a byte to specified length so there can be a prefix of
1275  * '/' added (if needed for paths).  Another is added for '\0'
1276  *
1277  * if offset is zero, new data overwrites old, if any.  Otherwise
1278  * new data is appended to the end.
1279  */
1280 
1281 static void
1282 get_bytes_to_string(parse_context_t *ctx, size_t *l, char **p,
1283     size_t offset)
1284 {
1285         ushort_t        len;
1286         char            *bp;
1287 
1288         adrm_u_short(&(ctx->adr), &len, 1);
1289 
1290         len++;  /* in case need to add '/' prefix */
1291         *p = realloc(*p, 1 + (size_t)len + offset);
1292         if (*p == NULL) {
1293                 perror("audit_sysudp.so");
1294                 return;
1295         }
1296         if (offset > 0)
1297                 offset--;       /* overwrite end of string */
1298 
1299         *l = (size_t)len - 2 + offset;
1300 
1301         bp = *p + offset;
1302         adrm_char(&(ctx->adr), bp, len - 1);
1303         *(bp + len - 1) = '\0';
1304 }
1305 
1306 
1307 /*
1308  * Format of host token:
1309  *      host            adr_uint32
1310  */
1311 int
1312 host_token(parse_context_t *ctx)
1313 {
1314         ctx->adr.adr_now += sizeof (int32_t);
1315 
1316         return (0);
1317 }
1318 
1319 /*
1320  * Format of useofauth token:
1321  *      uauth token id          adr_char
1322  *      uauth                   adr_string
1323  *
1324  */
1325 int
1326 useofauth_token(parse_context_t *ctx)
1327 {
1328         get_bytes_to_string(ctx, &(ctx->out.sf_uauthlen),
1329             &(ctx->out.sf_uauth), 0);
1330 
1331         return (0);
1332 }
1333 
1334 /*
1335  * Format of user token:
1336  *      user token id           adr_char
1337  *      uid                     adr_uid
1338  *      username                adr_string
1339  *
1340  */
1341 int
1342 user_token(parse_context_t *ctx)
1343 {
1344         ctx->adr.adr_now += sizeof (uid_t);
1345         skip_bytes(ctx);
1346 
1347         return (0);
1348 }
1349 
1350 /*
1351  * Format of zonename token:
1352  *      zonename token id               adr_char
1353  *      zonename                        adr_string
1354  *
1355  */
1356 int
1357 zonename_token(parse_context_t *ctx)
1358 {
1359         get_bytes_to_string(ctx,
1360             &(ctx->out.sf_zonelen),
1361             &(ctx->out.sf_zonename),
1362             0);
1363 
1364         return (0);
1365 }
1366 
1367 /*
1368  * Format of fmri token:
1369  *      fmri token id           adr_char
1370  *      fmri                    adr_string
1371  */
1372 int
1373 fmri_token(parse_context_t *ctx)
1374 {
1375         skip_bytes(ctx);
1376 
1377         return (0);
1378 }
1379 
1380 int
1381 xcolormap_token(parse_context_t *ctx)
1382 {
1383         return (xgeneric(ctx));
1384 }
1385 
1386 int
1387 xcursor_token(parse_context_t *ctx)
1388 {
1389         return (xgeneric(ctx));
1390 }
1391 
1392 int
1393 xfont_token(parse_context_t *ctx)
1394 {
1395         return (xgeneric(ctx));
1396 }
1397 
1398 int
1399 xgc_token(parse_context_t *ctx)
1400 {
1401         return (xgeneric(ctx));
1402 }
1403 
1404 int
1405 xpixmap_token(parse_context_t *ctx)
1406 {
1407         return (xgeneric(ctx));
1408 }
1409 
1410 int
1411 xwindow_token(parse_context_t *ctx)
1412 {
1413         return (xgeneric(ctx));
1414 }
1415 /*
1416  * Format of xgeneric token:
1417  *      XID                     adr_int32
1418  *      creator UID             adr_int32
1419  *
1420  * Includes:  xcolormap, xcursor, xfont, xgc, xpixmap, and xwindow
1421  */
1422 static int
1423 xgeneric(parse_context_t *ctx)
1424 {
1425         ctx->adr.adr_now += 2 * sizeof (int32_t);
1426 
1427         return (0);
1428 }
1429 /*
1430  * Format of xproperty token:
1431  *      XID                     adr_int32
1432  *      creator UID             adr_int32
1433  *      atom string             adr_string
1434  */
1435 int
1436 xproperty_token(parse_context_t *ctx)
1437 {
1438         ctx->adr.adr_now += 2 * sizeof (int32_t);
1439 
1440         return (0);
1441 }
1442 /*
1443  * Format of xclient token:
1444  *      xclient id              adr_int32
1445  */
1446 int
1447 xclient_token(parse_context_t *ctx)
1448 {
1449         ctx->adr.adr_now += sizeof (int32_t);
1450 
1451         return (0);
1452 }
1453 
1454 /*
1455  * -----------------------------------------------------------------------
1456  * privilege_token()    : Process privilege token and display contents
1457  *
1458  * Format of privilege token:
1459  *      privilege token id      adr_char
1460  *      privilege type          adr_string
1461  *      privilege               adr_string
1462  * -----------------------------------------------------------------------
1463  */
1464 
1465 int
1466 privilege_token(parse_context_t *ctx)
1467 {
1468         skip_bytes(ctx);
1469         skip_bytes(ctx);
1470 
1471         return (0);
1472 }
1473 
1474 /*
1475  * -----------------------------------------------------------------------
1476  * secflags_token()     : Process secflags token and display contents
1477  *
1478  * Format of privilege token:
1479  *      secflags token id       adr_char
1480  *      secflag set name        adr_string
1481  *      secflags                adr_string
1482  * -----------------------------------------------------------------------
1483  */
1484 int
1485 secflags_token(parse_context_t *ctx)
1486 {
1487         skip_bytes(ctx);
1488         skip_bytes(ctx);
1489 
1490         return (0);
1491 }
1492 
1493 /*
1494  * Format of label token:
1495  *      label ID                1 byte
1496  *      compartment length      1 byte
1497  *      classification          2 bytes
1498  *      compartment words       <compartment length> * 4 bytes
1499  */
1500 int
1501 label_token(parse_context_t *ctx)
1502 {
1503         char    c;
1504 
1505         ctx->adr.adr_now += sizeof (char);   /* label ID */
1506         adrm_char(&(ctx->adr), &c, 1);
1507 
1508         ctx->adr.adr_now += sizeof (ushort_t);       /* classification */
1509         ctx->adr.adr_now += 4 * c;           /* compartments */
1510 
1511         return (0);
1512 }
1513 
1514 /*
1515  * Format of useofpriv token:
1516  *      priv_type                       adr_char
1517  *      priv_set_t                      adr_short
1518  *      priv_set                        adr_char*(sizeof (priv_set_t))
1519  */
1520 int
1521 useofpriv_token(parse_context_t *ctx)
1522 {
1523         ctx->adr.adr_now += sizeof (char); /* success / fail */
1524         skip_bytes(ctx);
1525 
1526         return (0);
1527 }