xref: /illumos-gate/usr/src/lib/auditd_plugins/syslog/systoken.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * Token processing for sysupd; each token function does one
29  * or more operations.  All of them bump the buffer pointer
30  * to the next token; some of them extract one or more data
31  * from the token.
32  */
33 
34 #define	DEBUG	0
35 #if DEBUG
36 #define	DPRINT(x) {fprintf x; }
37 #else
38 #define	DPRINT(x)
39 #endif
40 
41 #include <locale.h>
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <sys/types.h>
46 #include <bsm/libbsm.h>
47 #include <sys/tsol/label.h>
48 #include "toktable.h"	/* ../praudit */
49 #include "sysplugin.h"
50 #include "systoken.h"
51 #include <audit_plugin.h>
52 
53 #if DEBUG
54 static FILE	*dbfp;			/* debug file */
55 #endif
56 
57 static void	anchor_path(char *);
58 static size_t	collapse_path(char *, size_t);
59 static void	get_bytes_to_string(parse_context_t *, size_t *, char **,
60 		    size_t);
61 static void	skip_bytes(parse_context_t *);
62 static void	skip_string(parse_context_t *);
63 static int	xgeneric(parse_context_t *);
64 
65 /*
66  * Process a token in a record to (1) extract data of interest if any
67  * and (2) point to the next token.
68  *
69  * returns 0 if ok.  + or - values are of debug value:
70  *
71  *	returns -1 if the parsing of the token failed.
72  *
73  *	returns +<previous id> if the token is not found.  This value
74  *	is used to help determine where in the record the problem
75  *	occurred.  The common failure case is that the parsing of
76  *	token M is incorrect and the buffer pointer ends up pointing
77  *	to garbage.  The positive error value of M *may* be the id of
78  *	the incorrectly parsed token.
79  */
80 
81 int
82 parse_token(parse_context_t *ctx)
83 {
84 	char		tokenid;
85 	static char	prev_tokenid = -1;
86 	int		rc;
87 
88 #if DEBUG
89 	static boolean_t	first = 1;
90 
91 	if (first) {
92 		dbfp = __auditd_debug_file_open();
93 		first = 0;
94 	}
95 #endif
96 
97 	adrm_char(&(ctx->adr), &tokenid, 1);
98 
99 	if ((tokenid > 0) && (tokentable[tokenid].func != NOFUNC)) {
100 		rc = (*tokentable[tokenid].func)(ctx);
101 		prev_tokenid = tokenid;
102 		return (rc);
103 	}
104 	/* here if token id is not in table */
105 	return (prev_tokenid);
106 }
107 
108 /* There should not be any file tokens in the middle of a record */
109 
110 /* ARGSUSED */
111 int
112 file_token(parse_context_t *ctx)
113 {
114 
115 	return (-1);
116 }
117 
118 /* ARGSUSED */
119 int
120 file64_token(parse_context_t *ctx)
121 {
122 	return (-1);
123 }
124 
125 static void
126 common_header(parse_context_t *ctx)
127 {
128 	adrm_u_int32(&(ctx->adr), &(ctx->out.sf_reclen), 1);
129 	ctx->adr.adr_now += sizeof (char);		/* version number */
130 	adrm_u_short(&(ctx->adr), &(ctx->out.sf_eventid), 1);
131 	ctx->adr.adr_now += sizeof (short);		/* modifier */
132 }
133 
134 /*
135  * 32bit header
136  */
137 int
138 header_token(parse_context_t *ctx)
139 {
140 	common_header(ctx);
141 	ctx->adr.adr_now += 2 * sizeof (int32_t);	/* time */
142 
143 	return (0);
144 }
145 
146 
147 int
148 header32_ex_token(parse_context_t *ctx)
149 {
150 	int32_t	type;
151 
152 	common_header(ctx);
153 
154 	adrm_int32(&(ctx->adr), &type, 1);		/* tid type */
155 	ctx->adr.adr_now += type * sizeof (char);	/* ip address */
156 
157 	ctx->adr.adr_now += 2 * sizeof (int32_t);	/* time */
158 
159 	return (0);
160 }
161 
162 
163 int
164 header64_ex_token(parse_context_t *ctx)
165 {
166 	int32_t	type;
167 
168 	common_header(ctx);
169 
170 	adrm_int32(&(ctx->adr), &type, 1);		/* tid type */
171 	ctx->adr.adr_now += type * sizeof (char);	/* ip address */
172 
173 	ctx->adr.adr_now += 2 * sizeof (int64_t);	/* time */
174 
175 	return (0);
176 }
177 
178 
179 int
180 header64_token(parse_context_t *ctx)
181 {
182 	common_header(ctx);
183 
184 	ctx->adr.adr_now += 2 * sizeof (int64_t);	/* time */
185 
186 	return (0);
187 }
188 
189 
190 /*
191  * ======================================================
192  *  The following token processing routines return
193  *  0: if parsed ok
194  * -1: can't parse and can't determine location of next token
195  * ======================================================
196  */
197 
198 int
199 trailer_token(parse_context_t *ctx)
200 {
201 	short	magic_number;
202 	uint32_t bytes;
203 
204 	adrm_u_short(&(ctx->adr), (ushort_t *)&magic_number, 1);
205 	if (magic_number != AUT_TRAILER_MAGIC)
206 		return (-1);
207 
208 	adrm_u_int32(&(ctx->adr), &bytes, 1);
209 
210 	return (0);
211 }
212 
213 
214 /*
215  * Format of arbitrary data token:
216  *	arbitrary data token id	&(ctx->adr) char
217  * 	how to print		adr_char
218  *	basic unit		adr_char
219  *	unit count		adr_char, specifying number of units of
220  *	data items		depends on basic unit
221  *
222  */
223 int
224 arbitrary_data_token(parse_context_t *ctx)
225 {
226 	char	basic_unit, unit_count;
227 
228 	ctx->adr.adr_now += sizeof (char); /* how to print */
229 
230 	adrm_char(&(ctx->adr), &basic_unit, 1);
231 	adrm_char(&(ctx->adr), &unit_count, 1);
232 
233 	switch (basic_unit) {
234 	case AUR_CHAR: /* same as AUR_BYTE */
235 		ctx->adr.adr_now += unit_count * sizeof (char);
236 		break;
237 	case AUR_SHORT:
238 		ctx->adr.adr_now += unit_count * sizeof (short);
239 		break;
240 	case AUR_INT32:	/* same as AUR_INT */
241 		ctx->adr.adr_now += unit_count * sizeof (int32_t);
242 		break;
243 	case AUR_INT64:
244 		ctx->adr.adr_now += unit_count * sizeof (int64_t);
245 		break;
246 	default:
247 		return (-1);
248 		break;
249 	}
250 	return (0);
251 }
252 
253 
254 /*
255  * Format of opaque token:
256  *	opaque token id		adr_char
257  *	size			adr_short
258  *	data			adr_char, size times
259  *
260  */
261 int
262 opaque_token(parse_context_t *ctx)
263 {
264 	skip_bytes(ctx);
265 	return (0);
266 }
267 
268 
269 /*
270  * Format of return32 value token:
271  * 	return value token id	adr_char
272  *	error number		adr_char
273  *	return value		adr_u_int32
274  *
275  */
276 int
277 return_value32_token(parse_context_t *ctx)
278 {
279 	char		errnum;
280 
281 	adrm_char(&(ctx->adr), &errnum, 1);	/* pass / fail */
282 	ctx->adr.adr_now += sizeof (int32_t);	/* error code */
283 
284 	ctx->out.sf_pass = (errnum == 0) ? 1 : -1;
285 
286 	return (0);
287 }
288 
289 /*
290  * Format of return64 value token:
291  * 	return value token id	adr_char
292  *	error number		adr_char
293  *	return value		adr_u_int64
294  *
295  */
296 int
297 return_value64_token(parse_context_t *ctx)
298 {
299 	char		errnum;
300 
301 	adrm_char(&(ctx->adr), &errnum, 1);	/* pass / fail */
302 	ctx->adr.adr_now += sizeof (int64_t);	/* error code */
303 
304 	ctx->out.sf_pass = (errnum == 0) ? 1 : -1;
305 
306 	return (0);
307 }
308 
309 
310 /*
311  * Format of sequence token:
312  *	sequence token id	adr_char
313  *	audit_count		int32_t
314  *
315  */
316 int
317 sequence_token(parse_context_t *ctx)
318 {
319 	adrm_int32(&(ctx->adr), &(ctx->out.sf_sequence), 1);
320 	return (0);
321 }
322 
323 
324 /*
325  * Format of text token:
326  *	text token id		adr_char
327  * 	text			adr_string
328  */
329 int
330 text_token(parse_context_t *ctx)
331 {
332 	ushort_t	len;
333 	size_t		separator_sz = 0;
334 	char		*bp;	/* pointer to output string */
335 
336 	adrm_u_short(&(ctx->adr), &len, 1);
337 
338 	if (ctx->out.sf_textlen > 0)
339 		separator_sz = sizeof (AU_TEXT_NAME) - 1;
340 
341 	DPRINT((dbfp, "text_token: start length=%d, add length=%d+%d\n",
342 	    ctx->out.sf_textlen, (size_t)len, separator_sz));
343 
344 	ctx->out.sf_text = realloc(ctx->out.sf_text,
345 	    ctx->out.sf_textlen + (size_t)len + separator_sz);
346 
347 	if (ctx->out.sf_text == NULL)
348 		return (-1);
349 
350 	bp = ctx->out.sf_text;
351 
352 	if (ctx->out.sf_textlen != 0) {	/* concatenation? */
353 		bp += ctx->out.sf_textlen;
354 		bp += strlcpy(bp, AU_TEXT_NAME, separator_sz + 1);
355 		ctx->out.sf_textlen += separator_sz;
356 		DPRINT((dbfp, "text_token: l is %d\n%s\n", ctx->out.sf_textlen,
357 		    ctx->out.sf_text));
358 	}
359 	adrm_char(&(ctx->adr), bp, len);
360 	len--;		/* includes EOS */
361 	*(bp + len) = '\0';
362 
363 	ctx->out.sf_textlen += len;
364 	DPRINT((dbfp, "text_token: l=%d\n%s\n", ctx->out.sf_textlen,
365 	    ctx->out.sf_text));
366 
367 	return (0);
368 }
369 
370 /*
371  * Format of tid token:
372  *	ip token id	adr_char
373  *	terminal type	adr_char
374  *  terminal type = AU_IPADR:
375  *	remote port:	ushort
376  *	local port:	ushort
377  *	IP type:	int32 -- AU_IPv4 or AU_IPv6
378  *	address:	int32 if IPv4, else 4 * int32
379  */
380 int
381 tid_token(parse_context_t *ctx)
382 {
383 	uchar_t		type;
384 	int32_t		ip_length;
385 
386 	adrm_char(&(ctx->adr), (char *)&type, 1);
387 
388 	switch (type) {
389 	default:
390 		return (-1);	/* other than IP type is not implemented */
391 	case AU_IPADR:
392 		ctx->adr.adr_now += 2 * sizeof (ushort_t);
393 		adrm_int32(&(ctx->adr), &ip_length, 1);
394 		ctx->adr.adr_now += ip_length;
395 		break;
396 	}
397 	return (0);
398 }
399 
400 /*
401  * Format of ip_addr token:
402  *	ip token id	adr_char
403  *	address		adr_int32
404  *
405  */
406 int
407 ip_addr_token(parse_context_t *ctx)
408 {
409 	ctx->adr.adr_now += sizeof (int32_t);
410 
411 	return (0);
412 }
413 
414 /*
415  * Format of ip_addr_ex token:
416  *	ip token id	adr_char
417  *	ip type		adr_int32
418  *	address		4*adr_int32
419  *
420  */
421 int
422 ip_addr_ex_token(parse_context_t *ctx)
423 {
424 	ctx->adr.adr_now += 5 * sizeof (int32_t);
425 
426 	return (0);
427 }
428 
429 /*
430  * Format of ip token:
431  *	ip header token id	adr_char
432  *	version			adr_char
433  *	type of service		adr_char
434  *	length			adr_short
435  *	id			adr_u_short
436  *	offset			adr_u_short
437  *	ttl			adr_char
438  *	protocol		adr_char
439  *	checksum		adr_u_short
440  *	source address		adr_int32
441  *	destination address	adr_int32
442  *
443  */
444 int
445 ip_token(parse_context_t *ctx)
446 {
447 	ctx->adr.adr_now += (2 * sizeof (char)) + (3 * sizeof (short)) +
448 	    (2 * sizeof (char)) + sizeof (short) + (2 * sizeof (int32_t));
449 	return (0);
450 }
451 
452 
453 /*
454  * Format of iport token:
455  *	ip port address token id	adr_char
456  *	port address			adr_short
457  *
458  */
459 int
460 iport_token(parse_context_t *ctx)
461 {
462 	ctx->adr.adr_now += sizeof (short);
463 
464 	return (0);
465 }
466 
467 
468 /*
469  * Format of groups token:
470  *	group token id		adr_char
471  *	group list		adr_int32, 16 times
472  *
473  */
474 int
475 group_token(parse_context_t *ctx)
476 {
477 	ctx->adr.adr_now += 16 * sizeof (int32_t);
478 
479 	return (0);
480 }
481 
482 /*
483  * Format of newgroups token:
484  *	group token id		adr_char
485  *	number of groups	adr_short
486  *	group list		adr_int32, "number" times
487  *
488  */
489 int
490 newgroup_token(parse_context_t *ctx)
491 {
492 	short int   number;
493 
494 	adrm_short(&(ctx->adr), &number, 1);
495 
496 	ctx->adr.adr_now += number * sizeof (int32_t);
497 
498 	return (0);
499 }
500 
501 /*
502  * Format of argument32 token:
503  *	argument token id	adr_char
504  *	argument number		adr_char
505  *	argument value		adr_int32
506  *	argument description	adr_string
507  *
508  */
509 int
510 argument32_token(parse_context_t *ctx)
511 {
512 	ctx->adr.adr_now += sizeof (char) + sizeof (int32_t);
513 	skip_bytes(ctx);
514 
515 	return (0);
516 }
517 
518 /*
519  * Format of argument64 token:
520  *	argument token id	adr_char
521  *	argument number		adr_char
522  *	argument value		adr_int64
523  *	argument description	adr_string
524  *
525  */
526 int
527 argument64_token(parse_context_t *ctx)
528 {
529 	ctx->adr.adr_now += sizeof (char) + sizeof (int64_t);
530 	skip_bytes(ctx);
531 
532 	return (0);
533 }
534 
535 /*
536  * Format of acl token:
537  * 	acl token id		adr_char
538  *	type			adr_u_int32
539  *	value			adr_u_int32
540  *	mode			adr_u_int32
541  */
542 int
543 acl_token(parse_context_t *ctx)
544 {
545 	ctx->adr.adr_now += 3 * sizeof (uint32_t);
546 
547 	return (0);
548 }
549 
550 /*
551  * Format of ace token:
552  * 	ace token id		adr_char
553  *	id			adr_u_int32
554  *	access_mask		adr_u_int32
555  *	flags			adr_u_short
556  *	type			adr_u_short
557  */
558 int
559 ace_token(parse_context_t *ctx)
560 {
561 	ctx->adr.adr_now += 2 * sizeof (uint32_t) + 2 * sizeof (ushort_t);
562 
563 	return (0);
564 }
565 
566 /*
567  * Format of attribute token: (old pre SunOS 5.7 format)
568  *	attribute token id	adr_char
569  * 	mode			adr_int32 (printed in octal)
570  *	uid			adr_int32
571  *	gid			adr_int32
572  *	file system id		adr_int32
573  *	node id			adr_int32
574  *	device			adr_int32
575  *
576  */
577 int
578 attribute_token(parse_context_t *ctx)
579 {
580 	ctx->adr.adr_now += 6 * sizeof (int32_t);
581 
582 	return (0);
583 }
584 
585 /*
586  * Format of attribute32 token:
587  *	attribute token id	adr_char
588  * 	mode			adr_int32 (printed in octal)
589  *	uid			adr_int32
590  *	gid			adr_int32
591  *	file system id		adr_int32
592  *	node id			adr_int64
593  *	device			adr_int32
594  *
595  */
596 int
597 attribute32_token(parse_context_t *ctx)
598 {
599 	ctx->adr.adr_now += (5 * sizeof (int32_t)) + sizeof (int64_t);
600 
601 	return (0);
602 }
603 
604 /*
605  * Format of attribute64 token:
606  *	attribute token id	adr_char
607  * 	mode			adr_int32 (printed in octal)
608  *	uid			adr_int32
609  *	gid			adr_int32
610  *	file system id		adr_int32
611  *	node id			adr_int64
612  *	device			adr_int64
613  *
614  */
615 int
616 attribute64_token(parse_context_t *ctx)
617 {
618 	ctx->adr.adr_now += (4 * sizeof (int32_t)) + (2 * sizeof (int64_t));
619 
620 	return (0);
621 }
622 
623 
624 /*
625  * Format of command token:
626  *	attribute token id	adr_char
627  *	argc			adr_short
628  *	argv len		adr_short	variable amount of argv len
629  *	argv text		argv len	and text
630  *	.
631  *	.
632  *	.
633  *	envp count		adr_short	variable amount of envp len
634  *	envp len		adr_short	and text
635  *	envp text		envp		len
636  *	.
637  *	.
638  *	.
639  *
640  */
641 int
642 cmd_token(parse_context_t *ctx)
643 {
644 	short	cnt;
645 	short	i;
646 
647 	adrm_short(&(ctx->adr), &cnt, 1);
648 
649 	for (i = 0; i < cnt; i++)
650 		skip_bytes(ctx);
651 
652 	adrm_short(&(ctx->adr), &cnt, 1);
653 
654 	for (i = 0; i < cnt; i++)
655 		skip_bytes(ctx);
656 
657 	return (0);
658 }
659 
660 
661 /*
662  * Format of exit token:
663  *	attribute token id	adr_char
664  *	return value		adr_int32
665  *	errno			adr_int32
666  *
667  */
668 int
669 exit_token(parse_context_t *ctx)
670 {
671 	int32_t	retval;
672 
673 	adrm_int32(&(ctx->adr), &retval, 1);
674 	ctx->adr.adr_now += sizeof (int32_t);
675 
676 	ctx->out.sf_pass = (retval == 0) ? 1 : -1;
677 	return (0);
678 }
679 
680 /*
681  * Format of exec_args token:
682  *	attribute token id	adr_char
683  *	count value		adr_int32
684  *	strings			null terminated strings
685  *
686  */
687 int
688 exec_args_token(parse_context_t *ctx)
689 {
690 	int count, i;
691 
692 	adrm_int32(&(ctx->adr), (int32_t *)&count, 1);
693 	for (i = 1; i <= count; i++) {
694 		skip_string(ctx);
695 	}
696 
697 	return (0);
698 }
699 
700 /*
701  * Format of exec_env token:
702  *	attribute token id	adr_char
703  *	count value		adr_int32
704  *	strings			null terminated strings
705  *
706  */
707 int
708 exec_env_token(parse_context_t *ctx)
709 {
710 	int count, i;
711 
712 	adrm_int32(&(ctx->adr), (int32_t *)&count, 1);
713 	for (i = 1; i <= count; i++)
714 		skip_string(ctx);
715 
716 	return (0);
717 }
718 
719 /*
720  * Format of liaison token:
721  */
722 int
723 liaison_token(parse_context_t *ctx)
724 {
725 	ctx->adr.adr_now += sizeof (int32_t);
726 
727 	return (0);
728 }
729 
730 
731 /*
732  * Format of path token:
733  *	path				adr_string
734  */
735 int
736 path_token(parse_context_t *ctx)
737 {
738 	get_bytes_to_string(ctx, &(ctx->out.sf_pathlen), &(ctx->out.sf_path),
739 	    0);
740 	if (ctx->out.sf_path == NULL)
741 		return (-1);
742 	/*
743 	 * anchor the path because collapse_path needs it
744 	 */
745 	if (*(ctx->out.sf_path) != '/') {
746 		anchor_path(ctx->out.sf_path);
747 		ctx->out.sf_pathlen++;
748 	}
749 	ctx->out.sf_pathlen = collapse_path(ctx->out.sf_path,
750 	    ctx->out.sf_pathlen);
751 
752 	return (0);
753 }
754 
755 /*
756  * path attr token / AUT_XATPATH
757  *
758  * Format of path attr token:
759  *	token id		adr_char
760  *	string count		adr_int32
761  *	strings			adr_string
762  *
763  * the sequence of strings is converted to a single string with
764  * a blank separator replacing the EOS for all but the last
765  * string.
766  */
767 int
768 path_attr_token(parse_context_t *ctx)
769 {
770 	int	count, i;
771 	int	last_len;
772 	size_t	offset;
773 	char	*p;
774 
775 	adrm_int32(&(ctx->adr), &count, 1);
776 
777 	offset = ctx->out.sf_atpathlen;
778 	p = ctx->adr.adr_now;
779 	for (i = 0; i <= count; i++) {
780 		last_len = strlen(p);
781 		ctx->out.sf_atpathlen += last_len + 1;
782 		p += last_len + 1;
783 	}
784 	ctx->out.sf_atpath = realloc(ctx->out.sf_atpath, ctx->out.sf_atpathlen);
785 	ctx->out.sf_atpath += offset;
786 	p = ctx->out.sf_atpath;		/* save for fix up, below */
787 	(void) memcpy(ctx->out.sf_atpath, ctx->adr.adr_now,
788 	    ctx->out.sf_atpathlen - offset);
789 	ctx->out.sf_atpathlen--;
790 
791 	/* fix up: replace each eos except the last with ' ' */
792 
793 	for (i = 0; i < count; i++) {
794 		while (*p++ != '\0')
795 			;
796 		*(p - 1) = ' ';
797 	}
798 	return (0);
799 }
800 
801 
802 /*
803  * Format of System V IPC permission token:
804  *	System V IPC permission token id	adr_char
805  * 	uid					adr_int32
806  *	gid					adr_int32
807  *	cuid					adr_int32
808  *	cgid					adr_int32
809  *	mode					adr_int32
810  *	seq					adr_int32
811  *	key					adr_int32
812  */
813 int
814 s5_IPC_perm_token(parse_context_t *ctx)
815 {
816 	ctx->adr.adr_now += (7 * sizeof (int32_t));
817 	return (0);
818 }
819 
820 static void
821 common_process(parse_context_t *ctx)
822 {
823 	int32_t	ruid, rgid, egid, pid;
824 	uint32_t asid;
825 
826 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_pauid), 1);
827 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_peuid), 1);
828 	adrm_int32(&(ctx->adr), &egid, 1);
829 	adrm_int32(&(ctx->adr), &ruid, 1);
830 	adrm_int32(&(ctx->adr), &rgid, 1);
831 	adrm_int32(&(ctx->adr), &pid, 1);
832 	adrm_u_int32(&(ctx->adr), &asid, 1);
833 }
834 
835 /*
836  * Format of process32 token:
837  *	process token id	adr_char
838  *	auid			adr_int32
839  *	euid			adr_int32
840  *	egid 			adr_int32
841  * 	ruid			adr_int32
842  *	rgid			adr_int32
843  * 	pid			adr_int32
844  * 	sid			adr_int32
845  * 	termid			adr_int32*2
846  *
847  */
848 int
849 process32_token(parse_context_t *ctx)
850 {
851 	int32_t port, machine;
852 
853 	common_process(ctx);
854 
855 	adrm_int32(&(ctx->adr), &port, 1);
856 	adrm_int32(&(ctx->adr), &machine, 1);
857 
858 	return (0);
859 }
860 
861 /*
862  * Format of process32_ex token:
863  *	process token id	adr_char
864  *	auid			adr_int32
865  *	euid			adr_int32
866  *	egid 			adr_int32
867  * 	ruid			adr_int32
868  *	rgid			adr_int32
869  * 	pid			adr_int32
870  * 	sid			adr_int32
871  * 	termid			adr_int32*6
872  *
873  */
874 int
875 process32_ex_token(parse_context_t *ctx)
876 {
877 	int32_t port, type, addr[4];
878 
879 	common_process(ctx);
880 
881 	adrm_int32(&(ctx->adr), &port, 1);
882 	adrm_int32(&(ctx->adr), &type, 1);
883 	adrm_int32(&(ctx->adr), &addr[0], 4);
884 
885 	return (0);
886 }
887 
888 /*
889  * Format of process64 token:
890  *	process token id	adr_char
891  *	auid			adr_int32
892  *	euid			adr_int32
893  *	egid 			adr_int32
894  * 	ruid			adr_int32
895  *	rgid			adr_int32
896  * 	pid			adr_int32
897  * 	sid			adr_int32
898  * 	termid			adr_int64+adr_int32
899  *
900  */
901 int
902 process64_token(parse_context_t *ctx)
903 {
904 	int64_t port;
905 	int32_t machine;
906 
907 	common_process(ctx);
908 
909 	adrm_int64(&(ctx->adr), &port, 1);
910 	adrm_int32(&(ctx->adr), &machine, 1);
911 
912 	return (0);
913 }
914 
915 /*
916  * Format of process64 token:
917  *	process token id	adr_char
918  *	auid			adr_int32
919  *	euid			adr_int32
920  *	egid 			adr_int32
921  * 	ruid			adr_int32
922  *	rgid			adr_int32
923  * 	pid			adr_int32
924  * 	sid			adr_int32
925  * 	termid			adr_int64+5*adr_int32
926  *
927  */
928 int
929 process64_ex_token(parse_context_t *ctx)
930 {
931 	int64_t port;
932 	int32_t type, addr[4];
933 
934 	common_process(ctx);
935 
936 	adrm_int64(&(ctx->adr), &port, 1);
937 	adrm_int32(&(ctx->adr), &type, 1);
938 	adrm_int32(&(ctx->adr), &addr[0], 4);
939 
940 	return (0);
941 }
942 
943 /*
944  * Format of System V IPC token:
945  *	System V IPC token id	adr_char
946  *	System V IPC type	adr_char
947  *	object id		adr_int32
948  *
949  */
950 int
951 s5_IPC_token(parse_context_t *ctx)
952 {
953 	ctx->adr.adr_now += sizeof (char);
954 	ctx->adr.adr_now += sizeof (int32_t);
955 
956 	return (0);
957 }
958 
959 
960 /*
961  * Format of socket token:
962  *	socket_type		adrm_short
963  *	remote_port		adrm_short
964  *	remote_inaddr		adrm_int32
965  *
966  */
967 int
968 socket_token(parse_context_t *ctx)
969 {
970 	ctx->adr.adr_now += (2 * sizeof (short)) + sizeof (int32_t);
971 
972 	return (0);
973 }
974 
975 
976 /*
977  * Format of socket token:
978  *
979  */
980 int
981 socket_ex_token(parse_context_t *ctx)
982 {
983 	short	ip_size;
984 
985 	ctx->adr.adr_now += (2 * sizeof (short));
986 	adrm_short(&(ctx->adr), &ip_size, 1);
987 
988 	ctx->adr.adr_now += sizeof (short) + (ip_size * sizeof (char)) +
989 	    sizeof (short) + (ip_size * sizeof (char));
990 	return (0);
991 }
992 
993 
994 static void
995 common_subject(parse_context_t *ctx)
996 {
997 	int32_t	ruid, rgid, pid;
998 
999 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_auid), 1);
1000 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_euid), 1);
1001 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_egid), 1);
1002 	adrm_int32(&(ctx->adr), &ruid, 1);
1003 	adrm_int32(&(ctx->adr), &rgid, 1);
1004 	adrm_int32(&(ctx->adr), &pid, 1);
1005 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_asid), 1);
1006 }
1007 
1008 /*
1009  * Format of subject32 token:
1010  *	subject token id	adr_char
1011  *	auid			adr_int32
1012  *	euid			adr_int32
1013  *	egid 			adr_int32
1014  * 	ruid			adr_int32
1015  *	rgid			adr_int32
1016  * 	pid			adr_int32
1017  * 	sid			adr_int32
1018  * 	termid			adr_int32*2
1019  *
1020  */
1021 int
1022 subject32_token(parse_context_t *ctx)
1023 {
1024 	int32_t port;	/* not used in output */
1025 
1026 	common_subject(ctx);
1027 
1028 	adrm_int32(&(ctx->adr), &port, 1);
1029 	ctx->out.sf_tid.at_type = AU_IPv4;
1030 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 4);
1031 
1032 	return (0);
1033 }
1034 
1035 /*
1036  * Format of subject32_ex token:
1037  *	subject token id	adr_char
1038  *	auid			adr_int32
1039  *	euid			adr_int32
1040  *	egid 			adr_int32
1041  * 	ruid			adr_int32
1042  *	rgid			adr_int32
1043  * 	pid			adr_int32
1044  * 	sid			adr_int32
1045  * 	termid_addr		adr_int32*6
1046  *
1047  */
1048 int
1049 subject32_ex_token(parse_context_t *ctx)
1050 {
1051 	int32_t port;	/* not used in output */
1052 
1053 	common_subject(ctx);
1054 
1055 	adrm_int32(&(ctx->adr), &port, 1);
1056 	adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1);
1057 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 16);
1058 
1059 	return (0);
1060 }
1061 
1062 /*
1063  * Format of subject64 token:
1064  *	subject token id	adr_char
1065  *	auid			adr_int32
1066  *	euid			adr_int32
1067  *	egid 			adr_int32
1068  * 	ruid			adr_int32
1069  *	rgid			adr_int32
1070  * 	pid			adr_int32
1071  * 	sid			adr_int32
1072  * 	termid			adr_int64+adr_int32
1073  *
1074  */
1075 int
1076 subject64_token(parse_context_t *ctx)
1077 {
1078 	int64_t port;
1079 
1080 	common_subject(ctx);
1081 
1082 	adrm_int64(&(ctx->adr), &port, 1);
1083 	ctx->out.sf_tid.at_type = AU_IPv4;
1084 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 4);
1085 
1086 	return (0);
1087 }
1088 
1089 /*
1090  * Format of subject64 token:
1091  *	subject token id	adr_char
1092  *	auid			adr_int32
1093  *	euid			adr_int32
1094  *	egid 			adr_int32
1095  * 	ruid			adr_int32
1096  *	rgid			adr_int32
1097  * 	pid			adr_int32
1098  * 	sid			adr_int32
1099  * 	termid			adr_int64+5*adr_int32
1100  *
1101  */
1102 int
1103 subject64_ex_token(parse_context_t *ctx)
1104 {
1105 	int64_t port;
1106 
1107 	common_subject(ctx);
1108 
1109 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_asid), 1);
1110 	adrm_int64(&(ctx->adr), &port, 1);
1111 	adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1);
1112 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 16);
1113 
1114 	return (0);
1115 }
1116 
1117 
1118 int
1119 xatom_token(parse_context_t *ctx)
1120 {
1121 	skip_bytes(ctx);
1122 
1123 	return (0);
1124 }
1125 
1126 
1127 int
1128 xselect_token(parse_context_t *ctx)
1129 {
1130 	skip_bytes(ctx);
1131 	skip_bytes(ctx);
1132 	skip_bytes(ctx);
1133 
1134 	return (0);
1135 }
1136 
1137 /*
1138  * anchor a path name with a slash
1139  * assume we have enough space
1140  */
1141 static void
1142 anchor_path(char *path)
1143 {
1144 
1145 	(void) memmove((void *)(path + 1), (void *)path, strlen(path) + 1);
1146 	*path = '/';
1147 }
1148 
1149 
1150 /*
1151  * copy path to collapsed path.
1152  * collapsed path does not contain:
1153  *	successive slashes
1154  *	instances of dot-slash
1155  *	instances of dot-dot-slash
1156  * passed path must be anchored with a '/'
1157  */
1158 static size_t
1159 collapse_path(char *s, size_t ls)
1160 {
1161 	int	id;	/* index of where we are in destination string */
1162 	int	is;	/* index of where we are in source string */
1163 	int	slashseen;	/* have we seen a slash */
1164 
1165 	ls++; /* source length including '\0' */
1166 
1167 	slashseen = 0;
1168 	for (is = 0, id = 0; is < ls; is++) {
1169 		if (s[is] == '\0') {
1170 			if (id > 1 && s[id-1] == '/') {
1171 				--id;
1172 			}
1173 			s[id++] = '\0';
1174 			break;
1175 		}
1176 		/* previous character was a / */
1177 		if (slashseen) {
1178 			if (s[is] == '/')
1179 				continue;	/* another slash, ignore it */
1180 		} else if (s[is] == '/') {
1181 			/* we see a /, just copy it and try again */
1182 			slashseen = 1;
1183 			s[id++] = '/';
1184 			continue;
1185 		}
1186 		/* /./ seen */
1187 		if (s[is] == '.' && s[is+1] == '/') {
1188 			is += 1;
1189 			continue;
1190 		}
1191 		/* XXX/. seen */
1192 		if (s[is] == '.' && s[is+1] == '\0') {
1193 			if (id > 1)
1194 				id--;
1195 			continue;
1196 		}
1197 		/* XXX/.. seen */
1198 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') {
1199 			is += 1;
1200 			if (id > 0)
1201 				id--;
1202 			while (id > 0 && s[--id] != '/')
1203 				;
1204 			id++;
1205 			continue;
1206 		}
1207 		/* XXX/../ seen */
1208 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
1209 			is += 2;
1210 			if (id > 0)
1211 				id--;
1212 			while (id > 0 && s[--id] != '/')
1213 				;
1214 			id++;
1215 			continue;
1216 		}
1217 		while (is < ls && (s[id++] = s[is++]) != '/')
1218 			;
1219 		is--;
1220 	}
1221 	return ((size_t)id - 1);
1222 }
1223 
1224 /*
1225  * for tokens with sub-fields that include a length, this
1226  * skips the sub-field.
1227  */
1228 
1229 static void
1230 skip_bytes(parse_context_t *ctx)
1231 {
1232 	ushort_t	c;
1233 
1234 	adrm_u_short(&(ctx->adr), &c, 1);
1235 	ctx->adr.adr_now += c;
1236 }
1237 
1238 static void
1239 skip_string(parse_context_t *ctx)
1240 {
1241 	char	c;
1242 
1243 	do {
1244 		adrm_char(&(ctx->adr), &c, 1);
1245 	} while (c != (char)0);
1246 }
1247 
1248 /*
1249  * add a byte to specified length so there can be a prefix of
1250  * '/' added (if needed for paths).  Another is added for '\0'
1251  *
1252  * if offset is zero, new data overwrites old, if any.  Otherwise
1253  * new data is appended to the end.
1254  */
1255 
1256 static void
1257 get_bytes_to_string(parse_context_t *ctx, size_t *l, char **p,
1258     size_t offset)
1259 {
1260 	ushort_t	len;
1261 	char		*bp;
1262 
1263 	adrm_u_short(&(ctx->adr), &len, 1);
1264 
1265 	len++;	/* in case need to add '/' prefix */
1266 	*p = realloc(*p, 1 + (size_t)len + offset);
1267 	if (*p == NULL) {
1268 		perror("audit_sysudp.so");
1269 		return;
1270 	}
1271 	if (offset > 0)
1272 		offset--;	/* overwrite end of string */
1273 
1274 	*l = (size_t)len - 2 + offset;
1275 
1276 	bp = *p + offset;
1277 	adrm_char(&(ctx->adr), bp, len - 1);
1278 	*(bp + len - 1) = '\0';
1279 }
1280 
1281 
1282 /*
1283  * Format of host token:
1284  *	host  		adr_uint32
1285  */
1286 int
1287 host_token(parse_context_t *ctx)
1288 {
1289 	ctx->adr.adr_now += sizeof (int32_t);
1290 
1291 	return (0);
1292 }
1293 
1294 /*
1295  * Format of useofauth token:
1296  *	uauth token id		adr_char
1297  * 	uauth			adr_string
1298  *
1299  */
1300 int
1301 useofauth_token(parse_context_t *ctx)
1302 {
1303 	get_bytes_to_string(ctx, &(ctx->out.sf_uauthlen),
1304 	    &(ctx->out.sf_uauth), 0);
1305 
1306 	return (0);
1307 }
1308 
1309 /*
1310  * Format of zonename token:
1311  *	zonename token id		adr_char
1312  * 	zonename			adr_string
1313  *
1314  */
1315 int
1316 zonename_token(parse_context_t *ctx)
1317 {
1318 	get_bytes_to_string(ctx,
1319 	    &(ctx->out.sf_zonelen),
1320 	    &(ctx->out.sf_zonename),
1321 	    0);
1322 
1323 	return (0);
1324 }
1325 
1326 /*
1327  * Format of fmri token:
1328  *	fmri token id		adr_char
1329  *	fmri			adr_string
1330  */
1331 int
1332 fmri_token(parse_context_t *ctx)
1333 {
1334 	skip_bytes(ctx);
1335 
1336 	return (0);
1337 }
1338 
1339 int
1340 xcolormap_token(parse_context_t *ctx)
1341 {
1342 	return (xgeneric(ctx));
1343 }
1344 
1345 int
1346 xcursor_token(parse_context_t *ctx)
1347 {
1348 	return (xgeneric(ctx));
1349 }
1350 
1351 int
1352 xfont_token(parse_context_t *ctx)
1353 {
1354 	return (xgeneric(ctx));
1355 }
1356 
1357 int
1358 xgc_token(parse_context_t *ctx)
1359 {
1360 	return (xgeneric(ctx));
1361 }
1362 
1363 int
1364 xpixmap_token(parse_context_t *ctx)
1365 {
1366 	return (xgeneric(ctx));
1367 }
1368 
1369 int
1370 xwindow_token(parse_context_t *ctx)
1371 {
1372 	return (xgeneric(ctx));
1373 }
1374 /*
1375  * Format of xgeneric token:
1376  *	XID			adr_int32
1377  *	creator UID		adr_int32
1378  *
1379  * Includes:  xcolormap, xcursor, xfont, xgc, xpixmap, and xwindow
1380  */
1381 static int
1382 xgeneric(parse_context_t *ctx)
1383 {
1384 	ctx->adr.adr_now += 2 * sizeof (int32_t);
1385 
1386 	return (0);
1387 }
1388 /*
1389  * Format of xproperty token:
1390  *	XID			adr_int32
1391  *	creator UID		adr_int32
1392  *	atom string		adr_string
1393  */
1394 int
1395 xproperty_token(parse_context_t *ctx)
1396 {
1397 	ctx->adr.adr_now += 2 * sizeof (int32_t);
1398 
1399 	return (0);
1400 }
1401 /*
1402  * Format of xclient token:
1403  * 	xclient id		adr_int32
1404  */
1405 int
1406 xclient_token(parse_context_t *ctx)
1407 {
1408 	ctx->adr.adr_now += sizeof (int32_t);
1409 
1410 	return (0);
1411 }
1412 
1413 /*
1414  * -----------------------------------------------------------------------
1415  * privilege_token()	: Process privilege token and display contents
1416  *
1417  * Format of privilege token:
1418  *	privilege token id	adr_char
1419  *	privilege type		adr_string
1420  *	privilege		adr_string
1421  * -----------------------------------------------------------------------
1422  */
1423 
1424 int
1425 privilege_token(parse_context_t *ctx)
1426 {
1427 	skip_bytes(ctx);
1428 	skip_bytes(ctx);
1429 
1430 	return (0);
1431 }
1432 
1433 
1434 /*
1435  * Format of label token:
1436  *	label ID                1 byte
1437  *	compartment length      1 byte
1438  *	classification          2 bytes
1439  *	compartment words       <compartment length> * 4 bytes
1440  */
1441 int
1442 label_token(parse_context_t *ctx)
1443 {
1444 	char	c;
1445 
1446 	ctx->adr.adr_now += sizeof (char);	/* label ID */
1447 	adrm_char(&(ctx->adr), &c, 1);
1448 
1449 	ctx->adr.adr_now += sizeof (ushort_t);	/* classification */
1450 	ctx->adr.adr_now += 4 * c;		/* compartments */
1451 
1452 	return (0);
1453 }
1454 
1455 /*
1456  * Format of useofpriv token:
1457  *	priv_type			adr_char
1458  *	priv_set_t			adr_short
1459  *	priv_set			adr_char*(sizeof (priv_set_t))
1460  */
1461 int
1462 useofpriv_token(parse_context_t *ctx)
1463 {
1464 	ctx->adr.adr_now += sizeof (char); /* success / fail */
1465 	skip_bytes(ctx);
1466 
1467 	return (0);
1468 }
1469