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