xref: /titanic_52/usr/src/lib/libtsol/common/stob.c (revision a6080eb58dc0a9948e87d1bd3773da387e2c64ca)
145916cd2Sjpk /*
245916cd2Sjpk  * CDDL HEADER START
345916cd2Sjpk  *
445916cd2Sjpk  * The contents of this file are subject to the terms of the
545916cd2Sjpk  * Common Development and Distribution License (the "License").
645916cd2Sjpk  * You may not use this file except in compliance with the License.
745916cd2Sjpk  *
845916cd2Sjpk  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
945916cd2Sjpk  * or http://www.opensolaris.org/os/licensing.
1045916cd2Sjpk  * See the License for the specific language governing permissions
1145916cd2Sjpk  * and limitations under the License.
1245916cd2Sjpk  *
1345916cd2Sjpk  * When distributing Covered Code, include this CDDL HEADER in each
1445916cd2Sjpk  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1545916cd2Sjpk  * If applicable, add the following below this CDDL HEADER, with the
1645916cd2Sjpk  * fields enclosed by brackets "[]" replaced with your own identifying
1745916cd2Sjpk  * information: Portions Copyright [yyyy] [name of copyright owner]
1845916cd2Sjpk  *
1945916cd2Sjpk  * CDDL HEADER END
2045916cd2Sjpk  */
2145916cd2Sjpk /*
22*a6080eb5Sgww  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2345916cd2Sjpk  * Use is subject to license terms.
2445916cd2Sjpk  */
2545916cd2Sjpk 
2645916cd2Sjpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
2745916cd2Sjpk 
2845916cd2Sjpk /*
2945916cd2Sjpk  *	String to binary label translations.
3045916cd2Sjpk  */
3145916cd2Sjpk 
3245916cd2Sjpk #include <ctype.h>
3345916cd2Sjpk #include <locale.h>
3445916cd2Sjpk #include <stdio.h>
3545916cd2Sjpk #include <stdlib.h>
3645916cd2Sjpk #include <strings.h>
3745916cd2Sjpk 
3845916cd2Sjpk #include <tsol/label.h>
3945916cd2Sjpk 
4045916cd2Sjpk #include "labeld.h"
4145916cd2Sjpk #include <sys/tsol/label_macro.h>
4245916cd2Sjpk 
4345916cd2Sjpk #undef	CALL_SIZE
4445916cd2Sjpk #define	CALL_SIZE(type, buf)	(size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
4545916cd2Sjpk 	+ (buf))
4645916cd2Sjpk 
4745916cd2Sjpk #if	!defined(TEXT_DOMAIN)		/* should be defined by Makefiles */
4845916cd2Sjpk #define	TEXT_DOMAIN "SYS_TEST"
4945916cd2Sjpk #endif	/* TEXT_DOMAIN */
5045916cd2Sjpk 
5145916cd2Sjpk /* short hands */
5245916cd2Sjpk 
5345916cd2Sjpk #define	IS_ADMIN_LOW(sl) \
5445916cd2Sjpk 	((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
5545916cd2Sjpk 
5645916cd2Sjpk #define	IS_ADMIN_HIGH(sh) \
5745916cd2Sjpk 	((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
5845916cd2Sjpk 
5945916cd2Sjpk #define	ISHEX(f, s) \
6045916cd2Sjpk 	(((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
6145916cd2Sjpk 	(((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
6245916cd2Sjpk 	(((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
6345916cd2Sjpk 
6445916cd2Sjpk #define	slcall callp->param.acall.cargs.stobsl_arg
6545916cd2Sjpk #define	slret callp->param.aret.rvals.stobsl_ret
6645916cd2Sjpk /*
6745916cd2Sjpk  *	stobsl - Translate Sensitivity Label string to a Binary Sensitivity
6845916cd2Sjpk  *		Label.
6945916cd2Sjpk  *
7045916cd2Sjpk  *	Entry	string = Sensitivity Label string to be translated.
7145916cd2Sjpk  *		label = Address of Binary Sensitivity Label to be initialized or
7245916cd2Sjpk  *			updated.
7345916cd2Sjpk  *		flags = Flags to control translation:
7445916cd2Sjpk  *			NO_CORRECTION implies NEW_LABEL.
7545916cd2Sjpk  *			NEW_LABEL, Initialize the label to a valid empty
7645916cd2Sjpk  *				Sensitivity Label structure.
7745916cd2Sjpk  *			NO_CORRECTION, Initialize the label to a valid
7845916cd2Sjpk  *				empty Sensitivity Label structure.
7945916cd2Sjpk  *				Prohibit correction to the Sensitivity Label.
8045916cd2Sjpk  *			Other, pass existing Sensitivity Label through for
8145916cd2Sjpk  *				modification.
8245916cd2Sjpk  *
8345916cd2Sjpk  *	Exit	label = Translated (updated) Binary Sensitivity Label.
8445916cd2Sjpk  *		error = If error reported, the error indicator,
8545916cd2Sjpk  *				-1, Unable to access label encodings file;
8645916cd2Sjpk  *				 0, Invalid binary label passed;
8745916cd2Sjpk  *				>0, Position after the first character in
8845916cd2Sjpk  *				    string of error, 1 indicates entire string.
8945916cd2Sjpk  *			Otherwise, unchanged.
9045916cd2Sjpk  *
9145916cd2Sjpk  *	Returns	0, If error.
9245916cd2Sjpk  *		1, If successful.
9345916cd2Sjpk  *
9445916cd2Sjpk  *	Calls	__call_labeld(STOBSL), ISHEX, htobsl, strlen,
9545916cd2Sjpk  *			isspace,
9645916cd2Sjpk  *			strncasecmp.
9745916cd2Sjpk  *
9845916cd2Sjpk  *	Uses	ADMIN_HIGH, ADMIN_LOW.
9945916cd2Sjpk  */
10045916cd2Sjpk 
10145916cd2Sjpk int
10245916cd2Sjpk stobsl(const char *string, bslabel_t *label, int flags, int *error)
10345916cd2Sjpk {
10445916cd2Sjpk 	labeld_data_t	call;
10545916cd2Sjpk 	labeld_data_t	*callp = &call;
10645916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
10745916cd2Sjpk 	size_t	datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
10845916cd2Sjpk 	int	rval;
10945916cd2Sjpk 	char	*s = (char *)string;
11045916cd2Sjpk 
11145916cd2Sjpk 	while (isspace(*s))
11245916cd2Sjpk 		s++;
11345916cd2Sjpk 	/* accept a leading '[' */
11445916cd2Sjpk 	if (*s == '[') {
11545916cd2Sjpk 		s++;
11645916cd2Sjpk 		while (isspace(*s))
11745916cd2Sjpk 			s++;
11845916cd2Sjpk 	}
11945916cd2Sjpk 	if (ISHEX(flags, s)) {
12045916cd2Sjpk 		if (htobsl(s, label)) {
12145916cd2Sjpk 			return (1);
12245916cd2Sjpk 		} else {
12345916cd2Sjpk 			if (error != NULL)
12445916cd2Sjpk 				*error = 1;
12545916cd2Sjpk 			return (0);
12645916cd2Sjpk 		}
12745916cd2Sjpk 	}
12845916cd2Sjpk 
12945916cd2Sjpk 	if (datasize > bufsize) {
13045916cd2Sjpk 		if ((callp = malloc(datasize)) == NULL) {
13145916cd2Sjpk 			if (error != NULL)
13245916cd2Sjpk 				*error = -1;
13345916cd2Sjpk 			return (0);
13445916cd2Sjpk 		}
13545916cd2Sjpk 		bufsize = datasize;
13645916cd2Sjpk 	}
13745916cd2Sjpk 	callp->callop = STOBSL;
13845916cd2Sjpk 	slcall.flags  = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
13945916cd2Sjpk 	slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
14045916cd2Sjpk 	slcall.label = *label;
14145916cd2Sjpk 	(void) strcpy(slcall.string, string);
14245916cd2Sjpk 
14345916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
14445916cd2Sjpk 		int err = callp->reterr;
14545916cd2Sjpk 
14645916cd2Sjpk 		if (callp != &call) {
14745916cd2Sjpk 			/* free allocated buffer */
14845916cd2Sjpk 			free(callp);
14945916cd2Sjpk 		}
15045916cd2Sjpk 		/*
15145916cd2Sjpk 		 * reterr == 0, OK,
15245916cd2Sjpk 		 * reterr < 0, invalid binary label,
15345916cd2Sjpk 		 * reterr > 0 error position, 1 == whole string
15445916cd2Sjpk 		 */
15545916cd2Sjpk 		if (err == 0) {
15645916cd2Sjpk 			*label = slret.label;
15745916cd2Sjpk 			return (1);
15845916cd2Sjpk 		} else if (err < 0) {
15945916cd2Sjpk 			err = 0;
16045916cd2Sjpk 		}
16145916cd2Sjpk 		if (error != NULL)
16245916cd2Sjpk 			*error = err;
16345916cd2Sjpk 		return (0);
16445916cd2Sjpk 	} else if (rval == NOSERVER) {
16545916cd2Sjpk 		if (callp != &call) {
16645916cd2Sjpk 			/* free allocated buffer */
16745916cd2Sjpk 			free(callp);
16845916cd2Sjpk 		}
16945916cd2Sjpk 		/* server not present */
17045916cd2Sjpk 		/* special case Admin High and Admin Low */
17145916cd2Sjpk 		if (IS_ADMIN_LOW(s)) {
17245916cd2Sjpk 			BSLLOW(label);
17345916cd2Sjpk 		} else if (IS_ADMIN_HIGH(s)) {
17445916cd2Sjpk 			BSLHIGH(label);
17545916cd2Sjpk 		} else {
17645916cd2Sjpk 			goto err1;
17745916cd2Sjpk 		}
17845916cd2Sjpk 		return (1);
17945916cd2Sjpk 	}
18045916cd2Sjpk 	if (callp != &call) {
18145916cd2Sjpk 		/* free allocated buffer */
18245916cd2Sjpk 		free(callp);
18345916cd2Sjpk 	}
18445916cd2Sjpk err1:
18545916cd2Sjpk 	if (error != NULL)
18645916cd2Sjpk 		*error = -1;
18745916cd2Sjpk 	return (0);
18845916cd2Sjpk }  /* stobsl */
18945916cd2Sjpk #undef	slcall
19045916cd2Sjpk #undef	slret
19145916cd2Sjpk 
19245916cd2Sjpk #define	clrcall callp->param.acall.cargs.stobclear_arg
19345916cd2Sjpk #define	clrret callp->param.aret.rvals.stobclear_ret
19445916cd2Sjpk /*
19545916cd2Sjpk  *	stobclear - Translate Clearance string to a Binary Clearance.
19645916cd2Sjpk  *
19745916cd2Sjpk  *	Entry	string = Clearance string to be translated.
19845916cd2Sjpk  *		clearance = Address of Binary Clearance to be initialized or
19945916cd2Sjpk  *			updated.
20045916cd2Sjpk  *		flags = Flags to control translation:
20145916cd2Sjpk  *			NO_CORRECTION implies NEW_LABEL.
20245916cd2Sjpk  *			NEW_LABEL, Initialize the label to a valid empty
20345916cd2Sjpk  *				Sensitivity Label structure.
20445916cd2Sjpk  *			NO_CORRECTION, Initialize the label to a valid
20545916cd2Sjpk  *				empty Sensitivity Label structure.
20645916cd2Sjpk  *				Prohibit correction to the Sensitivity Label.
20745916cd2Sjpk  *			Other, pass existing Sensitivity Label through for
20845916cd2Sjpk  *				modification.
20945916cd2Sjpk  *
21045916cd2Sjpk  *	Exit	clearance = Translated (updated) Binary Clearance.
21145916cd2Sjpk  *		error = If error reported, the error indicator,
21245916cd2Sjpk  *				-1, Unable to access label encodings file;
21345916cd2Sjpk  *				 0, Invalid binary label passed;
21445916cd2Sjpk  *				>0, Position after the first character in
21545916cd2Sjpk  *				    string of error, 1 indicates entire string.
21645916cd2Sjpk  *			Otherwise, unchanged.
21745916cd2Sjpk  *
21845916cd2Sjpk  *	Returns	0, If error.
21945916cd2Sjpk  *		1, If successful.
22045916cd2Sjpk  *
22145916cd2Sjpk  *	Calls	__call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
22245916cd2Sjpk  *			isspace,
22345916cd2Sjpk  *			strncasecmp.
22445916cd2Sjpk  *
22545916cd2Sjpk  *	Uses	ADMIN_HIGH, ADMIN_LOW.
22645916cd2Sjpk  */
22745916cd2Sjpk 
22845916cd2Sjpk int
22945916cd2Sjpk stobclear(const char *string, bclear_t *clearance, int flags, int *error)
23045916cd2Sjpk {
23145916cd2Sjpk 	labeld_data_t	call;
23245916cd2Sjpk 	labeld_data_t	*callp = &call;
23345916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
234*a6080eb5Sgww 	size_t	datasize = CALL_SIZE(stobclear_call_t, strlen(string) + 1);
23545916cd2Sjpk 	int	rval;
23645916cd2Sjpk 
23745916cd2Sjpk 	if (ISHEX(flags, string)) {
23845916cd2Sjpk 		if (htobclear(string, clearance)) {
23945916cd2Sjpk 			return (1);
24045916cd2Sjpk 		} else {
24145916cd2Sjpk 			if (error != NULL)
24245916cd2Sjpk 				*error = 1;
24345916cd2Sjpk 			return (0);
24445916cd2Sjpk 		}
24545916cd2Sjpk 	}
24645916cd2Sjpk 
24745916cd2Sjpk 	if (datasize > bufsize) {
24845916cd2Sjpk 		if ((callp = malloc(datasize)) == NULL) {
24945916cd2Sjpk 			if (error != NULL)
25045916cd2Sjpk 				*error = -1;
25145916cd2Sjpk 			return (0);
25245916cd2Sjpk 		}
25345916cd2Sjpk 		bufsize = datasize;
25445916cd2Sjpk 	}
25545916cd2Sjpk 	callp->callop = STOBCLEAR;
25645916cd2Sjpk 	clrcall.flags  = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
25745916cd2Sjpk 	clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
25845916cd2Sjpk 	clrcall.clear = *clearance;
25945916cd2Sjpk 	(void) strcpy(clrcall.string, string);
26045916cd2Sjpk 
26145916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
26245916cd2Sjpk 		int err = callp->reterr;
26345916cd2Sjpk 
26445916cd2Sjpk 		if (callp != &call) {
26545916cd2Sjpk 			/* free allocated buffer */
26645916cd2Sjpk 			free(callp);
26745916cd2Sjpk 		}
26845916cd2Sjpk 		/*
26945916cd2Sjpk 		 * reterr == 0, OK,
27045916cd2Sjpk 		 * reterr < 0, invalid binary label,
27145916cd2Sjpk 		 * reterr > 0 error position, 1 == whole string
27245916cd2Sjpk 		 */
27345916cd2Sjpk 		if (err == 0) {
27445916cd2Sjpk 			*clearance = clrret.clear;
27545916cd2Sjpk 			return (1);
27645916cd2Sjpk 		} else if (err < 0) {
27745916cd2Sjpk 			err = 0;
27845916cd2Sjpk 		}
27945916cd2Sjpk 		if (error != NULL)
28045916cd2Sjpk 			*error = err;
28145916cd2Sjpk 		return (0);
28245916cd2Sjpk 	} else if (rval == NOSERVER) {
28345916cd2Sjpk 		char *s = (char *)string;
28445916cd2Sjpk 
28545916cd2Sjpk 		if (callp != &call) {
28645916cd2Sjpk 			/* free allocated buffer */
28745916cd2Sjpk 			free(callp);
28845916cd2Sjpk 		}
28945916cd2Sjpk 		/* server not present */
29045916cd2Sjpk 		/* special case Admin High and Admin Low */
29145916cd2Sjpk 		while (isspace(*s))
29245916cd2Sjpk 			s++;
29345916cd2Sjpk 		if (IS_ADMIN_LOW(s)) {
29445916cd2Sjpk 			BCLEARLOW(clearance);
29545916cd2Sjpk 		} else if (IS_ADMIN_HIGH(s)) {
29645916cd2Sjpk 			BCLEARHIGH(clearance);
29745916cd2Sjpk 		} else {
29845916cd2Sjpk 			goto err1;
29945916cd2Sjpk 		}
30045916cd2Sjpk 		return (1);
30145916cd2Sjpk 	}
30245916cd2Sjpk 	if (callp != &call) {
30345916cd2Sjpk 		/* free allocated buffer */
30445916cd2Sjpk 		free(callp);
30545916cd2Sjpk 	}
30645916cd2Sjpk err1:
30745916cd2Sjpk 	if (error != NULL)
30845916cd2Sjpk 		*error = -1;
30945916cd2Sjpk 	return (0);
31045916cd2Sjpk }  /* stobclear */
31145916cd2Sjpk #undef	clrcall
31245916cd2Sjpk #undef	clrret
313