xref: /illumos-gate/usr/src/cmd/praudit/token.c (revision 1a220b56b93ff1dc80855691548503117af4cc10)
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 2006 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 			id++;
721 			continue;
722 		}
723 		/* XXX/../ seen */
724 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
725 			is += 2;
726 			if (id > 0)
727 				id--;
728 			while (id > 0 && s[--id] != '/');
729 			id++;
730 			continue;
731 		}
732 		while (is < ls && (s[id++] = s[is++]) != '/');
733 		is--;
734 	}
735 	return (s);
736 }
737 
738 /*
739  * -----------------------------------------------------------------------
740  * cmd_token()		: Process cmd token and display contents
741  * return codes		: -1 - error
742  *			:  0 - successful
743  * NOTE: At the time of call, the cmd token id has been retrieved
744  *
745  * Format of command token:
746  *	token id	adr_char
747  *	argc		adr_short
748  *	N*argv[i]	adr_string (short, string)
749  *	env cnt		adr_short
750  *	N*arge[i]	adr_string (short, string)
751  * -----------------------------------------------------------------------
752  */
753 int
754 cmd_token(pr_context_t *context)
755 {
756 	int	returnstat;
757 	short num;
758 
759 	returnstat = pr_adr_short(context, &num, 1);
760 	if (returnstat < 0)
761 		return (returnstat);
762 
763 	if (!(context->format & PRF_XMLM)) {
764 		returnstat = pr_printf(context, "%s%s%d%s",
765 		    (context->format & PRF_ONELINE) ? "" : gettext("argcnt"),
766 		    (context->format & PRF_ONELINE) ? "" : context->SEPARATOR,
767 		    num, context->SEPARATOR);
768 		if (returnstat < 0)
769 			return (returnstat);
770 	}
771 
772 	for (; num > 0; num--) {
773 		if ((returnstat = process_tag(context, TAG_ARGV,
774 		    returnstat, 0)) < 0)
775 			return (returnstat);
776 	}
777 
778 	if ((returnstat = pr_adr_short(context, &num, 1)) < 0)
779 		return (returnstat);
780 
781 	if (!(context->format & PRF_XMLM)) {
782 		returnstat = pr_printf(context, "%s%s%d%s",
783 		    (context->format & PRF_ONELINE) ? "" : gettext("envcnt"),
784 		    (context->format & PRF_ONELINE) ? "" : context->SEPARATOR,
785 		    num, context->SEPARATOR);
786 		if (returnstat < 0)
787 			return (returnstat);
788 	}
789 
790 	if ((num == 0) && !(context->format & PRF_XMLM)) {
791 		returnstat = pr_putchar(context, '\n');
792 		if (returnstat < 0)
793 			return (returnstat);
794 	}
795 
796 	for (; num > 1; num--) {
797 		if ((returnstat = process_tag(context, TAG_ARGE,
798 		    returnstat, 0)) < 0)
799 			return (returnstat);
800 	}
801 	if (num)
802 		returnstat = process_tag(context, TAG_ARGE, returnstat, 1);
803 
804 	return (returnstat);
805 
806 }
807 
808 /*
809  * -----------------------------------------------------------------------
810  * argument32_token()	: Process argument token and display contents
811  * return codes		: -1 - error
812  *			:  0 - successful
813  * NOTE: At the time of call, the arg token id has been retrieved
814  *
815  * Format of argument token:
816  *	current directory token id	adr_char
817  *	argument number			adr_char
818  *	argument value			adr_int32
819  *	argument description		adr_string
820  * -----------------------------------------------------------------------
821  */
822 int
823 argument32_token(pr_context_t *context)
824 {
825 	int	returnstat;
826 
827 	returnstat = process_tag(context, TAG_ARGNUM, 0, 0);
828 	returnstat = process_tag(context, TAG_ARGVAL32, returnstat, 0);
829 	returnstat = process_tag(context, TAG_ARGDESC, returnstat, 1);
830 
831 	return (returnstat);
832 
833 }
834 
835 /*
836  * -----------------------------------------------------------------------
837  * argument64_token()	: Process argument token and display contents
838  * return codes		: -1 - error
839  *			:  0 - successful
840  * NOTE: At the time of call, the arg token id has been retrieved
841  *
842  * Format of 64 bit argument token:
843  *	current directory token id	adr_char
844  *	argument number			adr_char
845  *	argument value			adr_int64
846  *	argument description		adr_string
847  * -----------------------------------------------------------------------
848  */
849 int
850 argument64_token(pr_context_t *context)
851 {
852 	int	returnstat;
853 
854 	returnstat = process_tag(context, TAG_ARGNUM, 0, 0);
855 	returnstat = process_tag(context, TAG_ARGVAL64, returnstat, 0);
856 	returnstat = process_tag(context, TAG_ARGDESC, returnstat, 1);
857 
858 	return (returnstat);
859 
860 }
861 
862 /*
863  * -----------------------------------------------------------------------
864  * process_token() 	: Process process token and display contents
865  * return codes		: -1 - error
866  *			:  0 - successful
867  * NOTE: At the time of call, the process token id has been retrieved
868  *
869  * Format of process token:
870  *	process token id	adr_char
871  *	auid			adr_u_int32
872  *	euid			adr_u_int32
873  *	egid			adr_u_int32
874  *	ruid			adr_u_int32
875  *	egid			adr_u_int32
876  *	pid			adr_u_int32
877  *	sid			adr_u_int32
878  *	tid			adr_u_int32, adr_u_int32
879  * -----------------------------------------------------------------------
880  */
881 int
882 process32_token(pr_context_t *context)
883 {
884 	int	returnstat;
885 
886 		/* auid */
887 	returnstat = process_tag(context, TAG_AUID, 0, 0);
888 		/* uid */
889 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
890 		/* gid */
891 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
892 		/* ruid */
893 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
894 		/* rgid */
895 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
896 		/* pid */
897 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
898 		/* sid */
899 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
900 		/* tid */
901 	returnstat = process_tag(context, TAG_TID32, returnstat, 1);
902 
903 	return (returnstat);
904 }
905 
906 int
907 process64_token(pr_context_t *context)
908 {
909 	int	returnstat;
910 
911 		/* auid */
912 	returnstat = process_tag(context, TAG_AUID, 0, 0);
913 		/* uid */
914 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
915 		/* gid */
916 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
917 		/* ruid */
918 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
919 		/* rgid */
920 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
921 		/* pid */
922 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
923 		/* sid */
924 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
925 		/* tid */
926 	returnstat = process_tag(context, TAG_TID64, returnstat, 1);
927 
928 	return (returnstat);
929 }
930 
931 /*
932  * -----------------------------------------------------------------------
933  * process_ex_token()	: Process process token and display contents
934  * return codes		: -1 - error
935  *			:  0 - successful
936  * NOTE: At the time of call, the process token id has been retrieved
937  *
938  * Format of extended process token:
939  *	process token id	adr_char
940  *	auid			adr_u_int32
941  *	euid			adr_u_int32
942  *	egid			adr_u_int32
943  *	ruid			adr_u_int32
944  *	egid			adr_u_int32
945  *	pid			adr_u_int32
946  *	sid			adr_u_int32
947  *	tid			adr_u_int32, adr_u_int32, 4*adr_u_int32
948  * -----------------------------------------------------------------------
949  */
950 int
951 process32_ex_token(pr_context_t *context)
952 {
953 	int	returnstat;
954 
955 		/* auid */
956 	returnstat = process_tag(context, TAG_AUID, 0, 0);
957 		/* uid */
958 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
959 		/* gid */
960 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
961 		/* ruid */
962 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
963 		/* rgid */
964 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
965 		/* pid */
966 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
967 		/* sid */
968 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
969 		/* tid */
970 	returnstat = process_tag(context, TAG_TID32_EX, returnstat, 1);
971 
972 	return (returnstat);
973 }
974 
975 int
976 process64_ex_token(pr_context_t *context)
977 {
978 	int	returnstat;
979 
980 		/* auid */
981 	returnstat = process_tag(context, TAG_AUID, 0, 0);
982 		/* uid */
983 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
984 		/* gid */
985 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
986 		/* ruid */
987 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
988 		/* rgid */
989 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
990 		/* pid */
991 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
992 		/* sid */
993 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
994 		/* tid */
995 	returnstat = process_tag(context, TAG_TID64_EX, returnstat, 1);
996 
997 	return (returnstat);
998 }
999 
1000 /*
1001  * -----------------------------------------------------------------------
1002  * return_value32_token(): Process return value and display contents
1003  * return codes		: -1 - error
1004  *			:  0 - successful
1005  * NOTE: At the time of call, the return value token id has been retrieved
1006  *
1007  * Format of return value token:
1008  * 	return value token id	adr_char
1009  *	error number		adr_char
1010  *	return value		adr_int32
1011  * -----------------------------------------------------------------------
1012  */
1013 int
1014 return_value32_token(pr_context_t *context)
1015 {
1016 	int		returnstat;
1017 	uchar_t		number;
1018 	int32_t		value;
1019 	char		pb[512];    /* print buffer */
1020 	uval_t		uval;
1021 	bool_t		used_ret_val = 0;
1022 
1023 	/*
1024 	 * Every audit record generated contains a return token.
1025 	 *
1026 	 * The return token is a special token. It indicates the success
1027 	 * or failure of the event that contains it.
1028 	 * The return32 token contains two pieces of data:
1029 	 *
1030 	 * 	char	number;
1031 	 * 	int32_t	return_value;
1032 	 *
1033 	 * For audit records generated by the kernel:
1034 	 * The kernel always puts a positive value in "number".
1035 	 * Upon success "number" is 0.
1036 	 * Upon failure "number" is a positive errno value that is less than
1037 	 * sys_nerr.
1038 	 *
1039 	 * For audit records generated at the user level:
1040 	 * Upon success "number" is 0.
1041 	 * Upon failure "number" is -1.
1042 	 *
1043 	 * For both kernel and user land the value of "return_value" is
1044 	 * arbitrary. For the kernel it contains the return value of
1045 	 * the system call. For user land it contains an arbitrary return
1046 	 * value if it is less than ADT_FAIL_VALUE; ADT_FAIL_VALUE
1047 	 * and above are messages defined in adt_event.h.   ADT_FAIL_PAM and
1048 	 * above are messages from pam_strerror().  No interpretation is done
1049 	 * on "return_value" if it is outside the range of ADT_FAIL_VALUE_* or
1050 	 * ADT_FAIL_PAM values.
1051 	 */
1052 	if ((returnstat = open_tag(context, TAG_ERRVAL)) != 0)
1053 		return (returnstat);
1054 
1055 	if ((returnstat = pr_adr_u_char(context, &number, 1)) == 0) {
1056 		if (!(context->format & PRF_RAWM)) {
1057 			used_ret_val = 1;
1058 			pa_error(number, pb, sizeof (pb));
1059 			uval.uvaltype = PRA_STRING;
1060 			uval.string_val = pb;
1061 			if ((returnstat = pa_print(context, &uval, 0)) != 0)
1062 				return (returnstat);
1063 			if ((returnstat = close_tag(context, TAG_ERRVAL)) != 0)
1064 				return (returnstat);
1065 			if ((returnstat = open_tag(context, TAG_RETVAL)) != 0)
1066 				return (returnstat);
1067 
1068 			if ((returnstat = pr_adr_int32(
1069 			    context, &value, 1)) != 0)
1070 				return (returnstat);
1071 
1072 			pa_retval(value, pb, sizeof (pb));
1073 		} else {
1074 			uval.uvaltype = PRA_INT32;
1075 			if ((char)number == -1)
1076 				uval.int32_val = -1;
1077 			else
1078 				uval.int32_val = number;
1079 		}
1080 		returnstat = pa_print(context, &uval, used_ret_val);
1081 	}
1082 	if (used_ret_val) {
1083 		if (returnstat == 0)
1084 			returnstat = close_tag(context, TAG_RETVAL);
1085 		return (returnstat);
1086 	}
1087 	if (!returnstat)
1088 		if (returnstat = close_tag(context, TAG_ERRVAL))
1089 			return (returnstat);
1090 
1091 	return (process_tag(context, TAG_RETVAL, returnstat, 1));
1092 }
1093 
1094 /*
1095  * -----------------------------------------------------------------------
1096  * return_value64_token(): Process return value and display contents
1097  * return codes		: -1 - error
1098  *			:  0 - successful
1099  * NOTE: At the time of call, the return value token id has been retrieved
1100  *
1101  * Format of return value token:
1102  * 	return value token id	adr_char
1103  *	error number		adr_char
1104  *	return value		adr_int64
1105  *
1106  * HOWEVER, the 64 bit return value is a concatenation of two
1107  * 32 bit return values; the first of which is the same as is
1108  * carried in the return32 token.  The second 32 bits are ignored
1109  * here so that the displayed return token will have the same
1110  * number whether the application is 32 or 64 bits.
1111  * -----------------------------------------------------------------------
1112  */
1113 int
1114 return_value64_token(pr_context_t *context)
1115 {
1116 	int		returnstat;
1117 	uchar_t		number;
1118 	rval_t		rval;
1119 	char		pb[512];    /* print buffer */
1120 	uval_t		uval;
1121 
1122 	/*
1123 	 * Every audit record generated contains a return token.
1124 	 *
1125 	 * The return token is a special token. It indicates the success
1126 	 * or failure of the event that contains it.
1127 	 * The return64 token contains two pieces of data:
1128 	 *
1129 	 * 	char	number;
1130 	 * 	int64_t	return_value;
1131 	 *
1132 	 * For audit records generated by the kernel:
1133 	 * The kernel always puts a positive value in "number".
1134 	 * Upon success "number" is 0.
1135 	 * Upon failure "number" is a positive errno value that is less than
1136 	 * sys_nerr.
1137 	 *
1138 	 * For audit records generated at the user level:
1139 	 * Upon success "number" is 0.
1140 	 * Upon failure "number" is -1.
1141 	 *
1142 	 * For both kernel and user land the value of "return_value" is
1143 	 * arbitrary. For the kernel it contains the return value of
1144 	 * the system call. For user land it contains an arbitrary return
1145 	 * value if it is less than ADT_FAIL_VALUE; ADT_FAIL_VALUE
1146 	 * and above are messages defined in adt_event.h.   ADT_FAIL_PAM and
1147 	 * above are messages from pam_strerror().  No interpretation is done
1148 	 * on "return_value" if it is outside the range of ADT_FAIL_VALUE_* or
1149 	 * ADT_FAIL_PAM values.
1150 	 *
1151 	 * The 64 bit return value consists of two 32bit parts; for
1152 	 * system calls, the first part is the value returned by the
1153 	 * system call and the second part depends on the system call
1154 	 * implementation.  In most cases, the second part is either 0
1155 	 * or garbage; because of that, it is omitted from the praudit
1156 	 * output.
1157 	 */
1158 	if ((returnstat = open_tag(context, TAG_ERRVAL)) != 0)
1159 		return (returnstat);
1160 
1161 	if ((returnstat = pr_adr_u_char(context, &number, 1)) == 0) {
1162 		if (!(context->format & PRF_RAWM)) {
1163 			pa_error(number, pb, sizeof (pb));
1164 			uval.uvaltype = PRA_STRING;
1165 			uval.string_val = pb;
1166 			if ((returnstat = pa_print(context, &uval, 0)) != 0)
1167 				return (returnstat);
1168 
1169 			if ((returnstat = close_tag(context, TAG_ERRVAL)) != 0)
1170 				return (returnstat);
1171 			if ((returnstat = open_tag(context, TAG_RETVAL)) != 0)
1172 				return (returnstat);
1173 
1174 			if ((returnstat = pr_adr_int64(context,
1175 			    &rval.r_vals, 1)) != 0)
1176 				return (returnstat);
1177 			pa_retval(rval.r_val1, pb, sizeof (pb));
1178 		} else {
1179 			uval.uvaltype = PRA_INT32;
1180 			if ((char)number == -1)
1181 				uval.int32_val = -1;
1182 			else
1183 				uval.int32_val = number;
1184 
1185 			if ((returnstat = pa_print(context, &uval, 0)) != 0)
1186 				return (returnstat);
1187 
1188 			if ((returnstat = close_tag(context, TAG_ERRVAL)) != 0)
1189 				return (returnstat);
1190 			if ((returnstat = open_tag(context, TAG_RETVAL)) != 0)
1191 				return (returnstat);
1192 
1193 			if ((returnstat = pr_adr_int64(context,
1194 			    &rval.r_vals, 1)) != 0)
1195 				return (returnstat);
1196 			uval.int32_val = rval.r_val1;
1197 		}
1198 		returnstat = pa_print(context, &uval, 1);
1199 	} else {
1200 		return (returnstat);
1201 	}
1202 
1203 	if (returnstat == 0)
1204 		returnstat = close_tag(context, TAG_RETVAL);
1205 
1206 	return (returnstat);
1207 }
1208 
1209 /*
1210  * -----------------------------------------------------------------------
1211  * subject32_token()	: Process subject token and display contents
1212  * return codes		: -1 - error
1213  *			:  0 - successful
1214  * NOTE: At the time of call, the subject token id has been retrieved
1215  *
1216  * Format of subject token:
1217  *	subject token id	adr_char
1218  *	auid			adr_u_int32
1219  *	euid			adr_u_int32
1220  *	egid			adr_u_int32
1221  *	ruid			adr_u_int32
1222  *	egid			adr_u_int32
1223  *	pid			adr_u_int32
1224  *	sid			adr_u_int32
1225  *	tid			adr_u_int32, adr_u_int32
1226  * -----------------------------------------------------------------------
1227  */
1228 int
1229 subject32_token(pr_context_t *context)
1230 {
1231 	int	returnstat;
1232 
1233 		/* auid */
1234 	returnstat = process_tag(context, TAG_AUID, 0, 0);
1235 		/* uid */
1236 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1237 		/* gid */
1238 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1239 		/* ruid */
1240 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1241 		/* rgid */
1242 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1243 		/* pid */
1244 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
1245 		/* sid */
1246 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
1247 		/* tid */
1248 	returnstat = process_tag(context, TAG_TID32, returnstat, 1);
1249 
1250 	return (returnstat);
1251 }
1252 
1253 int
1254 subject64_token(pr_context_t *context)
1255 {
1256 	int	returnstat;
1257 
1258 		/* auid */
1259 	returnstat = process_tag(context, TAG_AUID, 0, 0);
1260 		/* uid */
1261 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1262 		/* gid */
1263 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1264 		/* ruid */
1265 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1266 		/* rgid */
1267 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1268 		/* pid */
1269 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
1270 		/* sid */
1271 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
1272 		/* tid */
1273 	returnstat = process_tag(context, TAG_TID64, returnstat, 1);
1274 
1275 	return (returnstat);
1276 }
1277 
1278 /*
1279  * -----------------------------------------------------------------------
1280  * subject_ex_token(): Process subject token and display contents
1281  * return codes		: -1 - error
1282  *			:  0 - successful
1283  * NOTE: At the time of call, the subject token id has been retrieved
1284  *
1285  * Format of extended subject token:
1286  *	subject token id	adr_char
1287  *	auid			adr_u_int32
1288  *	euid			adr_u_int32
1289  *	egid			adr_u_int32
1290  *	ruid			adr_u_int32
1291  *	egid			adr_u_int32
1292  *	pid			adr_u_int32
1293  *	sid			adr_u_int32
1294  *	tid			adr_u_int32, adr_u_int32
1295  * -----------------------------------------------------------------------
1296  */
1297 int
1298 subject32_ex_token(pr_context_t *context)
1299 {
1300 	int	returnstat;
1301 
1302 		/* auid */
1303 	returnstat = process_tag(context, TAG_AUID, 0, 0);
1304 		/* uid */
1305 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1306 		/* gid */
1307 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1308 		/* ruid */
1309 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1310 		/* rgid */
1311 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1312 		/* pid */
1313 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
1314 		/* sid */
1315 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
1316 		/* tid */
1317 	returnstat = process_tag(context, TAG_TID32_EX, returnstat, 1);
1318 
1319 	return (returnstat);
1320 }
1321 
1322 int
1323 subject64_ex_token(pr_context_t *context)
1324 {
1325 	int	returnstat;
1326 
1327 		/* auid */
1328 	returnstat = process_tag(context, TAG_AUID, 0, 0);
1329 		/* uid */
1330 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1331 		/* gid */
1332 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1333 		/* ruid */
1334 	returnstat = process_tag(context, TAG_RUID, returnstat, 0);
1335 		/* rgid */
1336 	returnstat = process_tag(context, TAG_RGID, returnstat, 0);
1337 		/* pid */
1338 	returnstat = process_tag(context, TAG_PID, returnstat, 0);
1339 		/* sid */
1340 	returnstat = process_tag(context, TAG_SID, returnstat, 0);
1341 		/* tid */
1342 	returnstat = process_tag(context, TAG_TID64_EX, returnstat, 1);
1343 
1344 	return (returnstat);
1345 }
1346 
1347 /*
1348  * -----------------------------------------------------------------------
1349  * s5_IPC_token()	: Process System V IPC token and display contents
1350  * return codes		: -1 - error
1351  *			:  0 - successful
1352  * NOTE: At the time of call, the System V IPC id has been retrieved
1353  *
1354  * Format of System V IPC token:
1355  *	System V IPC token id	adr_char
1356  *	object id		adr_int32
1357  * -----------------------------------------------------------------------
1358  */
1359 int
1360 s5_IPC_token(pr_context_t *context)
1361 {
1362 	int	returnstat;
1363 	uchar_t ipctype;
1364 	uval_t	uval;
1365 
1366 	/*
1367 	 * TRANSLATION_NOTE
1368 	 * These names refer to the type of System V IPC object:
1369 	 * message queue, semaphore, shared memory.
1370 	 */
1371 
1372 	if (pr_adr_u_char(context, &ipctype, 1) == 0) {
1373 		if ((returnstat = open_tag(context, TAG_IPCTYPE)) != 0)
1374 			return (returnstat);
1375 
1376 		if (!(context->format & PRF_RAWM)) {
1377 			/* print in ASCII form */
1378 			uval.uvaltype = PRA_STRING;
1379 			switch (ipctype) {
1380 			case AT_IPC_MSG:
1381 				uval.string_val = gettext("msg");
1382 				break;
1383 			case AT_IPC_SEM:
1384 				uval.string_val = gettext("sem");
1385 				break;
1386 			case AT_IPC_SHM:
1387 				uval.string_val = gettext("shm");
1388 				break;
1389 			}
1390 			returnstat = pa_print(context, &uval, 0);
1391 		}
1392 		/* print in integer form */
1393 		if ((context->format & PRF_RAWM) || (returnstat == 1)) {
1394 			uval.uvaltype = PRA_BYTE;
1395 			uval.char_val = ipctype;
1396 			returnstat = pa_print(context, &uval, 0);
1397 		}
1398 		if ((returnstat = close_tag(context, TAG_IPCTYPE)) != 0)
1399 			return (returnstat);
1400 
1401 		/* next get and print ipc id */
1402 		return (process_tag(context, TAG_IPCID, returnstat, 1));
1403 	} else {
1404 		/* cannot retrieve ipc type */
1405 		return (-1);
1406 	}
1407 }
1408 
1409 /*
1410  * -----------------------------------------------------------------------
1411  * text_token()	: Process text token and display contents
1412  * return codes	: -1 - error
1413  *		:  0 - successful
1414  * NOTE: At the time of call, the text token id has been retrieved
1415  *
1416  * Format of text token:
1417  *	text token id		adr_char
1418  * 	text			adr_string
1419  * -----------------------------------------------------------------------
1420  */
1421 int
1422 text_token(pr_context_t *context)
1423 {
1424 	return (pa_adr_string(context, 0, 1));
1425 }
1426 
1427 /*
1428  * -----------------------------------------------------------------------
1429  * tid_token()		: Process a generic terminal id token / AUT_TID
1430  * return codes 	: -1 - error
1431  *			:  0 - successful
1432  * NOTE: At the time of call, the token id has been retrieved
1433  *
1434  * Format of tid token:
1435  *	ip token id	adr_char
1436  *	terminal type	adr_char
1437  *  terminal type = AU_IPADR:
1438  *	remote port:	adr_short
1439  *	local port:	adr_short
1440  *	IP type:	adt_int32 -- AU_IPv4 or AU_IPv6
1441  *	address:	adr_int32 if IPv4, else 4 * adr_int32
1442  * -----------------------------------------------------------------------
1443  */
1444 int
1445 tid_token(pr_context_t *context)
1446 {
1447 	int		returnstat;
1448 	uchar_t		type;
1449 	uval_t		uval;
1450 
1451 	if ((returnstat = pr_adr_u_char(context, &type, 1)) != 0)
1452 		return (returnstat);
1453 	uval.uvaltype = PRA_STRING;
1454 	if ((returnstat = open_tag(context, TAG_TID_TYPE)) != 0)
1455 		return (returnstat);
1456 
1457 	switch (type) {
1458 	default:
1459 		return (-1);	/* other than IP type is not implemented */
1460 	case AU_IPADR:
1461 		uval.string_val = "ip";
1462 		returnstat = pa_print(context, &uval, 0);
1463 		returnstat = close_tag(context, TAG_TID_TYPE);
1464 		returnstat = open_tag(context, TAG_IP);
1465 		returnstat = process_tag(context, TAG_IP_REMOTE, returnstat, 0);
1466 		returnstat = process_tag(context, TAG_IP_LOCAL, returnstat, 0);
1467 		returnstat = process_tag(context, TAG_IP_ADR, returnstat, 1);
1468 		returnstat = close_tag(context, TAG_IP);
1469 		break;
1470 	}
1471 	return (returnstat);
1472 }
1473 
1474 /*
1475  * -----------------------------------------------------------------------
1476  * ip_addr_token() 	: Process ip token and display contents
1477  * return codes 	: -1 - error
1478  *			:  0 - successful
1479  * NOTE: At the time of call, the ip token id has been retrieved
1480  *
1481  * Format of ip address token:
1482  *	ip token id	adr_char
1483  *	address		adr_int32 (printed in hex)
1484  * -----------------------------------------------------------------------
1485  */
1486 
1487 int
1488 ip_addr_token(pr_context_t *context)
1489 {
1490 	return (pa_hostname(context, 0, 1));
1491 }
1492 
1493 int
1494 ip_addr_ex_token(pr_context_t *context)
1495 {
1496 	int	returnstat;
1497 	uint32_t	ip_addr[16];
1498 	uint32_t	ip_type;
1499 	struct in_addr	ia;
1500 	char		*ipstring;
1501 	char		buf[256];
1502 	uval_t		uval;
1503 
1504 	/* get address type */
1505 	if ((returnstat = pr_adr_u_int32(context, &ip_type, 1)) != 0)
1506 		return (returnstat);
1507 
1508 	/* legal address types are either AU_IPv4 or AU_IPv6 only */
1509 	if ((ip_type != AU_IPv4) && (ip_type != AU_IPv6))
1510 		return (-1);
1511 
1512 	/* get address (4/16) */
1513 	if ((returnstat = pr_adr_char(context, (char *)ip_addr, ip_type)) != 0)
1514 		return (returnstat);
1515 
1516 	uval.uvaltype = PRA_STRING;
1517 	if (ip_type == AU_IPv4) {
1518 		uval.string_val = buf;
1519 
1520 		if (!(context->format & PRF_RAWM)) {
1521 			get_Hname(ip_addr[0], buf, sizeof (buf));
1522 			return (pa_print(context, &uval, 1));
1523 		}
1524 
1525 		ia.s_addr = ip_addr[0];
1526 		if ((ipstring = inet_ntoa(ia)) == NULL)
1527 			return (-1);
1528 
1529 		(void) snprintf(buf, sizeof (buf), "%s", ipstring);
1530 
1531 	} else {
1532 		uval.string_val = buf;
1533 
1534 		if (!(context->format & PRF_RAWM)) {
1535 			get_Hname_ex(ip_addr, buf, sizeof (buf));
1536 			return (pa_print(context, &uval, 1));
1537 		}
1538 
1539 		(void) inet_ntop(AF_INET6, (void *) ip_addr, buf,
1540 		    sizeof (buf));
1541 
1542 	}
1543 
1544 	return (pa_print(context, &uval, 1));
1545 }
1546 
1547 /*
1548  * -----------------------------------------------------------------------
1549  * ip_token()		: Process ip header token and display contents
1550  * return codes 	: -1 - error
1551  *			:  0 - successful
1552  * NOTE: At the time of call, the ip token id has been retrieved
1553  *
1554  * Format of ip header token:
1555  *	ip header token id	adr_char
1556  *	version			adr_char (printed in hex)
1557  *	type of service		adr_char (printed in hex)
1558  *	length			adr_short
1559  *	id			adr_u_short
1560  *	offset			adr_u_short
1561  *	ttl			adr_char (printed in hex)
1562  *	protocol		adr_char (printed in hex)
1563  *	checksum		adr_u_short
1564  *	source address		adr_int32 (printed in hex)
1565  *	destination address	adr_int32 (printed in hex)
1566  * -----------------------------------------------------------------------
1567  */
1568 int
1569 ip_token(pr_context_t *context)
1570 {
1571 	int	returnstat;
1572 
1573 	returnstat = process_tag(context, TAG_IPVERS, 0, 0);
1574 	returnstat = process_tag(context, TAG_IPSERV, returnstat, 0);
1575 	returnstat = process_tag(context, TAG_IPLEN, returnstat, 0);
1576 	returnstat = process_tag(context, TAG_IPID, returnstat, 0);
1577 	returnstat = process_tag(context, TAG_IPOFFS, returnstat, 0);
1578 	returnstat = process_tag(context, TAG_IPTTL, returnstat, 0);
1579 	returnstat = process_tag(context, TAG_IPPROTO, returnstat, 0);
1580 	returnstat = process_tag(context, TAG_IPCKSUM, returnstat, 0);
1581 	returnstat = process_tag(context, TAG_IPSRC, returnstat, 0);
1582 	returnstat = process_tag(context, TAG_IPDEST, returnstat, 1);
1583 
1584 	return (returnstat);
1585 }
1586 
1587 /*
1588  * -----------------------------------------------------------------------
1589  * iport_token() 	: Process ip port address token and display contents
1590  * return codes		: -1 - error
1591  *			:  0 - successful
1592  * NOTE: At time of call, the ip port address token id has been retrieved
1593  *
1594  * Format of ip port token:
1595  *	ip port address token id	adr_char
1596  *	port address			adr_short (in hex)
1597  * -----------------------------------------------------------------------
1598  */
1599 int
1600 iport_token(pr_context_t *context)
1601 {
1602 	return (pa_adr_shorthex(context, 0, 1));
1603 }
1604 
1605 /*
1606  * -----------------------------------------------------------------------
1607  * socket_token() 	: Process socket token and display contents
1608  * return codes		: -1 - error
1609  *			:  0 - successful
1610  * NOTE: At time of call, the socket token id has been retrieved
1611  *
1612  * Format of socket token:
1613  *	ip socket token id		adr_char
1614  *	socket type			adr_short (in hex)
1615  *	foreign port			adr_short (in hex)
1616  *	foreign internet address	adr_hostname/adr_int32 (in ascii/hex)
1617  * -----------------------------------------------------------------------
1618  *
1619  * Note: local port and local internet address have been removed for 5.x
1620  */
1621 int
1622 socket_token(pr_context_t *context)
1623 {
1624 	int	returnstat;
1625 
1626 	returnstat = process_tag(context, TAG_SOCKTYPE, 0, 0);
1627 	returnstat = process_tag(context, TAG_SOCKPORT, returnstat, 0);
1628 	if (returnstat != 0)
1629 		return (returnstat);
1630 
1631 	if ((returnstat = open_tag(context, TAG_SOCKADDR)) != 0)
1632 		return (returnstat);
1633 
1634 	if ((returnstat = pa_hostname(context, returnstat, 1)) != 0)
1635 		return (returnstat);
1636 
1637 	return (close_tag(context, TAG_SOCKADDR));
1638 }
1639 
1640 /*
1641  * -----------------------------------------------------------------------
1642  * socket_ex_token()	: Process socket token and display contents
1643  * return codes		: -1 - error
1644  *			:  0 - successful
1645  * NOTE: At time of call, the extended socket token id has been retrieved
1646  *
1647  * Format of extended socket token:
1648  *	token id			adr_char
1649  *	socket domain			adr_short (in hex)
1650  *	socket type			adr_short (in hex)
1651  *	IP address type			adr_short (in hex) [not displayed]
1652  *	local port			adr_short (in hex)
1653  *	local internet address		adr_hostname/adr_int32 (in ascii/hex)
1654  *	foreign port			adr_short (in hex)
1655  *	foreign internet address	adr_hostname/adr_int32 (in ascii/hex)
1656  * -----------------------------------------------------------------------
1657  *
1658  * Note: local port and local internet address have been removed for 5.x
1659  */
1660 int
1661 socket_ex_token(pr_context_t *context)
1662 {
1663 	int	returnstat;
1664 
1665 	returnstat = process_tag(context, TAG_SOCKEXDOM, 0, 0);
1666 	returnstat = process_tag(context, TAG_SOCKEXTYPE, returnstat, 0);
1667 	returnstat = pa_hostname_so(context, returnstat, 1);
1668 
1669 	return (returnstat);
1670 }
1671 
1672 /*
1673  * -----------------------------------------------------------------------
1674  * sequence_token()	: Process sequence token and display contents
1675  * return codes		: -1 - error
1676  *			:  0 - successful
1677  * NOTE: At time of call, the socket token id has been retrieved
1678  *
1679  * Format of sequence token:
1680  *	sequence token id		adr_char
1681  *	sequence number 		adr_u_int32 (in hex)
1682  * -----------------------------------------------------------------------
1683  */
1684 int
1685 sequence_token(pr_context_t *context)
1686 {
1687 	return (process_tag(context, TAG_SEQNUM, 0, 1));
1688 }
1689 
1690 /*
1691  * -----------------------------------------------------------------------
1692  * acl_token()	: Process access control list term
1693  * return codes	: -1 - error
1694  *		:  0 - successful
1695  *
1696  * Format of acl token:
1697  *	token id	adr_char
1698  *	term type	adr_u_int32
1699  *	term value	adr_u_int32 (depends on type)
1700  *	file mode	adr_u_int (in octal)
1701  * -----------------------------------------------------------------------
1702  */
1703 int
1704 acl_token(pr_context_t *context)
1705 {
1706 	int	returnstat;
1707 
1708 	returnstat = pa_pw_uid_gr_gid(context, 0, 0);
1709 
1710 	return (process_tag(context, TAG_MODE, returnstat, 1));
1711 }
1712 
1713 /*
1714  * -----------------------------------------------------------------------
1715  * attribute_token()	: Process attribute token and display contents
1716  * return codes 	: -1 - error
1717  *			:  0 - successful
1718  * NOTE: At the time of call, the attribute token id has been retrieved
1719  *
1720  * Format of attribute token:
1721  *	attribute token id	adr_char
1722  * 	mode			adr_u_int (printed in octal)
1723  *	uid			adr_u_int
1724  *	gid			adr_u_int
1725  *	file system id		adr_int
1726  *
1727  *	node id			adr_int		(attribute_token
1728  *						 pre SunOS 5.7)
1729  *	device			adr_u_int
1730  * or
1731  *	node id			adr_int64	(attribute32_token)
1732  *	device			adr_u_int
1733  * or
1734  *	node id			adr_int64	(attribute64_token)
1735  *	device			adr_u_int64
1736  * -----------------------------------------------------------------------
1737  */
1738 int
1739 attribute_token(pr_context_t *context)
1740 {
1741 	int	returnstat;
1742 
1743 	returnstat = process_tag(context, TAG_MODE, 0, 0);
1744 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1745 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1746 	returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1747 	returnstat = process_tag(context, TAG_NODEID32, returnstat, 0);
1748 	returnstat = process_tag(context, TAG_DEVICE32, returnstat, 1);
1749 
1750 	return (returnstat);
1751 }
1752 
1753 int
1754 attribute32_token(pr_context_t *context)
1755 {
1756 	int	returnstat;
1757 
1758 	returnstat = process_tag(context, TAG_MODE, 0, 0);
1759 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1760 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1761 	returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1762 	returnstat = process_tag(context, TAG_NODEID64, returnstat, 0);
1763 	returnstat = process_tag(context, TAG_DEVICE32, returnstat, 1);
1764 
1765 	return (returnstat);
1766 }
1767 
1768 int
1769 attribute64_token(pr_context_t *context)
1770 {
1771 	int	returnstat;
1772 
1773 	returnstat = process_tag(context, TAG_MODE, 0, 0);
1774 	returnstat = process_tag(context, TAG_UID, returnstat, 0);
1775 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1776 	returnstat = process_tag(context, TAG_FSID, returnstat, 0);
1777 	returnstat = process_tag(context, TAG_NODEID64, returnstat, 0);
1778 	returnstat = process_tag(context, TAG_DEVICE64, returnstat, 1);
1779 
1780 	return (returnstat);
1781 }
1782 
1783 /*
1784  * -----------------------------------------------------------------------
1785  * group_token() 	: Process group token and display contents
1786  * return codes 	: -1 - error
1787  *			:  0 - successful
1788  * NOTE: At the time of call, the group token id has been retrieved
1789  *
1790  * Format of group token:
1791  *	group token id		adr_char
1792  *	group list		adr_long, 16 times
1793  * -----------------------------------------------------------------------
1794  */
1795 int
1796 group_token(pr_context_t *context)
1797 {
1798 	int	returnstat = 0;
1799 	int	i;
1800 
1801 	for (i = 0; i < NGROUPS_MAX - 1; i++) {
1802 		if ((returnstat = process_tag(context, TAG_GROUPID,
1803 		    returnstat, 0)) < 0)
1804 			return (returnstat);
1805 	}
1806 
1807 	return (process_tag(context, TAG_GROUPID, returnstat, 1));
1808 }
1809 
1810 /*
1811  * -----------------------------------------------------------------------
1812  * newgroup_token() 	: Process group token and display contents
1813  * return codes 	: -1 - error
1814  *			:  0 - successful
1815  * NOTE: At the time of call, the group token id has been retrieved
1816  *
1817  * Format of new group token:
1818  *	group token id		adr_char
1819  *	group number		adr_short
1820  *	group list		adr_int32, group number times
1821  * -----------------------------------------------------------------------
1822  */
1823 int
1824 newgroup_token(pr_context_t *context)
1825 {
1826 	int	returnstat;
1827 	int	i, num;
1828 	short	n_groups;
1829 
1830 	returnstat = pr_adr_short(context, &n_groups, 1);
1831 	if (returnstat != 0)
1832 		return (returnstat);
1833 
1834 	num = (int)n_groups;
1835 	if (num == 0) {
1836 		if (!(context->format & PRF_XMLM)) {
1837 			/* sigh, have to put out a '\n' */
1838 			returnstat = pr_putchar(context, '\n');
1839 		}
1840 		return (returnstat);
1841 	}
1842 	for (i = 0; i < num - 1; i++) {
1843 		if ((returnstat = process_tag(context, TAG_GROUPID,
1844 		    returnstat, 0)) < 0)
1845 			return (returnstat);
1846 	}
1847 
1848 	return (process_tag(context, TAG_GROUPID, returnstat, 1));
1849 }
1850 
1851 static int
1852 string_token_common(pr_context_t *context, int tag)
1853 {
1854 	int	returnstat;
1855 	int	num;
1856 
1857 	returnstat = pr_adr_int32(context, (int32_t *)&num, 1);
1858 	if (returnstat != 0)
1859 		return (returnstat);
1860 
1861 	if (!(context->format & PRF_XMLM)) {
1862 		returnstat = pr_printf(context, "%d%s", num,
1863 		    context->SEPARATOR);
1864 		if (returnstat != 0)
1865 			return (returnstat);
1866 	}
1867 
1868 	if (num == 0)
1869 		return (0);
1870 
1871 	for (; num > 1; num--) {
1872 		if ((returnstat = (process_tag(context, tag,
1873 		    returnstat, 0))) < 0)
1874 			return (returnstat);
1875 	}
1876 
1877 	return (process_tag(context, tag, returnstat, 1));
1878 }
1879 
1880 int
1881 path_attr_token(pr_context_t *context)
1882 {
1883 	return (string_token_common(context, TAG_XAT));
1884 }
1885 
1886 int
1887 exec_args_token(pr_context_t *context)
1888 {
1889 	return (string_token_common(context, TAG_ARG));
1890 }
1891 
1892 int
1893 exec_env_token(pr_context_t *context)
1894 {
1895 	return (string_token_common(context, TAG_ENV));
1896 }
1897 
1898 /*
1899  * -----------------------------------------------------------------------
1900  * s5_IPC_perm_token() : Process System V IPC permission token and display
1901  *			 contents
1902  * return codes 	: -1 - error
1903  *			:  0 - successful
1904  * NOTE: At the time of call, the System V IPC permission token id
1905  * has been retrieved
1906  *
1907  * Format of System V IPC permission token:
1908  *	System V IPC permission token id	adr_char
1909  * 	uid					adr_u_int32
1910  *	gid					adr_u_int32
1911  *	cuid					adr_u_int32
1912  *	cgid					adr_u_int32
1913  *	mode					adr_u_int32
1914  *	seq					adr_u_int32
1915  *	key					adr_int32
1916  * -----------------------------------------------------------------------
1917  */
1918 int
1919 s5_IPC_perm_token(pr_context_t *context)
1920 {
1921 	int	returnstat;
1922 
1923 	returnstat = process_tag(context, TAG_UID, 0, 0);
1924 	returnstat = process_tag(context, TAG_GID, returnstat, 0);
1925 	returnstat = process_tag(context, TAG_CUID, returnstat, 0);
1926 	returnstat = process_tag(context, TAG_CGID, returnstat, 0);
1927 	returnstat = process_tag(context, TAG_MODE, returnstat, 0);
1928 	returnstat = process_tag(context, TAG_SEQ, returnstat, 0);
1929 	returnstat = process_tag(context, TAG_KEY, returnstat, 1);
1930 
1931 	return (returnstat);
1932 }
1933 
1934 /*
1935  * -----------------------------------------------------------------------
1936  * host_token()	: Process host token and display contents
1937  * return codes	: -1 - error
1938  *		:  0 - successful
1939  * NOTE: At the time of call, the host token id has been retrieved
1940  *
1941  * Format of host token:
1942  *	host token id		adr_char
1943  *	hostid			adr_u_int32
1944  * -----------------------------------------------------------------------
1945  */
1946 int
1947 host_token(pr_context_t *context)
1948 {
1949 	return (pa_hostname(context, 0, 1));
1950 }
1951 
1952 /*
1953  * -----------------------------------------------------------------------
1954  * liaison_token()	: Process liaison token and display contents
1955  * return codes 	: -1 - error
1956  *			:  0 - successful
1957  * NOTE: At the time of call, the liaison token id has been retrieved
1958  *
1959  * Format of liaison token:
1960  *	liaison token id	adr_char
1961  *	liaison			adr_u_int32
1962  * -----------------------------------------------------------------------
1963  */
1964 int
1965 liaison_token(pr_context_t *context)
1966 {
1967 	return (pa_liaison(context, 0, 1));
1968 }
1969 
1970 /*
1971  * -----------------------------------------------------------------------
1972  * useofauth_token(): Process useofauth token and display contents
1973  * return codes	: -1 - error
1974  *		:  0 - successful
1975  * NOTE: At the time of call, the uauth token id has been retrieved
1976  *
1977  * Format of useofauth token:
1978  *	uauth token id		adr_char
1979  * 	uauth			adr_string
1980  * -----------------------------------------------------------------------
1981  */
1982 int
1983 useofauth_token(pr_context_t *context)
1984 {
1985 	return (pa_adr_string(context, 0, 1));
1986 }
1987 
1988 /*
1989  * -----------------------------------------------------------------------
1990  * zonename_token(): Process zonename token and display contents
1991  * return codes	: -1 - error
1992  *		:  0 - successful
1993  * NOTE: At the time of call, the zonename token id has been retrieved
1994  *
1995  * Format of zonename token:
1996  *	zonename token id	adr_char
1997  * 	zone name		adr_string
1998  * -----------------------------------------------------------------------
1999  */
2000 int
2001 zonename_token(pr_context_t *context)
2002 {
2003 	return (process_tag(context, TAG_ZONENAME, 0, 1));
2004 }
2005 
2006 /*
2007  * -----------------------------------------------------------------------
2008  * fmri_token(): Process fmri token and display contents
2009  * return codes	: -1 - error
2010  *		:  0 - successful
2011  * NOTE: At the time of call, the fmri token id has been retrieved
2012  *
2013  * Format of fmri token:
2014  *	fmri token id		adr_char
2015  * 	service instance name	adr_string
2016  * -----------------------------------------------------------------------
2017  */
2018 int
2019 fmri_token(pr_context_t *context)
2020 {
2021 	return (pa_adr_string(context, 0, 1));
2022 }
2023 
2024 /*
2025  * -----------------------------------------------------------------------
2026  * xatom_token()	: Process Xatom token and display contents in hex.
2027  * return codes		: -1 - error
2028  *			:  0 - successful
2029  * NOTE: At the time of call, the xatom token id has been retrieved
2030  *
2031  * Format of xatom token:
2032  *	token id		adr_char
2033  * 	length			adr_short
2034  * 	atom			adr_char length times
2035  * -----------------------------------------------------------------------
2036  */
2037 int
2038 xatom_token(pr_context_t *context)
2039 {
2040 	return (pa_adr_string(context, 0, 1));
2041 }
2042 
2043 int
2044 xcolormap_token(pr_context_t *context)
2045 {
2046 	return (pa_xgeneric(context));
2047 }
2048 
2049 int
2050 xcursor_token(pr_context_t *context)
2051 {
2052 	return (pa_xgeneric(context));
2053 }
2054 
2055 int
2056 xfont_token(pr_context_t *context)
2057 {
2058 	return (pa_xgeneric(context));
2059 }
2060 
2061 int
2062 xgc_token(pr_context_t *context)
2063 {
2064 	return (pa_xgeneric(context));
2065 }
2066 
2067 int
2068 xpixmap_token(pr_context_t *context)
2069 {
2070 	return (pa_xgeneric(context));
2071 }
2072 
2073 int
2074 xwindow_token(pr_context_t *context)
2075 {
2076 	return (pa_xgeneric(context));
2077 }
2078 
2079 /*
2080  * -----------------------------------------------------------------------
2081  * xproperty_token(): Process Xproperty token and display contents
2082  *
2083  * return codes		: -1 - error
2084  *			:  0 - successful
2085  * NOTE: At the time of call, the xproperty token id has been retrieved
2086  *
2087  * Format of xproperty token:
2088  *	token id		adr_char
2089  *	XID			adr_u_int32
2090  *	creator UID		adr_u_int32
2091  *	text			adr_text
2092  * -----------------------------------------------------------------------
2093  */
2094 int
2095 xproperty_token(pr_context_t *context)
2096 {
2097 	int	returnstat;
2098 
2099 	returnstat = process_tag(context, TAG_XID, 0, 0);
2100 	returnstat = process_tag(context, TAG_XCUID, returnstat, 0);
2101 
2102 	/* Done with attributes; force end of token open */
2103 	if (returnstat == 0)
2104 		returnstat = finish_open_tag(context);
2105 
2106 	returnstat = pa_adr_string(context, returnstat, 1);
2107 
2108 	return (returnstat);
2109 }
2110 
2111 /*
2112  * -----------------------------------------------------------------------
2113  * xselect_token(): Process Xselect token and display contents in hex
2114  *
2115  * return codes		: -1 - error
2116  *			:  0 - successful
2117  * NOTE: At the time of call, the xselect token id has been retrieved
2118  *
2119  * Format of xselect token
2120  *	text token id		adr_char
2121  * 	property text		adr_string
2122  * 	property type		adr_string
2123  * 	property data		adr_string
2124  * -----------------------------------------------------------------------
2125  */
2126 int
2127 xselect_token(pr_context_t *context)
2128 {
2129 	int	returnstat;
2130 
2131 	returnstat = process_tag(context, TAG_XSELTEXT, 0, 0);
2132 	returnstat = process_tag(context, TAG_XSELTYPE, returnstat, 0);
2133 	returnstat = process_tag(context, TAG_XSELDATA, returnstat, 1);
2134 
2135 	return (returnstat);
2136 }
2137 
2138 /*
2139  * -----------------------------------------------------------------------
2140  * xclient_token(): Process Xclient token and display contents in hex.
2141  *
2142  * return codes		: -1 - error
2143  *			:  0 - successful
2144  *
2145  * Format of xclient token:
2146  *	token id		adr_char
2147  * 	client			adr_int32
2148  * -----------------------------------------------------------------------
2149  */
2150 int
2151 xclient_token(pr_context_t *context)
2152 {
2153 	return (pa_adr_int32(context, 0, 1));
2154 }
2155 
2156 /*
2157  * -----------------------------------------------------------------------
2158  * label_token() 	: Process label token and display contents
2159  * return codes 	: -1 - error
2160  *			: 0 - successful
2161  * NOTE: At the time of call, the label token id has been retrieved
2162  *
2163  * Format of label token:
2164  *	label token id			adr_char
2165  *      label ID                	adr_char
2166  *      label compartment length	adr_char
2167  *      label classification		adr_short
2168  *      label compartment words		<compartment length> * 4 adr_char
2169  * -----------------------------------------------------------------------
2170  */
2171 /*ARGSUSED*/
2172 int
2173 label_token(pr_context_t *context)
2174 {
2175 	static m_label_t *label = NULL;
2176 	static size_t l_size;
2177 	int	len;
2178 	int	returnstat;
2179 	uval_t	uval;
2180 
2181 	if (label == NULL) {
2182 		if ((label = m_label_alloc(MAC_LABEL)) == NULL) {
2183 			return (-1);
2184 		}
2185 		l_size = blabel_size() - 4;
2186 	}
2187 	if ((returnstat = pr_adr_char(context, (char *)label, 4)) == 0) {
2188 		len = (int)(((char *)label)[1] * 4);
2189 		if ((len > l_size) ||
2190 		    (pr_adr_char(context, &((char *)label)[4], len) != 0)) {
2191 			return (-1);
2192 		}
2193 		uval.uvaltype = PRA_STRING;
2194 		if (!(context->format & PRF_RAWM)) {
2195 			/* print in ASCII form */
2196 			if (label_to_str(label, &uval.string_val, M_LABEL,
2197 			    DEF_NAMES) == 0) {
2198 				returnstat = pa_print(context, &uval, 1);
2199 			} else /* cannot convert to string */
2200 				returnstat = 1;
2201 		}
2202 		/* print in hexadecimal form */
2203 		if ((context->format & PRF_RAWM) || (returnstat == 1)) {
2204 			uval.string_val = hexconvert((char *)label, len, len);
2205 			if (uval.string_val) {
2206 				returnstat = pa_print(context, &uval, 1);
2207 			}
2208 		}
2209 		free(uval.string_val);
2210 	}
2211 	return (returnstat);
2212 }
2213 
2214 /*
2215  * -----------------------------------------------------------------------
2216  * useofpriv_token() : Process priv token and display contents
2217  * return codes 	: -1 - error
2218  *			:  0 - successful
2219  * NOTE: At the time of call, the useofpriv token id has been retrieved
2220  *
2221  * Format of useofpriv token:
2222  *	useofpriv token id	adr_char
2223  *	success/failure flag	adr_char
2224  *	priv			adr_int32 (Trusted Solaris)
2225  *	priv_set		'\0' separated privileges.
2226  * -----------------------------------------------------------------------
2227  */
2228 /*ARGSUSED*/
2229 int
2230 useofpriv_token(pr_context_t *context)
2231 {
2232 	int	returnstat;
2233 	char	sf;
2234 	uval_t	uval;
2235 
2236 	if ((returnstat = pr_adr_char(context, &sf, 1)) != 0) {
2237 		return (returnstat);
2238 	}
2239 	if (!(context->format & PRF_RAWM)) {
2240 		/* print in ASCII form */
2241 
2242 		if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2243 			return (returnstat);
2244 
2245 		uval.uvaltype = PRA_STRING;
2246 		if (sf) {
2247 			uval.string_val = gettext("successful use of priv");
2248 			returnstat = pa_print(context, &uval, 0);
2249 		} else {
2250 			uval.string_val = gettext("failed use of priv");
2251 			returnstat = pa_print(context, &uval, 0);
2252 		}
2253 		if (returnstat == 0)
2254 			returnstat = close_tag(context, TAG_RESULT);
2255 
2256 		/* Done with attributes; force end of token open */
2257 		if (returnstat == 0)
2258 			returnstat = finish_open_tag(context);
2259 	} else {
2260 		/* print in hexadecimal form */
2261 		if ((returnstat = open_tag(context, TAG_RESULT)) != 0)
2262 			return (returnstat);
2263 		uval.uvaltype = PRA_SHORT;
2264 		uval.short_val = sf;
2265 		returnstat = pa_print(context, &uval, 0);
2266 		if (returnstat == 0)
2267 			returnstat = close_tag(context, TAG_RESULT);
2268 
2269 		/* Done with attributes; force end of token open */
2270 		if (returnstat == 0)
2271 			returnstat = finish_open_tag(context);
2272 	}
2273 	return (pa_adr_string(context, 0, 1));
2274 }
2275 
2276 /*
2277  * -----------------------------------------------------------------------
2278  * privilege_token()	: Process privilege token and display contents
2279  * return codes 	: -1 - error
2280  *			:  0 - successful
2281  * NOTE: At the time of call, the privilege token id has been retrieved
2282  *
2283  * Format of privilege token:
2284  *	privilege token id	adr_char
2285  *	privilege type		adr_string
2286  *	privilege		adr_string
2287  * -----------------------------------------------------------------------
2288  */
2289 int
2290 privilege_token(pr_context_t *context)
2291 {
2292 	int	returnstat;
2293 
2294 	/* privilege type: */
2295 	returnstat = process_tag(context, TAG_SETTYPE, 0, 0);
2296 
2297 	/* Done with attributes; force end of token open */
2298 	if (returnstat == 0)
2299 		returnstat = finish_open_tag(context);
2300 
2301 	/* privilege: */
2302 	return (pa_adr_string(context, returnstat, 1));
2303 }
2304