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 2006 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 /*
     30  *	Miscellaneous user interfaces to trusted label functions.
     31  *
     32  */
     33 
     34 
     35 #include <ctype.h>
     36 #include <stdlib.h>
     37 #include <strings.h>
     38 
     39 #include <sys/mman.h>
     40 
     41 #include <tsol/label.h>
     42 
     43 #include "labeld.h"
     44 #include "clnt.h"
     45 #include <sys/tsol/label_macro.h>
     46 #include <secdb.h>
     47 #include <user_attr.h>
     48 
     49 static	bslabel_t slow, shigh;	/* static Admin Low and High SLs */
     50 static	bclear_t  clow, chigh;	/* static Admin Low and High CLRs */
     51 
     52 static char color[MAXCOLOR];
     53 
     54 
     55 #define	incall callp->param.acall.cargs.inset_arg
     56 #define	inret callp->param.aret.rvals.inset_ret
     57 /*
     58  *	blinset - Check in a label set.
     59  *
     60  *	Entry	label = Sensitivity Label to check.
     61  *		id    = Label set identifier of set to check.
     62  *
     63  *	Exit	None.
     64  *
     65  *	Returns	-1, If label set unavailable, or server failure.
     66  *		 0, If label not in label set.
     67  *		 1, If label is in the label set.
     68  *
     69  *	Calls	__call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH.
     70  *
     71  *	Uses	slow, shigh.
     72  */
     73 
     74 int
     75 blinset(const bslabel_t *label, const set_id *id)
     76 {
     77 	if (id->type == SYSTEM_ACCREDITATION_RANGE) {
     78 		if (!BLTYPE(&slow, SUN_SL_ID)) {
     79 			/* initialize static labels. */
     80 
     81 			BSLLOW(&slow);
     82 			BSLHIGH(&shigh);
     83 		}
     84 
     85 		if (BLTYPE(label, SUN_SL_ID) &&
     86 		    (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
     87 
     88 			return (1);
     89 	}
     90 	if (id->type == USER_ACCREDITATION_RANGE ||
     91 	    id->type == SYSTEM_ACCREDITATION_RANGE) {
     92 		labeld_data_t	call;
     93 		labeld_data_t	*callp = &call;
     94 		size_t	bufsize = sizeof (labeld_data_t);
     95 		size_t	datasize = CALL_SIZE(inset_call_t, 0);
     96 
     97 		call.callop = BLINSET;
     98 		incall.label = *label;
     99 		incall.type = id->type;
    100 
    101 		if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
    102 			/* process error */
    103 
    104 			return (-1);
    105 		}
    106 		return (inret.inset);
    107 	} else {
    108 		/*
    109 		 * Only System and User Accreditation Ranges presently
    110 		 * implemented.
    111 		 */
    112 		return (-1);
    113 	}
    114 }
    115 #undef	incall
    116 #undef	inret
    117 
    118 #define	slvcall callp->param.acall.cargs.slvalid_arg
    119 #define	slvret callp->param.aret.rvals.slvalid_ret
    120 /*
    121  *	bslvalid - Check Sensitivity Label for validity.
    122  *
    123  *	Entry	label = Sensitivity Label to check.
    124  *
    125  *	Exit	None.
    126  *
    127  *	Returns	-1, If unable to access label encodings file, or server failure.
    128  *		 0, If label not valid.
    129  *		 1, If label is valid.
    130  *
    131  *	Calls	__call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH.
    132  *
    133  *	Uses	slow, shigh.
    134  *
    135  */
    136 
    137 int
    138 bslvalid(const bslabel_t *label)
    139 {
    140 	labeld_data_t	call;
    141 	labeld_data_t	*callp = &call;
    142 	size_t	bufsize = sizeof (labeld_data_t);
    143 	size_t	datasize = CALL_SIZE(slvalid_call_t, 0);
    144 
    145 	if (!BLTYPE(&slow, SUN_SL_ID)) {
    146 		/* initialize static labels. */
    147 
    148 		BSLLOW(&slow);
    149 		BSLHIGH(&shigh);
    150 	}
    151 
    152 	if (BLTYPE(label, SUN_SL_ID) &&
    153 	    (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
    154 
    155 		return (1);
    156 	}
    157 
    158 	call.callop = BSLVALID;
    159 	slvcall.label = *label;
    160 
    161 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
    162 		/* process error */
    163 
    164 		return (-1);
    165 	}
    166 	return (slvret.valid);
    167 }
    168 #undef	slvcall
    169 #undef	slvret
    170 
    171 #define	clrvcall callp->param.acall.cargs.clrvalid_arg
    172 #define	clrvret callp->param.aret.rvals.clrvalid_ret
    173 /*
    174  *	bclearvalid - Check Clearance for validity.
    175  *
    176  *	Entry	clearance = Clearance to check.
    177  *
    178  *	Exit	None.
    179  *
    180  *	Returns	-1, If unable to access label encodings file, or server failure.
    181  *		 0, If label not valid.
    182  *		 1, If label is valid.
    183  *
    184  *	Calls	__call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH.
    185  *
    186  *	Uses	clow, chigh.
    187  *
    188  */
    189 
    190 int
    191 bclearvalid(const bclear_t *clearance)
    192 {
    193 	labeld_data_t	call;
    194 	labeld_data_t	*callp = &call;
    195 	size_t	bufsize = sizeof (labeld_data_t);
    196 	size_t	datasize = CALL_SIZE(clrvalid_call_t, 0);
    197 
    198 	if (!BLTYPE(&clow, SUN_CLR_ID)) {
    199 		/* initialize static labels. */
    200 
    201 		BCLEARLOW(&clow);
    202 		BCLEARHIGH(&chigh);
    203 	}
    204 
    205 	if (BLTYPE(clearance, SUN_CLR_ID) &&
    206 	    (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
    207 
    208 		return (1);
    209 	}
    210 
    211 	call.callop = BCLEARVALID;
    212 	clrvcall.clear = *clearance;
    213 
    214 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
    215 		/* process error */
    216 
    217 		return (-1);
    218 	}
    219 	return (clrvret.valid);
    220 }
    221 #undef	clrvcall
    222 #undef	clrvret
    223 
    224 #define	inforet callp->param.aret.rvals.info_ret
    225 /*
    226  *	labelinfo - Get information about the label encodings file.
    227  *
    228  *	Entry	info = Address of label_info structure to update.
    229  *
    230  *	Exit	info = Updated.
    231  *
    232  *	Returns	-1, If unable to access label encodings file, or server failure.
    233  *		 1, If successful.
    234  *
    235  *	Calls	__call_labeld(LABELINFO).
    236  */
    237 
    238 int
    239 labelinfo(struct label_info *info)
    240 {
    241 	labeld_data_t	call;
    242 	labeld_data_t	*callp = &call;
    243 	size_t	bufsize = sizeof (labeld_data_t);
    244 	size_t	datasize = CALL_SIZE(info_call_t, 0);
    245 	int	rval;
    246 
    247 	call.callop = LABELINFO;
    248 
    249 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
    250 		/* process error */
    251 
    252 		return (-1);
    253 	}
    254 	*info = inforet.info;
    255 	return (rval);
    256 }
    257 #undef	inforet
    258 
    259 #define	lvret callp->param.aret.rvals.vers_ret
    260 /*
    261  *	labelvers - Get version string of the label encodings file.
    262  *
    263  *	Entry	version = Address of string pointer to return.
    264  *		len = Length of string if pre-allocated.
    265  *
    266  *	Exit	version = Updated.
    267  *
    268  *	Returns	-1, If unable to access label encodings file, or server failure.
    269  *		 0, If unable to allocate version string,
    270  *			or pre-allocated version string to short
    271  *			(and **version = '\0').
    272  *		length (including null) of version string, If successful.
    273  *
    274  *	Calls	__call_labeld(LABELVERS)
    275  *			malloc, strlen.
    276  */
    277 
    278 ssize_t
    279 labelvers(char **version, size_t len)
    280 {
    281 	labeld_data_t	call;
    282 	labeld_data_t	*callp = &call;
    283 	size_t	bufsize = sizeof (labeld_data_t);
    284 	size_t	datasize = CALL_SIZE(vers_call_t, 0);
    285 	size_t	ver_len;
    286 
    287 	call.callop = LABELVERS;
    288 
    289 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
    290 
    291 		if (callp != &call)
    292 			/* release return buffer */
    293 			(void) munmap((void *)callp, bufsize);
    294 		return (-1);
    295 	}
    296 
    297 	/* unpack length */
    298 
    299 	ver_len = strlen(lvret.vers) + 1;
    300 	if (*version == NULL) {
    301 		if ((*version = malloc(ver_len)) == NULL) {
    302 			if (callp != &call)
    303 				/* release return buffer */
    304 				(void) munmap((void *)callp, bufsize);
    305 			return (0);
    306 		}
    307 	} else if (ver_len > len) {
    308 		**version = '\0';
    309 		if (callp != &call)
    310 			/* release return buffer */
    311 			(void) munmap((void *)callp, bufsize);
    312 		return (0);
    313 	}
    314 	(void) strcpy(*version, lvret.vers);
    315 
    316 	if (callp != &call)
    317 		/* release return buffer */
    318 		(void) munmap((void *)callp, bufsize);
    319 	return (ver_len);
    320 }  /* labelvers */
    321 #undef	lvret
    322 
    323 #define	ccall callp->param.acall.cargs.color_arg
    324 #define	cret callp->param.aret.rvals.color_ret
    325 /*
    326  *	bltocolor - get ASCII color name of label.
    327  *
    328  *	Entry	label = Sensitivity Level of color to get.
    329  *		size  = Size of the color_name array.
    330  *		color_name = Storage for ASCII color name string to be returned.
    331  *
    332  *	Exit	None.
    333  *
    334  *	Returns	NULL, If error (label encodings file not accessible,
    335  *			   invalid label, no color for this label).
    336  *		Address of color_name parameter containing ASCII color name
    337  *			defined for the label.
    338  *
    339  *	Calls	__call_labeld(BLTOCOLOR), strlen.
    340  */
    341 
    342 char *
    343 bltocolor_r(const blevel_t *label, size_t size, char *color_name)
    344 {
    345 	labeld_data_t	call;
    346 	labeld_data_t	*callp = &call;
    347 	size_t	bufsize = sizeof (labeld_data_t);
    348 	size_t	datasize = CALL_SIZE(color_call_t, 0);
    349 	char	*colorp;
    350 
    351 	call.callop = BLTOCOLOR;
    352 	ccall.label = *label;
    353 
    354 	if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
    355 	    (callp->reterr != 0) ||
    356 	    (strlen(cret.color) >= size)) {
    357 
    358 		if (callp != &call)
    359 			/* release return buffer */
    360 			(void) munmap((void *)callp, bufsize);
    361 		return (NULL);
    362 	}
    363 
    364 	colorp = strcpy(color_name, cret.color);
    365 
    366 	if (callp != &call)
    367 		/* release return buffer */
    368 		(void) munmap((void *)callp, bufsize);
    369 	return (colorp);
    370 }  /* bltocolor_r */
    371 #undef	ccall
    372 #undef	cret
    373 
    374 /*
    375  *	bltocolor - get ASCII color name of label.
    376  *
    377  *	Entry	label = Sensitivity Level of color to get.
    378  *
    379  *	Exit	None.
    380  *
    381  *	Returns	NULL, If error (label encodings file not accessible,
    382  *			   invalid label, no color for this label).
    383  *		Address of statically allocated string containing ASCII
    384  *			color name defined for the classification contained
    385  *			in label.
    386  *
    387  *	Uses	color.
    388  *
    389  *	Calls	bltocolor_r.
    390  */
    391 
    392 char *
    393 bltocolor(const blevel_t *label)
    394 {
    395 	return (bltocolor_r(label, sizeof (color), color));
    396 }  /* bltocolor */
    397 
    398 blevel_t *
    399 blabel_alloc(void)
    400 {
    401 	return (m_label_alloc(MAC_LABEL));
    402 }
    403 
    404 void
    405 blabel_free(blevel_t *label_p)
    406 {
    407 	free(label_p);
    408 }
    409 
    410 size_t
    411 blabel_size(void)
    412 {
    413 	return (sizeof (blevel_t));
    414 }
    415 
    416 /*
    417  *	getuserrange - get label range for user
    418  *
    419  *	Entry	username of user
    420  *
    421  *	Exit	None.
    422  *
    423  *	Returns	NULL, If memory allocation failure or userdefs failure.
    424  *		otherwise returns the allocates m_range_t with the
    425  *		user's min and max labels set.
    426  */
    427 
    428 m_range_t *
    429 getuserrange(const char *username)
    430 {
    431 	char		*kv_str = NULL;
    432 	userattr_t 	*userp = NULL;
    433 	m_range_t 	*range;
    434 	m_label_t	*def_min, *def_clr;
    435 
    436 	/*
    437 	 * Get some memory
    438 	 */
    439 
    440 	if ((range = malloc(sizeof (m_range_t))) == NULL) {
    441 		return (NULL);
    442 	}
    443 	if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
    444 		free(range);
    445 		return (NULL);
    446 	}
    447 	def_min = range->lower_bound;
    448 	if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
    449 		m_label_free(range->lower_bound);
    450 		free(range);
    451 		return (NULL);
    452 	}
    453 	def_clr = range->upper_bound;
    454 
    455 	/* If the user has an explicit min_label or clearance, use it. */
    456 	if ((userp = getusernam(username)) != NULL) {
    457 		if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL))
    458 		    != NULL) {
    459 			(void) str_to_label(kv_str, &range->lower_bound,
    460 			    MAC_LABEL, L_NO_CORRECTION, NULL);
    461 			def_min = NULL;		/* don't get default later */
    462 		}
    463 		if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE))
    464 		    != NULL) {
    465 			(void) str_to_label(kv_str, &range->upper_bound,
    466 			    USER_CLEAR, L_NO_CORRECTION, NULL);
    467 			def_clr = NULL;		/* don't get default later */
    468 		}
    469 		free_userattr(userp);
    470 	}
    471 	if (def_min || def_clr) {
    472 		/* Need to use system default clearance and/or min_label */
    473 		if ((userdefs(def_min, def_clr)) == -1) {
    474 			m_label_free(range->lower_bound);
    475 			m_label_free(range->upper_bound);
    476 			free(range);
    477 			return (NULL);
    478 		}
    479 	}
    480 
    481 	return (range);
    482 }
    483