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