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