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 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 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 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 */ 192f875b4ebSrica 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