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