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 /* 23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * lslabels - Display all labels dominating the specified label. 31 */ 32 33 #include <errno.h> 34 #include <libintl.h> 35 #include <locale.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <unistd.h> 40 41 #include <sys/param.h> 42 43 #include <tsol/label.h> 44 #include <sys/tsol/label_macro.h> 45 #include <iso/limits_iso.h> 46 47 #if !defined(TEXT_DOMAIN) 48 #define TEXT_DOMAIN "SYS_TEST" 49 #endif /* !defined(TEXT_DOMAIN) */ 50 51 int hflg = 0; /* true if hex output */ 52 53 /* 54 * Compartment mask macros. 55 */ 56 57 typedef uint32_t comp_chunk_t; 58 59 #define __NBWRD (CHAR_BIT * sizeof (comp_chunk_t)) 60 #define COMP_BITS (CHAR_BIT * sizeof (Compartments_t)) 61 #define compmask(n) (1 << ((__NBWRD - 1) - ((n) % __NBWRD))) 62 #define compword(n) ((n)/__NBWRD) 63 64 #define COMP_ADDSET(a, p) ((comp_chunk_t *)(a))[compword(p)] |= \ 65 compmask(p) 66 #define COMP_DELSET(a, p) ((comp_chunk_t *)(a))[compword(p)] &= \ 67 ~compmask(p) 68 #define COMP_ISMEMBER(a, p) ((((comp_chunk_t *)(a))[compword(p)] & \ 69 compmask(p)) != 0) 70 71 /* Need functions to test if bit is on */ 72 73 74 void 75 bitfinder(m_label_t label, int next_bit) { 76 char *labelstr = NULL; 77 78 Compartments_t *comps = &label.compartments; 79 80 while (next_bit < COMP_BITS) { 81 if (COMP_ISMEMBER(comps, next_bit)) { 82 bitfinder(label, next_bit + 1); 83 COMP_DELSET(comps, next_bit); 84 85 if (label_to_str(&label, &labelstr, M_LABEL, 86 LONG_NAMES) == 0) { 87 m_label_t *label2 = NULL; 88 int err; 89 90 if (str_to_label(labelstr, &label2, MAC_LABEL, 91 L_NO_CORRECTION, &err) == 0) { 92 if (!hflg) { 93 (void) printf("%s\n", labelstr); 94 } else { 95 free(labelstr); 96 (void) label_to_str(&label, 97 &labelstr, M_INTERNAL, 0); 98 (void) printf("%s\n", labelstr); 99 } 100 m_label_free(label2); 101 } 102 free(labelstr); 103 } 104 bitfinder(label, next_bit + 1); 105 break; 106 } 107 next_bit++; 108 } 109 } 110 111 static void 112 label_error(const char *ascii, const int err) 113 { 114 if (errno == EINVAL) { 115 switch (err) { 116 case M_BAD_STRING: 117 (void) fprintf(stderr, 118 gettext("lslabels: bad string %s\n"), ascii); 119 break; 120 case M_BAD_LABEL: 121 (void) fprintf(stderr, 122 gettext("lslabels: bad previous label\n")); 123 break; 124 default: 125 (void) fprintf(stderr, 126 gettext("lslabels: parsing error found in " 127 "\"%s\" at position %d\n"), ascii, err); 128 break; 129 } 130 } else { 131 perror("lslabels"); 132 } 133 exit(1); 134 /*NOTREACHED*/ 135 } 136 137 int 138 main(int argc, char **argv) 139 { 140 int errflg = 0; /* true if arg error */ 141 m_label_t *label = NULL; /* binary labels */ 142 char ascii[PIPE_BUF]; /* human readable label */ 143 char *labelstr = NULL; /* external label to start from */ 144 int err = 0; /* label error */ 145 int c; 146 int mode = M_LABEL; 147 _Classification *level; 148 149 (void) setlocale(LC_ALL, ""); 150 (void) textdomain(TEXT_DOMAIN); 151 152 opterr = 0; 153 while ((c = getopt(argc, argv, "h")) != EOF) { 154 155 switch (c) { 156 case 'h': 157 hflg++; 158 mode = M_INTERNAL; 159 break; 160 161 default: 162 errflg++; 163 break; 164 } 165 } 166 167 argc -= optind - 1; 168 if (errflg || argc > 2) { 169 170 (void) fprintf(stderr, 171 gettext("usage: %s [-h] [label]\n"), 172 argv[0]); 173 exit(1); 174 /*NOTREACHED*/ 175 } 176 177 if (argc == 2) { 178 /* use label on command line */ 179 180 (void) strlcpy(ascii, argv[optind], sizeof (ascii)); 181 } else { 182 /* read label from standard input */ 183 if ((c = read(STDIN_FILENO, ascii, sizeof (ascii))) < 0) { 184 perror(gettext("reading ASCII coded label")); 185 exit(1); 186 /*NOTREACHED*/ 187 } 188 if (ascii[c-1] == '\n') { 189 /* replace '\n' with end of string */ 190 ascii[c-1] = '\0'; 191 } else { 192 /* ensure end of string */ 193 ascii[c] = '\0'; 194 } 195 } 196 197 if (str_to_label(ascii, &label, MAC_LABEL, L_NO_CORRECTION, 198 &err) == -1) { 199 label_error(ascii, err); 200 } 201 if (label_to_str(label, &labelstr, mode, 202 DEF_NAMES) == 0) { 203 (void) printf("%s\n", labelstr); 204 } 205 206 level = &label->classification.class_u.class_chunk; 207 while (*level > 0) { 208 bitfinder(*label, 0); 209 *level -= 1; 210 } 211 m_label_free(label); 212 213 return (0); /* really exit(0); */ 214 } 215