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