xref: /titanic_50/usr/src/cmd/praudit/token.c (revision 45179f4335d029f1129eb7283f8087740f0395f1)
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  *
1812  * Format of group token:
1813  *	group token id		adr_char
1814  *	group list		adr_long, 16 times
1815  * -----------------------------------------------------------------------
1816  */
1817 int
1818 group_token(pr_context_t *context)
1819 {
1820 	int	returnstat = 0;
1821 	int	i;
1822 
1823 	for (i = 0; i < NGROUPS_MAX - 1; i++) {
1824 		if ((returnstat = process_tag(context, TAG_GROUPID,
1825 		    returnstat, 0)) < 0)
1826 			return (returnstat);
1827 	}
1828 
1829 	return (process_tag(context, TAG_GROUPID, returnstat, 1));
1830 }
1831 
1832 /*
1833  * -----------------------------------------------------------------------
1834  * newgroup_token() 	: Process group token and display contents
1835  * return codes 	: -1 - error
1836  *			:  0 - successful
1837  * NOTE: At the time of call, the group token id has been retrieved
1838  *
1839  * Format of new group token:
1840  *	group token id		adr_char
1841  *	group number		adr_short
1842  *	group list		adr_int32, group number times
1843  * -----------------------------------------------------------------------
1844  */
1845 int
1846 newgroup_token(pr_context_t *context)
1847 {
1848 	int	returnstat;
1849 	int	i, num;
1850 	short	n_groups;
1851 
1852 	returnstat = pr_adr_short(context, &n_groups, 1);
1853 	if (returnstat != 0)
1854 		return (returnstat);
1855 
1856 	num = (int)n_groups;
1857 	if (num == 0) {
1858 		if (!(context->format & PRF_XMLM)) {
1859 			returnstat = do_newline(context, 1);
1860 		}
1861 		return (returnstat);
1862 	}
1863 	for (i = 0; i < num - 1; i++) {
1864 		if ((returnstat = process_tag(context, TAG_GROUPID,
1865 		    returnstat, 0)) < 0)
1866 			return (returnstat);
1867 	}
1868 
1869 	return (process_tag(context, TAG_GROUPID, returnstat, 1));
1870 }
1871 
1872 static int
1873 string_token_common(pr_context_t *context, int tag)
1874 {
1875 	int	returnstat;
1876 	int	num;
1877 
1878 	returnstat = pr_adr_int32(context, (int32_t *)&num, 1);
1879 	if (returnstat != 0)
1880 		return (returnstat);
1881 
1882 	if (!(context->format & PRF_XMLM)) {
1883 		returnstat = pr_printf(context, "%d%s", num,
1884 		    context->SEPARATOR);
1885 		if (returnstat != 0)
1886 			return (returnstat);
1887 	}
1888 
1889 	if (num == 0)
1890 		return (do_newline(context, 1));
1891 
1892 	for (; num > 1; num--) {
1893 		if ((returnstat = (process_tag(context, tag,
1894 		    returnstat, 0))) < 0)
1895 			return (returnstat);
1896 	}
1897 
1898 	return (process_tag(context, tag, returnstat, 1));
1899 }
1900 
1901 int
1902 path_attr_token(pr_context_t *context)
1903 {
1904 	return (string_token_common(context, TAG_XAT));
1905 }
1906 
1907 int
1908 exec_args_token(pr_context_t *context)
1909 {
1910 	return (string_token_common(context, TAG_ARG));
1911 }
1912 
1913 int
1914 exec_env_token(pr_context_t *context)
1915 {
1916 	return (string_token_common(context, TAG_ENV));
1917 }
1918 
1919 /*
1920  * -----------------------------------------------------------------------
1921  * s5_IPC_perm_token() : Process System V IPC permission token and display
1922  *			 contents
1923  * return codes 	: -1 - error
1924  *			:  0 - successful
1925  * NOTE: At the time of call, the System V IPC permission token id
1926  * has been retrieved
1927  *
1928  * Format of System V IPC permission token:
1929  *	System V IPC permission token id	adr_char
1930  * 	uid					adr_u_int32
1931  *	gid					adr_u_int32
1932  *	cuid					adr_u_int32
1933  *	cgid					adr_u_int32
1934  *	mode					adr_u_int32
1935  *	seq					adr_u_int32
1936  *	key					adr_int32
1937  * -----------------------------------------------------------------------
1938  */
1939 int
1940 s5_IPC_perm_token(pr_context_t *context)
1941 {
1942 	int	returnstat;
1943 
1944 	returnstat = process_tag(context, TAG_UID, 0, 0);
1945 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1946 	returnstat = process_tag(context, TAG_CUID, returnstat, 0);
1947 	returnstat = process_tag(context, TAG_CGID, returnstat, 0);
1948 	returnstat = process_tag(context, TAG_MODE, returnstat, 0);
1949 	returnstat = process_tag(context, TAG_SEQ, returnstat, 0);
1950 	returnstat = process_tag(context, TAG_KEY, returnstat, 1);
1951 
1952 	return (returnstat);
1953 }
1954 
1955 /*
1956  * -----------------------------------------------------------------------
1957  * host_token()	: Process host token and display contents
1958  * return codes	: -1 - error
1959  *		:  0 - successful
1960  * NOTE: At the time of call, the host token id has been retrieved
1961  *
1962  * Format of host token:
1963  *	host token id		adr_char
1964  *	hostid			adr_u_int32
1965  * -----------------------------------------------------------------------
1966  */
1967 int
1968 host_token(pr_context_t *context)
1969 {
1970 	return (pa_hostname(context, 0, 1));
1971 }
1972 
1973 /*
1974  * -----------------------------------------------------------------------
1975  * liaison_token()	: Process liaison token and display contents
1976  * return codes 	: -1 - error
1977  *			:  0 - successful
1978  * NOTE: At the time of call, the liaison token id has been retrieved
1979  *
1980  * Format of liaison token:
1981  *	liaison token id	adr_char
1982  *	liaison			adr_u_int32
1983  * -----------------------------------------------------------------------
1984  */
1985 int
1986 liaison_token(pr_context_t *context)
1987 {
1988 	return (pa_liaison(context, 0, 1));
1989 }
1990 
1991 /*
1992  * -----------------------------------------------------------------------
1993  * useofauth_token(): Process useofauth token and display contents
1994  * return codes	: -1 - error
1995  *		:  0 - successful
1996  * NOTE: At the time of call, the uauth token id has been retrieved
1997  *
1998  * Format of useofauth token:
1999  *	uauth token id		adr_char
2000  * 	uauth			adr_string
2001  * -----------------------------------------------------------------------
2002  */
2003 int
2004 useofauth_token(pr_context_t *context)
2005 {
2006 	return (pa_adr_string(context, 0, 1));
2007 }
2008 
2009 /*
2010  * -----------------------------------------------------------------------
2011  * zonename_token(): Process zonename token and display contents
2012  * return codes	: -1 - error
2013  *		:  0 - successful
2014  * NOTE: At the time of call, the zonename token id has been retrieved
2015  *
2016  * Format of zonename token:
2017  *	zonename token id	adr_char
2018  * 	zone name		adr_string
2019  * -----------------------------------------------------------------------
2020  */
2021 int
2022 zonename_token(pr_context_t *context)
2023 {
2024 	return (process_tag(context, TAG_ZONENAME, 0, 1));
2025 }
2026 
2027 /*
2028  * -----------------------------------------------------------------------
2029  * fmri_token(): Process fmri token and display contents
2030  * return codes	: -1 - error
2031  *		:  0 - successful
2032  * NOTE: At the time of call, the fmri token id has been retrieved
2033  *
2034  * Format of fmri token:
2035  *	fmri token id		adr_char
2036  * 	service instance name	adr_string
2037  * -----------------------------------------------------------------------
2038  */
2039 int
2040 fmri_token(pr_context_t *context)
2041 {
2042 	return (pa_adr_string(context, 0, 1));
2043 }
2044 
2045 /*
2046  * -----------------------------------------------------------------------
2047  * xatom_token()	: Process Xatom token and display contents in hex.
2048  * return codes		: -1 - error
2049  *			:  0 - successful
2050  * NOTE: At the time of call, the xatom token id has been retrieved
2051  *
2052  * Format of xatom token:
2053  *	token id		adr_char
2054  * 	length			adr_short
2055  * 	atom			adr_char length times
2056  * -----------------------------------------------------------------------
2057  */
2058 int
2059 xatom_token(pr_context_t *context)
2060 {
2061 	return (pa_adr_string(context, 0, 1));
2062 }
2063 
2064 int
2065 xcolormap_token(pr_context_t *context)
2066 {
2067 	return (pa_xgeneric(context));
2068 }
2069 
2070 int
2071 xcursor_token(pr_context_t *context)
2072 {
2073 	return (pa_xgeneric(context));
2074 }
2075 
2076 int
2077 xfont_token(pr_context_t *context)
2078 {
2079 	return (pa_xgeneric(context));
2080 }
2081 
2082 int
2083 xgc_token(pr_context_t *context)
2084 {
2085 	return (pa_xgeneric(context));
2086 }
2087 
2088 int
2089 xpixmap_token(pr_context_t *context)
2090 {
2091 	return (pa_xgeneric(context));
2092 }
2093 
2094 int
2095 xwindow_token(pr_context_t *context)
2096 {
2097 	return (pa_xgeneric(context));
2098 }
2099 
2100 /*
2101  * -----------------------------------------------------------------------
2102  * xproperty_token(): Process Xproperty token and display contents
2103  *
2104  * return codes		: -1 - error
2105  *			:  0 - successful
2106  * NOTE: At the time of call, the xproperty token id has been retrieved
2107  *
2108  * Format of xproperty token:
2109  *	token id		adr_char
2110  *	XID			adr_u_int32
2111  *	creator UID		adr_u_int32
2112  *	text			adr_text
2113  * -----------------------------------------------------------------------
2114  */
2115 int
2116 xproperty_token(pr_context_t *context)
2117 {
2118 	int	returnstat;
2119 
2120 	returnstat = process_tag(context, TAG_XID, 0, 0);
2121 	returnstat = process_tag(context, TAG_XCUID, returnstat, 0);
2122 
2123 	/* Done with attributes; force end of token open */
2124 	if (returnstat == 0)
2125 		returnstat = finish_open_tag(context);
2126 
2127 	returnstat = pa_adr_string(context, returnstat, 1);
2128 
2129 	return (returnstat);
2130 }
2131 
2132 /*
2133  * -----------------------------------------------------------------------
2134  * xselect_token(): Process Xselect token and display contents in hex
2135  *
2136  * return codes		: -1 - error
2137  *			:  0 - successful
2138  * NOTE: At the time of call, the xselect token id has been retrieved
2139  *
2140  * Format of xselect token
2141  *	text token id		adr_char
2142  * 	property text		adr_string
2143  * 	property type		adr_string
2144  * 	property data		adr_string
2145  * -----------------------------------------------------------------------
2146  */
2147 int
2148 xselect_token(pr_context_t *context)
2149 {
2150 	int	returnstat;
2151 
2152 	returnstat = process_tag(context, TAG_XSELTEXT, 0, 0);
2153 	returnstat = process_tag(context, TAG_XSELTYPE, returnstat, 0);
2154 	returnstat = process_tag(context, TAG_XSELDATA, returnstat, 1);
2155 
2156 	return (returnstat);
2157 }
2158 
2159 /*
2160  * -----------------------------------------------------------------------
2161  * xclient_token(): Process Xclient token and display contents in hex.
2162  *
2163  * return codes		: -1 - error
2164  *			:  0 - successful
2165  *
2166  * Format of xclient token:
2167  *	token id		adr_char
2168  * 	client			adr_int32
2169  * -----------------------------------------------------------------------
2170  */
2171 int
2172 xclient_token(pr_context_t *context)
2173 {
2174 	return (pa_adr_int32(context, 0, 1));
2175 }
2176 
2177 /*
2178  * -----------------------------------------------------------------------
2179  * label_token() 	: Process label token and display contents
2180  * return codes 	: -1 - error
2181  *			: 0 - successful
2182  * NOTE: At the time of call, the label token id has been retrieved
2183  *
2184  * Format of label token:
2185  *	label token id			adr_char
2186  *      label ID                	adr_char
2187  *      label compartment length	adr_char
2188  *      label classification		adr_short
2189  *      label compartment words		<compartment length> * 4 adr_char
2190  * -----------------------------------------------------------------------
2191  */
2192 /*ARGSUSED*/
2193 int
2194 label_token(pr_context_t *context)
2195 {
2196 	static m_label_t *label = NULL;
2197 	static size32_t l_size;
2198 	int	len;
2199 	int	returnstat;
2200 	uval_t	uval;
2201 
2202 	if (label == NULL) {
2203 		if ((label = m_label_alloc(MAC_LABEL)) == NULL) {
2204 			return (-1);
2205 		}
2206 		l_size = blabel_size() - 4;
2207 	}
2208 	if ((returnstat = pr_adr_char(context, (char *)label, 4)) == 0) {
2209 		len = (int)(((char *)label)[1] * 4);
2210 		if ((len > l_size) ||
2211 		    (pr_adr_char(context, &((char *)label)[4], len) != 0)) {
2212 			return (-1);
2213 		}
2214 		uval.uvaltype = PRA_STRING;
2215 		if (!(context->format & PRF_RAWM)) {
2216 			/* print in ASCII form */
2217 			if (label_to_str(label, &uval.string_val, M_LABEL,
2218 			    DEF_NAMES) == 0) {
2219 				returnstat = pa_print(context, &uval, 1);
2220 			} else /* cannot convert to string */
2221 				returnstat = 1;
2222 		}
2223 		/* print in hexadecimal form */
2224 		if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2225 			uval.string_val = hexconvert((char *)label, len, len);
2226 			if (uval.string_val) {
2227 				returnstat = pa_print(context, &uval, 1);
2228 			}
2229 		}
2230 		free(uval.string_val);
2231 	}
2232 	return (returnstat);
2233 }
2234 
2235 /*
2236  * -----------------------------------------------------------------------
2237  * useofpriv_token() : Process priv token and display contents
2238  * return codes 	: -1 - error
2239  *			:  0 - successful
2240  * NOTE: At the time of call, the useofpriv token id has been retrieved
2241  *
2242  * Format of useofpriv token:
2243  *	useofpriv token id	adr_char
2244  *	success/failure flag	adr_char
2245  *	priv			adr_int32 (Trusted Solaris)
2246  *	priv_set		'\0' separated privileges.
2247  * -----------------------------------------------------------------------
2248  */
2249 /*ARGSUSED*/
2250 int
2251 useofpriv_token(pr_context_t *context)
2252 {
2253 	int	returnstat;
2254 	char	sf;
2255 	uval_t	uval;
2256 
2257 	if ((returnstat = pr_adr_char(context, &sf, 1)) != 0) {
2258 		return (returnstat);
2259 	}
2260 	if (!(context->format & PRF_RAWM)) {
2261 		/* print in ASCII form */
2262 
2263 		if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2264 			return (returnstat);
2265 
2266 		uval.uvaltype = PRA_STRING;
2267 		if (sf) {
2268 			uval.string_val = gettext("successful use of priv");
2269 			returnstat = pa_print(context, &uval, 0);
2270 		} else {
2271 			uval.string_val = gettext("failed use of priv");
2272 			returnstat = pa_print(context, &uval, 0);
2273 		}
2274 		if (returnstat == 0)
2275 			returnstat = close_tag(context, TAG_RESULT);
2276 
2277 		/* Done with attributes; force end of token open */
2278 		if (returnstat == 0)
2279 			returnstat = finish_open_tag(context);
2280 	} else {
2281 		/* print in hexadecimal form */
2282 		if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2283 			return (returnstat);
2284 		uval.uvaltype = PRA_SHORT;
2285 		uval.short_val = sf;
2286 		returnstat = pa_print(context, &uval, 0);
2287 		if (returnstat == 0)
2288 			returnstat = close_tag(context, TAG_RESULT);
2289 
2290 		/* Done with attributes; force end of token open */
2291 		if (returnstat == 0)
2292 			returnstat = finish_open_tag(context);
2293 	}
2294 	return (pa_adr_string(context, 0, 1));
2295 }
2296 
2297 /*
2298  * -----------------------------------------------------------------------
2299  * privilege_token()	: Process privilege token and display contents
2300  * return codes 	: -1 - error
2301  *			:  0 - successful
2302  * NOTE: At the time of call, the privilege token id has been retrieved
2303  *
2304  * Format of privilege token:
2305  *	privilege token id	adr_char
2306  *	privilege type		adr_string
2307  *	privilege		adr_string
2308  * -----------------------------------------------------------------------
2309  */
2310 int
2311 privilege_token(pr_context_t *context)
2312 {
2313 	int	returnstat;
2314 
2315 	/* privilege type: */
2316 	returnstat = process_tag(context, TAG_SETTYPE, 0, 0);
2317 
2318 	/* Done with attributes; force end of token open */
2319 	if (returnstat == 0)
2320 		returnstat = finish_open_tag(context);
2321 
2322 	/* privilege: */
2323 	return (pa_adr_string(context, returnstat, 1));
2324 }
2325