xref: /onnv-gate/usr/src/lib/libtsol/common/stob.c (revision 4999:8b4ad656b6ab)
11676Sjpk /*
21676Sjpk  * CDDL HEADER START
31676Sjpk  *
41676Sjpk  * The contents of this file are subject to the terms of the
51676Sjpk  * Common Development and Distribution License (the "License").
61676Sjpk  * You may not use this file except in compliance with the License.
71676Sjpk  *
81676Sjpk  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91676Sjpk  * or http://www.opensolaris.org/os/licensing.
101676Sjpk  * See the License for the specific language governing permissions
111676Sjpk  * and limitations under the License.
121676Sjpk  *
131676Sjpk  * When distributing Covered Code, include this CDDL HEADER in each
141676Sjpk  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151676Sjpk  * If applicable, add the following below this CDDL HEADER, with the
161676Sjpk  * fields enclosed by brackets "[]" replaced with your own identifying
171676Sjpk  * information: Portions Copyright [yyyy] [name of copyright owner]
181676Sjpk  *
191676Sjpk  * CDDL HEADER END
201676Sjpk  */
211676Sjpk /*
22*4999Sgww  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
231676Sjpk  * Use is subject to license terms.
241676Sjpk  */
251676Sjpk 
261676Sjpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
271676Sjpk 
281676Sjpk /*
291676Sjpk  *	String to binary label translations.
301676Sjpk  */
311676Sjpk 
321676Sjpk #include <ctype.h>
331676Sjpk #include <locale.h>
341676Sjpk #include <stdio.h>
351676Sjpk #include <stdlib.h>
361676Sjpk #include <strings.h>
371676Sjpk 
381676Sjpk #include <tsol/label.h>
391676Sjpk 
401676Sjpk #include "labeld.h"
411676Sjpk #include <sys/tsol/label_macro.h>
421676Sjpk 
431676Sjpk #undef	CALL_SIZE
441676Sjpk #define	CALL_SIZE(type, buf)	(size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
451676Sjpk 	+ (buf))
461676Sjpk 
471676Sjpk #if	!defined(TEXT_DOMAIN)		/* should be defined by Makefiles */
481676Sjpk #define	TEXT_DOMAIN "SYS_TEST"
491676Sjpk #endif	/* TEXT_DOMAIN */
501676Sjpk 
511676Sjpk /* short hands */
521676Sjpk 
531676Sjpk #define	IS_ADMIN_LOW(sl) \
541676Sjpk 	((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
551676Sjpk 
561676Sjpk #define	IS_ADMIN_HIGH(sh) \
571676Sjpk 	((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
581676Sjpk 
591676Sjpk #define	ISHEX(f, s) \
601676Sjpk 	(((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
611676Sjpk 	(((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
621676Sjpk 	(((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
631676Sjpk 
641676Sjpk #define	slcall callp->param.acall.cargs.stobsl_arg
651676Sjpk #define	slret callp->param.aret.rvals.stobsl_ret
661676Sjpk /*
671676Sjpk  *	stobsl - Translate Sensitivity Label string to a Binary Sensitivity
681676Sjpk  *		Label.
691676Sjpk  *
701676Sjpk  *	Entry	string = Sensitivity Label string to be translated.
711676Sjpk  *		label = Address of Binary Sensitivity Label to be initialized or
721676Sjpk  *			updated.
731676Sjpk  *		flags = Flags to control translation:
741676Sjpk  *			NO_CORRECTION implies NEW_LABEL.
751676Sjpk  *			NEW_LABEL, Initialize the label to a valid empty
761676Sjpk  *				Sensitivity Label structure.
771676Sjpk  *			NO_CORRECTION, Initialize the label to a valid
781676Sjpk  *				empty Sensitivity Label structure.
791676Sjpk  *				Prohibit correction to the Sensitivity Label.
801676Sjpk  *			Other, pass existing Sensitivity Label through for
811676Sjpk  *				modification.
821676Sjpk  *
831676Sjpk  *	Exit	label = Translated (updated) Binary Sensitivity Label.
841676Sjpk  *		error = If error reported, the error indicator,
851676Sjpk  *				-1, Unable to access label encodings file;
861676Sjpk  *				 0, Invalid binary label passed;
871676Sjpk  *				>0, Position after the first character in
881676Sjpk  *				    string of error, 1 indicates entire string.
891676Sjpk  *			Otherwise, unchanged.
901676Sjpk  *
911676Sjpk  *	Returns	0, If error.
921676Sjpk  *		1, If successful.
931676Sjpk  *
941676Sjpk  *	Calls	__call_labeld(STOBSL), ISHEX, htobsl, strlen,
951676Sjpk  *			isspace,
961676Sjpk  *			strncasecmp.
971676Sjpk  *
981676Sjpk  *	Uses	ADMIN_HIGH, ADMIN_LOW.
991676Sjpk  */
1001676Sjpk 
1011676Sjpk int
stobsl(const char * string,bslabel_t * label,int flags,int * error)1021676Sjpk stobsl(const char *string, bslabel_t *label, int flags, int *error)
1031676Sjpk {
1041676Sjpk 	labeld_data_t	call;
1051676Sjpk 	labeld_data_t	*callp = &call;
1061676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
1071676Sjpk 	size_t	datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
1081676Sjpk 	int	rval;
1091676Sjpk 	char	*s = (char *)string;
1101676Sjpk 
1111676Sjpk 	while (isspace(*s))
1121676Sjpk 		s++;
1131676Sjpk 	/* accept a leading '[' */
1141676Sjpk 	if (*s == '[') {
1151676Sjpk 		s++;
1161676Sjpk 		while (isspace(*s))
1171676Sjpk 			s++;
1181676Sjpk 	}
1191676Sjpk 	if (ISHEX(flags, s)) {
1201676Sjpk 		if (htobsl(s, label)) {
1211676Sjpk 			return (1);
1221676Sjpk 		} else {
1231676Sjpk 			if (error != NULL)
1241676Sjpk 				*error = 1;
1251676Sjpk 			return (0);
1261676Sjpk 		}
1271676Sjpk 	}
1281676Sjpk 
1291676Sjpk 	if (datasize > bufsize) {
1301676Sjpk 		if ((callp = malloc(datasize)) == NULL) {
1311676Sjpk 			if (error != NULL)
1321676Sjpk 				*error = -1;
1331676Sjpk 			return (0);
1341676Sjpk 		}
1351676Sjpk 		bufsize = datasize;
1361676Sjpk 	}
1371676Sjpk 	callp->callop = STOBSL;
1381676Sjpk 	slcall.flags  = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
1391676Sjpk 	slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
1401676Sjpk 	slcall.label = *label;
1411676Sjpk 	(void) strcpy(slcall.string, string);
1421676Sjpk 
1431676Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
1441676Sjpk 		int err = callp->reterr;
1451676Sjpk 
1461676Sjpk 		if (callp != &call) {
1471676Sjpk 			/* free allocated buffer */
1481676Sjpk 			free(callp);
1491676Sjpk 		}
1501676Sjpk 		/*
1511676Sjpk 		 * reterr == 0, OK,
1521676Sjpk 		 * reterr < 0, invalid binary label,
1531676Sjpk 		 * reterr > 0 error position, 1 == whole string
1541676Sjpk 		 */
1551676Sjpk 		if (err == 0) {
1561676Sjpk 			*label = slret.label;
1571676Sjpk 			return (1);
1581676Sjpk 		} else if (err < 0) {
1591676Sjpk 			err = 0;
1601676Sjpk 		}
1611676Sjpk 		if (error != NULL)
1621676Sjpk 			*error = err;
1631676Sjpk 		return (0);
1641676Sjpk 	} else if (rval == NOSERVER) {
1651676Sjpk 		if (callp != &call) {
1661676Sjpk 			/* free allocated buffer */
1671676Sjpk 			free(callp);
1681676Sjpk 		}
1691676Sjpk 		/* server not present */
1701676Sjpk 		/* special case Admin High and Admin Low */
1711676Sjpk 		if (IS_ADMIN_LOW(s)) {
1721676Sjpk 			BSLLOW(label);
1731676Sjpk 		} else if (IS_ADMIN_HIGH(s)) {
1741676Sjpk 			BSLHIGH(label);
1751676Sjpk 		} else {
1761676Sjpk 			goto err1;
1771676Sjpk 		}
1781676Sjpk 		return (1);
1791676Sjpk 	}
1801676Sjpk 	if (callp != &call) {
1811676Sjpk 		/* free allocated buffer */
1821676Sjpk 		free(callp);
1831676Sjpk 	}
1841676Sjpk err1:
1851676Sjpk 	if (error != NULL)
1861676Sjpk 		*error = -1;
1871676Sjpk 	return (0);
1881676Sjpk }  /* stobsl */
1891676Sjpk #undef	slcall
1901676Sjpk #undef	slret
1911676Sjpk 
1921676Sjpk #define	clrcall callp->param.acall.cargs.stobclear_arg
1931676Sjpk #define	clrret callp->param.aret.rvals.stobclear_ret
1941676Sjpk /*
1951676Sjpk  *	stobclear - Translate Clearance string to a Binary Clearance.
1961676Sjpk  *
1971676Sjpk  *	Entry	string = Clearance string to be translated.
1981676Sjpk  *		clearance = Address of Binary Clearance to be initialized or
1991676Sjpk  *			updated.
2001676Sjpk  *		flags = Flags to control translation:
2011676Sjpk  *			NO_CORRECTION implies NEW_LABEL.
2021676Sjpk  *			NEW_LABEL, Initialize the label to a valid empty
2031676Sjpk  *				Sensitivity Label structure.
2041676Sjpk  *			NO_CORRECTION, Initialize the label to a valid
2051676Sjpk  *				empty Sensitivity Label structure.
2061676Sjpk  *				Prohibit correction to the Sensitivity Label.
2071676Sjpk  *			Other, pass existing Sensitivity Label through for
2081676Sjpk  *				modification.
2091676Sjpk  *
2101676Sjpk  *	Exit	clearance = Translated (updated) Binary Clearance.
2111676Sjpk  *		error = If error reported, the error indicator,
2121676Sjpk  *				-1, Unable to access label encodings file;
2131676Sjpk  *				 0, Invalid binary label passed;
2141676Sjpk  *				>0, Position after the first character in
2151676Sjpk  *				    string of error, 1 indicates entire string.
2161676Sjpk  *			Otherwise, unchanged.
2171676Sjpk  *
2181676Sjpk  *	Returns	0, If error.
2191676Sjpk  *		1, If successful.
2201676Sjpk  *
2211676Sjpk  *	Calls	__call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
2221676Sjpk  *			isspace,
2231676Sjpk  *			strncasecmp.
2241676Sjpk  *
2251676Sjpk  *	Uses	ADMIN_HIGH, ADMIN_LOW.
2261676Sjpk  */
2271676Sjpk 
2281676Sjpk int
stobclear(const char * string,bclear_t * clearance,int flags,int * error)2291676Sjpk stobclear(const char *string, bclear_t *clearance, int flags, int *error)
2301676Sjpk {
2311676Sjpk 	labeld_data_t	call;
2321676Sjpk 	labeld_data_t	*callp = &call;
2331676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
234*4999Sgww 	size_t	datasize = CALL_SIZE(stobclear_call_t, strlen(string) + 1);
2351676Sjpk 	int	rval;
2361676Sjpk 
2371676Sjpk 	if (ISHEX(flags, string)) {
2381676Sjpk 		if (htobclear(string, clearance)) {
2391676Sjpk 			return (1);
2401676Sjpk 		} else {
2411676Sjpk 			if (error != NULL)
2421676Sjpk 				*error = 1;
2431676Sjpk 			return (0);
2441676Sjpk 		}
2451676Sjpk 	}
2461676Sjpk 
2471676Sjpk 	if (datasize > bufsize) {
2481676Sjpk 		if ((callp = malloc(datasize)) == NULL) {
2491676Sjpk 			if (error != NULL)
2501676Sjpk 				*error = -1;
2511676Sjpk 			return (0);
2521676Sjpk 		}
2531676Sjpk 		bufsize = datasize;
2541676Sjpk 	}
2551676Sjpk 	callp->callop = STOBCLEAR;
2561676Sjpk 	clrcall.flags  = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
2571676Sjpk 	clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
2581676Sjpk 	clrcall.clear = *clearance;
2591676Sjpk 	(void) strcpy(clrcall.string, string);
2601676Sjpk 
2611676Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
2621676Sjpk 		int err = callp->reterr;
2631676Sjpk 
2641676Sjpk 		if (callp != &call) {
2651676Sjpk 			/* free allocated buffer */
2661676Sjpk 			free(callp);
2671676Sjpk 		}
2681676Sjpk 		/*
2691676Sjpk 		 * reterr == 0, OK,
2701676Sjpk 		 * reterr < 0, invalid binary label,
2711676Sjpk 		 * reterr > 0 error position, 1 == whole string
2721676Sjpk 		 */
2731676Sjpk 		if (err == 0) {
2741676Sjpk 			*clearance = clrret.clear;
2751676Sjpk 			return (1);
2761676Sjpk 		} else if (err < 0) {
2771676Sjpk 			err = 0;
2781676Sjpk 		}
2791676Sjpk 		if (error != NULL)
2801676Sjpk 			*error = err;
2811676Sjpk 		return (0);
2821676Sjpk 	} else if (rval == NOSERVER) {
2831676Sjpk 		char *s = (char *)string;
2841676Sjpk 
2851676Sjpk 		if (callp != &call) {
2861676Sjpk 			/* free allocated buffer */
2871676Sjpk 			free(callp);
2881676Sjpk 		}
2891676Sjpk 		/* server not present */
2901676Sjpk 		/* special case Admin High and Admin Low */
2911676Sjpk 		while (isspace(*s))
2921676Sjpk 			s++;
2931676Sjpk 		if (IS_ADMIN_LOW(s)) {
2941676Sjpk 			BCLEARLOW(clearance);
2951676Sjpk 		} else if (IS_ADMIN_HIGH(s)) {
2961676Sjpk 			BCLEARHIGH(clearance);
2971676Sjpk 		} else {
2981676Sjpk 			goto err1;
2991676Sjpk 		}
3001676Sjpk 		return (1);
3011676Sjpk 	}
3021676Sjpk 	if (callp != &call) {
3031676Sjpk 		/* free allocated buffer */
3041676Sjpk 		free(callp);
3051676Sjpk 	}
3061676Sjpk err1:
3071676Sjpk 	if (error != NULL)
3081676Sjpk 		*error = -1;
3091676Sjpk 	return (0);
3101676Sjpk }  /* stobclear */
3111676Sjpk #undef	clrcall
3121676Sjpk #undef	clrret
313