xref: /onnv-gate/usr/src/cmd/tsol/lslabels/lslabels.c (revision 8717:4e2791ce9469)
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