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 
  26 
  27 #include <ctype.h>
  28 #include <dirent.h>
  29 #include <grp.h>
  30 #include <libintl.h>
  31 #include <limits.h>
  32 #include <locale.h>
  33 #include <pwd.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <string.h>
  37 #include <sys/types.h>
  38 #include <sys/inttypes.h>
  39 #include <sys/file.h>
  40 #include <sys/param.h>
  41 #include <sys/uio.h>
  42 #include <sys/stat.h>
  43 #include <sys/acl.h>
  44 #include <sys/socket.h>
  45 #include <sys/errno.h>
  46 #include <sys/ipc.h>
  47 #include <sys/sem.h>
  48 #include <sys/systm.h>
  49 #include <netinet/in.h>
  50 #include <sys/tiuser.h>
  51 #include <rpc/types.h>
  52 #include <rpc/auth.h>
  53 #include <rpc/auth_unix.h>
  54 #include <rpc/svc.h>
  55 #include <rpc/xdr.h>
  56 #include <nfs/nfs.h>
  57 #include <sys/fs/ufs_quota.h>
  58 #include <sys/time.h>
  59 #include <sys/mkdev.h>
  60 #include <unistd.h>
  61 
  62 #include <bsm/audit.h>
  63 #include <bsm/audit_record.h>
  64 #include <bsm/libbsm.h>
  65 
  66 #include <tsol/label.h>
  67 
  68 #include "praudit.h"
  69 #include "toktable.h"
  70 
  71 #include <netdb.h>
  72 #include <arpa/inet.h>
  73 
  74 static char *anchor_path(char *);
  75 static char *collapse_path(char *);
  76 
  77 
  78 /*
  79  * -----------------------------------------------------------------------
  80  * is_file_token:
  81  *                Tests whether the specified token id represents a type
  82  *                of file token.
  83  * return codes :  1 - tokenid is a file token type
  84  *              :  0 - otherwise
  85  * -----------------------------------------------------------------------
  86  */
  87 int
  88 is_file_token(int tokenid)
  89 {
  90         if ((tokenid == AUT_OTHER_FILE32) || (tokenid == AUT_OTHER_FILE64))
  91                 return (1);
  92 
  93         return (0);
  94 }
  95 
  96 /*
  97  * -----------------------------------------------------------------------
  98  * is_header_token:
  99  *                Tests whether the specified token id represents a type
 100  *                of header token (signifying the start of a record).
 101  * return codes :  1 - tokenid is a header type
 102  *              :  0 - otherwise
 103  * -----------------------------------------------------------------------
 104  */
 105 int
 106 is_header_token(int tokenid)
 107 {
 108         if ((tokenid == AUT_OHEADER) || (tokenid == AUT_HEADER32) ||
 109             (tokenid == AUT_HEADER32_EX) || (tokenid == AUT_HEADER64) ||
 110             (tokenid == AUT_HEADER64_EX))
 111                 return (1);
 112 
 113         return (0);
 114 }
 115 
 116 /*
 117  * -----------------------------------------------------------------------
 118  * is_token:
 119  *                Tests whether the specified token id represents a true
 120  *                token, as opposed to a regular tag.
 121  * return codes :  1 - tokenid is a true token
 122  *              :  0 - otherwise
 123  * -----------------------------------------------------------------------
 124  */
 125 int
 126 is_token(int tokenid)
 127 {
 128         if ((tokenid > 0) && (tokenid <= MAXTOKEN))
 129                 return (1);
 130 
 131         return (0);
 132 }
 133 
 134 
 135 /*
 136  * -----------------------------------------------------------------------
 137  * exit_token()         : Process information label token and display contents
 138  * return codes         : -1 - error
 139  *                      :  0 - successful
 140  * NOTE: At the time of call, the label token id has been retrieved
 141  *
 142  * Format of exit token:
 143  *      exit token id           adr_char
 144  * -----------------------------------------------------------------------
 145  */
 146 int
 147 exit_token(pr_context_t *context)
 148 {
 149         int     returnstat;
 150         int     retval;
 151         uval_t  uval;
 152 
 153         if ((returnstat = open_tag(context, TAG_ERRVAL)) != 0)
 154                 return (returnstat);
 155 
 156         if ((returnstat = pr_adr_int32(context, (int32_t *)&retval, 1)) == 0) {
 157                 if (!(context->format & PRF_RAWM)) {
 158                         char *emsg = strerror(retval);
 159 
 160                         if (emsg == NULL)
 161                                 uval.string_val = gettext("Unknown errno");
 162                         else
 163                                 uval.string_val = gettext(emsg);
 164                         uval.uvaltype = PRA_STRING;
 165                 } else {
 166                         uval.uvaltype = PRA_INT32;
 167                         uval.int32_val = retval;
 168                 }
 169                 returnstat = pa_print(context, &uval, 0);
 170         }
 171         if (returnstat == 0)
 172                 returnstat = close_tag(context, TAG_ERRVAL);
 173 
 174         return (process_tag(context, TAG_RETVAL, returnstat, 1));
 175 }
 176 
 177 /*
 178  * ------------------------------------------------------------------
 179  * file_token() : prints out seconds of time and other file name
 180  * return codes : -1 - error
 181  *              :  0 - successful, valid file token fields
 182  * At the time of entry, the file token ID has already been retrieved
 183  *
 184  * Format of file token:
 185  *      file token id           adr_char
 186  *      seconds of time         adr_u_int
 187  *      name of other file      adr_string
 188  * ------------------------------------------------------------------
 189  */
 190 int
 191 file_token(pr_context_t *context)
 192 {
 193         int     returnstat;
 194 
 195         returnstat = pa_utime32(context, 0, 0);         /* time from usecs */
 196 
 197         /* other file name */
 198         returnstat = pa_file_string(context, returnstat, 1);
 199 
 200         return (returnstat);
 201 }
 202 
 203 int
 204 file64_token(pr_context_t *context)
 205 {
 206         int     returnstat;
 207 
 208         returnstat = pa_utime64(context, 0, 0);         /* time from usecs */
 209 
 210         /* other file name */
 211         returnstat = pa_file_string(context, returnstat, 1);
 212 
 213         return (returnstat);
 214 }
 215 
 216 /*
 217  * -----------------------------------------------------------------------
 218  * header_token()       : Process record header token and display contents
 219  * return codes         : -1 - error
 220  *                      :  0 - successful
 221  *                      :  1 - warning, password entry not found
 222  *
 223  * NOTE: At the time of call, the header token id has been retrieved
 224  *
 225  * Format of header token:
 226  *      header token id         adr_char
 227  *      record byte count       adr_u_int
 228  *      event type              adr_u_short (printed either ASCII or raw)
 229  *      event class             adr_u_int   (printed either ASCII or raw)
 230  *      event action            adr_u_int
 231  *      if extended:            extended host name (IPv4/IPv6)
 232  *      seconds of time         adr_u_int   (printed either ASCII or raw)
 233  *      nanoseconds of time     adr_u_int
 234  * -----------------------------------------------------------------------
 235  */
 236 int
 237 header_token(pr_context_t *context)
 238 {
 239         int     returnstat;
 240 
 241         returnstat = pa_reclen(context, 0);             /* record byte */
 242         /* version ID */
 243         returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
 244         /* event type */
 245         returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
 246         /* event modifier */
 247         returnstat = pa_event_modifier(context, returnstat, 0);
 248         /* time from nsec */
 249         returnstat = pa_ntime32(context, returnstat, 1);
 250 
 251         return (returnstat);
 252 }
 253 
 254 int
 255 header64_token(pr_context_t *context)
 256 {
 257         int     returnstat;
 258 
 259         returnstat = pa_reclen(context, 0);             /* record byte */
 260         /* version ID */
 261         returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
 262         /* event type */
 263         returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
 264         /* event modifier */
 265         returnstat = pa_event_modifier(context, returnstat, 0);
 266         /* time from nsec */
 267         returnstat = pa_ntime64(context, returnstat, 1);
 268 
 269         return (returnstat);
 270 }
 271 
 272 int
 273 header32_ex_token(pr_context_t *context)
 274 {
 275         int     returnstat;
 276 
 277         returnstat = pa_reclen(context, 0);             /* record byte */
 278         /* version ID */
 279         returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
 280         /* event type */
 281         returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
 282         /* event modifier */
 283         returnstat = pa_event_modifier(context, returnstat, 0);
 284         /* machine name */
 285         returnstat = pa_hostname_ex(context, returnstat, 0);
 286         /* time from nsec */
 287         returnstat = pa_ntime32(context, returnstat, 1);
 288 
 289         return (returnstat);
 290 }
 291 
 292 int
 293 header64_ex_token(pr_context_t *context)
 294 {
 295         int     returnstat;
 296 
 297         returnstat = pa_reclen(context, 0);             /* record byte */
 298         /* version ID */
 299         returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
 300         /* event type */
 301         returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
 302         /* event modifier */
 303         returnstat = pa_event_modifier(context, returnstat, 0);
 304         /* machine name */
 305         returnstat = pa_hostname_ex(context, returnstat, 0);
 306         /* time from nsec */
 307         returnstat = pa_ntime64(context, returnstat, 1);
 308 
 309         return (returnstat);
 310 }
 311 
 312 /*
 313  * -----------------------------------------------------------------------
 314  * trailer_token()      : Process record trailer token and display contents
 315  * return codes         : -1 - error
 316  *                      :  0 - successful
 317  * NOTE: At the time of call, the trailer token id has already been
 318  * retrieved
 319  *
 320  * Format of trailer token:
 321  *      trailer token id        adr_char
 322  *      record sequence no      adr_u_short (should be AUT_TRAILER_MAGIC)
 323  *      record byte count       adr_u_int
 324  * -----------------------------------------------------------------------
 325  */
 326 int
 327 trailer_token(pr_context_t *context)
 328 {
 329         short   magic_number;
 330 
 331         if (pr_adr_u_short(context, (ushort_t *)&magic_number, 1) < 0) {
 332                 (void) fprintf(stderr, gettext(
 333                     "praudit: Cannot retrieve trailer magic number\n"));
 334                 return (-1);
 335         } else {
 336                 if (magic_number != AUT_TRAILER_MAGIC) {
 337                         (void) fprintf(stderr, gettext(
 338                             "praudit: Invalid trailer magic number\n"));
 339                         return (-1);
 340                 } else
 341                         /* Do not display trailer in XML mode */
 342                         if (context->format & PRF_XMLM) {
 343                                 uint32_t        junk;
 344                                 int             retstat;
 345 
 346                                 retstat = pr_adr_u_int32(context, &junk, 1);
 347                                 return (retstat);
 348                         } else {
 349                                 return (pa_adr_u_int32(context, 0, 1));
 350                         }
 351         }
 352 }
 353 
 354 /*
 355  * -----------------------------------------------------------------------
 356  * arbitrary_data_token():
 357  *                        Process arbitrary data token and display contents
 358  * return codes         : -1 - error
 359  *                      :  0 - successful
 360  * NOTE: At the time of call, the arbitrary data token id has already
 361  * been retrieved
 362  *
 363  * Format of arbitrary data token:
 364  *      arbitrary data token id adr char
 365  *      how to print            adr_char
 366  *                              From audit_record.h, this may be either:
 367  *                              AUP_BINARY      binary
 368  *                              AUP_OCTAL       octal
 369  *                              AUP_DECIMAL     decimal
 370  *                              AUP_HEX         hexadecimal
 371  *      basic unit              adr_char
 372  *                              From audit_record.h, this may be either:
 373  *                              AUR_BYTE        byte
 374  *                              AUR_CHAR        char
 375  *                              AUR_SHORT       short
 376  *                              AUR_INT32       int32_t
 377  *                              AUR_INT64       int64_t
 378  *      unit count              adr_char, specifying number of units of
 379  *                              data in the "data items" parameter below
 380  *      data items              depends on basic unit
 381  *
 382  * -----------------------------------------------------------------------
 383  */
 384 int
 385 arbitrary_data_token(pr_context_t *context)
 386 {
 387         int     returnstat;
 388         int     i;
 389         char    c1;
 390         short   c2;
 391         int32_t c3;
 392         int64_t c4;
 393         char    how_to_print, basic_unit, unit_count, fwid;
 394         char    *p;
 395         int     index = 0;
 396         char    *pformat = "%*s";
 397 
 398         uval_t  uval;
 399 
 400         if ((returnstat = pr_adr_char(context, &how_to_print, 1)) != 0)
 401                 return (returnstat);
 402 
 403         if ((returnstat = pr_adr_char(context, &basic_unit, 1)) != 0)
 404                 return (returnstat);
 405 
 406         if ((returnstat = pr_adr_char(context, &unit_count, 1)) != 0)
 407                 return (returnstat);
 408 
 409         if (!(context->format & PRF_RAWM)) {
 410                 uval.uvaltype = PRA_STRING;
 411                 uval.string_val = htp2string(how_to_print);
 412         } else {
 413                 uval.uvaltype = PRA_INT32;
 414                 uval.int32_val = (int)how_to_print;
 415         }
 416 
 417         if ((returnstat = open_tag(context, TAG_ARBPRINT)) != 0)
 418                 return (returnstat);
 419         if ((returnstat = pa_print(context, &uval, 0)) < 0)
 420                 return (returnstat);
 421         if ((returnstat = close_tag(context, TAG_ARBPRINT)) != 0)
 422                 return (returnstat);
 423 
 424         if (!(context->format & PRF_RAWM)) {
 425                 uval.uvaltype = PRA_STRING;
 426                 uval.string_val = bu2string(basic_unit);
 427         } else {
 428                 uval.uvaltype = PRA_INT32;
 429                 uval.int32_val = (int32_t)basic_unit;
 430         }
 431 
 432         if ((returnstat = open_tag(context, TAG_ARBTYPE)) != 0)
 433                 return (returnstat);
 434         if ((returnstat = pa_print(context, &uval, 0)) < 0)
 435                 return (returnstat);
 436         if ((returnstat = close_tag(context, TAG_ARBTYPE)) != 0)
 437                 return (returnstat);
 438 
 439         uval.uvaltype = PRA_INT32;
 440         uval.int32_val = (int32_t)unit_count;
 441 
 442         if ((returnstat = open_tag(context, TAG_ARBCOUNT)) != 0)
 443                 return (returnstat);
 444         if ((returnstat = pa_print(context, &uval, 1)) < 0)
 445                 return (returnstat);
 446         if ((returnstat = close_tag(context, TAG_ARBCOUNT)) != 0)
 447                 return (returnstat);
 448 
 449         /* Done with attributes; force end of token open */
 450         if ((returnstat = finish_open_tag(context)) != 0)
 451                 return (returnstat);
 452 
 453         /* get the field width in case we need to format output */
 454         fwid = findfieldwidth(basic_unit, how_to_print);
 455         p = (char *)malloc(80);
 456 
 457         /* now get the data items and print them */
 458         for (i = 0; (i < unit_count); i++) {
 459                 switch (basic_unit) {
 460                         /* case AUR_BYTE: */
 461                 case AUR_CHAR:
 462                         if (pr_adr_char(context, &c1, 1) == 0)
 463                                 (void) convert_char_to_string(how_to_print,
 464                                     c1, p);
 465                         else {
 466                                 free(p);
 467                                 return (-1);
 468                         }
 469                         break;
 470                 case AUR_SHORT:
 471                         if (pr_adr_short(context, &c2, 1) == 0)
 472                                 (void) convert_short_to_string(how_to_print,
 473                                     c2, p);
 474                         else {
 475                                 free(p);
 476                                 return (-1);
 477                         }
 478                         break;
 479                 case AUR_INT32:
 480                         if (pr_adr_int32(context, &c3, 1) == 0)
 481                                 (void) convert_int32_to_string(how_to_print,
 482                                     c3, p);
 483                         else {
 484                                 free(p);
 485                                 return (-1);
 486                         }
 487                         break;
 488                 case AUR_INT64:
 489                         if (pr_adr_int64(context, &c4, 1) == 0)
 490                                 (void) convert_int64_to_string(how_to_print,
 491                                     c4, p);
 492                         else {
 493                                 free(p);
 494                                 return (-1);
 495                         }
 496                         break;
 497                 default:
 498                         free(p);
 499                         return (-1);
 500                         /*NOTREACHED*/
 501                 }
 502 
 503                 /*
 504                  * At this point, we have successfully retrieved a data
 505                  * item and converted it into an ASCII string pointed to
 506                  * by p. If all output is to be printed on one line,
 507                  * simply separate the data items by a space (or by the
 508                  * delimiter if this is the last data item), otherwise, we
 509                  * need to format the output before display.
 510                  */
 511                 if (context->format & PRF_ONELINE) {
 512                         returnstat = pr_printf(context, "%s", p);
 513                         if ((returnstat >= 0) && (i == (unit_count - 1)))
 514                                 returnstat = pr_printf(context, "%s",
 515                                     context->SEPARATOR);
 516                         else
 517                                 returnstat = pr_putchar(context, ' ');
 518                 } else {        /* format output */
 519                         returnstat = pr_printf(context, pformat, fwid, p);
 520                         index += fwid;
 521                         if ((returnstat >= 0) &&
 522                             (((index + fwid) > 75) ||
 523                             (i == (unit_count - 1)))) {
 524                                 returnstat = pr_putchar(context, '\n');
 525                                 index = 0;
 526                         }
 527                 } /* else if PRF_ONELINE */
 528                 if (returnstat < 0) {
 529                         free(p);
 530                         return (returnstat);
 531                 }
 532         }
 533         free(p);
 534 
 535         return (returnstat);
 536 }
 537 
 538 /*
 539  * -----------------------------------------------------------------------
 540  * opaque_token()       : Process opaque token and display contents
 541  * return codes         : -1 - error
 542  *                      :  0 - successful
 543  * NOTE: At the time of call, the opaque token id has already been
 544  * retrieved
 545  *
 546  * Format of opaque token:
 547  *      opaque token id         adr_char
 548  *      size                    adr_short
 549  *      data                    adr_char, size times
 550  * -----------------------------------------------------------------------
 551  */
 552 int
 553 opaque_token(pr_context_t *context)
 554 {
 555         int     returnstat;
 556         short   size;
 557         char    *charp;
 558         uval_t  uval;
 559 
 560 
 561         /* print the size of the token */
 562         if (pr_adr_short(context, &size, 1) == 0) {
 563                 uval.uvaltype = PRA_SHORT;
 564                 uval.short_val = size;
 565                 returnstat = pa_print(context, &uval, 0);
 566         } else
 567                 returnstat = -1;
 568 
 569         /* now print out the data field in hexadecimal */
 570         if (returnstat >= 0) {
 571                 /* try to allocate memory for the character string */
 572                 if ((charp = (char *)malloc(size * sizeof (char))) == NULL)
 573                         returnstat = -1;
 574                 else {
 575                         if ((returnstat = pr_adr_char(context, charp,
 576                             size)) == 0) {
 577                                 /* print out in hexadecimal format */
 578                                 uval.uvaltype = PRA_STRING;
 579                                 uval.string_val = hexconvert(charp, size, size);
 580                                 if (uval.string_val) {
 581                                         returnstat = pa_print(context,
 582                                             &uval, 1);
 583                                         free(uval.string_val);
 584                                 }
 585                         }
 586                         free(charp);
 587                 }
 588         }
 589 
 590         return (returnstat);
 591 }
 592 
 593 /*
 594  * -----------------------------------------------------------------------
 595  * path_token()         : Process path token and display contents
 596  * return codes         : -1 - error
 597  *                      :  0 - successful
 598  * NOTE: At the time of call, the path token id has been retrieved
 599  *
 600  * Format of path token:
 601  *      token id        adr_char
 602  *      path            adr_string
 603  * -----------------------------------------------------------------------
 604  */
 605 int
 606 path_token(pr_context_t *context)
 607 {
 608         char    *path;  /* path */
 609         char    *apath; /* anchored path */
 610         char    *cpath; /* collapsed path */
 611         short   length;
 612         int     returnstat;
 613         uval_t  uval;
 614 
 615         /*
 616          * We need to know how much space to allocate for our string, so
 617          * read the length first, then call pr_adr_char to read those bytes.
 618          */
 619         if (pr_adr_short(context, &length, 1) == 0) {
 620                 if ((path = (char *)malloc(length + 1)) == NULL) {
 621                         returnstat = -1;
 622                 } else if (pr_adr_char(context, path, length) == 0) {
 623                         path[length] = '\0';
 624                         uval.uvaltype = PRA_STRING;
 625                         if (*path != '/') {
 626                                 apath = anchor_path(path);
 627                                 free(path);
 628                         } else
 629                                 apath = path;
 630                         cpath = collapse_path(apath);
 631                         uval.string_val = cpath;
 632                         returnstat = pa_print(context, &uval, 1);
 633                         free(cpath);
 634                 } else {
 635                         free(path);
 636                         returnstat = -1;
 637                 }
 638                 return (returnstat);
 639         } else
 640                 return (-1);
 641 }
 642 
 643 /*
 644  * anchor a path name with a slash
 645  */
 646 char *
 647 anchor_path(char *sp)
 648 {
 649         char    *dp; /* destination path */
 650         char    *tp; /* temporary path */
 651         size_t  len;
 652 
 653         len = strlen(sp) + 2;
 654         if ((dp = tp = (char *)calloc(1, len)) == (char *)0)
 655                 return ((char *)0);
 656 
 657         *dp++ = '/';
 658 
 659         (void) strlcpy(dp, sp, len);
 660 
 661         return (tp);
 662 }
 663 
 664 /*
 665  * copy path to collapsed path.
 666  * collapsed path does not contain:
 667  *      successive slashes
 668  *      instances of dot-slash
 669  *      instances of dot-dot-slash
 670  * passed path must be anchored with a '/'
 671  */
 672 char *
 673 collapse_path(char *s)
 674 {
 675         int     id;     /* index of where we are in destination string */
 676         int     is;             /* index of where we are in source string */
 677         int     slashseen;      /* have we seen a slash */
 678         int     ls;             /* length of source string */
 679 
 680         ls = strlen(s) + 1;
 681 
 682         slashseen = 0;
 683         for (is = 0, id = 0; is < ls; is++) {
 684                 /* thats all folks, we've reached the end of input */
 685                 if (s[is] == '\0') {
 686                         if (id > 1 && s[id-1] == '/') {
 687                                 --id;
 688                         }
 689                         s[id++] = '\0';
 690                         break;
 691                 }
 692                 /* previous character was a / */
 693                 if (slashseen) {
 694                         if (s[is] == '/')
 695                                 continue;       /* another slash, ignore it */
 696                 } else if (s[is] == '/') {
 697                         /* we see a /, just copy it and try again */
 698                         slashseen = 1;
 699                         s[id++] = '/';
 700                         continue;
 701                 }
 702                 /* /./ seen */
 703                 if (s[is] == '.' && s[is+1] == '/') {
 704                         is += 1;
 705                         continue;
 706                 }
 707                 /* XXX/. seen */
 708                 if (s[is] == '.' && s[is+1] == '\0') {
 709                         if (id > 1)
 710                                 id--;
 711                         continue;
 712                 }
 713                 /* XXX/.. seen */
 714                 if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') {
 715                         is += 1;
 716                         if (id > 0)
 717                                 id--;
 718                         while (id > 0 && s[--id] != '/')
 719                                 continue;
 720                         id++;
 721                         continue;
 722                 }
 723                 /* XXX/../ seen */
 724                 if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
 725                         is += 2;
 726                         if (id > 0)
 727                                 id--;
 728                         while (id > 0 && s[--id] != '/')
 729                                 continue;
 730                         id++;
 731                         continue;
 732                 }
 733                 while (is < ls && (s[id++] = s[is++]) != '/')
 734                         continue;
 735                 is--;
 736         }
 737         return (s);
 738 }
 739 
 740 /*
 741  * -----------------------------------------------------------------------
 742  * cmd_token()          : Process cmd token and display contents
 743  * return codes         : -1 - error
 744  *                      :  0 - successful
 745  * NOTE: At the time of call, the cmd token id has been retrieved
 746  *
 747  * Format of command token:
 748  *      token id        adr_char
 749  *      argc            adr_short
 750  *      N*argv[i]       adr_string (short, string)
 751  *      env cnt         adr_short
 752  *      N*arge[i]       adr_string (short, string)
 753  * -----------------------------------------------------------------------
 754  */
 755 int
 756 cmd_token(pr_context_t *context)
 757 {
 758         int     returnstat;
 759         short num;
 760 
 761         returnstat = pr_adr_short(context, &num, 1);
 762         if (returnstat < 0)
 763                 return (returnstat);
 764 
 765         if (!(context->format & PRF_XMLM)) {
 766                 returnstat = pr_printf(context, "%s%s%d%s",
 767                     (context->format & PRF_ONELINE) ? "" : gettext("argcnt"),
 768                     (context->format & PRF_ONELINE) ? "" : context->SEPARATOR,
 769                     num, context->SEPARATOR);
 770                 if (returnstat < 0)
 771                         return (returnstat);
 772         }
 773 
 774         for (; num > 0; num--) {
 775                 if ((returnstat = process_tag(context, TAG_ARGV,
 776                     returnstat, 0)) < 0)
 777                         return (returnstat);
 778         }
 779 
 780         if ((returnstat = pr_adr_short(context, &num, 1)) < 0)
 781                 return (returnstat);
 782 
 783         if (!(context->format & PRF_XMLM)) {
 784                 returnstat = pr_printf(context, "%s%s%d%s",
 785                     (context->format & PRF_ONELINE) ? "" : gettext("envcnt"),
 786                     (context->format & PRF_ONELINE) ? "" : context->SEPARATOR,
 787                     num, context->SEPARATOR);
 788                 if (returnstat < 0)
 789                         return (returnstat);
 790         }
 791 
 792         if ((num == 0) && !(context->format & PRF_XMLM)) {
 793                 returnstat = do_newline(context, 1);
 794                 if (returnstat < 0)
 795                         return (returnstat);
 796         }
 797 
 798         for (; num > 1; num--) {
 799                 if ((returnstat = process_tag(context, TAG_ARGE,
 800                     returnstat, 0)) < 0)
 801                         return (returnstat);
 802         }
 803         if (num)
 804                 returnstat = process_tag(context, TAG_ARGE, returnstat, 1);
 805 
 806         return (returnstat);
 807 
 808 }
 809 
 810 /*
 811  * -----------------------------------------------------------------------
 812  * argument32_token()   : Process argument token and display contents
 813  * return codes         : -1 - error
 814  *                      :  0 - successful
 815  * NOTE: At the time of call, the arg token id has been retrieved
 816  *
 817  * Format of argument token:
 818  *      current directory token id      adr_char
 819  *      argument number                 adr_char
 820  *      argument value                  adr_int32
 821  *      argument description            adr_string
 822  * -----------------------------------------------------------------------
 823  */
 824 int
 825 argument32_token(pr_context_t *context)
 826 {
 827         int     returnstat;
 828 
 829         returnstat = process_tag(context, TAG_ARGNUM, 0, 0);
 830         returnstat = process_tag(context, TAG_ARGVAL32, returnstat, 0);
 831         returnstat = process_tag(context, TAG_ARGDESC, returnstat, 1);
 832 
 833         return (returnstat);
 834 
 835 }
 836 
 837 /*
 838  * -----------------------------------------------------------------------
 839  * argument64_token()   : Process argument token and display contents
 840  * return codes         : -1 - error
 841  *                      :  0 - successful
 842  * NOTE: At the time of call, the arg token id has been retrieved
 843  *
 844  * Format of 64 bit argument token:
 845  *      current directory token id      adr_char
 846  *      argument number                 adr_char
 847  *      argument value                  adr_int64
 848  *      argument description            adr_string
 849  * -----------------------------------------------------------------------
 850  */
 851 int
 852 argument64_token(pr_context_t *context)
 853 {
 854         int     returnstat;
 855 
 856         returnstat = process_tag(context, TAG_ARGNUM, 0, 0);
 857         returnstat = process_tag(context, TAG_ARGVAL64, returnstat, 0);
 858         returnstat = process_tag(context, TAG_ARGDESC, returnstat, 1);
 859 
 860         return (returnstat);
 861 
 862 }
 863 
 864 /*
 865  * -----------------------------------------------------------------------
 866  * process_token()      : Process process token and display contents
 867  * return codes         : -1 - error
 868  *                      :  0 - successful
 869  * NOTE: At the time of call, the process token id has been retrieved
 870  *
 871  * Format of process token:
 872  *      process token id        adr_char
 873  *      auid                    adr_u_int32
 874  *      euid                    adr_u_int32
 875  *      egid                    adr_u_int32
 876  *      ruid                    adr_u_int32
 877  *      egid                    adr_u_int32
 878  *      pid                     adr_u_int32
 879  *      sid                     adr_u_int32
 880  *      tid                     adr_u_int32, adr_u_int32
 881  * -----------------------------------------------------------------------
 882  */
 883 int
 884 process32_token(pr_context_t *context)
 885 {
 886         int     returnstat;
 887 
 888                 /* auid */
 889         returnstat = process_tag(context, TAG_AUID, 0, 0);
 890                 /* uid */
 891         returnstat = process_tag(context, TAG_UID, returnstat, 0);
 892                 /* gid */
 893         returnstat = process_tag(context, TAG_GID, returnstat, 0);
 894                 /* ruid */
 895         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
 896                 /* rgid */
 897         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
 898                 /* pid */
 899         returnstat = process_tag(context, TAG_PID, returnstat, 0);
 900                 /* sid */
 901         returnstat = process_tag(context, TAG_SID, returnstat, 0);
 902                 /* tid */
 903         returnstat = process_tag(context, TAG_TID32, returnstat, 1);
 904 
 905         return (returnstat);
 906 }
 907 
 908 int
 909 process64_token(pr_context_t *context)
 910 {
 911         int     returnstat;
 912 
 913                 /* auid */
 914         returnstat = process_tag(context, TAG_AUID, 0, 0);
 915                 /* uid */
 916         returnstat = process_tag(context, TAG_UID, returnstat, 0);
 917                 /* gid */
 918         returnstat = process_tag(context, TAG_GID, returnstat, 0);
 919                 /* ruid */
 920         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
 921                 /* rgid */
 922         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
 923                 /* pid */
 924         returnstat = process_tag(context, TAG_PID, returnstat, 0);
 925                 /* sid */
 926         returnstat = process_tag(context, TAG_SID, returnstat, 0);
 927                 /* tid */
 928         returnstat = process_tag(context, TAG_TID64, returnstat, 1);
 929 
 930         return (returnstat);
 931 }
 932 
 933 /*
 934  * -----------------------------------------------------------------------
 935  * process_ex_token()   : Process process token and display contents
 936  * return codes         : -1 - error
 937  *                      :  0 - successful
 938  * NOTE: At the time of call, the process token id has been retrieved
 939  *
 940  * Format of extended process token:
 941  *      process token id        adr_char
 942  *      auid                    adr_u_int32
 943  *      euid                    adr_u_int32
 944  *      egid                    adr_u_int32
 945  *      ruid                    adr_u_int32
 946  *      egid                    adr_u_int32
 947  *      pid                     adr_u_int32
 948  *      sid                     adr_u_int32
 949  *      tid                     adr_u_int32, adr_u_int32, 4*adr_u_int32
 950  * -----------------------------------------------------------------------
 951  */
 952 int
 953 process32_ex_token(pr_context_t *context)
 954 {
 955         int     returnstat;
 956 
 957                 /* auid */
 958         returnstat = process_tag(context, TAG_AUID, 0, 0);
 959                 /* uid */
 960         returnstat = process_tag(context, TAG_UID, returnstat, 0);
 961                 /* gid */
 962         returnstat = process_tag(context, TAG_GID, returnstat, 0);
 963                 /* ruid */
 964         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
 965                 /* rgid */
 966         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
 967                 /* pid */
 968         returnstat = process_tag(context, TAG_PID, returnstat, 0);
 969                 /* sid */
 970         returnstat = process_tag(context, TAG_SID, returnstat, 0);
 971                 /* tid */
 972         returnstat = process_tag(context, TAG_TID32_EX, returnstat, 1);
 973 
 974         return (returnstat);
 975 }
 976 
 977 int
 978 process64_ex_token(pr_context_t *context)
 979 {
 980         int     returnstat;
 981 
 982                 /* auid */
 983         returnstat = process_tag(context, TAG_AUID, 0, 0);
 984                 /* uid */
 985         returnstat = process_tag(context, TAG_UID, returnstat, 0);
 986                 /* gid */
 987         returnstat = process_tag(context, TAG_GID, returnstat, 0);
 988                 /* ruid */
 989         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
 990                 /* rgid */
 991         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
 992                 /* pid */
 993         returnstat = process_tag(context, TAG_PID, returnstat, 0);
 994                 /* sid */
 995         returnstat = process_tag(context, TAG_SID, returnstat, 0);
 996                 /* tid */
 997         returnstat = process_tag(context, TAG_TID64_EX, returnstat, 1);
 998 
 999         return (returnstat);
1000 }
1001 
1002 /*
1003  * -----------------------------------------------------------------------
1004  * return_value32_token(): Process return value and display contents
1005  * return codes         : -1 - error
1006  *                      :  0 - successful
1007  * NOTE: At the time of call, the return value token id has been retrieved
1008  *
1009  * Format of return value token:
1010  *      return value token id   adr_char
1011  *      error number            adr_char
1012  *      return value            adr_int32
1013  * -----------------------------------------------------------------------
1014  */
1015 int
1016 return_value32_token(pr_context_t *context)
1017 {
1018         int             returnstat;
1019         uchar_t         number;
1020         int32_t         value;
1021         char            pb[512];    /* print buffer */
1022         uval_t          uval;
1023         bool_t          used_ret_val = 0;
1024 
1025         /*
1026          * Every audit record generated contains a return token.
1027          *
1028          * The return token is a special token. It indicates the success
1029          * or failure of the event that contains it.
1030          * The return32 token contains two pieces of data:
1031          *
1032          *      char    number;
1033          *      int32_t return_value;
1034          *
1035          * For audit records generated by the kernel:
1036          * The kernel always puts a positive value in "number".
1037          * Upon success "number" is 0.
1038          * Upon failure "number" is a positive errno value that is less than
1039          * sys_nerr.
1040          *
1041          * For audit records generated at the user level:
1042          * Upon success "number" is 0.
1043          * Upon failure "number" is -1.
1044          *
1045          * For both kernel and user land the value of "return_value" is
1046          * arbitrary. For the kernel it contains the return value of
1047          * the system call. For user land it contains an arbitrary return
1048          * value if it is less than ADT_FAIL_VALUE; ADT_FAIL_VALUE
1049          * and above are messages defined in adt_event.h.   ADT_FAIL_PAM and
1050          * above are messages from pam_strerror().  No interpretation is done
1051          * on "return_value" if it is outside the range of ADT_FAIL_VALUE_* or
1052          * ADT_FAIL_PAM values.
1053          */
1054         if ((returnstat = open_tag(context, TAG_ERRVAL)) != 0)
1055                 return (returnstat);
1056 
1057         if ((returnstat = pr_adr_u_char(context, &number, 1)) == 0) {
1058                 if (!(context->format & PRF_RAWM)) {
1059                         used_ret_val = 1;
1060                         pa_error(number, pb, sizeof (pb));
1061                         uval.uvaltype = PRA_STRING;
1062                         uval.string_val = pb;
1063                         if ((returnstat = pa_print(context, &uval, 0)) != 0)
1064                                 return (returnstat);
1065                         if ((returnstat = close_tag(context, TAG_ERRVAL)) != 0)
1066                                 return (returnstat);
1067                         if ((returnstat = open_tag(context, TAG_RETVAL)) != 0)
1068                                 return (returnstat);
1069 
1070                         if ((returnstat = pr_adr_int32(
1071                             context, &value, 1)) != 0)
1072                                 return (returnstat);
1073 
1074                         pa_retval(number, value, pb, sizeof (pb));
1075                 } else {
1076                         uval.uvaltype = PRA_INT32;
1077                         if ((char)number == -1)
1078                                 uval.int32_val = -1;
1079                         else
1080                                 uval.int32_val = number;
1081                 }
1082                 returnstat = pa_print(context, &uval, used_ret_val);
1083         }
1084         if (used_ret_val) {
1085                 if (returnstat == 0)
1086                         returnstat = close_tag(context, TAG_RETVAL);
1087                 return (returnstat);
1088         }
1089         if (!returnstat)
1090                 if (returnstat = close_tag(context, TAG_ERRVAL))
1091                         return (returnstat);
1092 
1093         return (process_tag(context, TAG_RETVAL, returnstat, 1));
1094 }
1095 
1096 /*
1097  * -----------------------------------------------------------------------
1098  * return_value64_token(): Process return value and display contents
1099  * return codes         : -1 - error
1100  *                      :  0 - successful
1101  * NOTE: At the time of call, the return value token id has been retrieved
1102  *
1103  * Format of return value token:
1104  *      return value token id   adr_char
1105  *      error number            adr_char
1106  *      return value            adr_int64
1107  *
1108  * HOWEVER, the 64 bit return value is a concatenation of two
1109  * 32 bit return values; the first of which is the same as is
1110  * carried in the return32 token.  The second 32 bits are ignored
1111  * here so that the displayed return token will have the same
1112  * number whether the application is 32 or 64 bits.
1113  * -----------------------------------------------------------------------
1114  */
1115 int
1116 return_value64_token(pr_context_t *context)
1117 {
1118         int             returnstat;
1119         uchar_t         number;
1120         rval_t          rval;
1121         char            pb[512];    /* print buffer */
1122         uval_t          uval;
1123 
1124         /*
1125          * Every audit record generated contains a return token.
1126          *
1127          * The return token is a special token. It indicates the success
1128          * or failure of the event that contains it.
1129          * The return64 token contains two pieces of data:
1130          *
1131          *      char    number;
1132          *      int64_t return_value;
1133          *
1134          * For audit records generated by the kernel:
1135          * The kernel always puts a positive value in "number".
1136          * Upon success "number" is 0.
1137          * Upon failure "number" is a positive errno value that is less than
1138          * sys_nerr.
1139          *
1140          * For audit records generated at the user level:
1141          * Upon success "number" is 0.
1142          * Upon failure "number" is -1.
1143          *
1144          * For both kernel and user land the value of "return_value" is
1145          * arbitrary. For the kernel it contains the return value of
1146          * the system call. For user land it contains an arbitrary return
1147          * value if it is less than ADT_FAIL_VALUE; ADT_FAIL_VALUE
1148          * and above are messages defined in adt_event.h.   ADT_FAIL_PAM and
1149          * above are messages from pam_strerror().  No interpretation is done
1150          * on "return_value" if it is outside the range of ADT_FAIL_VALUE_* or
1151          * ADT_FAIL_PAM values.
1152          *
1153          * The 64 bit return value consists of two 32bit parts; for
1154          * system calls, the first part is the value returned by the
1155          * system call and the second part depends on the system call
1156          * implementation.  In most cases, the second part is either 0
1157          * or garbage; because of that, it is omitted from the praudit
1158          * output.
1159          */
1160         if ((returnstat = open_tag(context, TAG_ERRVAL)) != 0)
1161                 return (returnstat);
1162 
1163         if ((returnstat = pr_adr_u_char(context, &number, 1)) == 0) {
1164                 if (!(context->format & PRF_RAWM)) {
1165                         pa_error(number, pb, sizeof (pb));
1166                         uval.uvaltype = PRA_STRING;
1167                         uval.string_val = pb;
1168                         if ((returnstat = pa_print(context, &uval, 0)) != 0)
1169                                 return (returnstat);
1170 
1171                         if ((returnstat = close_tag(context, TAG_ERRVAL)) != 0)
1172                                 return (returnstat);
1173                         if ((returnstat = open_tag(context, TAG_RETVAL)) != 0)
1174                                 return (returnstat);
1175 
1176                         if ((returnstat = pr_adr_int64(context,
1177                             &rval.r_vals, 1)) != 0)
1178                                 return (returnstat);
1179                         pa_retval(number, rval.r_val1, pb, sizeof (pb));
1180                 } else {
1181                         uval.uvaltype = PRA_INT32;
1182                         if ((char)number == -1)
1183                                 uval.int32_val = -1;
1184                         else
1185                                 uval.int32_val = number;
1186 
1187                         if ((returnstat = pa_print(context, &uval, 0)) != 0)
1188                                 return (returnstat);
1189 
1190                         if ((returnstat = close_tag(context, TAG_ERRVAL)) != 0)
1191                                 return (returnstat);
1192                         if ((returnstat = open_tag(context, TAG_RETVAL)) != 0)
1193                                 return (returnstat);
1194 
1195                         if ((returnstat = pr_adr_int64(context,
1196                             &rval.r_vals, 1)) != 0)
1197                                 return (returnstat);
1198                         uval.int32_val = rval.r_val1;
1199                 }
1200                 returnstat = pa_print(context, &uval, 1);
1201         } else {
1202                 return (returnstat);
1203         }
1204 
1205         if (returnstat == 0)
1206                 returnstat = close_tag(context, TAG_RETVAL);
1207 
1208         return (returnstat);
1209 }
1210 
1211 /*
1212  * -----------------------------------------------------------------------
1213  * subject32_token()    : Process subject token and display contents
1214  * return codes         : -1 - error
1215  *                      :  0 - successful
1216  * NOTE: At the time of call, the subject token id has been retrieved
1217  *
1218  * Format of subject token:
1219  *      subject token id        adr_char
1220  *      auid                    adr_u_int32
1221  *      euid                    adr_u_int32
1222  *      egid                    adr_u_int32
1223  *      ruid                    adr_u_int32
1224  *      egid                    adr_u_int32
1225  *      pid                     adr_u_int32
1226  *      sid                     adr_u_int32
1227  *      tid                     adr_u_int32, adr_u_int32
1228  * -----------------------------------------------------------------------
1229  */
1230 int
1231 subject32_token(pr_context_t *context)
1232 {
1233         int     returnstat;
1234 
1235                 /* auid */
1236         returnstat = process_tag(context, TAG_AUID, 0, 0);
1237                 /* uid */
1238         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1239                 /* gid */
1240         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1241                 /* ruid */
1242         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1243                 /* rgid */
1244         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1245                 /* pid */
1246         returnstat = process_tag(context, TAG_PID, returnstat, 0);
1247                 /* sid */
1248         returnstat = process_tag(context, TAG_SID, returnstat, 0);
1249                 /* tid */
1250         returnstat = process_tag(context, TAG_TID32, returnstat, 1);
1251 
1252         return (returnstat);
1253 }
1254 
1255 int
1256 subject64_token(pr_context_t *context)
1257 {
1258         int     returnstat;
1259 
1260                 /* auid */
1261         returnstat = process_tag(context, TAG_AUID, 0, 0);
1262                 /* uid */
1263         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1264                 /* gid */
1265         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1266                 /* ruid */
1267         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1268                 /* rgid */
1269         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1270                 /* pid */
1271         returnstat = process_tag(context, TAG_PID, returnstat, 0);
1272                 /* sid */
1273         returnstat = process_tag(context, TAG_SID, returnstat, 0);
1274                 /* tid */
1275         returnstat = process_tag(context, TAG_TID64, returnstat, 1);
1276 
1277         return (returnstat);
1278 }
1279 
1280 /*
1281  * -----------------------------------------------------------------------
1282  * subject_ex_token(): Process subject token and display contents
1283  * return codes         : -1 - error
1284  *                      :  0 - successful
1285  * NOTE: At the time of call, the subject token id has been retrieved
1286  *
1287  * Format of extended subject token:
1288  *      subject token id        adr_char
1289  *      auid                    adr_u_int32
1290  *      euid                    adr_u_int32
1291  *      egid                    adr_u_int32
1292  *      ruid                    adr_u_int32
1293  *      egid                    adr_u_int32
1294  *      pid                     adr_u_int32
1295  *      sid                     adr_u_int32
1296  *      tid                     adr_u_int32, adr_u_int32
1297  * -----------------------------------------------------------------------
1298  */
1299 int
1300 subject32_ex_token(pr_context_t *context)
1301 {
1302         int     returnstat;
1303 
1304                 /* auid */
1305         returnstat = process_tag(context, TAG_AUID, 0, 0);
1306                 /* uid */
1307         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1308                 /* gid */
1309         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1310                 /* ruid */
1311         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1312                 /* rgid */
1313         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1314                 /* pid */
1315         returnstat = process_tag(context, TAG_PID, returnstat, 0);
1316                 /* sid */
1317         returnstat = process_tag(context, TAG_SID, returnstat, 0);
1318                 /* tid */
1319         returnstat = process_tag(context, TAG_TID32_EX, returnstat, 1);
1320 
1321         return (returnstat);
1322 }
1323 
1324 int
1325 subject64_ex_token(pr_context_t *context)
1326 {
1327         int     returnstat;
1328 
1329                 /* auid */
1330         returnstat = process_tag(context, TAG_AUID, 0, 0);
1331                 /* uid */
1332         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1333                 /* gid */
1334         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1335                 /* ruid */
1336         returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1337                 /* rgid */
1338         returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1339                 /* pid */
1340         returnstat = process_tag(context, TAG_PID, returnstat, 0);
1341                 /* sid */
1342         returnstat = process_tag(context, TAG_SID, returnstat, 0);
1343                 /* tid */
1344         returnstat = process_tag(context, TAG_TID64_EX, returnstat, 1);
1345 
1346         return (returnstat);
1347 }
1348 
1349 /*
1350  * -----------------------------------------------------------------------
1351  * s5_IPC_token()       : Process System V IPC token and display contents
1352  * return codes         : -1 - error
1353  *                      :  0 - successful
1354  * NOTE: At the time of call, the System V IPC id has been retrieved
1355  *
1356  * Format of System V IPC token:
1357  *      System V IPC token id   adr_char
1358  *      object id               adr_int32
1359  * -----------------------------------------------------------------------
1360  */
1361 int
1362 s5_IPC_token(pr_context_t *context)
1363 {
1364         int     returnstat;
1365         uchar_t ipctype;
1366         uval_t  uval;
1367 
1368         /*
1369          * TRANSLATION_NOTE
1370          * These names refer to the type of System V IPC object:
1371          * message queue, semaphore, shared memory.
1372          */
1373 
1374         if (pr_adr_u_char(context, &ipctype, 1) == 0) {
1375                 if ((returnstat = open_tag(context, TAG_IPCTYPE)) != 0)
1376                         return (returnstat);
1377 
1378                 if (!(context->format & PRF_RAWM)) {
1379                         /* print in ASCII form */
1380                         uval.uvaltype = PRA_STRING;
1381                         switch (ipctype) {
1382                         case AT_IPC_MSG:
1383                                 uval.string_val = gettext("msg");
1384                                 break;
1385                         case AT_IPC_SEM:
1386                                 uval.string_val = gettext("sem");
1387                                 break;
1388                         case AT_IPC_SHM:
1389                                 uval.string_val = gettext("shm");
1390                                 break;
1391                         }
1392                         returnstat = pa_print(context, &uval, 0);
1393                 }
1394                 /* print in integer form */
1395                 if ((context->format & PRF_RAWM) || (returnstat == 1)) {
1396                         uval.uvaltype = PRA_BYTE;
1397                         uval.char_val = ipctype;
1398                         returnstat = pa_print(context, &uval, 0);
1399                 }
1400                 if ((returnstat = close_tag(context, TAG_IPCTYPE)) != 0)
1401                         return (returnstat);
1402 
1403                 /* next get and print ipc id */
1404                 return (process_tag(context, TAG_IPCID, returnstat, 1));
1405         } else {
1406                 /* cannot retrieve ipc type */
1407                 return (-1);
1408         }
1409 }
1410 
1411 /*
1412  * -----------------------------------------------------------------------
1413  * text_token() : Process text token and display contents
1414  * return codes : -1 - error
1415  *              :  0 - successful
1416  * NOTE: At the time of call, the text token id has been retrieved
1417  *
1418  * Format of text token:
1419  *      text token id           adr_char
1420  *      text                    adr_string
1421  * -----------------------------------------------------------------------
1422  */
1423 int
1424 text_token(pr_context_t *context)
1425 {
1426         return (pa_adr_string(context, 0, 1));
1427 }
1428 
1429 /*
1430  * -----------------------------------------------------------------------
1431  * tid_token()          : Process a generic terminal id token / AUT_TID
1432  * return codes         : -1 - error
1433  *                      :  0 - successful
1434  * NOTE: At the time of call, the token id has been retrieved
1435  *
1436  * Format of tid token:
1437  *      ip token id     adr_char
1438  *      terminal type   adr_char
1439  *  terminal type = AU_IPADR:
1440  *      remote port:    adr_short
1441  *      local port:     adr_short
1442  *      IP type:        adt_int32 -- AU_IPv4 or AU_IPv6
1443  *      address:        adr_int32 if IPv4, else 4 * adr_int32
1444  * -----------------------------------------------------------------------
1445  */
1446 int
1447 tid_token(pr_context_t *context)
1448 {
1449         int             returnstat;
1450         uchar_t         type;
1451         uval_t          uval;
1452 
1453         if ((returnstat = pr_adr_u_char(context, &type, 1)) != 0)
1454                 return (returnstat);
1455         uval.uvaltype = PRA_STRING;
1456         if ((returnstat = open_tag(context, TAG_TID_TYPE)) != 0)
1457                 return (returnstat);
1458 
1459         switch (type) {
1460         default:
1461                 return (-1);    /* other than IP type is not implemented */
1462         case AU_IPADR:
1463                 uval.string_val = "ip";
1464                 returnstat = pa_print(context, &uval, 0);
1465                 returnstat = close_tag(context, TAG_TID_TYPE);
1466                 returnstat = open_tag(context, TAG_IP);
1467                 returnstat = process_tag(context, TAG_IP_REMOTE, returnstat, 0);
1468                 returnstat = process_tag(context, TAG_IP_LOCAL, returnstat, 0);
1469                 returnstat = process_tag(context, TAG_IP_ADR, returnstat, 1);
1470                 returnstat = close_tag(context, TAG_IP);
1471                 break;
1472         }
1473         return (returnstat);
1474 }
1475 
1476 /*
1477  * -----------------------------------------------------------------------
1478  * ip_addr_token()      : Process ip token and display contents
1479  * return codes         : -1 - error
1480  *                      :  0 - successful
1481  * NOTE: At the time of call, the ip token id has been retrieved
1482  *
1483  * Format of ip address token:
1484  *      ip token id     adr_char
1485  *      address         adr_int32 (printed in hex)
1486  * -----------------------------------------------------------------------
1487  */
1488 
1489 int
1490 ip_addr_token(pr_context_t *context)
1491 {
1492         return (pa_hostname(context, 0, 1));
1493 }
1494 
1495 int
1496 ip_addr_ex_token(pr_context_t *context)
1497 {
1498         int     returnstat;
1499         uint32_t        ip_addr[16];
1500         uint32_t        ip_type;
1501         struct in_addr  ia;
1502         char            *ipstring;
1503         char            buf[256];
1504         uval_t          uval;
1505 
1506         /* get address type */
1507         if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0)
1508                 return (returnstat);
1509 
1510         /* legal address types are either AU_IPv4 or AU_IPv6 only */
1511         if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
1512                 return (-1);
1513 
1514         /* get address (4/16) */
1515         if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
1516                 return (returnstat);
1517 
1518         uval.uvaltype = PRA_STRING;
1519         if (ip_type == AU_IPv4) {
1520                 uval.string_val = buf;
1521 
1522                 if (!(context->format & PRF_RAWM)) {
1523                         get_Hname(ip_addr[0], buf, sizeof (buf));
1524                         return (pa_print(context, &uval, 1));
1525                 }
1526 
1527                 ia.s_addr = ip_addr[0];
1528                 if ((ipstring = inet_ntoa(ia)) == NULL)
1529                         return (-1);
1530 
1531                 (void) snprintf(buf, sizeof (buf), "%s", ipstring);
1532 
1533         } else {
1534                 uval.string_val = buf;
1535 
1536                 if (!(context->format & PRF_RAWM)) {
1537                         get_Hname_ex(ip_addr, buf, sizeof (buf));
1538                         return (pa_print(context, &uval, 1));
1539                 }
1540 
1541                 (void) inet_ntop(AF_INET6, (void *) ip_addr, buf,
1542                     sizeof (buf));
1543 
1544         }
1545 
1546         return (pa_print(context, &uval, 1));
1547 }
1548 
1549 /*
1550  * -----------------------------------------------------------------------
1551  * ip_token()           : Process ip header token and display contents
1552  * return codes         : -1 - error
1553  *                      :  0 - successful
1554  * NOTE: At the time of call, the ip token id has been retrieved
1555  *
1556  * Format of ip header token:
1557  *      ip header token id      adr_char
1558  *      version                 adr_char (printed in hex)
1559  *      type of service         adr_char (printed in hex)
1560  *      length                  adr_short
1561  *      id                      adr_u_short
1562  *      offset                  adr_u_short
1563  *      ttl                     adr_char (printed in hex)
1564  *      protocol                adr_char (printed in hex)
1565  *      checksum                adr_u_short
1566  *      source address          adr_int32 (printed in hex)
1567  *      destination address     adr_int32 (printed in hex)
1568  * -----------------------------------------------------------------------
1569  */
1570 int
1571 ip_token(pr_context_t *context)
1572 {
1573         int     returnstat;
1574 
1575         returnstat = process_tag(context, TAG_IPVERS, 0, 0);
1576         returnstat = process_tag(context, TAG_IPSERV, returnstat, 0);
1577         returnstat = process_tag(context, TAG_IPLEN, returnstat, 0);
1578         returnstat = process_tag(context, TAG_IPID, returnstat, 0);
1579         returnstat = process_tag(context, TAG_IPOFFS, returnstat, 0);
1580         returnstat = process_tag(context, TAG_IPTTL, returnstat, 0);
1581         returnstat = process_tag(context, TAG_IPPROTO, returnstat, 0);
1582         returnstat = process_tag(context, TAG_IPCKSUM, returnstat, 0);
1583         returnstat = process_tag(context, TAG_IPSRC, returnstat, 0);
1584         returnstat = process_tag(context, TAG_IPDEST, returnstat, 1);
1585 
1586         return (returnstat);
1587 }
1588 
1589 /*
1590  * -----------------------------------------------------------------------
1591  * iport_token()        : Process ip port address token and display contents
1592  * return codes         : -1 - error
1593  *                      :  0 - successful
1594  * NOTE: At time of call, the ip port address token id has been retrieved
1595  *
1596  * Format of ip port token:
1597  *      ip port address token id        adr_char
1598  *      port address                    adr_short (in_port_t == uint16_t)
1599  * -----------------------------------------------------------------------
1600  */
1601 int
1602 iport_token(pr_context_t *context)
1603 {
1604         return (pa_adr_u_short(context, 0, 1));
1605 }
1606 
1607 /*
1608  * -----------------------------------------------------------------------
1609  * socket_token()       : Process socket token and display contents
1610  * return codes         : -1 - error
1611  *                      :  0 - successful
1612  * NOTE: At time of call, the socket token id has been retrieved
1613  *
1614  * Format of socket token:
1615  *      ip socket token id              adr_char
1616  *      socket type                     adr_short (in hex)
1617  *      foreign port                    adr_short (in hex)
1618  *      foreign internet address        adr_hostname/adr_int32 (in ascii/hex)
1619  * -----------------------------------------------------------------------
1620  *
1621  * Note: local port and local internet address have been removed for 5.x
1622  */
1623 int
1624 socket_token(pr_context_t *context)
1625 {
1626         int     returnstat;
1627 
1628         returnstat = process_tag(context, TAG_SOCKTYPE, 0, 0);
1629         returnstat = process_tag(context, TAG_SOCKPORT, returnstat, 0);
1630         if (returnstat != 0)
1631                 return (returnstat);
1632 
1633         if ((returnstat = open_tag(context, TAG_SOCKADDR)) != 0)
1634                 return (returnstat);
1635 
1636         if ((returnstat = pa_hostname(context, returnstat, 1)) != 0)
1637                 return (returnstat);
1638 
1639         return (close_tag(context, TAG_SOCKADDR));
1640 }
1641 
1642 /*
1643  * -----------------------------------------------------------------------
1644  * socket_ex_token()    : Process socket token and display contents
1645  * return codes         : -1 - error
1646  *                      :  0 - successful
1647  * NOTE: At time of call, the extended socket token id has been retrieved
1648  *
1649  * Format of extended socket token:
1650  *      token id                        adr_char
1651  *      socket domain                   adr_short (in hex)
1652  *      socket type                     adr_short (in hex)
1653  *      IP address type                 adr_short (in hex) [not displayed]
1654  *      local port                      adr_short (in hex)
1655  *      local internet address          adr_hostname/adr_int32 (in ascii/hex)
1656  *      foreign port                    adr_short (in hex)
1657  *      foreign internet address        adr_hostname/adr_int32 (in ascii/hex)
1658  * -----------------------------------------------------------------------
1659  *
1660  * Note: local port and local internet address have been removed for 5.x
1661  */
1662 int
1663 socket_ex_token(pr_context_t *context)
1664 {
1665         int     returnstat;
1666 
1667         returnstat = process_tag(context, TAG_SOCKEXDOM, 0, 0);
1668         returnstat = process_tag(context, TAG_SOCKEXTYPE, returnstat, 0);
1669         returnstat = pa_hostname_so(context, returnstat, 1);
1670 
1671         return (returnstat);
1672 }
1673 
1674 /*
1675  * -----------------------------------------------------------------------
1676  * sequence_token()     : Process sequence token and display contents
1677  * return codes         : -1 - error
1678  *                      :  0 - successful
1679  * NOTE: At time of call, the socket token id has been retrieved
1680  *
1681  * Format of sequence token:
1682  *      sequence token id               adr_char
1683  *      sequence number                 adr_u_int32 (in hex)
1684  * -----------------------------------------------------------------------
1685  */
1686 int
1687 sequence_token(pr_context_t *context)
1688 {
1689         return (process_tag(context, TAG_SEQNUM, 0, 1));
1690 }
1691 
1692 /*
1693  * -----------------------------------------------------------------------
1694  * acl_token()  : Process access control list term
1695  * return codes : -1 - error
1696  *              :  0 - successful
1697  *
1698  * Format of acl token:
1699  *      token id        adr_char
1700  *      term type       adr_u_int32
1701  *      term value      adr_u_int32 (depends on type)
1702  *      file mode       adr_u_int (in octal)
1703  * -----------------------------------------------------------------------
1704  */
1705 int
1706 acl_token(pr_context_t *context)
1707 {
1708         int     returnstat;
1709 
1710         returnstat = pa_pw_uid_gr_gid(context, 0, 0);
1711 
1712         return (process_tag(context, TAG_MODE, returnstat, 1));
1713 }
1714 
1715 /*
1716  * -----------------------------------------------------------------------
1717  * ace_token()  : Process ZFS/NFSv4 access control list term
1718  * return codes : -1 - error
1719  *              :  0 - successful
1720  *
1721  * Format of ace token:
1722  *      token id        adr_char
1723  *      term who        adr_u_int32 (uid/gid)
1724  *      term mask       adr_u_int32
1725  *      term flags      adr_u_int16
1726  *      term type       adr_u_int16
1727  * -----------------------------------------------------------------------
1728  */
1729 int
1730 ace_token(pr_context_t *context)
1731 {
1732         return (pa_ace(context, 0, 1));
1733 }
1734 
1735 /*
1736  * -----------------------------------------------------------------------
1737  * attribute_token()    : Process attribute token and display contents
1738  * return codes         : -1 - error
1739  *                      :  0 - successful
1740  * NOTE: At the time of call, the attribute token id has been retrieved
1741  *
1742  * Format of attribute token:
1743  *      attribute token id      adr_char
1744  *      mode                    adr_u_int (printed in octal)
1745  *      uid                     adr_u_int
1746  *      gid                     adr_u_int
1747  *      file system id          adr_int
1748  *
1749  *      node id                 adr_int         (attribute_token
1750  *                                               pre SunOS 5.7)
1751  *      device                  adr_u_int
1752  * or
1753  *      node id                 adr_int64       (attribute32_token)
1754  *      device                  adr_u_int
1755  * or
1756  *      node id                 adr_int64       (attribute64_token)
1757  *      device                  adr_u_int64
1758  * -----------------------------------------------------------------------
1759  */
1760 int
1761 attribute_token(pr_context_t *context)
1762 {
1763         int     returnstat;
1764 
1765         returnstat = process_tag(context, TAG_MODE, 0, 0);
1766         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1767         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1768         returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1769         returnstat = process_tag(context, TAG_NODEID32, returnstat, 0);
1770         returnstat = process_tag(context, TAG_DEVICE32, returnstat, 1);
1771 
1772         return (returnstat);
1773 }
1774 
1775 int
1776 attribute32_token(pr_context_t *context)
1777 {
1778         int     returnstat;
1779 
1780         returnstat = process_tag(context, TAG_MODE, 0, 0);
1781         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1782         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1783         returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1784         returnstat = process_tag(context, TAG_NODEID64, returnstat, 0);
1785         returnstat = process_tag(context, TAG_DEVICE32, returnstat, 1);
1786 
1787         return (returnstat);
1788 }
1789 
1790 int
1791 attribute64_token(pr_context_t *context)
1792 {
1793         int     returnstat;
1794 
1795         returnstat = process_tag(context, TAG_MODE, 0, 0);
1796         returnstat = process_tag(context, TAG_UID, returnstat, 0);
1797         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1798         returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1799         returnstat = process_tag(context, TAG_NODEID64, returnstat, 0);
1800         returnstat = process_tag(context, TAG_DEVICE64, returnstat, 1);
1801 
1802         return (returnstat);
1803 }
1804 
1805 /*
1806  * -----------------------------------------------------------------------
1807  * group_token()        : Process group token and display contents
1808  * return codes         : -1 - error
1809  *                      :  0 - successful
1810  * NOTE: At the time of call, the group token id has been retrieved
1811  * NOTE: This token is obsolete; it supports exactly NGROUPS_MAX
1812  * groups.
1813  *
1814  * Format of group token:
1815  *      group token id          adr_char
1816  *      group list              adr_long, 16 times
1817  * -----------------------------------------------------------------------
1818  */
1819 int
1820 group_token(pr_context_t *context)
1821 {
1822         int     returnstat = 0;
1823         int     i;
1824 
1825         for (i = 0; i < NGROUPS_MAX - 1; i++) {
1826                 if ((returnstat = process_tag(context, TAG_GROUPID,
1827                     returnstat, 0)) < 0)
1828                         return (returnstat);
1829         }
1830 
1831         return (process_tag(context, TAG_GROUPID, returnstat, 1));
1832 }
1833 
1834 /*
1835  * -----------------------------------------------------------------------
1836  * newgroup_token()     : Process group token and display contents
1837  * return codes         : -1 - error
1838  *                      :  0 - successful
1839  * NOTE: At the time of call, the group token id has been retrieved
1840  *
1841  * Format of new group token:
1842  *      group token id          adr_char
1843  *      group number            adr_short
1844  *      group list              adr_int32, group number times
1845  * -----------------------------------------------------------------------
1846  */
1847 int
1848 newgroup_token(pr_context_t *context)
1849 {
1850         int     returnstat;
1851         int     i, num;
1852         short   n_groups;
1853 
1854         returnstat = pr_adr_short(context, &n_groups, 1);
1855         if (returnstat != 0)
1856                 return (returnstat);
1857 
1858         num = (int)n_groups;
1859         if (num == 0) {
1860                 if (!(context->format & PRF_XMLM)) {
1861                         returnstat = do_newline(context, 1);
1862                 }
1863                 return (returnstat);
1864         }
1865         for (i = 0; i < num - 1; i++) {
1866                 if ((returnstat = process_tag(context, TAG_GROUPID,
1867                     returnstat, 0)) < 0)
1868                         return (returnstat);
1869         }
1870 
1871         return (process_tag(context, TAG_GROUPID, returnstat, 1));
1872 }
1873 
1874 static int
1875 string_token_common(pr_context_t *context, int tag)
1876 {
1877         int     returnstat;
1878         int     num;
1879 
1880         returnstat = pr_adr_int32(context, (int32_t *)&num, 1);
1881         if (returnstat != 0)
1882                 return (returnstat);
1883 
1884         if (!(context->format & PRF_XMLM)) {
1885                 returnstat = pr_printf(context, "%d%s", num,
1886                     context->SEPARATOR);
1887                 if (returnstat != 0)
1888                         return (returnstat);
1889         }
1890 
1891         if (num == 0)
1892                 return (do_newline(context, 1));
1893 
1894         for (; num > 1; num--) {
1895                 if ((returnstat = (process_tag(context, tag,
1896                     returnstat, 0))) < 0)
1897                         return (returnstat);
1898         }
1899 
1900         return (process_tag(context, tag, returnstat, 1));
1901 }
1902 
1903 int
1904 path_attr_token(pr_context_t *context)
1905 {
1906         return (string_token_common(context, TAG_XAT));
1907 }
1908 
1909 int
1910 exec_args_token(pr_context_t *context)
1911 {
1912         return (string_token_common(context, TAG_ARG));
1913 }
1914 
1915 int
1916 exec_env_token(pr_context_t *context)
1917 {
1918         return (string_token_common(context, TAG_ENV));
1919 }
1920 
1921 /*
1922  * -----------------------------------------------------------------------
1923  * s5_IPC_perm_token() : Process System V IPC permission token and display
1924  *                       contents
1925  * return codes         : -1 - error
1926  *                      :  0 - successful
1927  * NOTE: At the time of call, the System V IPC permission token id
1928  * has been retrieved
1929  *
1930  * Format of System V IPC permission token:
1931  *      System V IPC permission token id        adr_char
1932  *      uid                                     adr_u_int32
1933  *      gid                                     adr_u_int32
1934  *      cuid                                    adr_u_int32
1935  *      cgid                                    adr_u_int32
1936  *      mode                                    adr_u_int32
1937  *      seq                                     adr_u_int32
1938  *      key                                     adr_int32
1939  * -----------------------------------------------------------------------
1940  */
1941 int
1942 s5_IPC_perm_token(pr_context_t *context)
1943 {
1944         int     returnstat;
1945 
1946         returnstat = process_tag(context, TAG_UID, 0, 0);
1947         returnstat = process_tag(context, TAG_GID, returnstat, 0);
1948         returnstat = process_tag(context, TAG_CUID, returnstat, 0);
1949         returnstat = process_tag(context, TAG_CGID, returnstat, 0);
1950         returnstat = process_tag(context, TAG_MODE, returnstat, 0);
1951         returnstat = process_tag(context, TAG_SEQ, returnstat, 0);
1952         returnstat = process_tag(context, TAG_KEY, returnstat, 1);
1953 
1954         return (returnstat);
1955 }
1956 
1957 /*
1958  * -----------------------------------------------------------------------
1959  * host_token() : Process host token and display contents
1960  * return codes : -1 - error
1961  *              :  0 - successful
1962  * NOTE: At the time of call, the host token id has been retrieved
1963  *
1964  * Format of host token:
1965  *      host token id           adr_char
1966  *      hostid                  adr_u_int32
1967  * -----------------------------------------------------------------------
1968  */
1969 int
1970 host_token(pr_context_t *context)
1971 {
1972         return (pa_hostname(context, 0, 1));
1973 }
1974 
1975 /*
1976  * -----------------------------------------------------------------------
1977  * liaison_token()      : Process liaison token and display contents
1978  * return codes         : -1 - error
1979  *                      :  0 - successful
1980  * NOTE: At the time of call, the liaison token id has been retrieved
1981  *
1982  * Format of liaison token:
1983  *      liaison token id        adr_char
1984  *      liaison                 adr_u_int32
1985  * -----------------------------------------------------------------------
1986  */
1987 int
1988 liaison_token(pr_context_t *context)
1989 {
1990         return (pa_liaison(context, 0, 1));
1991 }
1992 
1993 /*
1994  * -----------------------------------------------------------------------
1995  * useofauth_token(): Process useofauth token and display contents
1996  * return codes : -1 - error
1997  *              :  0 - successful
1998  * NOTE: At the time of call, the uauth token id has been retrieved
1999  *
2000  * Format of useofauth token:
2001  *      uauth token id          adr_char
2002  *      uauth                   adr_string
2003  * -----------------------------------------------------------------------
2004  */
2005 int
2006 useofauth_token(pr_context_t *context)
2007 {
2008         return (pa_adr_string(context, 0, 1));
2009 }
2010 
2011 /*
2012  * -----------------------------------------------------------------------
2013  * user_token(): Process user token and display contents
2014  * return codes : -1 - error
2015  *              :  0 - successful
2016  * NOTE: At the time of call, the user token id has been retrieved
2017  *
2018  * Format of user token:
2019  *      user token id           adr_char
2020  *      user id                 adr_uid
2021  *      user name               adr_string
2022  * -----------------------------------------------------------------------
2023  */
2024 int
2025 user_token(pr_context_t *context)
2026 {
2027         int     returnstat;
2028 
2029         returnstat = process_tag(context, TAG_UID, 0, 0);
2030         return (process_tag(context, TAG_USERNAME, returnstat, 1));
2031 }
2032 
2033 /*
2034  * -----------------------------------------------------------------------
2035  * zonename_token(): Process zonename token and display contents
2036  * return codes : -1 - error
2037  *              :  0 - successful
2038  * NOTE: At the time of call, the zonename token id has been retrieved
2039  *
2040  * Format of zonename token:
2041  *      zonename token id       adr_char
2042  *      zone name               adr_string
2043  * -----------------------------------------------------------------------
2044  */
2045 int
2046 zonename_token(pr_context_t *context)
2047 {
2048         return (process_tag(context, TAG_ZONENAME, 0, 1));
2049 }
2050 
2051 /*
2052  * -----------------------------------------------------------------------
2053  * fmri_token(): Process fmri token and display contents
2054  * return codes : -1 - error
2055  *              :  0 - successful
2056  * NOTE: At the time of call, the fmri token id has been retrieved
2057  *
2058  * Format of fmri token:
2059  *      fmri token id           adr_char
2060  *      service instance name   adr_string
2061  * -----------------------------------------------------------------------
2062  */
2063 int
2064 fmri_token(pr_context_t *context)
2065 {
2066         return (pa_adr_string(context, 0, 1));
2067 }
2068 
2069 /*
2070  * -----------------------------------------------------------------------
2071  * xatom_token()        : Process Xatom token and display contents in hex.
2072  * return codes         : -1 - error
2073  *                      :  0 - successful
2074  * NOTE: At the time of call, the xatom token id has been retrieved
2075  *
2076  * Format of xatom token:
2077  *      token id                adr_char
2078  *      length                  adr_short
2079  *      atom                    adr_char length times
2080  * -----------------------------------------------------------------------
2081  */
2082 int
2083 xatom_token(pr_context_t *context)
2084 {
2085         return (pa_adr_string(context, 0, 1));
2086 }
2087 
2088 int
2089 xcolormap_token(pr_context_t *context)
2090 {
2091         return (pa_xgeneric(context));
2092 }
2093 
2094 int
2095 xcursor_token(pr_context_t *context)
2096 {
2097         return (pa_xgeneric(context));
2098 }
2099 
2100 int
2101 xfont_token(pr_context_t *context)
2102 {
2103         return (pa_xgeneric(context));
2104 }
2105 
2106 int
2107 xgc_token(pr_context_t *context)
2108 {
2109         return (pa_xgeneric(context));
2110 }
2111 
2112 int
2113 xpixmap_token(pr_context_t *context)
2114 {
2115         return (pa_xgeneric(context));
2116 }
2117 
2118 int
2119 xwindow_token(pr_context_t *context)
2120 {
2121         return (pa_xgeneric(context));
2122 }
2123 
2124 /*
2125  * -----------------------------------------------------------------------
2126  * xproperty_token(): Process Xproperty token and display contents
2127  *
2128  * return codes         : -1 - error
2129  *                      :  0 - successful
2130  * NOTE: At the time of call, the xproperty token id has been retrieved
2131  *
2132  * Format of xproperty token:
2133  *      token id                adr_char
2134  *      XID                     adr_u_int32
2135  *      creator UID             adr_u_int32
2136  *      text                    adr_text
2137  * -----------------------------------------------------------------------
2138  */
2139 int
2140 xproperty_token(pr_context_t *context)
2141 {
2142         int     returnstat;
2143 
2144         returnstat = process_tag(context, TAG_XID, 0, 0);
2145         returnstat = process_tag(context, TAG_XCUID, returnstat, 0);
2146 
2147         /* Done with attributes; force end of token open */
2148         if (returnstat == 0)
2149                 returnstat = finish_open_tag(context);
2150 
2151         returnstat = pa_adr_string(context, returnstat, 1);
2152 
2153         return (returnstat);
2154 }
2155 
2156 /*
2157  * -----------------------------------------------------------------------
2158  * xselect_token(): Process Xselect token and display contents in hex
2159  *
2160  * return codes         : -1 - error
2161  *                      :  0 - successful
2162  * NOTE: At the time of call, the xselect token id has been retrieved
2163  *
2164  * Format of xselect token
2165  *      text token id           adr_char
2166  *      property text           adr_string
2167  *      property type           adr_string
2168  *      property data           adr_string
2169  * -----------------------------------------------------------------------
2170  */
2171 int
2172 xselect_token(pr_context_t *context)
2173 {
2174         int     returnstat;
2175 
2176         returnstat = process_tag(context, TAG_XSELTEXT, 0, 0);
2177         returnstat = process_tag(context, TAG_XSELTYPE, returnstat, 0);
2178         returnstat = process_tag(context, TAG_XSELDATA, returnstat, 1);
2179 
2180         return (returnstat);
2181 }
2182 
2183 /*
2184  * -----------------------------------------------------------------------
2185  * xclient_token(): Process Xclient token and display contents in hex.
2186  *
2187  * return codes         : -1 - error
2188  *                      :  0 - successful
2189  *
2190  * Format of xclient token:
2191  *      token id                adr_char
2192  *      client                  adr_int32
2193  * -----------------------------------------------------------------------
2194  */
2195 int
2196 xclient_token(pr_context_t *context)
2197 {
2198         return (pa_adr_int32(context, 0, 1));
2199 }
2200 
2201 /*
2202  * -----------------------------------------------------------------------
2203  * label_token()        : Process label token and display contents
2204  * return codes         : -1 - error
2205  *                      : 0 - successful
2206  * NOTE: At the time of call, the label token id has been retrieved
2207  *
2208  * Format of label token:
2209  *      label token id                  adr_char
2210  *      label ID                        adr_char
2211  *      label compartment length        adr_char
2212  *      label classification            adr_short
2213  *      label compartment words         <compartment length> * 4 adr_char
2214  * -----------------------------------------------------------------------
2215  */
2216 /*ARGSUSED*/
2217 int
2218 label_token(pr_context_t *context)
2219 {
2220         static m_label_t *label = NULL;
2221         static size32_t l_size;
2222         int     len;
2223         int     returnstat;
2224         uval_t  uval;
2225 
2226         if (label == NULL) {
2227                 if ((label = m_label_alloc(MAC_LABEL)) == NULL) {
2228                         return (-1);
2229                 }
2230                 l_size = blabel_size() - 4;
2231         }
2232         if ((returnstat = pr_adr_char(context, (char *)label, 4)) == 0) {
2233                 len = (int)(((char *)label)[1] * 4);
2234                 if ((len > l_size) ||
2235                     (pr_adr_char(context, &((char *)label)[4], len) != 0)) {
2236                         return (-1);
2237                 }
2238                 uval.uvaltype = PRA_STRING;
2239                 if (!(context->format & PRF_RAWM)) {
2240                         /* print in ASCII form */
2241                         if (label_to_str(label, &uval.string_val, M_LABEL,
2242                             DEF_NAMES) == 0) {
2243                                 returnstat = pa_print(context, &uval, 1);
2244                         } else /* cannot convert to string */
2245                                 returnstat = 1;
2246                 }
2247                 /* print in hexadecimal form */
2248                 if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2249                         uval.string_val = hexconvert((char *)label, len, len);
2250                         if (uval.string_val) {
2251                                 returnstat = pa_print(context, &uval, 1);
2252                         }
2253                 }
2254                 free(uval.string_val);
2255         }
2256         return (returnstat);
2257 }
2258 
2259 /*
2260  * -----------------------------------------------------------------------
2261  * useofpriv_token() : Process priv token and display contents
2262  * return codes         : -1 - error
2263  *                      :  0 - successful
2264  * NOTE: At the time of call, the useofpriv token id has been retrieved
2265  *
2266  * Format of useofpriv token:
2267  *      useofpriv token id      adr_char
2268  *      success/failure flag    adr_char
2269  *      priv                    adr_int32 (Trusted Solaris)
2270  *      priv_set                '\0' separated privileges.
2271  * -----------------------------------------------------------------------
2272  */
2273 /*ARGSUSED*/
2274 int
2275 useofpriv_token(pr_context_t *context)
2276 {
2277         int     returnstat;
2278         char    sf;
2279         uval_t  uval;
2280 
2281         if ((returnstat = pr_adr_char(context, &sf, 1)) != 0) {
2282                 return (returnstat);
2283         }
2284         if (!(context->format & PRF_RAWM)) {
2285                 /* print in ASCII form */
2286 
2287                 if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2288                         return (returnstat);
2289 
2290                 uval.uvaltype = PRA_STRING;
2291                 if (sf) {
2292                         uval.string_val = gettext("successful use of priv");
2293                         returnstat = pa_print(context, &uval, 0);
2294                 } else {
2295                         uval.string_val = gettext("failed use of priv");
2296                         returnstat = pa_print(context, &uval, 0);
2297                 }
2298                 if (returnstat == 0)
2299                         returnstat = close_tag(context, TAG_RESULT);
2300 
2301                 /* Done with attributes; force end of token open */
2302                 if (returnstat == 0)
2303                         returnstat = finish_open_tag(context);
2304         } else {
2305                 /* print in hexadecimal form */
2306                 if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2307                         return (returnstat);
2308                 uval.uvaltype = PRA_SHORT;
2309                 uval.short_val = sf;
2310                 returnstat = pa_print(context, &uval, 0);
2311                 if (returnstat == 0)
2312                         returnstat = close_tag(context, TAG_RESULT);
2313 
2314                 /* Done with attributes; force end of token open */
2315                 if (returnstat == 0)
2316                         returnstat = finish_open_tag(context);
2317         }
2318         return (pa_adr_string(context, 0, 1));
2319 }
2320 
2321 /*
2322  * -----------------------------------------------------------------------
2323  * privilege_token()    : Process privilege token and display contents
2324  * return codes         : -1 - error
2325  *                      :  0 - successful
2326  * NOTE: At the time of call, the privilege token id has been retrieved
2327  *
2328  * Format of privilege token:
2329  *      privilege token id      adr_char
2330  *      privilege type          adr_string
2331  *      privilege               adr_string
2332  * -----------------------------------------------------------------------
2333  */
2334 int
2335 privilege_token(pr_context_t *context)
2336 {
2337         int     returnstat;
2338 
2339         /* privilege type: */
2340         returnstat = process_tag(context, TAG_SETTYPE, 0, 0);
2341 
2342         /* Done with attributes; force end of token open */
2343         if (returnstat == 0)
2344                 returnstat = finish_open_tag(context);
2345 
2346         /* privilege: */
2347         return (pa_adr_string(context, returnstat, 1));
2348 }