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