Home | History | Annotate | Download | only in common
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 /*
     29  *	String to binary label translations.
     30  */
     31 
     32 #include <ctype.h>
     33 #include <locale.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <strings.h>
     37 
     38 #include <tsol/label.h>
     39 
     40 #include "labeld.h"
     41 #include <sys/tsol/label_macro.h>
     42 
     43 #undef	CALL_SIZE
     44 #define	CALL_SIZE(type, buf)	(size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
     45 	+ (buf))
     46 
     47 #if	!defined(TEXT_DOMAIN)		/* should be defined by Makefiles */
     48 #define	TEXT_DOMAIN "SYS_TEST"
     49 #endif	/* TEXT_DOMAIN */
     50 
     51 /* short hands */
     52 
     53 #define	IS_ADMIN_LOW(sl) \
     54 	((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
     55 
     56 #define	IS_ADMIN_HIGH(sh) \
     57 	((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
     58 
     59 #define	ISHEX(f, s) \
     60 	(((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
     61 	(((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
     62 	(((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
     63 
     64 #define	slcall callp->param.acall.cargs.stobsl_arg
     65 #define	slret callp->param.aret.rvals.stobsl_ret
     66 /*
     67  *	stobsl - Translate Sensitivity Label string to a Binary Sensitivity
     68  *		Label.
     69  *
     70  *	Entry	string = Sensitivity Label string to be translated.
     71  *		label = Address of Binary Sensitivity Label to be initialized or
     72  *			updated.
     73  *		flags = Flags to control translation:
     74  *			NO_CORRECTION implies NEW_LABEL.
     75  *			NEW_LABEL, Initialize the label to a valid empty
     76  *				Sensitivity Label structure.
     77  *			NO_CORRECTION, Initialize the label to a valid
     78  *				empty Sensitivity Label structure.
     79  *				Prohibit correction to the Sensitivity Label.
     80  *			Other, pass existing Sensitivity Label through for
     81  *				modification.
     82  *
     83  *	Exit	label = Translated (updated) Binary Sensitivity Label.
     84  *		error = If error reported, the error indicator,
     85  *				-1, Unable to access label encodings file;
     86  *				 0, Invalid binary label passed;
     87  *				>0, Position after the first character in
     88  *				    string of error, 1 indicates entire string.
     89  *			Otherwise, unchanged.
     90  *
     91  *	Returns	0, If error.
     92  *		1, If successful.
     93  *
     94  *	Calls	__call_labeld(STOBSL), ISHEX, htobsl, strlen,
     95  *			isspace,
     96  *			strncasecmp.
     97  *
     98  *	Uses	ADMIN_HIGH, ADMIN_LOW.
     99  */
    100 
    101 int
    102 stobsl(const char *string, bslabel_t *label, int flags, int *error)
    103 {
    104 	labeld_data_t	call;
    105 	labeld_data_t	*callp = &call;
    106 	size_t	bufsize = sizeof (labeld_data_t);
    107 	size_t	datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
    108 	int	rval;
    109 	char	*s = (char *)string;
    110 
    111 	while (isspace(*s))
    112 		s++;
    113 	/* accept a leading '[' */
    114 	if (*s == '[') {
    115 		s++;
    116 		while (isspace(*s))
    117 			s++;
    118 	}
    119 	if (ISHEX(flags, s)) {
    120 		if (htobsl(s, label)) {
    121 			return (1);
    122 		} else {
    123 			if (error != NULL)
    124 				*error = 1;
    125 			return (0);
    126 		}
    127 	}
    128 
    129 	if (datasize > bufsize) {
    130 		if ((callp = malloc(datasize)) == NULL) {
    131 			if (error != NULL)
    132 				*error = -1;
    133 			return (0);
    134 		}
    135 		bufsize = datasize;
    136 	}
    137 	callp->callop = STOBSL;
    138 	slcall.flags  = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
    139 	slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
    140 	slcall.label = *label;
    141 	(void) strcpy(slcall.string, string);
    142 
    143 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
    144 		int err = callp->reterr;
    145 
    146 		if (callp != &call) {
    147 			/* free allocated buffer */
    148 			free(callp);
    149 		}
    150 		/*
    151 		 * reterr == 0, OK,
    152 		 * reterr < 0, invalid binary label,
    153 		 * reterr > 0 error position, 1 == whole string
    154 		 */
    155 		if (err == 0) {
    156 			*label = slret.label;
    157 			return (1);
    158 		} else if (err < 0) {
    159 			err = 0;
    160 		}
    161 		if (error != NULL)
    162 			*error = err;
    163 		return (0);
    164 	} else if (rval == NOSERVER) {
    165 		if (callp != &call) {
    166 			/* free allocated buffer */
    167 			free(callp);
    168 		}
    169 		/* server not present */
    170 		/* special case Admin High and Admin Low */
    171 		if (IS_ADMIN_LOW(s)) {
    172 			BSLLOW(label);
    173 		} else if (IS_ADMIN_HIGH(s)) {
    174 			BSLHIGH(label);
    175 		} else {
    176 			goto err1;
    177 		}
    178 		return (1);
    179 	}
    180 	if (callp != &call) {
    181 		/* free allocated buffer */
    182 		free(callp);
    183 	}
    184 err1:
    185 	if (error != NULL)
    186 		*error = -1;
    187 	return (0);
    188 }  /* stobsl */
    189 #undef	slcall
    190 #undef	slret
    191 
    192 #define	clrcall callp->param.acall.cargs.stobclear_arg
    193 #define	clrret callp->param.aret.rvals.stobclear_ret
    194 /*
    195  *	stobclear - Translate Clearance string to a Binary Clearance.
    196  *
    197  *	Entry	string = Clearance string to be translated.
    198  *		clearance = Address of Binary Clearance to be initialized or
    199  *			updated.
    200  *		flags = Flags to control translation:
    201  *			NO_CORRECTION implies NEW_LABEL.
    202  *			NEW_LABEL, Initialize the label to a valid empty
    203  *				Sensitivity Label structure.
    204  *			NO_CORRECTION, Initialize the label to a valid
    205  *				empty Sensitivity Label structure.
    206  *				Prohibit correction to the Sensitivity Label.
    207  *			Other, pass existing Sensitivity Label through for
    208  *				modification.
    209  *
    210  *	Exit	clearance = Translated (updated) Binary Clearance.
    211  *		error = If error reported, the error indicator,
    212  *				-1, Unable to access label encodings file;
    213  *				 0, Invalid binary label passed;
    214  *				>0, Position after the first character in
    215  *				    string of error, 1 indicates entire string.
    216  *			Otherwise, unchanged.
    217  *
    218  *	Returns	0, If error.
    219  *		1, If successful.
    220  *
    221  *	Calls	__call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
    222  *			isspace,
    223  *			strncasecmp.
    224  *
    225  *	Uses	ADMIN_HIGH, ADMIN_LOW.
    226  */
    227 
    228 int
    229 stobclear(const char *string, bclear_t *clearance, int flags, int *error)
    230 {
    231 	labeld_data_t	call;
    232 	labeld_data_t	*callp = &call;
    233 	size_t	bufsize = sizeof (labeld_data_t);
    234 	size_t	datasize = CALL_SIZE(stobclear_call_t, strlen(string) + 1);
    235 	int	rval;
    236 
    237 	if (ISHEX(flags, string)) {
    238 		if (htobclear(string, clearance)) {
    239 			return (1);
    240 		} else {
    241 			if (error != NULL)
    242 				*error = 1;
    243 			return (0);
    244 		}
    245 	}
    246 
    247 	if (datasize > bufsize) {
    248 		if ((callp = malloc(datasize)) == NULL) {
    249 			if (error != NULL)
    250 				*error = -1;
    251 			return (0);
    252 		}
    253 		bufsize = datasize;
    254 	}
    255 	callp->callop = STOBCLEAR;
    256 	clrcall.flags  = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
    257 	clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
    258 	clrcall.clear = *clearance;
    259 	(void) strcpy(clrcall.string, string);
    260 
    261 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
    262 		int err = callp->reterr;
    263 
    264 		if (callp != &call) {
    265 			/* free allocated buffer */
    266 			free(callp);
    267 		}
    268 		/*
    269 		 * reterr == 0, OK,
    270 		 * reterr < 0, invalid binary label,
    271 		 * reterr > 0 error position, 1 == whole string
    272 		 */
    273 		if (err == 0) {
    274 			*clearance = clrret.clear;
    275 			return (1);
    276 		} else if (err < 0) {
    277 			err = 0;
    278 		}
    279 		if (error != NULL)
    280 			*error = err;
    281 		return (0);
    282 	} else if (rval == NOSERVER) {
    283 		char *s = (char *)string;
    284 
    285 		if (callp != &call) {
    286 			/* free allocated buffer */
    287 			free(callp);
    288 		}
    289 		/* server not present */
    290 		/* special case Admin High and Admin Low */
    291 		while (isspace(*s))
    292 			s++;
    293 		if (IS_ADMIN_LOW(s)) {
    294 			BCLEARLOW(clearance);
    295 		} else if (IS_ADMIN_HIGH(s)) {
    296 			BCLEARHIGH(clearance);
    297 		} else {
    298 			goto err1;
    299 		}
    300 		return (1);
    301 	}
    302 	if (callp != &call) {
    303 		/* free allocated buffer */
    304 		free(callp);
    305 	}
    306 err1:
    307 	if (error != NULL)
    308 		*error = -1;
    309 	return (0);
    310 }  /* stobclear */
    311 #undef	clrcall
    312 #undef	clrret
    313