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