14746Srica /*
24746Srica * CDDL HEADER START
34746Srica *
44746Srica * The contents of this file are subject to the terms of the
54746Srica * Common Development and Distribution License (the "License").
64746Srica * You may not use this file except in compliance with the License.
74746Srica *
84746Srica * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94746Srica * or http://www.opensolaris.org/os/licensing.
104746Srica * See the License for the specific language governing permissions
114746Srica * and limitations under the License.
124746Srica *
134746Srica * When distributing Covered Code, include this CDDL HEADER in each
144746Srica * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154746Srica * If applicable, add the following below this CDDL HEADER, with the
164746Srica * fields enclosed by brackets "[]" replaced with your own identifying
174746Srica * information: Portions Copyright [yyyy] [name of copyright owner]
184746Srica *
194746Srica * CDDL HEADER END
204746Srica */
214746Srica
224746Srica /*
23*8717STon.Nguyen@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
244746Srica * Use is subject to license terms.
254746Srica */
264746Srica
274746Srica
284746Srica /*
294746Srica * lslabels - Display all labels dominating the specified label.
304746Srica */
314746Srica
324746Srica #include <errno.h>
334746Srica #include <libintl.h>
344746Srica #include <locale.h>
354746Srica #include <stdio.h>
364746Srica #include <stdlib.h>
374746Srica #include <string.h>
384746Srica #include <unistd.h>
39*8717STon.Nguyen@Sun.COM #include <stropts.h>
404746Srica
414746Srica #include <sys/param.h>
424746Srica
434746Srica #include <tsol/label.h>
444746Srica #include <sys/tsol/label_macro.h>
454746Srica #include <iso/limits_iso.h>
464746Srica
474746Srica #if !defined(TEXT_DOMAIN)
484746Srica #define TEXT_DOMAIN "SYS_TEST"
494746Srica #endif /* !defined(TEXT_DOMAIN) */
504746Srica
514746Srica int hflg = 0; /* true if hex output */
524746Srica
534746Srica /*
544746Srica * Compartment mask macros.
554746Srica */
564746Srica
574746Srica typedef uint32_t comp_chunk_t;
584746Srica
594746Srica #define __NBWRD (CHAR_BIT * sizeof (comp_chunk_t))
604746Srica #define COMP_BITS (CHAR_BIT * sizeof (Compartments_t))
614746Srica #define compmask(n) (1 << ((__NBWRD - 1) - ((n) % __NBWRD)))
624746Srica #define compword(n) ((n)/__NBWRD)
634746Srica
644746Srica #define COMP_ADDSET(a, p) ((comp_chunk_t *)(a))[compword(p)] |= \
654746Srica compmask(p)
664746Srica #define COMP_DELSET(a, p) ((comp_chunk_t *)(a))[compword(p)] &= \
674746Srica ~compmask(p)
684746Srica #define COMP_ISMEMBER(a, p) ((((comp_chunk_t *)(a))[compword(p)] & \
694746Srica compmask(p)) != 0)
704746Srica
714746Srica /* Need functions to test if bit is on */
724746Srica
734746Srica
744746Srica void
bitfinder(m_label_t label,int next_bit)754746Srica bitfinder(m_label_t label, int next_bit) {
764746Srica char *labelstr = NULL;
774746Srica
784746Srica Compartments_t *comps = &label.compartments;
794746Srica
804746Srica while (next_bit < COMP_BITS) {
814746Srica if (COMP_ISMEMBER(comps, next_bit)) {
824746Srica bitfinder(label, next_bit + 1);
834746Srica COMP_DELSET(comps, next_bit);
844746Srica
854746Srica if (label_to_str(&label, &labelstr, M_LABEL,
864746Srica LONG_NAMES) == 0) {
874746Srica m_label_t *label2 = NULL;
884746Srica int err;
894746Srica
904746Srica if (str_to_label(labelstr, &label2, MAC_LABEL,
914746Srica L_NO_CORRECTION, &err) == 0) {
924746Srica if (!hflg) {
934746Srica (void) printf("%s\n", labelstr);
944746Srica } else {
954746Srica free(labelstr);
964746Srica (void) label_to_str(&label,
974746Srica &labelstr, M_INTERNAL, 0);
984746Srica (void) printf("%s\n", labelstr);
994746Srica }
1004746Srica m_label_free(label2);
1014746Srica }
1024746Srica free(labelstr);
1034746Srica }
1044746Srica bitfinder(label, next_bit + 1);
1054746Srica break;
1064746Srica }
1074746Srica next_bit++;
1084746Srica }
1094746Srica }
1104746Srica
1114746Srica static void
label_error(const char * ascii,const int err)1124746Srica label_error(const char *ascii, const int err)
1134746Srica {
1144746Srica if (errno == EINVAL) {
1154746Srica switch (err) {
1164746Srica case M_BAD_STRING:
1174746Srica (void) fprintf(stderr,
1184746Srica gettext("lslabels: bad string %s\n"), ascii);
1194746Srica break;
1204746Srica case M_BAD_LABEL:
1214746Srica (void) fprintf(stderr,
1224746Srica gettext("lslabels: bad previous label\n"));
1234746Srica break;
1244746Srica default:
1254746Srica (void) fprintf(stderr,
1264746Srica gettext("lslabels: parsing error found in "
1274746Srica "\"%s\" at position %d\n"), ascii, err);
1284746Srica break;
1294746Srica }
1304746Srica } else {
1314746Srica perror("lslabels");
1324746Srica }
1334746Srica exit(1);
1344746Srica /*NOTREACHED*/
1354746Srica }
1364746Srica
1374746Srica int
main(int argc,char ** argv)1384746Srica main(int argc, char **argv)
1394746Srica {
1404746Srica int errflg = 0; /* true if arg error */
1414746Srica m_label_t *label = NULL; /* binary labels */
1424746Srica char ascii[PIPE_BUF]; /* human readable label */
1434746Srica char *labelstr = NULL; /* external label to start from */
1444746Srica int err = 0; /* label error */
1454746Srica int c;
1464746Srica int mode = M_LABEL;
1474746Srica _Classification *level;
1484746Srica
1494746Srica (void) setlocale(LC_ALL, "");
1504746Srica (void) textdomain(TEXT_DOMAIN);
1514746Srica
1524746Srica opterr = 0;
1534746Srica while ((c = getopt(argc, argv, "h")) != EOF) {
1544746Srica
1554746Srica switch (c) {
1564746Srica case 'h':
1574746Srica hflg++;
1584746Srica mode = M_INTERNAL;
1594746Srica break;
1604746Srica
1614746Srica default:
1624746Srica errflg++;
1634746Srica break;
1644746Srica }
1654746Srica }
1664746Srica
1674746Srica argc -= optind - 1;
1684746Srica if (errflg || argc > 2) {
1694746Srica
1704746Srica (void) fprintf(stderr,
1714746Srica gettext("usage: %s [-h] [label]\n"),
1724746Srica argv[0]);
1734746Srica exit(1);
1744746Srica /*NOTREACHED*/
1754746Srica }
1764746Srica
1774746Srica if (argc == 2) {
1784746Srica /* use label on command line */
1794746Srica
1804746Srica (void) strlcpy(ascii, argv[optind], sizeof (ascii));
1814746Srica } else {
1824746Srica /* read label from standard input */
183*8717STon.Nguyen@Sun.COM if ((c = read(STDIN_FILENO, ascii, sizeof (ascii))) <= 0) {
1844746Srica perror(gettext("reading ASCII coded label"));
1854746Srica exit(1);
1864746Srica /*NOTREACHED*/
1874746Srica }
188*8717STon.Nguyen@Sun.COM
189*8717STon.Nguyen@Sun.COM /*
190*8717STon.Nguyen@Sun.COM * replace '\n' or (end of buffer) with end of string.
191*8717STon.Nguyen@Sun.COM */
192*8717STon.Nguyen@Sun.COM ascii[c-1] = '\0';
193*8717STon.Nguyen@Sun.COM
194*8717STon.Nguyen@Sun.COM /*
195*8717STon.Nguyen@Sun.COM * flush any remaining input past the size of the buffer.
196*8717STon.Nguyen@Sun.COM */
197*8717STon.Nguyen@Sun.COM (void) ioctl(STDIN_FILENO, I_FLUSH, FLUSHR);
1984746Srica }
1994746Srica
2004746Srica if (str_to_label(ascii, &label, MAC_LABEL, L_NO_CORRECTION,
2014746Srica &err) == -1) {
2024746Srica label_error(ascii, err);
2034746Srica }
2044746Srica if (label_to_str(label, &labelstr, mode,
2054746Srica DEF_NAMES) == 0) {
2064746Srica (void) printf("%s\n", labelstr);
2074746Srica }
2084746Srica
2094746Srica level = &label->classification.class_u.class_chunk;
2104746Srica while (*level > 0) {
2114746Srica bitfinder(*label, 0);
2124746Srica *level -= 1;
2134746Srica }
2144746Srica m_label_free(label);
2154746Srica
2164746Srica return (0); /* really exit(0); */
2174746Srica }
218