1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23 * Use is subject to license terms.
24 * Copyright 2012 Milan Jurik. All rights reserved.
25 */
26
27
28/*
29 * Token processing for auditreduce.
30 */
31
32#include <locale.h>
33#include <sys/zone.h>
34#include "auditr.h"
35#include "toktable.h"
36
37extern int	re_exec2(char *);
38
39static void	anchor_path(char *path);
40static char	*collapse_path(char *s);
41static void	get_string(adr_t *adr, char **p);
42static int	ipc_type_match(int flag, char type);
43static void	skip_string(adr_t *adr);
44static int	xgeneric(adr_t *adr);
45
46#if	AUDIT_REC
47void
48print_id(int id)
49{
50	char *suffix;
51
52	if ((id < 0) || (id > MAXTOKEN) ||
53	    (tokentable[id].func == NOFUNC)) {
54		(void) fprintf(stderr,
55		    "token_processing: token %d not found\n", id);
56		return;
57	}
58
59	switch (id) {
60	case AUT_NEWGROUPS:
61		suffix = "_new";
62		break;
63	case AUT_ATTR32:
64		suffix = "32";
65		break;
66	case AUT_ARG64:
67	case AUT_RETURN64:
68	case AUT_ATTR64:
69	case AUT_HEADER64:
70	case AUT_SUBJECT64:
71	case AUT_PROCESS64:
72	case AUT_OTHER_FILE64:
73		suffix = "64";
74		break;
75	case AUT_SOCKET_EX:
76	case AUT_IN_ADDR_EX:
77		suffix = "_ex";
78		break;
79	case AUT_HEADER32_EX:
80	case AUT_SUBJECT32_EX:
81	case AUT_PROCESS32_EX:
82		suffix = "32_ex";
83		break;
84	case AUT_HEADER64_EX:
85	case AUT_SUBJECT64_EX:
86	case AUT_PROCESS64_EX:
87		suffix = "64_ex";
88		break;
89	default:
90		suffix = "";
91		break;
92	}
93	(void) fprintf(stderr, "token_processing: %s%s\n",
94	    tokentable[id].t_name, suffix);
95}
96#endif	/* AUDIT_REC */
97
98/*
99 * Process a token in a record to determine whether the record is interesting.
100 */
101
102int
103token_processing(adr_t *adr, int tokenid)
104{
105	if ((tokenid > 0) && (tokenid <= MAXTOKEN) &&
106	    (tokentable[tokenid].func != NOFUNC)) {
107#if	AUDIT_REC
108		print_id(tokenid);
109#endif	/* AUDIT_REC */
110		return ((*tokentable[tokenid].func)(adr));
111	}
112
113	/* here if token id is not in table */
114	return (-2);
115}
116
117
118/* There should not be any file or header tokens in the middle of a record */
119
120/* ARGSUSED */
121int
122file_token(adr_t *adr)
123{
124	return (-2);
125}
126
127/* ARGSUSED */
128int
129file64_token(adr_t *adr)
130{
131	return (-2);
132}
133
134/* ARGSUSED */
135int
136header_token(adr_t *adr)
137{
138	return (-2);
139}
140
141/* ARGSUSED */
142int
143header32_ex_token(adr_t *adr)
144{
145	return (-2);
146}
147
148/* ARGSUSED */
149int
150header64_ex_token(adr_t *adr)
151{
152	return (-2);
153}
154
155/* ARGSUSED */
156int
157header64_token(adr_t *adr)
158{
159	return (-2);
160}
161
162
163/*
164 * ======================================================
165 *  The following token processing routines return
166 *  -1: if the record is not interesting
167 *  -2: if an error is found
168 * ======================================================
169 */
170
171int
172trailer_token(adr_t *adr)
173{
174	short	magic_number;
175	uint32_t bytes;
176
177	adrm_u_short(adr, (ushort_t *)&magic_number, 1);
178	if (magic_number != AUT_TRAILER_MAGIC) {
179		(void) fprintf(stderr, "%s\n",
180		    gettext("auditreduce: Bad trailer token"));
181		return (-2);
182	}
183	adrm_u_int32(adr, &bytes, 1);
184
185	return (-1);
186}
187
188
189/*
190 * Format of arbitrary data token:
191 *	arbitrary data token id	adr char
192 * 	how to print		adr_char
193 *	basic unit		adr_char
194 *	unit count		adr_char, specifying number of units of
195 *	data items		depends on basic unit
196 */
197int
198arbitrary_data_token(adr_t *adr)
199{
200	int	i;
201	char	c1;
202	short	c2;
203	int32_t	c3;
204	int64_t c4;
205	char	how_to_print, basic_unit, unit_count;
206
207	/* get how_to_print, basic_unit, and unit_count */
208	adrm_char(adr, &how_to_print, 1);
209	adrm_char(adr, &basic_unit, 1);
210	adrm_char(adr, &unit_count, 1);
211	for (i = 0; i < unit_count; i++) {
212		switch (basic_unit) {
213			/* case AUR_BYTE: has same value as AUR_CHAR */
214		case AUR_CHAR:
215			adrm_char(adr, &c1, 1);
216			break;
217		case AUR_SHORT:
218			adrm_short(adr, &c2, 1);
219			break;
220		case AUR_INT32:
221			adrm_int32(adr, (int32_t *)&c3, 1);
222			break;
223		case AUR_INT64:
224			adrm_int64(adr, (int64_t *)&c4, 1);
225			break;
226		default:
227			return (-2);
228		}
229	}
230	return (-1);
231}
232
233
234/*
235 * Format of opaque token:
236 *	opaque token id		adr_char
237 *	size			adr_short
238 *	data			adr_char, size times
239 */
240int
241opaque_token(adr_t *adr)
242{
243	skip_string(adr);
244	return (-1);
245}
246
247
248
249/*
250 * Format of return32 value token:
251 * 	return value token id	adr_char
252 *	error number		adr_char
253 *	return value		adr_u_int32
254 */
255int
256return_value32_token(adr_t *adr)
257{
258	char		errnum;
259	uint32_t	value;
260
261	adrm_char(adr, &errnum, 1);
262	adrm_u_int32(adr, &value, 1);
263	if ((flags & M_SORF) &&
264	    ((global_class & mask.am_success) && (errnum == 0)) ||
265	    ((global_class & mask.am_failure) && (errnum != 0))) {
266		checkflags |= M_SORF;
267	}
268	return (-1);
269}
270
271/*
272 * Format of return64 value token:
273 * 	return value token id	adr_char
274 *	error number		adr_char
275 *	return value		adr_u_int64
276 */
277int
278return_value64_token(adr_t *adr)
279{
280	char		errnum;
281	uint64_t	value;
282
283	adrm_char(adr, &errnum, 1);
284	adrm_u_int64(adr, &value, 1);
285	if ((flags & M_SORF) &&
286	    ((global_class & mask.am_success) && (errnum == 0)) ||
287	    ((global_class & mask.am_failure) && (errnum != 0))) {
288		checkflags |= M_SORF;
289	}
290	return (-1);
291}
292
293
294/*
295 * Format of sequence token:
296 *	sequence token id	adr_char
297 *	audit_count		int32_t
298 */
299int
300sequence_token(adr_t *adr)
301{
302	int32_t	audit_count;
303
304	adrm_int32(adr, &audit_count, 1);
305	return (-1);
306}
307
308
309/*
310 * Format of text token:
311 *	text token id		adr_char
312 * 	text			adr_string
313 */
314int
315text_token(adr_t *adr)
316{
317	skip_string(adr);
318	return (-1);
319}
320
321
322/*
323 * Format of ip_addr token:
324 *	ip token id	adr_char
325 *	address		adr_int32
326 */
327int
328ip_addr_token(adr_t *adr)
329{
330	int32_t	address;
331
332	adrm_char(adr, (char *)&address, 4);
333
334	return (-1);
335}
336
337/*
338 * Format of ip_addr_ex token:
339 *	ip token id	adr_char
340 *	ip type		adr_int32
341 *	ip address	adr_u_char*type
342 */
343int
344ip_addr_ex_token(adr_t *adr)
345{
346	int32_t type;
347	uchar_t	address[16];
348
349	adrm_int32(adr, (int32_t *)&type, 1);
350	adrm_u_char(adr, address, type);
351
352	return (-1);
353}
354
355/*
356 * Format of ip token:
357 *	ip header token id	adr_char
358 *	version			adr_char
359 *	type of service		adr_char
360 *	length			adr_short
361 *	id			adr_u_short
362 *	offset			adr_u_short
363 *	ttl			adr_char
364 *	protocol		adr_char
365 *	checksum		adr_u_short
366 *	source address		adr_int32
367 *	destination address	adr_int32
368 */
369int
370ip_token(adr_t *adr)
371{
372	char	version;
373	char	type;
374	short	len;
375	unsigned short	id, offset, checksum;
376	char	ttl, protocol;
377	int32_t	src, dest;
378
379	adrm_char(adr, &version, 1);
380	adrm_char(adr, &type, 1);
381	adrm_short(adr, &len, 1);
382	adrm_u_short(adr, &id, 1);
383	adrm_u_short(adr, &offset, 1);
384	adrm_char(adr, &ttl, 1);
385	adrm_char(adr, &protocol, 1);
386	adrm_u_short(adr, &checksum, 1);
387	adrm_char(adr, (char *)&src, 4);
388	adrm_char(adr, (char *)&dest, 4);
389
390	return (-1);
391}
392
393
394/*
395 * Format of iport token:
396 *	ip port address token id	adr_char
397 *	port address			adr_short
398 */
399int
400iport_token(adr_t *adr)
401{
402	short	address;
403
404	adrm_short(adr, &address, 1);
405
406	return (-1);
407}
408
409
410/*
411 * Format of groups token:
412 *	group token id		adr_char
413 *	group list		adr_int32, 16 times
414 */
415int
416group_token(adr_t *adr)
417{
418	int	gid[16];
419	int	i;
420	int	flag = 0;
421
422	for (i = 0; i < 16; i++) {
423		adrm_int32(adr, (int32_t *)&gid[i], 1);
424		if (flags & M_GROUPR) {
425			if ((unsigned short)m_groupr == gid[i])
426				flag = 1;
427		}
428	}
429
430	if (flags & M_GROUPR) {
431		if (flag)
432			checkflags |= M_GROUPR;
433	}
434	return (-1);
435}
436
437/*
438 * Format of newgroups token:
439 *	group token id		adr_char
440 *	number of groups	adr_short
441 *	group list		adr_int32, "number" times
442 */
443int
444newgroup_token(adr_t *adr)
445{
446	gid_t	gid;
447	int	i;
448	short int   number;
449
450	adrm_short(adr, &number, 1);
451
452	for (i = 0; i < number; i++) {
453		adrm_int32(adr, (int32_t *)&gid, 1);
454		if (flags & M_GROUPR) {
455			if (m_groupr == gid)
456				checkflags |= M_GROUPR;
457		}
458	}
459
460	return (-1);
461}
462
463/*
464 * Format of argument32 token:
465 *	argument token id	adr_char
466 *	argument number		adr_char
467 *	argument value		adr_int32
468 *	argument description	adr_string
469 */
470int
471argument32_token(adr_t *adr)
472{
473	char	arg_num;
474	int32_t	arg_val;
475
476	adrm_char(adr, &arg_num, 1);
477	adrm_int32(adr, &arg_val, 1);
478	skip_string(adr);
479
480	return (-1);
481}
482
483/*
484 * Format of argument64 token:
485 *	argument token id	adr_char
486 *	argument number		adr_char
487 *	argument value		adr_int64
488 *	argument description	adr_string
489 */
490int
491argument64_token(adr_t *adr)
492{
493	char	arg_num;
494	int64_t	arg_val;
495
496	adrm_char(adr, &arg_num, 1);
497	adrm_int64(adr, &arg_val, 1);
498	skip_string(adr);
499
500	return (-1);
501}
502
503/*
504 * Format of acl token:
505 *	acl token id		adr_char
506 *	acl type		adr_u_int32
507 *	acl value		adr_u_int32 (depends on type)
508 *	file mode		adr_u_int (in octal)
509 */
510int
511acl_token(adr_t *adr)
512{
513
514	int32_t	id;
515	int32_t	mode;
516	int32_t	type;
517
518	adrm_int32(adr, &type, 1);
519	adrm_int32(adr, &id, 1);
520	adrm_int32(adr, &mode, 1);
521
522	return (-1);
523}
524
525/*
526 * Format of ace token:
527 *	ace token id		adr_char
528 *	ace who			adr_u_int32 (uid/gid)
529 *	access mask		adr_u_int32
530 *	ace flags		adr_u_int16
531 *	ace type		adr_u_int16
532 */
533int
534ace_token(adr_t *adr)
535{
536	uid_t		who;
537	uint32_t	access_mask;
538	uint16_t	flags, type;
539
540	adrm_uid(adr, &who, 1);
541	adrm_u_int32(adr, &access_mask, 1);
542	adrm_u_short(adr, &flags, 1);
543	adrm_u_short(adr, &type, 1);
544
545	return (-1);
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 */
558int
559attribute_token(adr_t *adr)
560{
561	int32_t	dev;
562	int32_t	file_sysid;
563	int32_t	gid;
564	int32_t	mode;
565	int32_t	nodeid;
566	int32_t	uid;
567
568	adrm_int32(adr, &mode, 1);
569	adrm_int32(adr, &uid, 1);
570	adrm_int32(adr, &gid, 1);
571	adrm_int32(adr, &file_sysid, 1);
572	adrm_int32(adr, &nodeid, 1);
573	adrm_int32(adr, &dev, 1);
574
575	if (!new_mode && (flags & M_USERE)) {
576		if (m_usere == uid)
577			checkflags |= M_USERE;
578	}
579	if (!new_mode && (flags & M_GROUPE)) {
580		if (m_groupe == gid)
581			checkflags |= M_GROUPE;
582	}
583
584	if (flags & M_OBJECT) {
585		if ((obj_flag & OBJ_FGROUP) &&
586		    (obj_group == gid))
587			checkflags |= M_OBJECT;
588		else if ((obj_flag & OBJ_FOWNER) &&
589		    (obj_owner == uid))
590			checkflags |= M_OBJECT;
591	}
592	return (-1);
593}
594
595/*
596 * Format of attribute32 token:
597 *	attribute token id	adr_char
598 * 	mode			adr_int32 (printed in octal)
599 *	uid			adr_int32
600 *	gid			adr_int32
601 *	file system id		adr_int32
602 *	node id			adr_int64
603 *	device			adr_int32
604 */
605int
606attribute32_token(adr_t *adr)
607{
608	int32_t	dev;
609	int32_t	file_sysid;
610	int32_t	gid;
611	int32_t	mode;
612	int64_t	nodeid;
613	int32_t	uid;
614
615	adrm_int32(adr, &mode, 1);
616	adrm_int32(adr, &uid, 1);
617	adrm_int32(adr, &gid, 1);
618	adrm_int32(adr, &file_sysid, 1);
619	adrm_int64(adr, &nodeid, 1);
620	adrm_int32(adr, &dev, 1);
621
622	if (!new_mode && (flags & M_USERE)) {
623		if (m_usere == uid)
624			checkflags |= M_USERE;
625	}
626	if (!new_mode && (flags & M_GROUPE)) {
627		if (m_groupe == gid)
628			checkflags |= M_GROUPE;
629	}
630
631	if (flags & M_OBJECT) {
632		if ((obj_flag & OBJ_FGROUP) &&
633		    (obj_group == gid))
634			checkflags |= M_OBJECT;
635		else if ((obj_flag & OBJ_FOWNER) &&
636		    (obj_owner == uid))
637			checkflags |= M_OBJECT;
638	}
639	return (-1);
640}
641
642/*
643 * Format of attribute64 token:
644 *	attribute token id	adr_char
645 * 	mode			adr_int32 (printed in octal)
646 *	uid			adr_int32
647 *	gid			adr_int32
648 *	file system id		adr_int32
649 *	node id			adr_int64
650 *	device			adr_int64
651 */
652int
653attribute64_token(adr_t *adr)
654{
655	int64_t	dev;
656	int32_t	file_sysid;
657	int32_t	gid;
658	int32_t	mode;
659	int64_t	nodeid;
660	int32_t	uid;
661
662	adrm_int32(adr, &mode, 1);
663	adrm_int32(adr, &uid, 1);
664	adrm_int32(adr, &gid, 1);
665	adrm_int32(adr, &file_sysid, 1);
666	adrm_int64(adr, &nodeid, 1);
667	adrm_int64(adr, &dev, 1);
668
669	if (!new_mode && (flags & M_USERE)) {
670		if (m_usere == uid)
671			checkflags |= M_USERE;
672	}
673	if (!new_mode && (flags & M_GROUPE)) {
674		if (m_groupe == gid)
675			checkflags |= M_GROUPE;
676	}
677
678	if (flags & M_OBJECT) {
679		if ((obj_flag & OBJ_FGROUP) &&
680		    (obj_group == gid))
681			checkflags |= M_OBJECT;
682		else if ((obj_flag & OBJ_FOWNER) &&
683		    (obj_owner == uid))
684			checkflags |= M_OBJECT;
685	}
686	return (-1);
687}
688
689
690/*
691 * Format of command token:
692 *	attribute token id	adr_char
693 *	argc			adr_short
694 *	argv len		adr_short	variable amount of argv len
695 *	argv text		argv len	and text
696 *	.
697 *	.
698 *	.
699 *	envp count		adr_short	variable amount of envp len
700 *	envp len		adr_short	and text
701 *	envp text		envp		len
702 *	.
703 *	.
704 *	.
705 */
706int
707cmd_token(adr_t *adr)
708{
709	short	cnt;
710	short	i;
711
712	adrm_short(adr, &cnt, 1);
713
714	for (i = 0; i < cnt; i++)
715		skip_string(adr);
716
717	adrm_short(adr, &cnt, 1);
718
719	for (i = 0; i < cnt; i++)
720		skip_string(adr);
721
722	return (-1);
723}
724
725
726/*
727 * Format of exit token:
728 *	attribute token id	adr_char
729 *	return value		adr_int32
730 *	errno			adr_int32
731 */
732int
733exit_token(adr_t *adr)
734{
735	int32_t	retval;
736	int32_t	errno;
737
738	adrm_int32(adr, &retval, 1);
739	adrm_int32(adr, &errno, 1);
740	return (-1);
741}
742
743/*
744 * Format of strings array token:
745 *	token id		adr_char
746 *	count value		adr_int32
747 *	strings			null terminated strings
748 */
749static int
750strings_common_token(adr_t *adr)
751{
752	int count, i;
753	char c;
754
755	adrm_int32(adr, (int32_t *)&count, 1);
756	for (i = 1; i <= count; i++) {
757		adrm_char(adr, &c, 1);
758		while (c != (char)0)
759			adrm_char(adr, &c, 1);
760	}
761	/* no dump option here, since we will have variable length fields */
762	return (-1);
763}
764
765int
766path_attr_token(adr_t *adr)
767{
768	return (strings_common_token(adr));
769}
770
771int
772exec_args_token(adr_t *adr)
773{
774	return (strings_common_token(adr));
775}
776
777int
778exec_env_token(adr_t *adr)
779{
780	return (strings_common_token(adr));
781}
782
783/*
784 * Format of liaison token:
785 */
786int
787liaison_token(adr_t *adr)
788{
789	int32_t	li;
790
791	adrm_int32(adr, &li, 1);
792	return (-1);
793}
794
795
796/*
797 * Format of path token:
798 *	path				adr_string
799 */
800int
801path_token(adr_t *adr)
802{
803	if ((flags & M_OBJECT) && (obj_flag == OBJ_PATH)) {
804		char *path;
805
806		get_string(adr, &path);
807		if (path[0] != '/')
808			/*
809			 * anchor the path. user apps may not do it.
810			 */
811			anchor_path(path);
812		/*
813		 * match against the collapsed path. that is what user sees.
814		 */
815		if (re_exec2(collapse_path(path)) == 1)
816			checkflags |= M_OBJECT;
817		free(path);
818	} else {
819		skip_string(adr);
820	}
821	return (-1);
822}
823
824
825/*
826 * Format of System V IPC permission token:
827 *	System V IPC permission token id	adr_char
828 * 	uid					adr_int32
829 *	gid					adr_int32
830 *	cuid					adr_int32
831 *	cgid					adr_int32
832 *	mode					adr_int32
833 *	seq					adr_int32
834 *	key					adr_int32
835 */
836int
837s5_IPC_perm_token(adr_t *adr)
838{
839	int32_t	uid, gid, cuid, cgid, mode, seq;
840	int32_t	key;
841
842	adrm_int32(adr, &uid, 1);
843	adrm_int32(adr, &gid, 1);
844	adrm_int32(adr, &cuid, 1);
845	adrm_int32(adr, &cgid, 1);
846	adrm_int32(adr, &mode, 1);
847	adrm_int32(adr, &seq, 1);
848	adrm_int32(adr, &key, 1);
849
850	if (!new_mode && (flags & M_USERE)) {
851		if (m_usere == uid)
852			checkflags |= M_USERE;
853	}
854
855	if (!new_mode && (flags & M_USERE)) {
856		if (m_usere == cuid)
857			checkflags |= M_USERE;
858	}
859
860	if (!new_mode && (flags & M_GROUPR)) {
861		if (m_groupr == gid)
862			checkflags |= M_GROUPR;
863	}
864
865	if (!new_mode && (flags & M_GROUPR)) {
866		if (m_groupr == cgid)
867			checkflags |= M_GROUPR;
868	}
869
870	if ((flags & M_OBJECT) &&
871	    ((obj_owner == uid) ||
872	    (obj_owner == cuid) ||
873	    (obj_group == gid) ||
874	    (obj_group == cgid))) {
875
876		switch (obj_flag) {
877		case OBJ_MSGGROUP:
878		case OBJ_MSGOWNER:
879			if (ipc_type_match(OBJ_MSG, ipc_type))
880				checkflags |= M_OBJECT;
881			break;
882		case OBJ_SEMGROUP:
883		case OBJ_SEMOWNER:
884			if (ipc_type_match(OBJ_SEM, ipc_type))
885				checkflags |= M_OBJECT;
886			break;
887		case OBJ_SHMGROUP:
888		case OBJ_SHMOWNER:
889			if (ipc_type_match(OBJ_SHM, ipc_type))
890				checkflags |= M_OBJECT;
891			break;
892		}
893	}
894	return (-1);
895}
896
897
898/*
899 * Format of process32 token:
900 *	process token id	adr_char
901 *	auid			adr_int32
902 *	euid			adr_int32
903 *	egid 			adr_int32
904 * 	ruid			adr_int32
905 *	rgid			adr_int32
906 * 	pid			adr_int32
907 * 	sid			adr_int32
908 * 	termid			adr_int32*2
909 */
910int
911process32_token(adr_t *adr)
912{
913	int32_t	auid, euid, egid, ruid, rgid, pid;
914	int32_t	sid;
915	int32_t port, machine;
916
917	adrm_int32(adr, &auid, 1);
918	adrm_int32(adr, &euid, 1);
919	adrm_int32(adr, &egid, 1);
920	adrm_int32(adr, &ruid, 1);
921	adrm_int32(adr, &rgid, 1);
922	adrm_int32(adr, &pid, 1);
923	adrm_int32(adr, &sid, 1);
924	adrm_int32(adr, &port, 1);
925	adrm_int32(adr, &machine, 1);
926
927	if (!new_mode && (flags & M_USERA)) {
928		if (m_usera == auid)
929			checkflags |= M_USERA;
930	}
931	if (!new_mode && (flags & M_USERE)) {
932		if (m_usere == euid)
933			checkflags |= M_USERE;
934	}
935	if (!new_mode && (flags & M_USERR)) {
936		if (m_userr == ruid)
937			checkflags |= M_USERR;
938	}
939	if (!new_mode && (flags & M_GROUPR)) {
940		if (m_groupr == rgid)
941			checkflags |= M_GROUPR;
942	}
943	if (!new_mode && (flags & M_GROUPE)) {
944		if (m_groupe == egid)
945			checkflags |= M_GROUPE;
946	}
947
948	if (flags & M_OBJECT) {
949		if ((obj_flag & OBJ_PROC) &&
950		    (obj_id == pid)) {
951			checkflags |= M_OBJECT;
952		} else if ((obj_flag & OBJ_PGROUP) &&
953		    ((obj_group == egid) ||
954		    (obj_group == rgid))) {
955			checkflags |= M_OBJECT;
956		} else if ((obj_flag & OBJ_POWNER) &&
957		    ((obj_owner == euid) ||
958		    (obj_group == ruid))) {
959			checkflags |= M_OBJECT;
960		}
961	}
962	return (-1);
963}
964
965/*
966 * Format of process32_ex token:
967 *	process token id	adr_char
968 *	auid			adr_int32
969 *	euid			adr_int32
970 *	egid 			adr_int32
971 * 	ruid			adr_int32
972 *	rgid			adr_int32
973 * 	pid			adr_int32
974 * 	sid			adr_int32
975 * 	termid
976 *		port		adr_int32
977 *		type		adr_int32
978 *		ip address	adr_u_char*type
979 */
980int
981process32_ex_token(adr_t *adr)
982{
983	int32_t	auid, euid, egid, ruid, rgid, pid;
984	int32_t	sid;
985	int32_t port, type;
986	uchar_t addr[16];
987
988	adrm_int32(adr, &auid, 1);
989	adrm_int32(adr, &euid, 1);
990	adrm_int32(adr, &egid, 1);
991	adrm_int32(adr, &ruid, 1);
992	adrm_int32(adr, &rgid, 1);
993	adrm_int32(adr, &pid, 1);
994	adrm_int32(adr, &sid, 1);
995	adrm_int32(adr, &port, 1);
996	adrm_int32(adr, &type, 1);
997	adrm_u_char(adr, addr, type);
998
999	if (!new_mode && (flags & M_USERA)) {
1000		if (m_usera == auid)
1001			checkflags = checkflags | M_USERA;
1002	}
1003	if (!new_mode && (flags & M_USERE)) {
1004		if (m_usere == euid)
1005			checkflags = checkflags | M_USERE;
1006	}
1007	if (!new_mode && (flags & M_USERR)) {
1008		if (m_userr == ruid)
1009			checkflags = checkflags | M_USERR;
1010	}
1011	if (!new_mode && (flags & M_GROUPR)) {
1012		if (m_groupr == egid)
1013			checkflags = checkflags | M_GROUPR;
1014	}
1015	if (!new_mode && (flags & M_GROUPE)) {
1016		if (m_groupe == egid)
1017			checkflags = checkflags | M_GROUPE;
1018	}
1019
1020	if (flags & M_OBJECT) {
1021		if ((obj_flag & OBJ_PROC) &&
1022		    (obj_id == pid)) {
1023			checkflags = checkflags | M_OBJECT;
1024		} else if ((obj_flag & OBJ_PGROUP) &&
1025		    ((obj_group == egid) ||
1026		    (obj_group == rgid))) {
1027			checkflags = checkflags | M_OBJECT;
1028		} else if ((obj_flag & OBJ_POWNER) &&
1029		    ((obj_owner == euid) ||
1030		    (obj_group == ruid))) {
1031			checkflags = checkflags | M_OBJECT;
1032		}
1033	}
1034	return (-1);
1035}
1036
1037/*
1038 * Format of process64 token:
1039 *	process token id	adr_char
1040 *	auid			adr_int32
1041 *	euid			adr_int32
1042 *	egid 			adr_int32
1043 * 	ruid			adr_int32
1044 *	rgid			adr_int32
1045 * 	pid			adr_int32
1046 * 	sid			adr_int32
1047 * 	termid			adr_int64+adr_int32
1048 */
1049int
1050process64_token(adr_t *adr)
1051{
1052	int32_t	auid, euid, egid, ruid, rgid, pid;
1053	int32_t	sid;
1054	int64_t port;
1055	int32_t machine;
1056
1057	adrm_int32(adr, &auid, 1);
1058	adrm_int32(adr, &euid, 1);
1059	adrm_int32(adr, &egid, 1);
1060	adrm_int32(adr, &ruid, 1);
1061	adrm_int32(adr, &rgid, 1);
1062	adrm_int32(adr, &pid, 1);
1063	adrm_int32(adr, &sid, 1);
1064	adrm_int64(adr, &port, 1);
1065	adrm_int32(adr, &machine, 1);
1066
1067	if (!new_mode && (flags & M_USERA)) {
1068		if (m_usera == auid)
1069			checkflags |= M_USERA;
1070	}
1071	if (!new_mode && (flags & M_USERE)) {
1072		if (m_usere == euid)
1073			checkflags |= M_USERE;
1074	}
1075	if (!new_mode && (flags & M_USERR)) {
1076		if (m_userr == ruid)
1077			checkflags |= M_USERR;
1078	}
1079	if (!new_mode && (flags & M_GROUPR)) {
1080		if (m_groupr == rgid)
1081			checkflags |= M_GROUPR;
1082	}
1083	if (!new_mode && (flags & M_GROUPE)) {
1084		if (m_groupe == egid)
1085			checkflags |= M_GROUPE;
1086	}
1087
1088	if (flags & M_OBJECT) {
1089		if ((obj_flag & OBJ_PROC) &&
1090		    (obj_id == pid)) {
1091			checkflags |= M_OBJECT;
1092		} else if ((obj_flag & OBJ_PGROUP) &&
1093		    ((obj_group == egid) ||
1094		    (obj_group == rgid))) {
1095			checkflags |= M_OBJECT;
1096		} else if ((obj_flag & OBJ_POWNER) &&
1097		    ((obj_owner == euid) ||
1098		    (obj_group == ruid))) {
1099			checkflags |= M_OBJECT;
1100		}
1101	}
1102	return (-1);
1103}
1104
1105/*
1106 * Format of process64_ex token:
1107 *	process token id	adr_char
1108 *	auid			adr_int32
1109 *	euid			adr_int32
1110 *	egid 			adr_int32
1111 * 	ruid			adr_int32
1112 *	rgid			adr_int32
1113 * 	pid			adr_int32
1114 * 	sid			adr_int32
1115 * 	termid
1116 * 		port		adr_int64
1117 * 		type		adr_int32
1118 * 		ip address	adr_u_char*type
1119 */
1120int
1121process64_ex_token(adr_t *adr)
1122{
1123	int32_t	auid, euid, egid, ruid, rgid, pid;
1124	int32_t	sid;
1125	int64_t port;
1126	int32_t type;
1127	uchar_t addr[16];
1128
1129	adrm_int32(adr, &auid, 1);
1130	adrm_int32(adr, &euid, 1);
1131	adrm_int32(adr, &egid, 1);
1132	adrm_int32(adr, &ruid, 1);
1133	adrm_int32(adr, &rgid, 1);
1134	adrm_int32(adr, &pid, 1);
1135	adrm_int32(adr, &sid, 1);
1136	adrm_int64(adr, &port, 1);
1137	adrm_int32(adr, &type, 1);
1138	adrm_u_char(adr, addr, type);
1139
1140	if (!new_mode && (flags & M_USERA)) {
1141		if (m_usera == auid)
1142			checkflags = checkflags | M_USERA;
1143	}
1144	if (!new_mode && (flags & M_USERE)) {
1145		if (m_usere == euid)
1146			checkflags = checkflags | M_USERE;
1147	}
1148	if (!new_mode && (flags & M_USERR)) {
1149		if (m_userr == ruid)
1150			checkflags = checkflags | M_USERR;
1151	}
1152	if (!new_mode && (flags & M_GROUPR)) {
1153		if (m_groupr == egid)
1154			checkflags = checkflags | M_GROUPR;
1155	}
1156	if (!new_mode && (flags & M_GROUPE)) {
1157		if (m_groupe == egid)
1158			checkflags = checkflags | M_GROUPE;
1159	}
1160
1161	if (flags & M_OBJECT) {
1162		if ((obj_flag & OBJ_PROC) &&
1163		    (obj_id == pid)) {
1164			checkflags = checkflags | M_OBJECT;
1165		} else if ((obj_flag & OBJ_PGROUP) &&
1166		    ((obj_group == egid) ||
1167		    (obj_group == rgid))) {
1168			checkflags = checkflags | M_OBJECT;
1169		} else if ((obj_flag & OBJ_POWNER) &&
1170		    ((obj_owner == euid) ||
1171		    (obj_group == ruid))) {
1172			checkflags = checkflags | M_OBJECT;
1173		}
1174	}
1175	return (-1);
1176}
1177
1178/*
1179 * Format of System V IPC token:
1180 *	System V IPC token id	adr_char
1181 *	object id		adr_int32
1182 */
1183int
1184s5_IPC_token(adr_t *adr)
1185{
1186	int32_t	ipc_id;
1187
1188	adrm_char(adr, &ipc_type, 1);	/* Global */
1189	adrm_int32(adr, &ipc_id, 1);
1190
1191	if ((flags & M_OBJECT) &&
1192	    ipc_type_match(obj_flag, ipc_type) &&
1193	    (obj_id == ipc_id))
1194		checkflags |= M_OBJECT;
1195
1196	return (-1);
1197}
1198
1199
1200/*
1201 * Format of socket token:
1202 *	socket_type		adrm_short
1203 *	remote_port		adrm_short
1204 *	remote_inaddr		adrm_int32
1205 */
1206int
1207socket_token(adr_t *adr)
1208{
1209	short	socket_type;
1210	short	remote_port;
1211	int32_t	remote_inaddr;
1212
1213	adrm_short(adr, &socket_type, 1);
1214	adrm_short(adr, &remote_port, 1);
1215	adrm_char(adr, (char *)&remote_inaddr, 4);
1216
1217	if ((flags & M_OBJECT) && (obj_flag == OBJ_SOCK)) {
1218		if (socket_flag == SOCKFLG_MACHINE) {
1219			if (remote_inaddr == obj_id)
1220				checkflags |= M_OBJECT;
1221		} else if (socket_flag == SOCKFLG_PORT) {
1222			if (remote_port == obj_id)
1223				checkflags |= M_OBJECT;
1224		}
1225	}
1226	return (-1);
1227}
1228
1229
1230/*
1231 * Format of socket_ex token:
1232 *	socket_domain		adrm_short
1233 *	socket_type		adrm_short
1234 *	address_type		adrm_short
1235 *	local_port		adrm_short
1236 *	local_inaddr		adrm_u_char*address_type
1237 *	remote_port		adrm_short
1238 *	remote_inaddr		adrm_u_char*address_type
1239 */
1240int
1241socket_ex_token(adr_t *adr)
1242{
1243	short	socket_domain;
1244	short	socket_type;
1245	short	ip_size;
1246	short	local_port;
1247	uchar_t	local_inaddr[16];
1248	short	remote_port;
1249	uchar_t	remote_inaddr[16];
1250	uchar_t	*caddr = (uchar_t *)&obj_id;
1251
1252	adrm_short(adr, &socket_domain, 1);
1253	adrm_short(adr, &socket_type, 1);
1254	adrm_short(adr, &ip_size, 1);
1255
1256	/* validate ip size */
1257	if ((ip_size != AU_IPv6) && (ip_size != AU_IPv4))
1258		return (0);
1259
1260	adrm_short(adr, &local_port, 1);
1261	adrm_char(adr, (char *)local_inaddr, ip_size);
1262
1263	adrm_short(adr, &remote_port, 1);
1264	adrm_char(adr, (char *)remote_inaddr, ip_size);
1265
1266	/* if IP type mis-match, then nothing to do */
1267	if (ip_size != ip_type)
1268		return (-1);
1269
1270	if ((flags & M_OBJECT) && (obj_flag == OBJ_SOCK)) {
1271		if (socket_flag == SOCKFLG_MACHINE) {
1272			if (ip_type == AU_IPv6) {
1273				caddr = (uchar_t *)ip_ipv6;
1274			}
1275			if ((memcmp(local_inaddr, caddr, ip_type) == 0) ||
1276			    (memcmp(remote_inaddr, caddr, ip_type) == 0)) {
1277				checkflags |= M_OBJECT;
1278			}
1279		} else if (socket_flag == SOCKFLG_PORT) {
1280			if ((local_port == obj_id) || (remote_port == obj_id)) {
1281				checkflags |= M_OBJECT;
1282			}
1283		}
1284	}
1285	return (-1);
1286}
1287
1288
1289/*
1290 * Format of subject32 token:
1291 *	subject token id	adr_char
1292 *	auid			adr_int32
1293 *	euid			adr_int32
1294 *	egid 			adr_int32
1295 * 	ruid			adr_int32
1296 *	rgid			adr_int32
1297 * 	pid			adr_int32
1298 * 	sid			adr_int32
1299 * 	termid			adr_int32*2
1300 */
1301int
1302subject32_token(adr_t *adr)
1303{
1304	int32_t	auid, euid, egid, ruid, rgid, pid;
1305	int32_t	sid;
1306	int32_t port, machine;
1307
1308	adrm_int32(adr, &auid, 1);
1309	adrm_int32(adr, &euid, 1);
1310	adrm_int32(adr, &egid, 1);
1311	adrm_int32(adr, &ruid, 1);
1312	adrm_int32(adr, &rgid, 1);
1313	adrm_int32(adr, &pid, 1);
1314	adrm_int32(adr, &sid, 1);
1315	adrm_int32(adr, &port, 1);
1316	adrm_int32(adr, &machine, 1);
1317
1318	if (flags & M_SUBJECT) {
1319		if (subj_id == pid)
1320			checkflags |= M_SUBJECT;
1321	}
1322	if (flags & M_USERA) {
1323		if (m_usera == auid)
1324			checkflags |= M_USERA;
1325	}
1326	if (flags & M_USERE) {
1327		if (m_usere == euid)
1328			checkflags |= M_USERE;
1329	}
1330	if (flags & M_USERR) {
1331		if (m_userr == ruid)
1332			checkflags |= M_USERR;
1333	}
1334	if (flags & M_GROUPR) {
1335		if (m_groupr == rgid)
1336			checkflags |= M_GROUPR;
1337	}
1338	if (flags & M_GROUPE) {
1339		if (m_groupe == egid)
1340			checkflags |= M_GROUPE;
1341	}
1342	if (flags & M_SID) {
1343		if (m_sid == (au_asid_t)sid)
1344			checkflags |= M_SID;
1345	}
1346	return (-1);
1347}
1348
1349/*
1350 * Format of subject32_ex token:
1351 *	subject token id	adr_char
1352 *	auid			adr_int32
1353 *	euid			adr_int32
1354 *	egid 			adr_int32
1355 * 	ruid			adr_int32
1356 *	rgid			adr_int32
1357 * 	pid			adr_int32
1358 * 	sid			adr_int32
1359 * 	termid
1360 * 		port		adr_int32
1361 * 		type		adr_int32
1362 * 		ip address	adr_u_char*type
1363 */
1364int
1365subject32_ex_token(adr_t *adr)
1366{
1367	int32_t	auid, euid, egid, ruid, rgid, pid;
1368	int32_t	sid;
1369	int32_t port, type;
1370	uchar_t addr[16];
1371
1372	adrm_int32(adr, &auid, 1);
1373	adrm_int32(adr, &euid, 1);
1374	adrm_int32(adr, &egid, 1);
1375	adrm_int32(adr, &ruid, 1);
1376	adrm_int32(adr, &rgid, 1);
1377	adrm_int32(adr, &pid, 1);
1378	adrm_int32(adr, &sid, 1);
1379	adrm_int32(adr, &port, 1);
1380	adrm_int32(adr, &type, 1);
1381	adrm_u_char(adr, addr, type);
1382
1383	if (flags & M_SUBJECT) {
1384		if (subj_id == pid)
1385			checkflags = checkflags | M_SUBJECT;
1386	}
1387	if (flags & M_USERA) {
1388		if (m_usera == auid)
1389			checkflags = checkflags | M_USERA;
1390	}
1391	if (flags & M_USERE) {
1392		if (m_usere == euid)
1393			checkflags = checkflags | M_USERE;
1394	}
1395	if (flags & M_USERR) {
1396		if (m_userr == ruid)
1397			checkflags = checkflags | M_USERR;
1398	}
1399	if (flags & M_GROUPR) {
1400		if (m_groupr == egid)
1401			checkflags = checkflags | M_GROUPR;
1402	}
1403	if (flags & M_GROUPE) {
1404		if (m_groupe == egid)
1405			checkflags = checkflags | M_GROUPE;
1406	}
1407	if (flags & M_SID) {
1408		if (m_sid == (au_asid_t)sid)
1409			checkflags = checkflags | M_SID;
1410	}
1411	return (-1);
1412}
1413
1414/*
1415 * Format of subject64 token:
1416 *	subject token id	adr_char
1417 *	auid			adr_int32
1418 *	euid			adr_int32
1419 *	egid 			adr_int32
1420 * 	ruid			adr_int32
1421 *	rgid			adr_int32
1422 * 	pid			adr_int32
1423 * 	sid			adr_int32
1424 * 	termid			adr_int64+adr_int32
1425 */
1426int
1427subject64_token(adr_t *adr)
1428{
1429	int32_t	auid, euid, egid, ruid, rgid, pid;
1430	int32_t	sid;
1431	int64_t port;
1432	int32_t machine;
1433
1434	adrm_int32(adr, &auid, 1);
1435	adrm_int32(adr, &euid, 1);
1436	adrm_int32(adr, &egid, 1);
1437	adrm_int32(adr, &ruid, 1);
1438	adrm_int32(adr, &rgid, 1);
1439	adrm_int32(adr, &pid, 1);
1440	adrm_int32(adr, &sid, 1);
1441	adrm_int64(adr, &port, 1);
1442	adrm_int32(adr, &machine, 1);
1443
1444	if (flags & M_SUBJECT) {
1445		if (subj_id == pid)
1446			checkflags |= M_SUBJECT;
1447	}
1448	if (flags & M_USERA) {
1449		if (m_usera == auid)
1450			checkflags |= M_USERA;
1451	}
1452	if (flags & M_USERE) {
1453		if (m_usere == euid)
1454			checkflags |= M_USERE;
1455	}
1456	if (flags & M_USERR) {
1457		if (m_userr == ruid)
1458			checkflags |= M_USERR;
1459	}
1460	if (flags & M_GROUPR) {
1461		if (m_groupr == rgid)
1462			checkflags |= M_GROUPR;
1463	}
1464	if (flags & M_GROUPE) {
1465		if (m_groupe == egid)
1466			checkflags |= M_GROUPE;
1467	}
1468	if (flags & M_SID) {
1469		if (m_sid == (au_asid_t)sid)
1470			checkflags |= M_SID;
1471	}
1472	return (-1);
1473}
1474
1475/*
1476 * Format of subject64_ex token:
1477 *	subject token id	adr_char
1478 *	auid			adr_int32
1479 *	euid			adr_int32
1480 *	egid 			adr_int32
1481 * 	ruid			adr_int32
1482 *	rgid			adr_int32
1483 * 	pid			adr_int32
1484 * 	sid			adr_int32
1485 * 	termid
1486 * 		port		adr_int64
1487 * 		type		adr_int32
1488 * 		ip address	adr_u_char*type
1489 */
1490int
1491subject64_ex_token(adr_t *adr)
1492{
1493	int32_t	auid, euid, egid, ruid, rgid, pid;
1494	int32_t	sid;
1495	int64_t port;
1496	int32_t type;
1497	uchar_t	addr[16];
1498
1499	adrm_int32(adr, &auid, 1);
1500	adrm_int32(adr, &euid, 1);
1501	adrm_int32(adr, &egid, 1);
1502	adrm_int32(adr, &ruid, 1);
1503	adrm_int32(adr, &rgid, 1);
1504	adrm_int32(adr, &pid, 1);
1505	adrm_int32(adr, &sid, 1);
1506	adrm_int64(adr, &port, 1);
1507	adrm_int32(adr, &type, 1);
1508	adrm_u_char(adr, addr, type);
1509
1510	if (flags & M_SUBJECT) {
1511		if (subj_id == pid)
1512			checkflags = checkflags | M_SUBJECT;
1513	}
1514	if (flags & M_USERA) {
1515		if (m_usera == auid)
1516			checkflags = checkflags | M_USERA;
1517	}
1518	if (flags & M_USERE) {
1519		if (m_usere == euid)
1520			checkflags = checkflags | M_USERE;
1521	}
1522	if (flags & M_USERR) {
1523		if (m_userr == ruid)
1524			checkflags = checkflags | M_USERR;
1525	}
1526	if (flags & M_GROUPR) {
1527		if (m_groupr == egid)
1528			checkflags = checkflags | M_GROUPR;
1529	}
1530	if (flags & M_GROUPE) {
1531		if (m_groupe == egid)
1532			checkflags = checkflags | M_GROUPE;
1533	}
1534	if (flags & M_SID) {
1535		if (m_sid == (au_asid_t)sid)
1536			checkflags = checkflags | M_SID;
1537	}
1538	return (-1);
1539}
1540
1541/*
1542 * -----------------------------------------------------------------------
1543 * tid_token(): Process tid token and display contents
1544 *
1545 * Format of tid token:
1546 *	tid token id			adr_char
1547 * 	address type			adr_char
1548 *	For address type of AU_IPADR...
1549 *		remote port		adr_short
1550 *		local port		adr_short
1551 *		IP type			adr_int32
1552 *		IP addr			adr_int32 if IPv4
1553 *		IP addr			4 x adr_int32 if IPv6
1554 * address types other than AU_IPADR are not yet defined
1555 * -----------------------------------------------------------------------
1556 */
1557int
1558tid_token(adr_t *adr)
1559{
1560	int32_t	address[4];
1561	int32_t	ip_type;
1562	char	tid_type;
1563	short	rport;
1564	short	lport;
1565
1566	adrm_char(adr, &tid_type, 1);
1567	switch (tid_type) {
1568	case AU_IPADR:
1569		adrm_short(adr, &rport, 1);
1570		adrm_short(adr, &lport, 1);
1571		adrm_int32(adr, &ip_type, 1);
1572		adrm_char(adr, (char *)&address, ip_type);
1573		break;
1574	default:
1575		return (0);
1576	}
1577	return (-1);
1578}
1579
1580/*
1581 * -----------------------------------------------------------------------
1582 * zonename_token(): Process zonename token and display contents
1583 *
1584 * Format of zonename token:
1585 *	zonename token id		adr_char
1586 * 	zone name			adr_string
1587 * -----------------------------------------------------------------------
1588 */
1589int
1590zonename_token(adr_t *adr)
1591{
1592	char	*name;
1593
1594	if (flags & M_ZONENAME) {
1595		get_string(adr, &name);
1596		if (strncmp(zonename, name, ZONENAME_MAX) == 0)
1597			checkflags |= M_ZONENAME;
1598		free(name);
1599	} else {
1600		skip_string(adr);
1601	}
1602	return (-1);
1603}
1604
1605/*
1606 * fmri_token():
1607 *
1608 * Format of fmri token:
1609 * 	fmri				adr_string
1610 */
1611int
1612fmri_token(adr_t *adr)
1613{
1614	if ((flags & M_OBJECT) && (obj_flag == OBJ_FMRI)) {
1615		char	*fmri_name;
1616
1617		get_string(adr, &fmri_name);
1618
1619		/* match token against service instance */
1620		if (scf_cmp_pattern(fmri_name, &fmri) == 1) {
1621			checkflags |= M_OBJECT;
1622		}
1623		free(fmri_name);
1624	} else {
1625		skip_string(adr);
1626	}
1627	return (-1);
1628}
1629
1630/*
1631 * Format of xatom token:
1632 */
1633int
1634xatom_token(adr_t *adr)
1635{
1636	skip_string(adr);
1637
1638	return (-1);
1639}
1640
1641/*
1642 * Format of xselect token:
1643 */
1644int
1645xselect_token(adr_t *adr)
1646{
1647	skip_string(adr);
1648	skip_string(adr);
1649	skip_string(adr);
1650
1651	return (-1);
1652}
1653
1654/*
1655 * anchor a path name with a slash
1656 * assume we have enough space
1657 */
1658void
1659anchor_path(char *path)
1660{
1661	(void) memmove((void *)(path + 1), (void *)path, strlen(path) + 1);
1662	*path = '/';
1663}
1664
1665
1666/*
1667 * copy path to collapsed path.
1668 * collapsed path does not contain:
1669 *	successive slashes
1670 *	instances of dot-slash
1671 *	instances of dot-dot-slash
1672 * passed path must be anchored with a '/'
1673 */
1674char *
1675collapse_path(char *s)
1676{
1677	int	id;	/* index of where we are in destination string */
1678	int	is;	/* index of where we are in source string */
1679	int	slashseen;	/* have we seen a slash */
1680	int	ls;		/* length of source string */
1681
1682	ls = strlen(s) + 1;
1683
1684	slashseen = 0;
1685	for (is = 0, id = 0; is < ls; is++) {
1686		/* thats all folks, we've reached the end of input */
1687		if (s[is] == '\0') {
1688			if (id > 1 && s[id-1] == '/') {
1689				--id;
1690			}
1691			s[id++] = '\0';
1692			break;
1693		}
1694		/* previous character was a / */
1695		if (slashseen) {
1696			if (s[is] == '/')
1697				continue;	/* another slash, ignore it */
1698		} else if (s[is] == '/') {
1699			/* we see a /, just copy it and try again */
1700			slashseen = 1;
1701			s[id++] = '/';
1702			continue;
1703		}
1704		/* /./ seen */
1705		if (s[is] == '.' && s[is+1] == '/') {
1706			is += 1;
1707			continue;
1708		}
1709		/* XXX/. seen */
1710		if (s[is] == '.' && s[is+1] == '\0') {
1711			if (id > 1)
1712				id--;
1713			continue;
1714		}
1715		/* XXX/.. seen */
1716		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '\0') {
1717			is += 1;
1718			if (id > 0)
1719				id--;
1720			while (id > 0 && s[--id] != '/')
1721				;
1722			id++;
1723			continue;
1724		}
1725		/* XXX/../ seen */
1726		if (s[is] == '.' && s[is+1] == '.' && s[is+2] == '/') {
1727			is += 2;
1728			if (id > 0)
1729				id--;
1730			while (id > 0 && s[--id] != '/')
1731				;
1732			id++;
1733			continue;
1734		}
1735		while (is < ls && (s[id++] = s[is++]) != '/')
1736			;
1737		is--;
1738	}
1739	return (s);
1740}
1741
1742
1743int
1744ipc_type_match(int flag, char type)
1745{
1746	if (flag == OBJ_SEM && type == AT_IPC_SEM)
1747		return (1);
1748
1749	if (flag == OBJ_MSG && type == AT_IPC_MSG)
1750		return (1);
1751
1752	if (flag == OBJ_SHM && type == AT_IPC_SHM)
1753		return (1);
1754
1755	return (0);
1756}
1757
1758
1759void
1760skip_string(adr_t *adr)
1761{
1762	ushort_t	c;
1763
1764	adrm_u_short(adr, &c, 1);
1765	adr->adr_now += c;
1766}
1767
1768
1769void
1770get_string(adr_t *adr, char **p)
1771{
1772	ushort_t	c;
1773
1774	adrm_u_short(adr, &c, 1);
1775	*p = a_calloc(1, (size_t)c);
1776	adrm_char(adr, *p, c);
1777}
1778
1779
1780/*
1781 * Format of host token:
1782 *	host  		ard_uint32
1783 */
1784int
1785host_token(adr_t *adr)
1786{
1787	uint32_t host;
1788
1789	adrm_u_int32(adr, &host, 1);
1790
1791	return (-1);
1792}
1793
1794/*
1795 * Format of useofauth token:
1796 *	uauth token id		adr_char
1797 * 	uauth			adr_string
1798 */
1799int
1800useofauth_token(adr_t *adr)
1801{
1802	skip_string(adr);
1803	return (-1);
1804}
1805
1806/*
1807 * Format of user token:
1808 *	user token id		adr_char
1809 *	uid			adr_uid
1810 * 	username		adr_string
1811 */
1812int
1813user_token(adr_t *adr)
1814{
1815	uid_t	uid;
1816
1817	adrm_uid(adr, &uid, 1);
1818	skip_string(adr);
1819
1820	if ((flags & M_OBJECT) && (obj_flag == OBJ_USER) &&
1821	    (uid == obj_user)) {
1822		checkflags |= M_OBJECT;
1823	}
1824
1825	return (-1);
1826}
1827
1828int
1829xcolormap_token(adr_t *adr)
1830{
1831	return (xgeneric(adr));
1832}
1833
1834int
1835xcursor_token(adr_t *adr)
1836{
1837	return (xgeneric(adr));
1838}
1839
1840int
1841xfont_token(adr_t *adr)
1842{
1843	return (xgeneric(adr));
1844}
1845
1846int
1847xgc_token(adr_t *adr)
1848{
1849	return (xgeneric(adr));
1850}
1851
1852int
1853xpixmap_token(adr_t *adr)
1854{
1855	return (xgeneric(adr));
1856}
1857
1858int
1859xwindow_token(adr_t *adr)
1860{
1861	return (xgeneric(adr));
1862}
1863
1864
1865/*
1866 * Format of xgeneric token:
1867 *	XID			adr_int32
1868 *	creator UID		adr_int32
1869 *
1870 * Includes:  xcolormap, xcursor, xfont, xgc, xpixmap, and xwindow
1871 */
1872int
1873xgeneric(adr_t *adr)
1874{
1875	int32_t xid;
1876	int32_t uid;
1877
1878	adrm_int32(adr, &xid, 1);
1879	adrm_int32(adr, &uid, 1);
1880
1881	if (flags & M_USERE) {
1882		if (m_usere == uid)
1883			checkflags = checkflags | M_USERE;
1884	}
1885
1886	return (-1);
1887}
1888
1889
1890/*
1891 * Format of xproperty token:
1892 *	XID			adr_int32
1893 *	creator UID		adr_int32
1894 *	atom string		adr_string
1895 */
1896int
1897xproperty_token(adr_t *adr)
1898{
1899	int32_t	xid;
1900	int32_t uid;
1901
1902	adrm_int32(adr, &xid, 1);
1903	adrm_int32(adr, &uid, 1);
1904	skip_string(adr);
1905
1906	if (flags & M_USERE) {
1907		if (m_usere == uid)
1908			checkflags = checkflags | M_USERE;
1909	}
1910
1911	return (-1);
1912}
1913
1914
1915/*
1916 * Format of xclient token:
1917 * 	xclient id		adr_int32
1918 */
1919int
1920xclient_token(adr_t *adr)
1921{
1922	int32_t	client_id;
1923
1924	adrm_int32(adr, &client_id, 1);
1925
1926	return (-1);
1927}
1928
1929/*
1930 * Format of privilege set token:
1931 *	priv_set type		string
1932 *	priv_set		string
1933 */
1934
1935int
1936privilege_token(adr_t *adr)
1937{
1938	skip_string(adr);	/* set type name */
1939	skip_string(adr);	/* privilege set */
1940	return (-1);
1941}
1942
1943/*
1944 * Format of security flags token:
1945 *	security flag set		string
1946 *	security flags		string
1947 */
1948
1949int
1950secflags_token(adr_t *adr)
1951{
1952	skip_string(adr);	/* set name */
1953	skip_string(adr);	/* security flags */
1954	return (-1);
1955}
1956
1957/*
1958 * Format of label token:
1959 *      label ID                1 byte
1960 *      compartment length      1 byte
1961 *      classification          2 bytes
1962 *      compartment words       <compartment length> * 4 bytes
1963 */
1964int
1965label_token(adr_t *adr)
1966{
1967	static m_label_t *label = NULL;
1968	static size32_t l_size;
1969	int len;
1970
1971	if (label == NULL) {
1972		label = m_label_alloc(MAC_LABEL);
1973		l_size = blabel_size() - 4;
1974	}
1975
1976	if (label == NULL) {
1977		/* out of memory, should never happen; skip label */
1978		char	l;	/* length */
1979
1980		adr->adr_now += sizeof (char);
1981		adrm_char(adr, (char *)&l, 1);
1982		adr->adr_now += sizeof (short) + (4 * l);
1983		return (-1);
1984	}
1985
1986	adrm_char(adr, (char *)label, 4);
1987	len = (int)(((char *)label)[1] * 4);
1988	if (len > l_size) {
1989		return (-1);
1990	}
1991	adrm_char(adr, &((char *)label)[4], len);
1992
1993	if (flags & M_LABEL) {
1994		if (blinrange(label, m_label))
1995			checkflags = checkflags | M_LABEL;
1996	}
1997
1998	return (-1);
1999}
2000
2001
2002/*
2003 * Format of useofpriv token:
2004 *	success/failure		adr_char
2005 *	privilege(s)		adr_string
2006 */
2007/* ARGSUSED */
2008int
2009useofpriv_token(adr_t *adr)
2010{
2011	char	flag;
2012
2013	adrm_char(adr, &flag, 1);
2014	skip_string(adr);
2015	return (-1);
2016}
2017