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