xref: /illumos-gate/usr/src/cmd/praudit/token.c (revision 3d393ee6c37fa10ac512ed6d36109ad616dc7c1a)
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 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <ctype.h>
29 #include <dirent.h>
30 #include <grp.h>
31 #include <libintl.h>
32 #include <limits.h>
33 #include <locale.h>
34 #include <pwd.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/types.h>
39 #include <sys/inttypes.h>
40 #include <sys/file.h>
41 #include <sys/param.h>
42 #include <sys/uio.h>
43 #include <sys/stat.h>
44 #include <sys/acl.h>
45 #include <sys/socket.h>
46 #include <sys/errno.h>
47 #include <sys/ipc.h>
48 #include <sys/sem.h>
49 #include <sys/systm.h>
50 #include <netinet/in.h>
51 #include <sys/tiuser.h>
52 #include <rpc/types.h>
53 #include <rpc/auth.h>
54 #include <rpc/auth_unix.h>
55 #include <rpc/svc.h>
56 #include <rpc/xdr.h>
57 #include <nfs/nfs.h>
58 #include <sys/fs/ufs_quota.h>
59 #include <sys/time.h>
60 #include <sys/mkdev.h>
61 #include <unistd.h>
62 
63 #include <bsm/audit.h>
64 #include <bsm/audit_record.h>
65 #include <bsm/libbsm.h>
66 
67 #include <tsol/label.h>
68 
69 #include "praudit.h"
70 #include "toktable.h"
71 
72 #include <netdb.h>
73 #include <arpa/inet.h>
74 
75 static char *anchor_path(char *);
76 static char *collapse_path(char *);
77 
78 
79 /*
80  * -----------------------------------------------------------------------
81  * is_file_token:
82  *		  Tests whether the specified token id represents a type
83  *		  of file token.
84  * return codes :  1 - tokenid is a file token type
85  *		:  0 - otherwise
86  * -----------------------------------------------------------------------
87  */
88 int
89 is_file_token(int tokenid)
90 {
91 	if ((tokenid == AUT_OTHER_FILE32) || (tokenid == AUT_OTHER_FILE64))
92 		return (1);
93 
94 	return (0);
95 }
96 
97 /*
98  * -----------------------------------------------------------------------
99  * is_header_token:
100  *		  Tests whether the specified token id represents a type
101  *		  of header token (signifying the start of a record).
102  * return codes :  1 - tokenid is a header type
103  *		:  0 - otherwise
104  * -----------------------------------------------------------------------
105  */
106 int
107 is_header_token(int tokenid)
108 {
109 	if ((tokenid == AUT_OHEADER) || (tokenid == AUT_HEADER32) ||
110 	    (tokenid == AUT_HEADER32_EX) || (tokenid == AUT_HEADER64) ||
111 	    (tokenid == AUT_HEADER64_EX))
112 		return (1);
113 
114 	return (0);
115 }
116 
117 /*
118  * -----------------------------------------------------------------------
119  * is_token:
120  *		  Tests whether the specified token id represents a true
121  *		  token, as opposed to a regular tag.
122  * return codes :  1 - tokenid is a true token
123  *		:  0 - otherwise
124  * -----------------------------------------------------------------------
125  */
126 int
127 is_token(int tokenid)
128 {
129 	if ((tokenid > 0) && (tokenid <= MAXTOKEN))
130 		return (1);
131 
132 	return (0);
133 }
134 
135 
136 /*
137  * -----------------------------------------------------------------------
138  * exit_token() 	: Process information label token and display contents
139  * return codes		: -1 - error
140  *			:  0 - successful
141  * NOTE: At the time of call, the label token id has been retrieved
142  *
143  * Format of exit token:
144  *	exit token id		adr_char
145  * -----------------------------------------------------------------------
146  */
147 int
148 exit_token(pr_context_t *context)
149 {
150 	int	returnstat;
151 	int	retval;
152 	uval_t	uval;
153 
154 	if ((returnstat = open_tag(context, TAG_ERRVAL)) != 0)
155 		return (returnstat);
156 
157 	if ((returnstat = pr_adr_int32(context, (int32_t *)&retval, 1)) == 0) {
158 		if (!(context->format & PRF_RAWM)) {
159 			char *emsg = strerror(retval);
160 
161 			if (emsg == NULL)
162 				uval.string_val = gettext("Unknown errno");
163 			else
164 				uval.string_val = gettext(emsg);
165 			uval.uvaltype = PRA_STRING;
166 		} else {
167 			uval.uvaltype = PRA_INT32;
168 			uval.int32_val = retval;
169 		}
170 		returnstat = pa_print(context, &uval, 0);
171 	}
172 	if (returnstat == 0)
173 		returnstat = close_tag(context, TAG_ERRVAL);
174 
175 	return (process_tag(context, TAG_RETVAL, returnstat, 1));
176 }
177 
178 /*
179  * ------------------------------------------------------------------
180  * file_token()	: prints out seconds of time and other file name
181  * return codes : -1 - error
182  *		:  0 - successful, valid file token fields
183  * At the time of entry, the file token ID has already been retrieved
184  *
185  * Format of file token:
186  *	file token id		adr_char
187  *	seconds of time		adr_u_int
188  *	name of other file	adr_string
189  * ------------------------------------------------------------------
190  */
191 int
192 file_token(pr_context_t *context)
193 {
194 	int	returnstat;
195 
196 	returnstat = pa_utime32(context, 0, 0);		/* time from usecs */
197 
198 	/* other file name */
199 	returnstat = pa_file_string(context, returnstat, 1);
200 
201 	return (returnstat);
202 }
203 
204 int
205 file64_token(pr_context_t *context)
206 {
207 	int	returnstat;
208 
209 	returnstat = pa_utime64(context, 0, 0);		/* time from usecs */
210 
211 	/* other file name */
212 	returnstat = pa_file_string(context, returnstat, 1);
213 
214 	return (returnstat);
215 }
216 
217 /*
218  * -----------------------------------------------------------------------
219  * header_token()	: Process record header token and display contents
220  * return codes		: -1 - error
221  *			:  0 - successful
222  *			:  1 - warning, password entry not found
223  *
224  * NOTE: At the time of call, the header token id has been retrieved
225  *
226  * Format of header token:
227  *	header token id 	adr_char
228  * 	record byte count	adr_u_int
229  *	event type		adr_u_short (printed either ASCII or raw)
230  *	event class		adr_u_int   (printed either ASCII or raw)
231  *	event action		adr_u_int
232  *	if extended:		extended host name (IPv4/IPv6)
233  *	seconds of time		adr_u_int   (printed either ASCII or raw)
234  *	nanoseconds of time	adr_u_int
235  * -----------------------------------------------------------------------
236  */
237 int
238 header_token(pr_context_t *context)
239 {
240 	int	returnstat;
241 
242 	returnstat = pa_reclen(context, 0);		/* record byte */
243 	/* version ID */
244 	returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
245 	/* event type */
246 	returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
247 	/* event modifier */
248 	returnstat = pa_event_modifier(context, returnstat, 0);
249 	/* time from nsec */
250 	returnstat = pa_ntime32(context, returnstat, 1);
251 
252 	return (returnstat);
253 }
254 
255 int
256 header64_token(pr_context_t *context)
257 {
258 	int	returnstat;
259 
260 	returnstat = pa_reclen(context, 0);		/* record byte */
261 	/* version ID */
262 	returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
263 	/* event type */
264 	returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
265 	/* event modifier */
266 	returnstat = pa_event_modifier(context, returnstat, 0);
267 	/* time from nsec */
268 	returnstat = pa_ntime64(context, returnstat, 1);
269 
270 	return (returnstat);
271 }
272 
273 int
274 header32_ex_token(pr_context_t *context)
275 {
276 	int	returnstat;
277 
278 	returnstat = pa_reclen(context, 0);		/* record byte */
279 	/* version ID */
280 	returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
281 	/* event type */
282 	returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
283 	/* event modifier */
284 	returnstat = pa_event_modifier(context, returnstat, 0);
285 	/* machine name */
286 	returnstat = pa_hostname_ex(context, returnstat, 0);
287 	/* time from nsec */
288 	returnstat = pa_ntime32(context, returnstat, 1);
289 
290 	return (returnstat);
291 }
292 
293 int
294 header64_ex_token(pr_context_t *context)
295 {
296 	int	returnstat;
297 
298 	returnstat = pa_reclen(context, 0);		/* record byte */
299 	/* version ID */
300 	returnstat = process_tag(context, TAG_TOKVERS, returnstat, 0);
301 	/* event type */
302 	returnstat = process_tag(context, TAG_EVTYPE, returnstat, 0);
303 	/* event modifier */
304 	returnstat = pa_event_modifier(context, returnstat, 0);
305 	/* machine name */
306 	returnstat = pa_hostname_ex(context, returnstat, 0);
307 	/* time from nsec */
308 	returnstat = pa_ntime64(context, returnstat, 1);
309 
310 	return (returnstat);
311 }
312 
313 /*
314  * -----------------------------------------------------------------------
315  * trailer_token()	: Process record trailer token and display contents
316  * return codes		: -1 - error
317  *			:  0 - successful
318  * NOTE: At the time of call, the trailer token id has already been
319  * retrieved
320  *
321  * Format of trailer token:
322  * 	trailer token id	adr_char
323  * 	record sequence no	adr_u_short (should be AUT_TRAILER_MAGIC)
324  *	record byte count	adr_u_int
325  * -----------------------------------------------------------------------
326  */
327 int
328 trailer_token(pr_context_t *context)
329 {
330 	short	magic_number;
331 
332 	if (pr_adr_u_short(context, (ushort_t *)&magic_number, 1) < 0) {
333 		(void) fprintf(stderr, gettext(
334 		    "praudit: Cannot retrieve trailer magic number\n"));
335 		return (-1);
336 	} else {
337 		if (magic_number != AUT_TRAILER_MAGIC) {
338 			(void) fprintf(stderr, gettext(
339 			    "praudit: Invalid trailer magic number\n"));
340 			return (-1);
341 		} else
342 			/* Do not display trailer in XML mode */
343 			if (context->format & PRF_XMLM) {
344 				uint32_t	junk;
345 				int		retstat;
346 
347 				retstat = pr_adr_u_int32(context, &junk, 1);
348 				return (retstat);
349 			} else {
350 				return (pa_adr_u_int32(context, 0, 1));
351 			}
352 	}
353 }
354 
355 /*
356  * -----------------------------------------------------------------------
357  * arbitrary_data_token():
358  *			  Process arbitrary data token and display contents
359  * return codes		: -1 - error
360  *			:  0 - successful
361  * NOTE: At the time of call, the arbitrary data token id has already
362  * been retrieved
363  *
364  * Format of arbitrary data token:
365  *	arbitrary data token id	adr char
366  * 	how to print		adr_char
367  *				From audit_record.h, this may be either:
368  *				AUP_BINARY	binary
369  *				AUP_OCTAL	octal
370  *				AUP_DECIMAL	decimal
371  *				AUP_HEX		hexadecimal
372  *	basic unit		adr_char
373  *				From audit_record.h, this may be either:
374  *				AUR_BYTE	byte
375  *				AUR_CHAR	char
376  *				AUR_SHORT	short
377  *				AUR_INT32	int32_t
378  *				AUR_INT64	int64_t
379  *	unit count		adr_char, specifying number of units of
380  *				data in the "data items" parameter below
381  *	data items		depends on basic unit
382  *
383  * -----------------------------------------------------------------------
384  */
385 int
386 arbitrary_data_token(pr_context_t *context)
387 {
388 	int	returnstat;
389 	int	i;
390 	char	c1;
391 	short	c2;
392 	int32_t	c3;
393 	int64_t c4;
394 	char	how_to_print, basic_unit, unit_count, fwid;
395 	char	*p;
396 	int	index = 0;
397 	char	*pformat = "%*s";
398 
399 	uval_t	uval;
400 
401 	if ((returnstat = pr_adr_char(context, &how_to_print, 1)) != 0)
402 		return (returnstat);
403 
404 	if ((returnstat = pr_adr_char(context, &basic_unit, 1)) != 0)
405 		return (returnstat);
406 
407 	if ((returnstat = pr_adr_char(context, &unit_count, 1)) != 0)
408 		return (returnstat);
409 
410 	if (!(context->format & PRF_RAWM)) {
411 		uval.uvaltype = PRA_STRING;
412 		uval.string_val = htp2string(how_to_print);
413 	} else {
414 		uval.uvaltype = PRA_INT32;
415 		uval.int32_val = (int)how_to_print;
416 	}
417 
418 	if ((returnstat = open_tag(context, TAG_ARBPRINT)) != 0)
419 		return (returnstat);
420 	if ((returnstat = pa_print(context, &uval, 0)) < 0)
421 		return (returnstat);
422 	if ((returnstat = close_tag(context, TAG_ARBPRINT)) != 0)
423 		return (returnstat);
424 
425 	if (!(context->format & PRF_RAWM)) {
426 		uval.uvaltype = PRA_STRING;
427 		uval.string_val = bu2string(basic_unit);
428 	} else {
429 		uval.uvaltype = PRA_INT32;
430 		uval.int32_val = (int32_t)basic_unit;
431 	}
432 
433 	if ((returnstat = open_tag(context, TAG_ARBTYPE)) != 0)
434 		return (returnstat);
435 	if ((returnstat = pa_print(context, &uval, 0)) < 0)
436 		return (returnstat);
437 	if ((returnstat = close_tag(context, TAG_ARBTYPE)) != 0)
438 		return (returnstat);
439 
440 	uval.uvaltype = PRA_INT32;
441 	uval.int32_val = (int32_t)unit_count;
442 
443 	if ((returnstat = open_tag(context, TAG_ARBCOUNT)) != 0)
444 		return (returnstat);
445 	if ((returnstat = pa_print(context, &uval, 1)) < 0)
446 		return (returnstat);
447 	if ((returnstat = close_tag(context, TAG_ARBCOUNT)) != 0)
448 		return (returnstat);
449 
450 	/* Done with attributes; force end of token open */
451 	if ((returnstat = finish_open_tag(context)) != 0)
452 		return (returnstat);
453 
454 	/* get the field width in case we need to format output */
455 	fwid = findfieldwidth(basic_unit, how_to_print);
456 	p = (char *)malloc(80);
457 
458 	/* now get the data items and print them */
459 	for (i = 0; (i < unit_count); i++) {
460 		switch (basic_unit) {
461 			/* case AUR_BYTE: */
462 		case AUR_CHAR:
463 			if (pr_adr_char(context, &c1, 1) == 0)
464 				(void) convert_char_to_string(how_to_print,
465 				    c1, p);
466 			else {
467 				free(p);
468 				return (-1);
469 			}
470 			break;
471 		case AUR_SHORT:
472 			if (pr_adr_short(context, &c2, 1) == 0)
473 				(void) convert_short_to_string(how_to_print,
474 				    c2, p);
475 			else {
476 				free(p);
477 				return (-1);
478 			}
479 			break;
480 		case AUR_INT32:
481 			if (pr_adr_int32(context, &c3, 1) == 0)
482 				(void) convert_int32_to_string(how_to_print,
483 				    c3, p);
484 			else {
485 				free(p);
486 				return (-1);
487 			}
488 			break;
489 		case AUR_INT64:
490 			if (pr_adr_int64(context, &c4, 1) == 0)
491 				(void) convert_int64_to_string(how_to_print,
492 				    c4, p);
493 			else {
494 				free(p);
495 				return (-1);
496 			}
497 			break;
498 		default:
499 			free(p);
500 			return (-1);
501 			/*NOTREACHED*/
502 		}
503 
504 		/*
505 		 * At this point, we have successfully retrieved a data
506 		 * item and converted it into an ASCII string pointed to
507 		 * by p. If all output is to be printed on one line,
508 		 * simply separate the data items by a space (or by the
509 		 * delimiter if this is the last data item), otherwise, we
510 		 * need to format the output before display.
511 		 */
512 		if (context->format & PRF_ONELINE) {
513 			returnstat = pr_printf(context, "%s", p);
514 			if ((returnstat >= 0) && (i == (unit_count - 1)))
515 				returnstat = pr_printf(context, "%s",
516 				    context->SEPARATOR);
517 			else
518 				returnstat = pr_putchar(context, ' ');
519 		} else {	/* format output */
520 			returnstat = pr_printf(context, pformat, fwid, p);
521 			index += fwid;
522 			if ((returnstat >= 0) &&
523 			    (((index + fwid) > 75) ||
524 			    (i == (unit_count - 1)))) {
525 				returnstat = pr_putchar(context, '\n');
526 				index = 0;
527 			}
528 		} /* else if PRF_ONELINE */
529 		if (returnstat < 0) {
530 			free(p);
531 			return (returnstat);
532 		}
533 	}
534 	free(p);
535 
536 	return (returnstat);
537 }
538 
539 /*
540  * -----------------------------------------------------------------------
541  * opaque_token() 	: Process opaque token and display contents
542  * return codes		: -1 - error
543  *			:  0 - successful
544  * NOTE: At the time of call, the opaque token id has already been
545  * retrieved
546  *
547  * Format of opaque token:
548  *	opaque token id		adr_char
549  *	size			adr_short
550  *	data			adr_char, size times
551  * -----------------------------------------------------------------------
552  */
553 int
554 opaque_token(pr_context_t *context)
555 {
556 	int	returnstat;
557 	short	size;
558 	char	*charp;
559 	uval_t	uval;
560 
561 
562 	/* print the size of the token */
563 	if (pr_adr_short(context, &size, 1) == 0) {
564 		uval.uvaltype = PRA_SHORT;
565 		uval.short_val = size;
566 		returnstat = pa_print(context, &uval, 0);
567 	} else
568 		returnstat = -1;
569 
570 	/* now print out the data field in hexadecimal */
571 	if (returnstat >= 0) {
572 		/* try to allocate memory for the character string */
573 		if ((charp = (char *)malloc(size * sizeof (char))) == NULL)
574 			returnstat = -1;
575 		else {
576 			if ((returnstat = pr_adr_char(context, charp,
577 			    size)) == 0) {
578 				/* print out in hexadecimal format */
579 				uval.uvaltype = PRA_STRING;
580 				uval.string_val = hexconvert(charp, size, size);
581 				if (uval.string_val) {
582 					returnstat = pa_print(context,
583 					    &uval, 1);
584 					free(uval.string_val);
585 				}
586 			}
587 			free(charp);
588 		}
589 	}
590 
591 	return (returnstat);
592 }
593 
594 /*
595  * -----------------------------------------------------------------------
596  * path_token() 	: Process path token and display contents
597  * return codes		: -1 - error
598  *			:  0 - successful
599  * NOTE: At the time of call, the path token id has been retrieved
600  *
601  * Format of path token:
602  *	token id	adr_char
603  *	path		adr_string
604  * -----------------------------------------------------------------------
605  */
606 int
607 path_token(pr_context_t *context)
608 {
609 	char	*path;	/* path */
610 	char	*apath;	/* anchored path */
611 	char	*cpath;	/* collapsed path */
612 	short	length;
613 	int	returnstat;
614 	uval_t	uval;
615 
616 	/*
617 	 * We need to know how much space to allocate for our string, so
618 	 * read the length first, then call pr_adr_char to read those bytes.
619 	 */
620 	if (pr_adr_short(context, &length, 1) == 0) {
621 		if ((path = (char *)malloc(length + 1)) == NULL) {
622 			returnstat = -1;
623 		} else if (pr_adr_char(context, path, length) == 0) {
624 			path[length] = '\0';
625 			uval.uvaltype = PRA_STRING;
626 			if (*path != '/') {
627 				apath = anchor_path(path);
628 				free(path);
629 			} else
630 				apath = path;
631 			cpath = collapse_path(apath);
632 			uval.string_val = cpath;
633 			returnstat = pa_print(context, &uval, 1);
634 			free(cpath);
635 		} else {
636 			free(path);
637 			returnstat = -1;
638 		}
639 		return (returnstat);
640 	} else
641 		return (-1);
642 }
643 
644 /*
645  * anchor a path name with a slash
646  */
647 char *
648 anchor_path(char *sp)
649 {
650 	char	*dp; /* destination path */
651 	char	*tp; /* temporary path */
652 	size_t	len;
653 
654 	len = strlen(sp) + 2;
655 	if ((dp = tp = (char *)calloc(1, len)) == (char *)0)
656 		return ((char *)0);
657 
658 	*dp++ = '/';
659 
660 	(void) strlcpy(dp, sp, len);
661 
662 	return (tp);
663 }
664 
665 /*
666  * copy path to collapsed path.
667  * collapsed path does not contain:
668  *	successive slashes
669  *	instances of dot-slash
670  *	instances of dot-dot-slash
671  * passed path must be anchored with a '/'
672  */
673 char *
674 collapse_path(char *s)
675 {
676 	int	id;	/* index of where we are in destination string */
677 	int	is;		/* index of where we are in source string */
678 	int	slashseen;	/* have we seen a slash */
679 	int	ls;		/* length of source string */
680 
681 	ls = strlen(s) + 1;
682 
683 	slashseen = 0;
684 	for (is = 0, id = 0; is < ls; is++) {
685 		/* thats all folks, we've reached the end of input */
686 		if (s[is] == '\0') {
687 			if (id > 1 && s[id-1] == '/') {
688 				--id;
689 			}
690 			s[id++] = '\0';
691 			break;
692 		}
693 		/* previous character was a / */
694 		if (slashseen) {
695 			if (s[is] == '/')
696 				continue;	/* another slash, ignore it */
697 		} else if (s[is] == '/') {
698 			/* we see a /, just copy it and try again */
699 			slashseen = 1;
700 			s[id++] = '/';
701 			continue;
702 		}
703 		/* /./ seen */
704 		if (s[is] == '.' && s[is+1] == '/') {
705 			is += 1;
706 			continue;
707 		}
708 		/* XXX/. seen */
709 		if (s[is] == '.' && s[is+1] == '\0') {
710 			if (id > 1)
711 				id--;
712 			continue;
713 		}
714 		/* XXX/.. seen */
715 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') {
716 			is += 1;
717 			if (id > 0)
718 				id--;
719 			while (id > 0 && s[--id] != '/')
720 				continue;
721 			id++;
722 			continue;
723 		}
724 		/* XXX/../ seen */
725 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
726 			is += 2;
727 			if (id > 0)
728 				id--;
729 			while (id > 0 && s[--id] != '/')
730 				continue;
731 			id++;
732 			continue;
733 		}
734 		while (is < ls && (s[id++] = s[is++]) != '/')
735 			continue;
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 = do_newline(context, 1);
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(number, 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(number, 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_port_t == uint16_t)
1600  * -----------------------------------------------------------------------
1601  */
1602 int
1603 iport_token(pr_context_t *context)
1604 {
1605 	return (pa_adr_u_short(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  * ace_token()	: Process ZFS/NFSv4 access control list term
1719  * return codes	: -1 - error
1720  *		:  0 - successful
1721  *
1722  * Format of ace token:
1723  *	token id	adr_char
1724  *	term who	adr_u_int32 (uid/gid)
1725  *	term mask	adr_u_int32
1726  *	term flags	adr_u_int16
1727  *	term type	adr_u_int16
1728  * -----------------------------------------------------------------------
1729  */
1730 int
1731 ace_token(pr_context_t *context)
1732 {
1733 	return (pa_ace(context, 0, 1));
1734 }
1735 
1736 /*
1737  * -----------------------------------------------------------------------
1738  * attribute_token()	: Process attribute token and display contents
1739  * return codes 	: -1 - error
1740  *			:  0 - successful
1741  * NOTE: At the time of call, the attribute token id has been retrieved
1742  *
1743  * Format of attribute token:
1744  *	attribute token id	adr_char
1745  * 	mode			adr_u_int (printed in octal)
1746  *	uid			adr_u_int
1747  *	gid			adr_u_int
1748  *	file system id		adr_int
1749  *
1750  *	node id			adr_int		(attribute_token
1751  *						 pre SunOS 5.7)
1752  *	device			adr_u_int
1753  * or
1754  *	node id			adr_int64	(attribute32_token)
1755  *	device			adr_u_int
1756  * or
1757  *	node id			adr_int64	(attribute64_token)
1758  *	device			adr_u_int64
1759  * -----------------------------------------------------------------------
1760  */
1761 int
1762 attribute_token(pr_context_t *context)
1763 {
1764 	int	returnstat;
1765 
1766 	returnstat = process_tag(context, TAG_MODE, 0, 0);
1767 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1768 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1769 	returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1770 	returnstat = process_tag(context, TAG_NODEID32, returnstat, 0);
1771 	returnstat = process_tag(context, TAG_DEVICE32, returnstat, 1);
1772 
1773 	return (returnstat);
1774 }
1775 
1776 int
1777 attribute32_token(pr_context_t *context)
1778 {
1779 	int	returnstat;
1780 
1781 	returnstat = process_tag(context, TAG_MODE, 0, 0);
1782 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1783 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1784 	returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1785 	returnstat = process_tag(context, TAG_NODEID64, returnstat, 0);
1786 	returnstat = process_tag(context, TAG_DEVICE32, returnstat, 1);
1787 
1788 	return (returnstat);
1789 }
1790 
1791 int
1792 attribute64_token(pr_context_t *context)
1793 {
1794 	int	returnstat;
1795 
1796 	returnstat = process_tag(context, TAG_MODE, 0, 0);
1797 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1798 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1799 	returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1800 	returnstat = process_tag(context, TAG_NODEID64, returnstat, 0);
1801 	returnstat = process_tag(context, TAG_DEVICE64, returnstat, 1);
1802 
1803 	return (returnstat);
1804 }
1805 
1806 /*
1807  * -----------------------------------------------------------------------
1808  * group_token() 	: Process group token and display contents
1809  * return codes 	: -1 - error
1810  *			:  0 - successful
1811  * NOTE: At the time of call, the group token id has been retrieved
1812  *
1813  * Format of group token:
1814  *	group token id		adr_char
1815  *	group list		adr_long, 16 times
1816  * -----------------------------------------------------------------------
1817  */
1818 int
1819 group_token(pr_context_t *context)
1820 {
1821 	int	returnstat = 0;
1822 	int	i;
1823 
1824 	for (i = 0; i < NGROUPS_MAX - 1; i++) {
1825 		if ((returnstat = process_tag(context, TAG_GROUPID,
1826 		    returnstat, 0)) < 0)
1827 			return (returnstat);
1828 	}
1829 
1830 	return (process_tag(context, TAG_GROUPID, returnstat, 1));
1831 }
1832 
1833 /*
1834  * -----------------------------------------------------------------------
1835  * newgroup_token() 	: Process group token and display contents
1836  * return codes 	: -1 - error
1837  *			:  0 - successful
1838  * NOTE: At the time of call, the group token id has been retrieved
1839  *
1840  * Format of new group token:
1841  *	group token id		adr_char
1842  *	group number		adr_short
1843  *	group list		adr_int32, group number times
1844  * -----------------------------------------------------------------------
1845  */
1846 int
1847 newgroup_token(pr_context_t *context)
1848 {
1849 	int	returnstat;
1850 	int	i, num;
1851 	short	n_groups;
1852 
1853 	returnstat = pr_adr_short(context, &n_groups, 1);
1854 	if (returnstat != 0)
1855 		return (returnstat);
1856 
1857 	num = (int)n_groups;
1858 	if (num == 0) {
1859 		if (!(context->format & PRF_XMLM)) {
1860 			returnstat = do_newline(context, 1);
1861 		}
1862 		return (returnstat);
1863 	}
1864 	for (i = 0; i < num - 1; i++) {
1865 		if ((returnstat = process_tag(context, TAG_GROUPID,
1866 		    returnstat, 0)) < 0)
1867 			return (returnstat);
1868 	}
1869 
1870 	return (process_tag(context, TAG_GROUPID, returnstat, 1));
1871 }
1872 
1873 static int
1874 string_token_common(pr_context_t *context, int tag)
1875 {
1876 	int	returnstat;
1877 	int	num;
1878 
1879 	returnstat = pr_adr_int32(context, (int32_t *)&num, 1);
1880 	if (returnstat != 0)
1881 		return (returnstat);
1882 
1883 	if (!(context->format & PRF_XMLM)) {
1884 		returnstat = pr_printf(context, "%d%s", num,
1885 		    context->SEPARATOR);
1886 		if (returnstat != 0)
1887 			return (returnstat);
1888 	}
1889 
1890 	if (num == 0)
1891 		return (do_newline(context, 1));
1892 
1893 	for (; num > 1; num--) {
1894 		if ((returnstat = (process_tag(context, tag,
1895 		    returnstat, 0))) < 0)
1896 			return (returnstat);
1897 	}
1898 
1899 	return (process_tag(context, tag, returnstat, 1));
1900 }
1901 
1902 int
1903 path_attr_token(pr_context_t *context)
1904 {
1905 	return (string_token_common(context, TAG_XAT));
1906 }
1907 
1908 int
1909 exec_args_token(pr_context_t *context)
1910 {
1911 	return (string_token_common(context, TAG_ARG));
1912 }
1913 
1914 int
1915 exec_env_token(pr_context_t *context)
1916 {
1917 	return (string_token_common(context, TAG_ENV));
1918 }
1919 
1920 /*
1921  * -----------------------------------------------------------------------
1922  * s5_IPC_perm_token() : Process System V IPC permission token and display
1923  *			 contents
1924  * return codes 	: -1 - error
1925  *			:  0 - successful
1926  * NOTE: At the time of call, the System V IPC permission token id
1927  * has been retrieved
1928  *
1929  * Format of System V IPC permission token:
1930  *	System V IPC permission token id	adr_char
1931  * 	uid					adr_u_int32
1932  *	gid					adr_u_int32
1933  *	cuid					adr_u_int32
1934  *	cgid					adr_u_int32
1935  *	mode					adr_u_int32
1936  *	seq					adr_u_int32
1937  *	key					adr_int32
1938  * -----------------------------------------------------------------------
1939  */
1940 int
1941 s5_IPC_perm_token(pr_context_t *context)
1942 {
1943 	int	returnstat;
1944 
1945 	returnstat = process_tag(context, TAG_UID, 0, 0);
1946 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1947 	returnstat = process_tag(context, TAG_CUID, returnstat, 0);
1948 	returnstat = process_tag(context, TAG_CGID, returnstat, 0);
1949 	returnstat = process_tag(context, TAG_MODE, returnstat, 0);
1950 	returnstat = process_tag(context, TAG_SEQ, returnstat, 0);
1951 	returnstat = process_tag(context, TAG_KEY, returnstat, 1);
1952 
1953 	return (returnstat);
1954 }
1955 
1956 /*
1957  * -----------------------------------------------------------------------
1958  * host_token()	: Process host token and display contents
1959  * return codes	: -1 - error
1960  *		:  0 - successful
1961  * NOTE: At the time of call, the host token id has been retrieved
1962  *
1963  * Format of host token:
1964  *	host token id		adr_char
1965  *	hostid			adr_u_int32
1966  * -----------------------------------------------------------------------
1967  */
1968 int
1969 host_token(pr_context_t *context)
1970 {
1971 	return (pa_hostname(context, 0, 1));
1972 }
1973 
1974 /*
1975  * -----------------------------------------------------------------------
1976  * liaison_token()	: Process liaison token and display contents
1977  * return codes 	: -1 - error
1978  *			:  0 - successful
1979  * NOTE: At the time of call, the liaison token id has been retrieved
1980  *
1981  * Format of liaison token:
1982  *	liaison token id	adr_char
1983  *	liaison			adr_u_int32
1984  * -----------------------------------------------------------------------
1985  */
1986 int
1987 liaison_token(pr_context_t *context)
1988 {
1989 	return (pa_liaison(context, 0, 1));
1990 }
1991 
1992 /*
1993  * -----------------------------------------------------------------------
1994  * useofauth_token(): Process useofauth token and display contents
1995  * return codes	: -1 - error
1996  *		:  0 - successful
1997  * NOTE: At the time of call, the uauth token id has been retrieved
1998  *
1999  * Format of useofauth token:
2000  *	uauth token id		adr_char
2001  * 	uauth			adr_string
2002  * -----------------------------------------------------------------------
2003  */
2004 int
2005 useofauth_token(pr_context_t *context)
2006 {
2007 	return (pa_adr_string(context, 0, 1));
2008 }
2009 
2010 /*
2011  * -----------------------------------------------------------------------
2012  * zonename_token(): Process zonename token and display contents
2013  * return codes	: -1 - error
2014  *		:  0 - successful
2015  * NOTE: At the time of call, the zonename token id has been retrieved
2016  *
2017  * Format of zonename token:
2018  *	zonename token id	adr_char
2019  * 	zone name		adr_string
2020  * -----------------------------------------------------------------------
2021  */
2022 int
2023 zonename_token(pr_context_t *context)
2024 {
2025 	return (process_tag(context, TAG_ZONENAME, 0, 1));
2026 }
2027 
2028 /*
2029  * -----------------------------------------------------------------------
2030  * fmri_token(): Process fmri token and display contents
2031  * return codes	: -1 - error
2032  *		:  0 - successful
2033  * NOTE: At the time of call, the fmri token id has been retrieved
2034  *
2035  * Format of fmri token:
2036  *	fmri token id		adr_char
2037  * 	service instance name	adr_string
2038  * -----------------------------------------------------------------------
2039  */
2040 int
2041 fmri_token(pr_context_t *context)
2042 {
2043 	return (pa_adr_string(context, 0, 1));
2044 }
2045 
2046 /*
2047  * -----------------------------------------------------------------------
2048  * xatom_token()	: Process Xatom token and display contents in hex.
2049  * return codes		: -1 - error
2050  *			:  0 - successful
2051  * NOTE: At the time of call, the xatom token id has been retrieved
2052  *
2053  * Format of xatom token:
2054  *	token id		adr_char
2055  * 	length			adr_short
2056  * 	atom			adr_char length times
2057  * -----------------------------------------------------------------------
2058  */
2059 int
2060 xatom_token(pr_context_t *context)
2061 {
2062 	return (pa_adr_string(context, 0, 1));
2063 }
2064 
2065 int
2066 xcolormap_token(pr_context_t *context)
2067 {
2068 	return (pa_xgeneric(context));
2069 }
2070 
2071 int
2072 xcursor_token(pr_context_t *context)
2073 {
2074 	return (pa_xgeneric(context));
2075 }
2076 
2077 int
2078 xfont_token(pr_context_t *context)
2079 {
2080 	return (pa_xgeneric(context));
2081 }
2082 
2083 int
2084 xgc_token(pr_context_t *context)
2085 {
2086 	return (pa_xgeneric(context));
2087 }
2088 
2089 int
2090 xpixmap_token(pr_context_t *context)
2091 {
2092 	return (pa_xgeneric(context));
2093 }
2094 
2095 int
2096 xwindow_token(pr_context_t *context)
2097 {
2098 	return (pa_xgeneric(context));
2099 }
2100 
2101 /*
2102  * -----------------------------------------------------------------------
2103  * xproperty_token(): Process Xproperty token and display contents
2104  *
2105  * return codes		: -1 - error
2106  *			:  0 - successful
2107  * NOTE: At the time of call, the xproperty token id has been retrieved
2108  *
2109  * Format of xproperty token:
2110  *	token id		adr_char
2111  *	XID			adr_u_int32
2112  *	creator UID		adr_u_int32
2113  *	text			adr_text
2114  * -----------------------------------------------------------------------
2115  */
2116 int
2117 xproperty_token(pr_context_t *context)
2118 {
2119 	int	returnstat;
2120 
2121 	returnstat = process_tag(context, TAG_XID, 0, 0);
2122 	returnstat = process_tag(context, TAG_XCUID, returnstat, 0);
2123 
2124 	/* Done with attributes; force end of token open */
2125 	if (returnstat == 0)
2126 		returnstat = finish_open_tag(context);
2127 
2128 	returnstat = pa_adr_string(context, returnstat, 1);
2129 
2130 	return (returnstat);
2131 }
2132 
2133 /*
2134  * -----------------------------------------------------------------------
2135  * xselect_token(): Process Xselect token and display contents in hex
2136  *
2137  * return codes		: -1 - error
2138  *			:  0 - successful
2139  * NOTE: At the time of call, the xselect token id has been retrieved
2140  *
2141  * Format of xselect token
2142  *	text token id		adr_char
2143  * 	property text		adr_string
2144  * 	property type		adr_string
2145  * 	property data		adr_string
2146  * -----------------------------------------------------------------------
2147  */
2148 int
2149 xselect_token(pr_context_t *context)
2150 {
2151 	int	returnstat;
2152 
2153 	returnstat = process_tag(context, TAG_XSELTEXT, 0, 0);
2154 	returnstat = process_tag(context, TAG_XSELTYPE, returnstat, 0);
2155 	returnstat = process_tag(context, TAG_XSELDATA, returnstat, 1);
2156 
2157 	return (returnstat);
2158 }
2159 
2160 /*
2161  * -----------------------------------------------------------------------
2162  * xclient_token(): Process Xclient token and display contents in hex.
2163  *
2164  * return codes		: -1 - error
2165  *			:  0 - successful
2166  *
2167  * Format of xclient token:
2168  *	token id		adr_char
2169  * 	client			adr_int32
2170  * -----------------------------------------------------------------------
2171  */
2172 int
2173 xclient_token(pr_context_t *context)
2174 {
2175 	return (pa_adr_int32(context, 0, 1));
2176 }
2177 
2178 /*
2179  * -----------------------------------------------------------------------
2180  * label_token() 	: Process label token and display contents
2181  * return codes 	: -1 - error
2182  *			: 0 - successful
2183  * NOTE: At the time of call, the label token id has been retrieved
2184  *
2185  * Format of label token:
2186  *	label token id			adr_char
2187  *      label ID                	adr_char
2188  *      label compartment length	adr_char
2189  *      label classification		adr_short
2190  *      label compartment words		<compartment length> * 4 adr_char
2191  * -----------------------------------------------------------------------
2192  */
2193 /*ARGSUSED*/
2194 int
2195 label_token(pr_context_t *context)
2196 {
2197 	static m_label_t *label = NULL;
2198 	static size_t l_size;
2199 	int	len;
2200 	int	returnstat;
2201 	uval_t	uval;
2202 
2203 	if (label == NULL) {
2204 		if ((label = m_label_alloc(MAC_LABEL)) == NULL) {
2205 			return (-1);
2206 		}
2207 		l_size = blabel_size() - 4;
2208 	}
2209 	if ((returnstat = pr_adr_char(context, (char *)label, 4)) == 0) {
2210 		len = (int)(((char *)label)[1] * 4);
2211 		if ((len > l_size) ||
2212 		    (pr_adr_char(context, &((char *)label)[4], len) != 0)) {
2213 			return (-1);
2214 		}
2215 		uval.uvaltype = PRA_STRING;
2216 		if (!(context->format & PRF_RAWM)) {
2217 			/* print in ASCII form */
2218 			if (label_to_str(label, &uval.string_val, M_LABEL,
2219 			    DEF_NAMES) == 0) {
2220 				returnstat = pa_print(context, &uval, 1);
2221 			} else /* cannot convert to string */
2222 				returnstat = 1;
2223 		}
2224 		/* print in hexadecimal form */
2225 		if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2226 			uval.string_val = hexconvert((char *)label, len, len);
2227 			if (uval.string_val) {
2228 				returnstat = pa_print(context, &uval, 1);
2229 			}
2230 		}
2231 		free(uval.string_val);
2232 	}
2233 	return (returnstat);
2234 }
2235 
2236 /*
2237  * -----------------------------------------------------------------------
2238  * useofpriv_token() : Process priv token and display contents
2239  * return codes 	: -1 - error
2240  *			:  0 - successful
2241  * NOTE: At the time of call, the useofpriv token id has been retrieved
2242  *
2243  * Format of useofpriv token:
2244  *	useofpriv token id	adr_char
2245  *	success/failure flag	adr_char
2246  *	priv			adr_int32 (Trusted Solaris)
2247  *	priv_set		'\0' separated privileges.
2248  * -----------------------------------------------------------------------
2249  */
2250 /*ARGSUSED*/
2251 int
2252 useofpriv_token(pr_context_t *context)
2253 {
2254 	int	returnstat;
2255 	char	sf;
2256 	uval_t	uval;
2257 
2258 	if ((returnstat = pr_adr_char(context, &sf, 1)) != 0) {
2259 		return (returnstat);
2260 	}
2261 	if (!(context->format & PRF_RAWM)) {
2262 		/* print in ASCII form */
2263 
2264 		if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2265 			return (returnstat);
2266 
2267 		uval.uvaltype = PRA_STRING;
2268 		if (sf) {
2269 			uval.string_val = gettext("successful use of priv");
2270 			returnstat = pa_print(context, &uval, 0);
2271 		} else {
2272 			uval.string_val = gettext("failed use of priv");
2273 			returnstat = pa_print(context, &uval, 0);
2274 		}
2275 		if (returnstat == 0)
2276 			returnstat = close_tag(context, TAG_RESULT);
2277 
2278 		/* Done with attributes; force end of token open */
2279 		if (returnstat == 0)
2280 			returnstat = finish_open_tag(context);
2281 	} else {
2282 		/* print in hexadecimal form */
2283 		if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2284 			return (returnstat);
2285 		uval.uvaltype = PRA_SHORT;
2286 		uval.short_val = sf;
2287 		returnstat = pa_print(context, &uval, 0);
2288 		if (returnstat == 0)
2289 			returnstat = close_tag(context, TAG_RESULT);
2290 
2291 		/* Done with attributes; force end of token open */
2292 		if (returnstat == 0)
2293 			returnstat = finish_open_tag(context);
2294 	}
2295 	return (pa_adr_string(context, 0, 1));
2296 }
2297 
2298 /*
2299  * -----------------------------------------------------------------------
2300  * privilege_token()	: Process privilege token and display contents
2301  * return codes 	: -1 - error
2302  *			:  0 - successful
2303  * NOTE: At the time of call, the privilege token id has been retrieved
2304  *
2305  * Format of privilege token:
2306  *	privilege token id	adr_char
2307  *	privilege type		adr_string
2308  *	privilege		adr_string
2309  * -----------------------------------------------------------------------
2310  */
2311 int
2312 privilege_token(pr_context_t *context)
2313 {
2314 	int	returnstat;
2315 
2316 	/* privilege type: */
2317 	returnstat = process_tag(context, TAG_SETTYPE, 0, 0);
2318 
2319 	/* Done with attributes; force end of token open */
2320 	if (returnstat == 0)
2321 		returnstat = finish_open_tag(context);
2322 
2323 	/* privilege: */
2324 	return (pa_adr_string(context, returnstat, 1));
2325 }
2326