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