1f875b4ebSrica /*
2f875b4ebSrica  * CDDL HEADER START
3f875b4ebSrica  *
4f875b4ebSrica  * The contents of this file are subject to the terms of the
5f875b4ebSrica  * Common Development and Distribution License (the "License").
6f875b4ebSrica  * You may not use this file except in compliance with the License.
7f875b4ebSrica  *
8f875b4ebSrica  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f875b4ebSrica  * or http://www.opensolaris.org/os/licensing.
10f875b4ebSrica  * See the License for the specific language governing permissions
11f875b4ebSrica  * and limitations under the License.
12f875b4ebSrica  *
13f875b4ebSrica  * When distributing Covered Code, include this CDDL HEADER in each
14f875b4ebSrica  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f875b4ebSrica  * If applicable, add the following below this CDDL HEADER, with the
16f875b4ebSrica  * fields enclosed by brackets "[]" replaced with your own identifying
17f875b4ebSrica  * information: Portions Copyright [yyyy] [name of copyright owner]
18f875b4ebSrica  *
19f875b4ebSrica  * CDDL HEADER END
20f875b4ebSrica  */
21f875b4ebSrica 
22f875b4ebSrica /*
23*50981ffcSTony Nguyen  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24f875b4ebSrica  * Use is subject to license terms.
25f875b4ebSrica  */
26f875b4ebSrica 
27f875b4ebSrica 
28f875b4ebSrica /*
29f875b4ebSrica  *	lslabels - Display all labels dominating the specified label.
30f875b4ebSrica  */
31f875b4ebSrica 
32f875b4ebSrica #include <errno.h>
33f875b4ebSrica #include <libintl.h>
34f875b4ebSrica #include <locale.h>
35f875b4ebSrica #include <stdio.h>
36f875b4ebSrica #include <stdlib.h>
37f875b4ebSrica #include <string.h>
38f875b4ebSrica #include <unistd.h>
39*50981ffcSTony Nguyen #include <stropts.h>
40f875b4ebSrica 
41f875b4ebSrica #include <sys/param.h>
42f875b4ebSrica 
43f875b4ebSrica #include <tsol/label.h>
44f875b4ebSrica #include <sys/tsol/label_macro.h>
45f875b4ebSrica #include <iso/limits_iso.h>
46f875b4ebSrica 
47f875b4ebSrica #if !defined(TEXT_DOMAIN)
48f875b4ebSrica #define	TEXT_DOMAIN	 "SYS_TEST"
49f875b4ebSrica #endif	/* !defined(TEXT_DOMAIN) */
50f875b4ebSrica 
51f875b4ebSrica int hflg = 0;			/* true if hex output */
52f875b4ebSrica 
53f875b4ebSrica /*
54f875b4ebSrica  * Compartment mask macros.
55f875b4ebSrica  */
56f875b4ebSrica 
57f875b4ebSrica typedef uint32_t comp_chunk_t;
58f875b4ebSrica 
59f875b4ebSrica #define	__NBWRD		(CHAR_BIT * sizeof (comp_chunk_t))
60f875b4ebSrica #define	COMP_BITS	(CHAR_BIT * sizeof (Compartments_t))
61f875b4ebSrica #define	compmask(n)	(1 << ((__NBWRD - 1) - ((n) % __NBWRD)))
62f875b4ebSrica #define	compword(n)	((n)/__NBWRD)
63f875b4ebSrica 
64f875b4ebSrica #define	COMP_ADDSET(a, p)	((comp_chunk_t *)(a))[compword(p)] |= \
65f875b4ebSrica 				    compmask(p)
66f875b4ebSrica #define	COMP_DELSET(a, p)	((comp_chunk_t *)(a))[compword(p)] &= \
67f875b4ebSrica 				    ~compmask(p)
68f875b4ebSrica #define	COMP_ISMEMBER(a, p)	((((comp_chunk_t *)(a))[compword(p)] & \
69f875b4ebSrica 				    compmask(p)) != 0)
70f875b4ebSrica 
71f875b4ebSrica /* Need functions to test if bit is on */
72f875b4ebSrica 
73f875b4ebSrica 
74f875b4ebSrica void
bitfinder(m_label_t label,int next_bit)75f875b4ebSrica bitfinder(m_label_t label, int next_bit) {
76f875b4ebSrica 	char *labelstr = NULL;
77f875b4ebSrica 
78f875b4ebSrica 	Compartments_t *comps = &label.compartments;
79f875b4ebSrica 
80f875b4ebSrica 	while (next_bit < COMP_BITS) {
81f875b4ebSrica 		if (COMP_ISMEMBER(comps, next_bit)) {
82f875b4ebSrica 			bitfinder(label, next_bit + 1);
83f875b4ebSrica 			COMP_DELSET(comps, next_bit);
84f875b4ebSrica 
85f875b4ebSrica 			if (label_to_str(&label, &labelstr, M_LABEL,
86f875b4ebSrica 			    LONG_NAMES) == 0) {
87f875b4ebSrica 				m_label_t *label2 = NULL;
88f875b4ebSrica 				int err;
89f875b4ebSrica 
90f875b4ebSrica 				if (str_to_label(labelstr, &label2, MAC_LABEL,
91f875b4ebSrica 				    L_NO_CORRECTION, &err) == 0) {
92f875b4ebSrica 					if (!hflg) {
93f875b4ebSrica 						(void) printf("%s\n", labelstr);
94f875b4ebSrica 					} else {
95f875b4ebSrica 						free(labelstr);
96f875b4ebSrica 						(void) label_to_str(&label,
97f875b4ebSrica 						    &labelstr, M_INTERNAL, 0);
98f875b4ebSrica 						(void) printf("%s\n", labelstr);
99f875b4ebSrica 					}
100f875b4ebSrica 					m_label_free(label2);
101f875b4ebSrica 				}
102f875b4ebSrica 				free(labelstr);
103f875b4ebSrica 			}
104f875b4ebSrica 			bitfinder(label, next_bit + 1);
105f875b4ebSrica 			break;
106f875b4ebSrica 		}
107f875b4ebSrica 		next_bit++;
108f875b4ebSrica 		}
109f875b4ebSrica }
110f875b4ebSrica 
111f875b4ebSrica static void
label_error(const char * ascii,const int err)112f875b4ebSrica label_error(const char *ascii, const int err)
113f875b4ebSrica {
114f875b4ebSrica 	if (errno == EINVAL) {
115f875b4ebSrica 		switch (err) {
116f875b4ebSrica 		case M_BAD_STRING:
117f875b4ebSrica 			(void) fprintf(stderr,
118f875b4ebSrica 			    gettext("lslabels: bad string %s\n"), ascii);
119f875b4ebSrica 		break;
120f875b4ebSrica 		case M_BAD_LABEL:
121f875b4ebSrica 			(void) fprintf(stderr,
122f875b4ebSrica 			    gettext("lslabels: bad previous label\n"));
123f875b4ebSrica 		break;
124f875b4ebSrica 		default:
125f875b4ebSrica 			(void) fprintf(stderr,
126f875b4ebSrica 			    gettext("lslabels: parsing error found in "
127f875b4ebSrica 			    "\"%s\" at position %d\n"), ascii, err);
128f875b4ebSrica 		break;
129f875b4ebSrica 		}
130f875b4ebSrica 	} else {
131f875b4ebSrica 		perror("lslabels");
132f875b4ebSrica 	}
133f875b4ebSrica 	exit(1);
134f875b4ebSrica 	/*NOTREACHED*/
135f875b4ebSrica }
136f875b4ebSrica 
137f875b4ebSrica int
main(int argc,char ** argv)138f875b4ebSrica main(int argc, char **argv)
139f875b4ebSrica {
140f875b4ebSrica 	int errflg = 0;			/* true if arg error */
141f875b4ebSrica 	m_label_t *label = NULL;	/* binary labels */
142f875b4ebSrica 	char ascii[PIPE_BUF];		/* human readable label */
143f875b4ebSrica 	char *labelstr = NULL;		/* external label to start from */
144f875b4ebSrica 	int err = 0;			/* label error */
145f875b4ebSrica 	int c;
146f875b4ebSrica 	int mode = M_LABEL;
147f875b4ebSrica 	_Classification *level;
148f875b4ebSrica 
149f875b4ebSrica 	(void) setlocale(LC_ALL, "");
150f875b4ebSrica 	(void) textdomain(TEXT_DOMAIN);
151f875b4ebSrica 
152f875b4ebSrica 	opterr = 0;
153f875b4ebSrica 	while ((c = getopt(argc, argv, "h")) != EOF) {
154f875b4ebSrica 
155f875b4ebSrica 		switch (c) {
156f875b4ebSrica 		case 'h':
157f875b4ebSrica 			hflg++;
158f875b4ebSrica 			mode = M_INTERNAL;
159f875b4ebSrica 			break;
160f875b4ebSrica 
161f875b4ebSrica 		default:
162f875b4ebSrica 			errflg++;
163f875b4ebSrica 			break;
164f875b4ebSrica 		}
165f875b4ebSrica 	}
166f875b4ebSrica 
167f875b4ebSrica 	argc -= optind - 1;
168f875b4ebSrica 	if (errflg || argc > 2) {
169f875b4ebSrica 
170f875b4ebSrica 		(void) fprintf(stderr,
171f875b4ebSrica 		    gettext("usage: %s [-h] [label]\n"),
172f875b4ebSrica 		    argv[0]);
173f875b4ebSrica 		exit(1);
174f875b4ebSrica 		/*NOTREACHED*/
175f875b4ebSrica 	}
176f875b4ebSrica 
177f875b4ebSrica 	if (argc == 2) {
178f875b4ebSrica 		/* use label on command line */
179f875b4ebSrica 
180f875b4ebSrica 		(void) strlcpy(ascii, argv[optind], sizeof (ascii));
181f875b4ebSrica 	} else {
182f875b4ebSrica 		/* read label from standard input */
183*50981ffcSTony Nguyen 		if ((c = read(STDIN_FILENO, ascii, sizeof (ascii))) <= 0) {
184f875b4ebSrica 			perror(gettext("reading ASCII coded label"));
185f875b4ebSrica 			exit(1);
186f875b4ebSrica 			/*NOTREACHED*/
187f875b4ebSrica 		}
188*50981ffcSTony Nguyen 
189*50981ffcSTony Nguyen 		/*
190*50981ffcSTony Nguyen 		 * replace '\n' or (end of buffer) with end of string.
191*50981ffcSTony Nguyen 		 */
192*50981ffcSTony Nguyen 		ascii[c-1] = '\0';
193*50981ffcSTony Nguyen 
194*50981ffcSTony Nguyen 		/*
195*50981ffcSTony Nguyen 		 * flush any remaining input past the size of the buffer.
196*50981ffcSTony Nguyen 		 */
197*50981ffcSTony Nguyen 		(void) ioctl(STDIN_FILENO, I_FLUSH, FLUSHR);
198f875b4ebSrica 	}
199f875b4ebSrica 
200f875b4ebSrica 	if (str_to_label(ascii, &label, MAC_LABEL, L_NO_CORRECTION,
201f875b4ebSrica 	    &err) == -1) {
202f875b4ebSrica 		label_error(ascii, err);
203f875b4ebSrica 	}
204f875b4ebSrica 	if (label_to_str(label, &labelstr, mode,
205f875b4ebSrica 	    DEF_NAMES) == 0) {
206f875b4ebSrica 		(void) printf("%s\n", labelstr);
207f875b4ebSrica 	}
208f875b4ebSrica 
209f875b4ebSrica 	level =  &label->classification.class_u.class_chunk;
210f875b4ebSrica 	while (*level > 0) {
211f875b4ebSrica 		bitfinder(*label, 0);
212f875b4ebSrica 		*level -= 1;
213f875b4ebSrica 	}
214f875b4ebSrica 	m_label_free(label);
215f875b4ebSrica 
216f875b4ebSrica 	return (0);		/* really exit(0); */
217f875b4ebSrica }
218