xref: /illumos-gate/usr/src/lib/auditd_plugins/syslog/systoken.c (revision 8d0c3d29bb99f6521f2dc5058a7e4debebad7899)
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 2010 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) { (void) 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  *	ip address	adr_u_char*type
419  *
420  */
421 int
422 ip_addr_ex_token(parse_context_t *ctx)
423 {
424 	int32_t	type;
425 
426 	adrm_int32(&(ctx->adr), &type, 1);		/* ip type */
427 	ctx->adr.adr_now += type * sizeof (uchar_t);	/* ip address */
428 
429 	return (0);
430 }
431 
432 /*
433  * Format of ip token:
434  *	ip header token id	adr_char
435  *	version			adr_char
436  *	type of service		adr_char
437  *	length			adr_short
438  *	id			adr_u_short
439  *	offset			adr_u_short
440  *	ttl			adr_char
441  *	protocol		adr_char
442  *	checksum		adr_u_short
443  *	source address		adr_int32
444  *	destination address	adr_int32
445  *
446  */
447 int
448 ip_token(parse_context_t *ctx)
449 {
450 	ctx->adr.adr_now += (2 * sizeof (char)) + (3 * sizeof (short)) +
451 	    (2 * sizeof (char)) + sizeof (short) + (2 * sizeof (int32_t));
452 	return (0);
453 }
454 
455 
456 /*
457  * Format of iport token:
458  *	ip port address token id	adr_char
459  *	port address			adr_short
460  *
461  */
462 int
463 iport_token(parse_context_t *ctx)
464 {
465 	ctx->adr.adr_now += sizeof (short);
466 
467 	return (0);
468 }
469 
470 
471 /*
472  * Format of groups token:
473  *	group token id		adr_char
474  *	group list		adr_int32, 16 times
475  *
476  */
477 int
478 group_token(parse_context_t *ctx)
479 {
480 	ctx->adr.adr_now += 16 * sizeof (int32_t);
481 
482 	return (0);
483 }
484 
485 /*
486  * Format of newgroups token:
487  *	group token id		adr_char
488  *	number of groups	adr_short
489  *	group list		adr_int32, "number" times
490  *
491  */
492 int
493 newgroup_token(parse_context_t *ctx)
494 {
495 	short int   number;
496 
497 	adrm_short(&(ctx->adr), &number, 1);
498 
499 	ctx->adr.adr_now += number * sizeof (int32_t);
500 
501 	return (0);
502 }
503 
504 /*
505  * Format of argument32 token:
506  *	argument token id	adr_char
507  *	argument number		adr_char
508  *	argument value		adr_int32
509  *	argument description	adr_string
510  *
511  */
512 int
513 argument32_token(parse_context_t *ctx)
514 {
515 	ctx->adr.adr_now += sizeof (char) + sizeof (int32_t);
516 	skip_bytes(ctx);
517 
518 	return (0);
519 }
520 
521 /*
522  * Format of argument64 token:
523  *	argument token id	adr_char
524  *	argument number		adr_char
525  *	argument value		adr_int64
526  *	argument description	adr_string
527  *
528  */
529 int
530 argument64_token(parse_context_t *ctx)
531 {
532 	ctx->adr.adr_now += sizeof (char) + sizeof (int64_t);
533 	skip_bytes(ctx);
534 
535 	return (0);
536 }
537 
538 /*
539  * Format of acl token:
540  * 	acl token id		adr_char
541  *	type			adr_u_int32
542  *	value			adr_u_int32
543  *	mode			adr_u_int32
544  */
545 int
546 acl_token(parse_context_t *ctx)
547 {
548 	ctx->adr.adr_now += 3 * sizeof (uint32_t);
549 
550 	return (0);
551 }
552 
553 /*
554  * Format of ace token:
555  * 	ace token id		adr_char
556  *	id			adr_u_int32
557  *	access_mask		adr_u_int32
558  *	flags			adr_u_short
559  *	type			adr_u_short
560  */
561 int
562 ace_token(parse_context_t *ctx)
563 {
564 	ctx->adr.adr_now += 2 * sizeof (uint32_t) + 2 * sizeof (ushort_t);
565 
566 	return (0);
567 }
568 
569 /*
570  * Format of attribute token: (old pre SunOS 5.7 format)
571  *	attribute token id	adr_char
572  * 	mode			adr_int32 (printed in octal)
573  *	uid			adr_int32
574  *	gid			adr_int32
575  *	file system id		adr_int32
576  *	node id			adr_int32
577  *	device			adr_int32
578  *
579  */
580 int
581 attribute_token(parse_context_t *ctx)
582 {
583 	ctx->adr.adr_now += 6 * sizeof (int32_t);
584 
585 	return (0);
586 }
587 
588 /*
589  * Format of attribute32 token:
590  *	attribute token id	adr_char
591  * 	mode			adr_int32 (printed in octal)
592  *	uid			adr_int32
593  *	gid			adr_int32
594  *	file system id		adr_int32
595  *	node id			adr_int64
596  *	device			adr_int32
597  *
598  */
599 int
600 attribute32_token(parse_context_t *ctx)
601 {
602 	ctx->adr.adr_now += (5 * sizeof (int32_t)) + sizeof (int64_t);
603 
604 	return (0);
605 }
606 
607 /*
608  * Format of attribute64 token:
609  *	attribute token id	adr_char
610  * 	mode			adr_int32 (printed in octal)
611  *	uid			adr_int32
612  *	gid			adr_int32
613  *	file system id		adr_int32
614  *	node id			adr_int64
615  *	device			adr_int64
616  *
617  */
618 int
619 attribute64_token(parse_context_t *ctx)
620 {
621 	ctx->adr.adr_now += (4 * sizeof (int32_t)) + (2 * sizeof (int64_t));
622 
623 	return (0);
624 }
625 
626 
627 /*
628  * Format of command token:
629  *	attribute token id	adr_char
630  *	argc			adr_short
631  *	argv len		adr_short	variable amount of argv len
632  *	argv text		argv len	and text
633  *	.
634  *	.
635  *	.
636  *	envp count		adr_short	variable amount of envp len
637  *	envp len		adr_short	and text
638  *	envp text		envp		len
639  *	.
640  *	.
641  *	.
642  *
643  */
644 int
645 cmd_token(parse_context_t *ctx)
646 {
647 	short	cnt;
648 	short	i;
649 
650 	adrm_short(&(ctx->adr), &cnt, 1);
651 
652 	for (i = 0; i < cnt; i++)
653 		skip_bytes(ctx);
654 
655 	adrm_short(&(ctx->adr), &cnt, 1);
656 
657 	for (i = 0; i < cnt; i++)
658 		skip_bytes(ctx);
659 
660 	return (0);
661 }
662 
663 
664 /*
665  * Format of exit token:
666  *	attribute token id	adr_char
667  *	return value		adr_int32
668  *	errno			adr_int32
669  *
670  */
671 int
672 exit_token(parse_context_t *ctx)
673 {
674 	int32_t	retval;
675 
676 	adrm_int32(&(ctx->adr), &retval, 1);
677 	ctx->adr.adr_now += sizeof (int32_t);
678 
679 	ctx->out.sf_pass = (retval == 0) ? 1 : -1;
680 	return (0);
681 }
682 
683 /*
684  * Format of exec_args token:
685  *	attribute token id	adr_char
686  *	count value		adr_int32
687  *	strings			null terminated strings
688  *
689  */
690 int
691 exec_args_token(parse_context_t *ctx)
692 {
693 	int count, i;
694 
695 	adrm_int32(&(ctx->adr), (int32_t *)&count, 1);
696 	for (i = 1; i <= count; i++) {
697 		skip_string(ctx);
698 	}
699 
700 	return (0);
701 }
702 
703 /*
704  * Format of exec_env token:
705  *	attribute token id	adr_char
706  *	count value		adr_int32
707  *	strings			null terminated strings
708  *
709  */
710 int
711 exec_env_token(parse_context_t *ctx)
712 {
713 	int count, i;
714 
715 	adrm_int32(&(ctx->adr), (int32_t *)&count, 1);
716 	for (i = 1; i <= count; i++)
717 		skip_string(ctx);
718 
719 	return (0);
720 }
721 
722 /*
723  * Format of liaison token:
724  */
725 int
726 liaison_token(parse_context_t *ctx)
727 {
728 	ctx->adr.adr_now += sizeof (int32_t);
729 
730 	return (0);
731 }
732 
733 
734 /*
735  * Format of path token:
736  *	path				adr_string
737  */
738 int
739 path_token(parse_context_t *ctx)
740 {
741 	get_bytes_to_string(ctx, &(ctx->out.sf_pathlen), &(ctx->out.sf_path),
742 	    0);
743 	if (ctx->out.sf_path == NULL)
744 		return (-1);
745 	/*
746 	 * anchor the path because collapse_path needs it
747 	 */
748 	if (*(ctx->out.sf_path) != '/') {
749 		anchor_path(ctx->out.sf_path);
750 		ctx->out.sf_pathlen++;
751 	}
752 	ctx->out.sf_pathlen = collapse_path(ctx->out.sf_path,
753 	    ctx->out.sf_pathlen);
754 
755 	return (0);
756 }
757 
758 /*
759  * path attr token / AUT_XATPATH
760  *
761  * Format of path attr token:
762  *	token id		adr_char
763  *	string count		adr_int32
764  *	strings			adr_string
765  *
766  * the sequence of strings is converted to a single string with
767  * a blank separator replacing the EOS for all but the last
768  * string.
769  */
770 int
771 path_attr_token(parse_context_t *ctx)
772 {
773 	int	count, i;
774 	int	last_len;
775 	size_t	offset;
776 	char	*p;
777 
778 	adrm_int32(&(ctx->adr), &count, 1);
779 
780 	offset = ctx->out.sf_atpathlen;
781 	p = ctx->adr.adr_now;
782 	for (i = 0; i <= count; i++) {
783 		last_len = strlen(p);
784 		ctx->out.sf_atpathlen += last_len + 1;
785 		p += last_len + 1;
786 	}
787 	ctx->out.sf_atpath = realloc(ctx->out.sf_atpath, ctx->out.sf_atpathlen);
788 	ctx->out.sf_atpath += offset;
789 	p = ctx->out.sf_atpath;		/* save for fix up, below */
790 	(void) memcpy(ctx->out.sf_atpath, ctx->adr.adr_now,
791 	    ctx->out.sf_atpathlen - offset);
792 	ctx->out.sf_atpathlen--;
793 
794 	/* fix up: replace each eos except the last with ' ' */
795 
796 	for (i = 0; i < count; i++) {
797 		while (*p++ != '\0')
798 			;
799 		*(p - 1) = ' ';
800 	}
801 	return (0);
802 }
803 
804 
805 /*
806  * Format of System V IPC permission token:
807  *	System V IPC permission token id	adr_char
808  * 	uid					adr_int32
809  *	gid					adr_int32
810  *	cuid					adr_int32
811  *	cgid					adr_int32
812  *	mode					adr_int32
813  *	seq					adr_int32
814  *	key					adr_int32
815  */
816 int
817 s5_IPC_perm_token(parse_context_t *ctx)
818 {
819 	ctx->adr.adr_now += (7 * sizeof (int32_t));
820 	return (0);
821 }
822 
823 static void
824 common_process(parse_context_t *ctx)
825 {
826 	int32_t	ruid, rgid, egid, pid;
827 	uint32_t asid;
828 
829 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_pauid), 1);
830 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_peuid), 1);
831 	adrm_int32(&(ctx->adr), &egid, 1);
832 	adrm_int32(&(ctx->adr), &ruid, 1);
833 	adrm_int32(&(ctx->adr), &rgid, 1);
834 	adrm_int32(&(ctx->adr), &pid, 1);
835 	adrm_u_int32(&(ctx->adr), &asid, 1);
836 }
837 
838 /*
839  * Format of process32 token:
840  *	process token id	adr_char
841  *	auid			adr_int32
842  *	euid			adr_int32
843  *	egid 			adr_int32
844  * 	ruid			adr_int32
845  *	rgid			adr_int32
846  * 	pid			adr_int32
847  * 	sid			adr_int32
848  * 	termid			adr_int32*2
849  *
850  */
851 int
852 process32_token(parse_context_t *ctx)
853 {
854 	int32_t port, machine;
855 
856 	common_process(ctx);
857 
858 	adrm_int32(&(ctx->adr), &port, 1);
859 	adrm_int32(&(ctx->adr), &machine, 1);
860 
861 	return (0);
862 }
863 
864 /*
865  * Format of process32_ex token:
866  *	process token id	adr_char
867  *	auid			adr_int32
868  *	euid			adr_int32
869  *	egid 			adr_int32
870  * 	ruid			adr_int32
871  *	rgid			adr_int32
872  * 	pid			adr_int32
873  * 	sid			adr_int32
874  * 	termid
875  *		port		adr_int32
876  *		type		adr_int32
877  *		ip address	adr_u_char*type
878  *
879  */
880 int
881 process32_ex_token(parse_context_t *ctx)
882 {
883 	int32_t port, type;
884 	uchar_t addr[16];
885 
886 	common_process(ctx);
887 
888 	adrm_int32(&(ctx->adr), &port, 1);
889 	adrm_int32(&(ctx->adr), &type, 1);
890 	adrm_u_char(&(ctx->adr), addr, type);
891 
892 	return (0);
893 }
894 
895 /*
896  * Format of process64 token:
897  *	process token id	adr_char
898  *	auid			adr_int32
899  *	euid			adr_int32
900  *	egid 			adr_int32
901  * 	ruid			adr_int32
902  *	rgid			adr_int32
903  * 	pid			adr_int32
904  * 	sid			adr_int32
905  * 	termid			adr_int64+adr_int32
906  *
907  */
908 int
909 process64_token(parse_context_t *ctx)
910 {
911 	int64_t port;
912 	int32_t machine;
913 
914 	common_process(ctx);
915 
916 	adrm_int64(&(ctx->adr), &port, 1);
917 	adrm_int32(&(ctx->adr), &machine, 1);
918 
919 	return (0);
920 }
921 
922 /*
923  * Format of process64_ex token:
924  *	process token id	adr_char
925  *	auid			adr_int32
926  *	euid			adr_int32
927  *	egid 			adr_int32
928  * 	ruid			adr_int32
929  *	rgid			adr_int32
930  * 	pid			adr_int32
931  * 	sid			adr_int32
932  * 	termid
933  *		port		adr_int64
934  *		type		adr_int32
935  *		ip address	adr_u_char*type
936  *
937  */
938 int
939 process64_ex_token(parse_context_t *ctx)
940 {
941 	int64_t port;
942 	int32_t type;
943 	uchar_t	addr[16];
944 
945 	common_process(ctx);
946 
947 	adrm_int64(&(ctx->adr), &port, 1);
948 	adrm_int32(&(ctx->adr), &type, 1);
949 	adrm_u_char(&(ctx->adr), addr, type);
950 
951 	return (0);
952 }
953 
954 /*
955  * Format of System V IPC token:
956  *	System V IPC token id	adr_char
957  *	System V IPC type	adr_char
958  *	object id		adr_int32
959  *
960  */
961 int
962 s5_IPC_token(parse_context_t *ctx)
963 {
964 	ctx->adr.adr_now += sizeof (char);
965 	ctx->adr.adr_now += sizeof (int32_t);
966 
967 	return (0);
968 }
969 
970 
971 /*
972  * Format of socket token:
973  *	socket_type		adrm_short
974  *	remote_port		adrm_short
975  *	remote_inaddr		adrm_int32
976  *
977  */
978 int
979 socket_token(parse_context_t *ctx)
980 {
981 	ctx->adr.adr_now += (2 * sizeof (short)) + sizeof (int32_t);
982 
983 	return (0);
984 }
985 
986 
987 /*
988  * Format of socket_ex token:
989  *	socket_domain		adrm_short
990  *	socket_type		adrm_short
991  *	address_type		adrm_short
992  *	local_port		adrm_short
993  *	local_inaddr		adrm_u_char*address_type
994  *	remote_port		adrm_short
995  *	remote_inaddr		adrm_u_char*address_type
996  *
997  */
998 int
999 socket_ex_token(parse_context_t *ctx)
1000 {
1001 	short	ip_size;
1002 
1003 	ctx->adr.adr_now += (2 * sizeof (short));
1004 	adrm_short(&(ctx->adr), &ip_size, 1);
1005 
1006 	ctx->adr.adr_now += sizeof (short) + (ip_size * sizeof (char)) +
1007 	    sizeof (short) + (ip_size * sizeof (char));
1008 	return (0);
1009 }
1010 
1011 
1012 static void
1013 common_subject(parse_context_t *ctx)
1014 {
1015 	int32_t	ruid, rgid, pid;
1016 
1017 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_auid), 1);
1018 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_euid), 1);
1019 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_egid), 1);
1020 	adrm_int32(&(ctx->adr), &ruid, 1);
1021 	adrm_int32(&(ctx->adr), &rgid, 1);
1022 	adrm_int32(&(ctx->adr), &pid, 1);
1023 	adrm_u_int32(&(ctx->adr), (uint32_t *)&(ctx->out.sf_asid), 1);
1024 }
1025 
1026 /*
1027  * Format of subject32 token:
1028  *	subject token id	adr_char
1029  *	auid			adr_int32
1030  *	euid			adr_int32
1031  *	egid 			adr_int32
1032  * 	ruid			adr_int32
1033  *	rgid			adr_int32
1034  * 	pid			adr_int32
1035  * 	sid			adr_int32
1036  * 	termid			adr_int32*2
1037  *
1038  */
1039 int
1040 subject32_token(parse_context_t *ctx)
1041 {
1042 	int32_t port;	/* not used in output */
1043 
1044 	common_subject(ctx);
1045 
1046 	adrm_int32(&(ctx->adr), &port, 1);
1047 	ctx->out.sf_tid.at_type = AU_IPv4;
1048 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 4);
1049 
1050 	return (0);
1051 }
1052 
1053 /*
1054  * Format of subject32_ex token:
1055  *	subject token id	adr_char
1056  *	auid			adr_int32
1057  *	euid			adr_int32
1058  *	egid 			adr_int32
1059  * 	ruid			adr_int32
1060  *	rgid			adr_int32
1061  * 	pid			adr_int32
1062  * 	sid			adr_int32
1063  * 	termid
1064  *		port		adr_int32
1065  *		type		adr_int32
1066  *		ip address	adr_u_char*type
1067  *
1068  */
1069 int
1070 subject32_ex_token(parse_context_t *ctx)
1071 {
1072 	int32_t port;	/* not used in output */
1073 
1074 	common_subject(ctx);
1075 
1076 	adrm_int32(&(ctx->adr), &port, 1);
1077 	adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1);
1078 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]),
1079 	    ctx->out.sf_tid.at_type);
1080 
1081 	return (0);
1082 }
1083 
1084 /*
1085  * Format of subject64 token:
1086  *	subject token id	adr_char
1087  *	auid			adr_int32
1088  *	euid			adr_int32
1089  *	egid 			adr_int32
1090  * 	ruid			adr_int32
1091  *	rgid			adr_int32
1092  * 	pid			adr_int32
1093  * 	sid			adr_int32
1094  * 	termid			adr_int64+adr_int32
1095  *
1096  */
1097 int
1098 subject64_token(parse_context_t *ctx)
1099 {
1100 	int64_t port;
1101 
1102 	common_subject(ctx);
1103 
1104 	adrm_int64(&(ctx->adr), &port, 1);
1105 	ctx->out.sf_tid.at_type = AU_IPv4;
1106 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]), 4);
1107 
1108 	return (0);
1109 }
1110 
1111 /*
1112  * Format of subject64_ex token:
1113  *	subject token id	adr_char
1114  *	auid			adr_int32
1115  *	euid			adr_int32
1116  *	egid 			adr_int32
1117  * 	ruid			adr_int32
1118  *	rgid			adr_int32
1119  * 	pid			adr_int32
1120  * 	sid			adr_int32
1121  * 	termid
1122  *		port		adr_int64
1123  *		type		adr_int32
1124  *		ip address	adr_u_char*type
1125  *
1126  */
1127 int
1128 subject64_ex_token(parse_context_t *ctx)
1129 {
1130 	int64_t port;
1131 
1132 	common_subject(ctx);
1133 
1134 	adrm_int64(&(ctx->adr), &port, 1);
1135 	adrm_u_int32(&(ctx->adr), &(ctx->out.sf_tid.at_type), 1);
1136 	adrm_u_char(&(ctx->adr), (uchar_t *)&(ctx->out.sf_tid.at_addr[0]),
1137 	    ctx->out.sf_tid.at_type);
1138 
1139 	return (0);
1140 }
1141 
1142 
1143 int
1144 xatom_token(parse_context_t *ctx)
1145 {
1146 	skip_bytes(ctx);
1147 
1148 	return (0);
1149 }
1150 
1151 
1152 int
1153 xselect_token(parse_context_t *ctx)
1154 {
1155 	skip_bytes(ctx);
1156 	skip_bytes(ctx);
1157 	skip_bytes(ctx);
1158 
1159 	return (0);
1160 }
1161 
1162 /*
1163  * anchor a path name with a slash
1164  * assume we have enough space
1165  */
1166 static void
1167 anchor_path(char *path)
1168 {
1169 
1170 	(void) memmove((void *)(path + 1), (void *)path, strlen(path) + 1);
1171 	*path = '/';
1172 }
1173 
1174 
1175 /*
1176  * copy path to collapsed path.
1177  * collapsed path does not contain:
1178  *	successive slashes
1179  *	instances of dot-slash
1180  *	instances of dot-dot-slash
1181  * passed path must be anchored with a '/'
1182  */
1183 static size_t
1184 collapse_path(char *s, size_t ls)
1185 {
1186 	int	id;	/* index of where we are in destination string */
1187 	int	is;	/* index of where we are in source string */
1188 	int	slashseen;	/* have we seen a slash */
1189 
1190 	ls++; /* source length including '\0' */
1191 
1192 	slashseen = 0;
1193 	for (is = 0, id = 0; is < ls; is++) {
1194 		if (s[is] == '\0') {
1195 			if (id > 1 && s[id-1] == '/') {
1196 				--id;
1197 			}
1198 			s[id++] = '\0';
1199 			break;
1200 		}
1201 		/* previous character was a / */
1202 		if (slashseen) {
1203 			if (s[is] == '/')
1204 				continue;	/* another slash, ignore it */
1205 		} else if (s[is] == '/') {
1206 			/* we see a /, just copy it and try again */
1207 			slashseen = 1;
1208 			s[id++] = '/';
1209 			continue;
1210 		}
1211 		/* /./ seen */
1212 		if (s[is] == '.' && s[is+1] == '/') {
1213 			is += 1;
1214 			continue;
1215 		}
1216 		/* XXX/. seen */
1217 		if (s[is] == '.' && s[is+1] == '\0') {
1218 			if (id > 1)
1219 				id--;
1220 			continue;
1221 		}
1222 		/* XXX/.. seen */
1223 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') {
1224 			is += 1;
1225 			if (id > 0)
1226 				id--;
1227 			while (id > 0 && s[--id] != '/')
1228 				;
1229 			id++;
1230 			continue;
1231 		}
1232 		/* XXX/../ seen */
1233 		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
1234 			is += 2;
1235 			if (id > 0)
1236 				id--;
1237 			while (id > 0 && s[--id] != '/')
1238 				;
1239 			id++;
1240 			continue;
1241 		}
1242 		while (is < ls && (s[id++] = s[is++]) != '/')
1243 			;
1244 		is--;
1245 	}
1246 	return ((size_t)id - 1);
1247 }
1248 
1249 /*
1250  * for tokens with sub-fields that include a length, this
1251  * skips the sub-field.
1252  */
1253 
1254 static void
1255 skip_bytes(parse_context_t *ctx)
1256 {
1257 	ushort_t	c;
1258 
1259 	adrm_u_short(&(ctx->adr), &c, 1);
1260 	ctx->adr.adr_now += c;
1261 }
1262 
1263 static void
1264 skip_string(parse_context_t *ctx)
1265 {
1266 	char	c;
1267 
1268 	do {
1269 		adrm_char(&(ctx->adr), &c, 1);
1270 	} while (c != (char)0);
1271 }
1272 
1273 /*
1274  * add a byte to specified length so there can be a prefix of
1275  * '/' added (if needed for paths).  Another is added for '\0'
1276  *
1277  * if offset is zero, new data overwrites old, if any.  Otherwise
1278  * new data is appended to the end.
1279  */
1280 
1281 static void
1282 get_bytes_to_string(parse_context_t *ctx, size_t *l, char **p,
1283     size_t offset)
1284 {
1285 	ushort_t	len;
1286 	char		*bp;
1287 
1288 	adrm_u_short(&(ctx->adr), &len, 1);
1289 
1290 	len++;	/* in case need to add '/' prefix */
1291 	*p = realloc(*p, 1 + (size_t)len + offset);
1292 	if (*p == NULL) {
1293 		perror("audit_sysudp.so");
1294 		return;
1295 	}
1296 	if (offset > 0)
1297 		offset--;	/* overwrite end of string */
1298 
1299 	*l = (size_t)len - 2 + offset;
1300 
1301 	bp = *p + offset;
1302 	adrm_char(&(ctx->adr), bp, len - 1);
1303 	*(bp + len - 1) = '\0';
1304 }
1305 
1306 
1307 /*
1308  * Format of host token:
1309  *	host  		adr_uint32
1310  */
1311 int
1312 host_token(parse_context_t *ctx)
1313 {
1314 	ctx->adr.adr_now += sizeof (int32_t);
1315 
1316 	return (0);
1317 }
1318 
1319 /*
1320  * Format of useofauth token:
1321  *	uauth token id		adr_char
1322  * 	uauth			adr_string
1323  *
1324  */
1325 int
1326 useofauth_token(parse_context_t *ctx)
1327 {
1328 	get_bytes_to_string(ctx, &(ctx->out.sf_uauthlen),
1329 	    &(ctx->out.sf_uauth), 0);
1330 
1331 	return (0);
1332 }
1333 
1334 /*
1335  * Format of user token:
1336  *	user token id		adr_char
1337  *	uid			adr_uid
1338  * 	username		adr_string
1339  *
1340  */
1341 int
1342 user_token(parse_context_t *ctx)
1343 {
1344 	ctx->adr.adr_now += sizeof (uid_t);
1345 	skip_bytes(ctx);
1346 
1347 	return (0);
1348 }
1349 
1350 /*
1351  * Format of zonename token:
1352  *	zonename token id		adr_char
1353  * 	zonename			adr_string
1354  *
1355  */
1356 int
1357 zonename_token(parse_context_t *ctx)
1358 {
1359 	get_bytes_to_string(ctx,
1360 	    &(ctx->out.sf_zonelen),
1361 	    &(ctx->out.sf_zonename),
1362 	    0);
1363 
1364 	return (0);
1365 }
1366 
1367 /*
1368  * Format of fmri token:
1369  *	fmri token id		adr_char
1370  *	fmri			adr_string
1371  */
1372 int
1373 fmri_token(parse_context_t *ctx)
1374 {
1375 	skip_bytes(ctx);
1376 
1377 	return (0);
1378 }
1379 
1380 int
1381 xcolormap_token(parse_context_t *ctx)
1382 {
1383 	return (xgeneric(ctx));
1384 }
1385 
1386 int
1387 xcursor_token(parse_context_t *ctx)
1388 {
1389 	return (xgeneric(ctx));
1390 }
1391 
1392 int
1393 xfont_token(parse_context_t *ctx)
1394 {
1395 	return (xgeneric(ctx));
1396 }
1397 
1398 int
1399 xgc_token(parse_context_t *ctx)
1400 {
1401 	return (xgeneric(ctx));
1402 }
1403 
1404 int
1405 xpixmap_token(parse_context_t *ctx)
1406 {
1407 	return (xgeneric(ctx));
1408 }
1409 
1410 int
1411 xwindow_token(parse_context_t *ctx)
1412 {
1413 	return (xgeneric(ctx));
1414 }
1415 /*
1416  * Format of xgeneric token:
1417  *	XID			adr_int32
1418  *	creator UID		adr_int32
1419  *
1420  * Includes:  xcolormap, xcursor, xfont, xgc, xpixmap, and xwindow
1421  */
1422 static int
1423 xgeneric(parse_context_t *ctx)
1424 {
1425 	ctx->adr.adr_now += 2 * sizeof (int32_t);
1426 
1427 	return (0);
1428 }
1429 /*
1430  * Format of xproperty token:
1431  *	XID			adr_int32
1432  *	creator UID		adr_int32
1433  *	atom string		adr_string
1434  */
1435 int
1436 xproperty_token(parse_context_t *ctx)
1437 {
1438 	ctx->adr.adr_now += 2 * sizeof (int32_t);
1439 
1440 	return (0);
1441 }
1442 /*
1443  * Format of xclient token:
1444  * 	xclient id		adr_int32
1445  */
1446 int
1447 xclient_token(parse_context_t *ctx)
1448 {
1449 	ctx->adr.adr_now += sizeof (int32_t);
1450 
1451 	return (0);
1452 }
1453 
1454 /*
1455  * -----------------------------------------------------------------------
1456  * privilege_token()	: Process privilege token and display contents
1457  *
1458  * Format of privilege token:
1459  *	privilege token id	adr_char
1460  *	privilege type		adr_string
1461  *	privilege		adr_string
1462  * -----------------------------------------------------------------------
1463  */
1464 
1465 int
1466 privilege_token(parse_context_t *ctx)
1467 {
1468 	skip_bytes(ctx);
1469 	skip_bytes(ctx);
1470 
1471 	return (0);
1472 }
1473 
1474 
1475 /*
1476  * Format of label token:
1477  *	label ID                1 byte
1478  *	compartment length      1 byte
1479  *	classification          2 bytes
1480  *	compartment words       <compartment length> * 4 bytes
1481  */
1482 int
1483 label_token(parse_context_t *ctx)
1484 {
1485 	char	c;
1486 
1487 	ctx->adr.adr_now += sizeof (char);	/* label ID */
1488 	adrm_char(&(ctx->adr), &c, 1);
1489 
1490 	ctx->adr.adr_now += sizeof (ushort_t);	/* classification */
1491 	ctx->adr.adr_now += 4 * c;		/* compartments */
1492 
1493 	return (0);
1494 }
1495 
1496 /*
1497  * Format of useofpriv token:
1498  *	priv_type			adr_char
1499  *	priv_set_t			adr_short
1500  *	priv_set			adr_char*(sizeof (priv_set_t))
1501  */
1502 int
1503 useofpriv_token(parse_context_t *ctx)
1504 {
1505 	ctx->adr.adr_now += sizeof (char); /* success / fail */
1506 	skip_bytes(ctx);
1507 
1508 	return (0);
1509 }
1510