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