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