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 /*
221676Sjpk  * Copyright 2006 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 /*
301676Sjpk  *	Miscellaneous user interfaces to trusted label functions.
311676Sjpk  *
321676Sjpk  */
331676Sjpk 
341676Sjpk 
351676Sjpk #include <ctype.h>
361676Sjpk #include <stdlib.h>
371676Sjpk #include <strings.h>
381676Sjpk 
391676Sjpk #include <sys/mman.h>
401676Sjpk 
411676Sjpk #include <tsol/label.h>
421676Sjpk 
431676Sjpk #include "labeld.h"
441676Sjpk #include "clnt.h"
451676Sjpk #include <sys/tsol/label_macro.h>
461676Sjpk #include <secdb.h>
471676Sjpk #include <user_attr.h>
481676Sjpk 
491676Sjpk static	bslabel_t slow, shigh;	/* static Admin Low and High SLs */
501676Sjpk static	bclear_t  clow, chigh;	/* static Admin Low and High CLRs */
511676Sjpk 
521676Sjpk static char color[MAXCOLOR];
531676Sjpk 
541676Sjpk 
551676Sjpk #define	incall callp->param.acall.cargs.inset_arg
561676Sjpk #define	inret callp->param.aret.rvals.inset_ret
571676Sjpk /*
581676Sjpk  *	blinset - Check in a label set.
591676Sjpk  *
601676Sjpk  *	Entry	label = Sensitivity Label to check.
611676Sjpk  *		id    = Label set identifier of set to check.
621676Sjpk  *
631676Sjpk  *	Exit	None.
641676Sjpk  *
651676Sjpk  *	Returns	-1, If label set unavailable, or server failure.
661676Sjpk  *		 0, If label not in label set.
671676Sjpk  *		 1, If label is in the label set.
681676Sjpk  *
691676Sjpk  *	Calls	__call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH.
701676Sjpk  *
711676Sjpk  *	Uses	slow, shigh.
721676Sjpk  */
731676Sjpk 
741676Sjpk int
751676Sjpk blinset(const bslabel_t *label, const set_id *id)
761676Sjpk {
771676Sjpk 	if (id->type == SYSTEM_ACCREDITATION_RANGE) {
781676Sjpk 		if (!BLTYPE(&slow, SUN_SL_ID)) {
791676Sjpk 			/* initialize static labels. */
801676Sjpk 
811676Sjpk 			BSLLOW(&slow);
821676Sjpk 			BSLHIGH(&shigh);
831676Sjpk 		}
841676Sjpk 
851676Sjpk 		if (BLTYPE(label, SUN_SL_ID) &&
861676Sjpk 		    (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
871676Sjpk 
881676Sjpk 			return (1);
891676Sjpk 	}
901676Sjpk 	if (id->type == USER_ACCREDITATION_RANGE ||
911676Sjpk 	    id->type == SYSTEM_ACCREDITATION_RANGE) {
921676Sjpk 		labeld_data_t	call;
931676Sjpk 		labeld_data_t	*callp = &call;
941676Sjpk 		size_t	bufsize = sizeof (labeld_data_t);
951676Sjpk 		size_t	datasize = CALL_SIZE(inset_call_t, 0);
961676Sjpk 
971676Sjpk 		call.callop = BLINSET;
981676Sjpk 		incall.label = *label;
991676Sjpk 		incall.type = id->type;
1001676Sjpk 
1011676Sjpk 		if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
1021676Sjpk 			/* process error */
1031676Sjpk 
1041676Sjpk 			return (-1);
1051676Sjpk 		}
1061676Sjpk 		return (inret.inset);
1071676Sjpk 	} else {
1081676Sjpk 		/*
1091676Sjpk 		 * Only System and User Accreditation Ranges presently
1101676Sjpk 		 * implemented.
1111676Sjpk 		 */
1121676Sjpk 		return (-1);
1131676Sjpk 	}
1141676Sjpk }
1151676Sjpk #undef	incall
1161676Sjpk #undef	inret
1171676Sjpk 
1181676Sjpk #define	slvcall callp->param.acall.cargs.slvalid_arg
1191676Sjpk #define	slvret callp->param.aret.rvals.slvalid_ret
1201676Sjpk /*
1211676Sjpk  *	bslvalid - Check Sensitivity Label for validity.
1221676Sjpk  *
1231676Sjpk  *	Entry	label = Sensitivity Label to check.
1241676Sjpk  *
1251676Sjpk  *	Exit	None.
1261676Sjpk  *
1271676Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
1281676Sjpk  *		 0, If label not valid.
1291676Sjpk  *		 1, If label is valid.
1301676Sjpk  *
1311676Sjpk  *	Calls	__call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH.
1321676Sjpk  *
1331676Sjpk  *	Uses	slow, shigh.
1341676Sjpk  *
1351676Sjpk  */
1361676Sjpk 
1371676Sjpk int
1381676Sjpk bslvalid(const bslabel_t *label)
1391676Sjpk {
1401676Sjpk 	labeld_data_t	call;
1411676Sjpk 	labeld_data_t	*callp = &call;
1421676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
1431676Sjpk 	size_t	datasize = CALL_SIZE(slvalid_call_t, 0);
1441676Sjpk 
1451676Sjpk 	if (!BLTYPE(&slow, SUN_SL_ID)) {
1461676Sjpk 		/* initialize static labels. */
1471676Sjpk 
1481676Sjpk 		BSLLOW(&slow);
1491676Sjpk 		BSLHIGH(&shigh);
1501676Sjpk 	}
1511676Sjpk 
1521676Sjpk 	if (BLTYPE(label, SUN_SL_ID) &&
1531676Sjpk 	    (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
1541676Sjpk 
1551676Sjpk 		return (1);
1561676Sjpk 	}
1571676Sjpk 
1581676Sjpk 	call.callop = BSLVALID;
1591676Sjpk 	slvcall.label = *label;
1601676Sjpk 
1611676Sjpk 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
1621676Sjpk 		/* process error */
1631676Sjpk 
1641676Sjpk 		return (-1);
1651676Sjpk 	}
1661676Sjpk 	return (slvret.valid);
1671676Sjpk }
1681676Sjpk #undef	slvcall
1691676Sjpk #undef	slvret
1701676Sjpk 
1711676Sjpk #define	clrvcall callp->param.acall.cargs.clrvalid_arg
1721676Sjpk #define	clrvret callp->param.aret.rvals.clrvalid_ret
1731676Sjpk /*
1741676Sjpk  *	bclearvalid - Check Clearance for validity.
1751676Sjpk  *
1761676Sjpk  *	Entry	clearance = Clearance to check.
1771676Sjpk  *
1781676Sjpk  *	Exit	None.
1791676Sjpk  *
1801676Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
1811676Sjpk  *		 0, If label not valid.
1821676Sjpk  *		 1, If label is valid.
1831676Sjpk  *
1841676Sjpk  *	Calls	__call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH.
1851676Sjpk  *
1861676Sjpk  *	Uses	clow, chigh.
1871676Sjpk  *
1881676Sjpk  */
1891676Sjpk 
1901676Sjpk int
1911676Sjpk bclearvalid(const bclear_t *clearance)
1921676Sjpk {
1931676Sjpk 	labeld_data_t	call;
1941676Sjpk 	labeld_data_t	*callp = &call;
1951676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
1961676Sjpk 	size_t	datasize = CALL_SIZE(clrvalid_call_t, 0);
1971676Sjpk 
1981676Sjpk 	if (!BLTYPE(&clow, SUN_CLR_ID)) {
1991676Sjpk 		/* initialize static labels. */
2001676Sjpk 
2011676Sjpk 		BCLEARLOW(&clow);
2021676Sjpk 		BCLEARHIGH(&chigh);
2031676Sjpk 	}
2041676Sjpk 
2051676Sjpk 	if (BLTYPE(clearance, SUN_CLR_ID) &&
2061676Sjpk 	    (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
2071676Sjpk 
2081676Sjpk 		return (1);
2091676Sjpk 	}
2101676Sjpk 
2111676Sjpk 	call.callop = BCLEARVALID;
2121676Sjpk 	clrvcall.clear = *clearance;
2131676Sjpk 
2141676Sjpk 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
2151676Sjpk 		/* process error */
2161676Sjpk 
2171676Sjpk 		return (-1);
2181676Sjpk 	}
2191676Sjpk 	return (clrvret.valid);
2201676Sjpk }
2211676Sjpk #undef	clrvcall
2221676Sjpk #undef	clrvret
2231676Sjpk 
2241676Sjpk #define	inforet callp->param.aret.rvals.info_ret
2251676Sjpk /*
2261676Sjpk  *	labelinfo - Get information about the label encodings file.
2271676Sjpk  *
2281676Sjpk  *	Entry	info = Address of label_info structure to update.
2291676Sjpk  *
2301676Sjpk  *	Exit	info = Updated.
2311676Sjpk  *
2321676Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
2331676Sjpk  *		 1, If successful.
2341676Sjpk  *
2351676Sjpk  *	Calls	__call_labeld(LABELINFO).
2361676Sjpk  */
2371676Sjpk 
2381676Sjpk int
2391676Sjpk labelinfo(struct label_info *info)
2401676Sjpk {
2411676Sjpk 	labeld_data_t	call;
2421676Sjpk 	labeld_data_t	*callp = &call;
2431676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
2441676Sjpk 	size_t	datasize = CALL_SIZE(info_call_t, 0);
2451676Sjpk 	int	rval;
2461676Sjpk 
2471676Sjpk 	call.callop = LABELINFO;
2481676Sjpk 
2491676Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
2501676Sjpk 		/* process error */
2511676Sjpk 
2521676Sjpk 		return (-1);
2531676Sjpk 	}
2541676Sjpk 	*info = inforet.info;
2551676Sjpk 	return (rval);
2561676Sjpk }
2571676Sjpk #undef	inforet
2581676Sjpk 
2591676Sjpk #define	lvret callp->param.aret.rvals.vers_ret
2601676Sjpk /*
2611676Sjpk  *	labelvers - Get version string of the label encodings file.
2621676Sjpk  *
2631676Sjpk  *	Entry	version = Address of string pointer to return.
2641676Sjpk  *		len = Length of string if pre-allocated.
2651676Sjpk  *
2661676Sjpk  *	Exit	version = Updated.
2671676Sjpk  *
2681676Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
2691676Sjpk  *		 0, If unable to allocate version string,
2701676Sjpk  *			or pre-allocated version string to short
2711676Sjpk  *			(and **version = '\0').
2721676Sjpk  *		length (including null) of version string, If successful.
2731676Sjpk  *
2741676Sjpk  *	Calls	__call_labeld(LABELVERS)
2751676Sjpk  *			malloc, strlen.
2761676Sjpk  */
2771676Sjpk 
2781676Sjpk ssize_t
2791676Sjpk labelvers(char **version, size_t len)
2801676Sjpk {
2811676Sjpk 	labeld_data_t	call;
2821676Sjpk 	labeld_data_t	*callp = &call;
2831676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
2841676Sjpk 	size_t	datasize = CALL_SIZE(vers_call_t, 0);
2851676Sjpk 	size_t	ver_len;
2861676Sjpk 
2871676Sjpk 	call.callop = LABELVERS;
2881676Sjpk 
2891676Sjpk 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
2901676Sjpk 
2911676Sjpk 		if (callp != &call)
2921676Sjpk 			/* release return buffer */
2931676Sjpk 			(void) munmap((void *)callp, bufsize);
2941676Sjpk 		return (-1);
2951676Sjpk 	}
2961676Sjpk 
2971676Sjpk 	/* unpack length */
2981676Sjpk 
2991676Sjpk 	ver_len = strlen(lvret.vers) + 1;
3001676Sjpk 	if (*version == NULL) {
3011676Sjpk 		if ((*version = malloc(ver_len)) == NULL) {
3021676Sjpk 			if (callp != &call)
3031676Sjpk 				/* release return buffer */
3041676Sjpk 				(void) munmap((void *)callp, bufsize);
3051676Sjpk 			return (0);
3061676Sjpk 		}
3071676Sjpk 	} else if (ver_len > len) {
3081676Sjpk 		**version = '\0';
3091676Sjpk 		if (callp != &call)
3101676Sjpk 			/* release return buffer */
3111676Sjpk 			(void) munmap((void *)callp, bufsize);
3121676Sjpk 		return (0);
3131676Sjpk 	}
3141676Sjpk 	(void) strcpy(*version, lvret.vers);
3151676Sjpk 
3161676Sjpk 	if (callp != &call)
3171676Sjpk 		/* release return buffer */
3181676Sjpk 		(void) munmap((void *)callp, bufsize);
3191676Sjpk 	return (ver_len);
3201676Sjpk }  /* labelvers */
3211676Sjpk #undef	lvret
3221676Sjpk 
3231676Sjpk #define	ccall callp->param.acall.cargs.color_arg
3241676Sjpk #define	cret callp->param.aret.rvals.color_ret
3251676Sjpk /*
3261676Sjpk  *	bltocolor - get ASCII color name of label.
3271676Sjpk  *
3281676Sjpk  *	Entry	label = Sensitivity Level of color to get.
3291676Sjpk  *		size  = Size of the color_name array.
3301676Sjpk  *		color_name = Storage for ASCII color name string to be returned.
3311676Sjpk  *
3321676Sjpk  *	Exit	None.
3331676Sjpk  *
3341676Sjpk  *	Returns	NULL, If error (label encodings file not accessible,
3351676Sjpk  *			   invalid label, no color for this label).
3361676Sjpk  *		Address of color_name parameter containing ASCII color name
3371676Sjpk  *			defined for the label.
3381676Sjpk  *
3391676Sjpk  *	Calls	__call_labeld(BLTOCOLOR), strlen.
3401676Sjpk  */
3411676Sjpk 
3421676Sjpk char *
3431676Sjpk bltocolor_r(const blevel_t *label, size_t size, char *color_name)
3441676Sjpk {
3451676Sjpk 	labeld_data_t	call;
3461676Sjpk 	labeld_data_t	*callp = &call;
3471676Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
3481676Sjpk 	size_t	datasize = CALL_SIZE(color_call_t, 0);
3491676Sjpk 	char	*colorp;
3501676Sjpk 
3511676Sjpk 	call.callop = BLTOCOLOR;
3521676Sjpk 	ccall.label = *label;
3531676Sjpk 
3541676Sjpk 	if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
3551676Sjpk 	    (callp->reterr != 0) ||
3561676Sjpk 	    (strlen(cret.color) >= size)) {
3571676Sjpk 
3581676Sjpk 		if (callp != &call)
3591676Sjpk 			/* release return buffer */
3601676Sjpk 			(void) munmap((void *)callp, bufsize);
3611676Sjpk 		return (NULL);
3621676Sjpk 	}
3631676Sjpk 
3641676Sjpk 	colorp = strcpy(color_name, cret.color);
3651676Sjpk 
3661676Sjpk 	if (callp != &call)
3671676Sjpk 		/* release return buffer */
3681676Sjpk 		(void) munmap((void *)callp, bufsize);
3691676Sjpk 	return (colorp);
3701676Sjpk }  /* bltocolor_r */
3711676Sjpk #undef	ccall
3721676Sjpk #undef	cret
3731676Sjpk 
3741676Sjpk /*
3751676Sjpk  *	bltocolor - get ASCII color name of label.
3761676Sjpk  *
3771676Sjpk  *	Entry	label = Sensitivity Level of color to get.
3781676Sjpk  *
3791676Sjpk  *	Exit	None.
3801676Sjpk  *
3811676Sjpk  *	Returns	NULL, If error (label encodings file not accessible,
3821676Sjpk  *			   invalid label, no color for this label).
3831676Sjpk  *		Address of statically allocated string containing ASCII
3841676Sjpk  *			color name defined for the classification contained
3851676Sjpk  *			in label.
3861676Sjpk  *
3871676Sjpk  *	Uses	color.
3881676Sjpk  *
3891676Sjpk  *	Calls	bltocolor_r.
3901676Sjpk  */
3911676Sjpk 
3921676Sjpk char *
3931676Sjpk bltocolor(const blevel_t *label)
3941676Sjpk {
3951676Sjpk 	return (bltocolor_r(label, sizeof (color), color));
3961676Sjpk }  /* bltocolor */
3971676Sjpk 
3981676Sjpk blevel_t *
3991676Sjpk blabel_alloc(void)
4001676Sjpk {
4011676Sjpk 	return (m_label_alloc(MAC_LABEL));
4021676Sjpk }
4031676Sjpk 
4041676Sjpk void
4051676Sjpk blabel_free(blevel_t *label_p)
4061676Sjpk {
4071676Sjpk 	free(label_p);
4081676Sjpk }
4091676Sjpk 
4101676Sjpk size_t
4111676Sjpk blabel_size(void)
4121676Sjpk {
4131676Sjpk 	return (sizeof (blevel_t));
4141676Sjpk }
4151676Sjpk 
4161676Sjpk /*
4171676Sjpk  *	getuserrange - get label range for user
4181676Sjpk  *
4191676Sjpk  *	Entry	username of user
4201676Sjpk  *
4211676Sjpk  *	Exit	None.
4221676Sjpk  *
4231676Sjpk  *	Returns	NULL, If memory allocation failure or userdefs failure.
4241676Sjpk  *		otherwise returns the allocates m_range_t with the
4251676Sjpk  *		user's min and max labels set.
4261676Sjpk  */
4271676Sjpk 
4281676Sjpk m_range_t *
4291676Sjpk getuserrange(const char *username)
4301676Sjpk {
4311676Sjpk 	char		*kv_str = NULL;
4321676Sjpk 	userattr_t 	*userp = NULL;
4331676Sjpk 	m_range_t 	*range;
434*2664Srica 	m_label_t	*def_min, *def_clr;
4351676Sjpk 
4361676Sjpk 	/*
4371676Sjpk 	 * Get some memory
4381676Sjpk 	 */
4391676Sjpk 
4401676Sjpk 	if ((range = malloc(sizeof (m_range_t))) == NULL) {
4411676Sjpk 		return (NULL);
4421676Sjpk 	}
4431676Sjpk 	if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
4441676Sjpk 		free(range);
4451676Sjpk 		return (NULL);
4461676Sjpk 	}
447*2664Srica 	def_min = range->lower_bound;
4481676Sjpk 	if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
4491676Sjpk 		m_label_free(range->lower_bound);
4501676Sjpk 		free(range);
4511676Sjpk 		return (NULL);
4521676Sjpk 	}
453*2664Srica 	def_clr = range->upper_bound;
454*2664Srica 
455*2664Srica 	/* If the user has an explicit min_label or clearance, use it. */
456*2664Srica 	if ((userp = getusernam(username)) != NULL) {
457*2664Srica 		if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL))
458*2664Srica 		    != NULL) {
459*2664Srica 			(void) str_to_label(kv_str, &range->lower_bound,
460*2664Srica 			    MAC_LABEL, L_NO_CORRECTION, NULL);
461*2664Srica 			def_min = NULL;		/* don't get default later */
462*2664Srica 		}
463*2664Srica 		if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE))
464*2664Srica 		    != NULL) {
465*2664Srica 			(void) str_to_label(kv_str, &range->upper_bound,
466*2664Srica 			    USER_CLEAR, L_NO_CORRECTION, NULL);
467*2664Srica 			def_clr = NULL;		/* don't get default later */
468*2664Srica 		}
469*2664Srica 		free_userattr(userp);
4701676Sjpk 	}
471*2664Srica 	if (def_min || def_clr) {
472*2664Srica 		/* Need to use system default clearance and/or min_label */
473*2664Srica 		if ((userdefs(def_min, def_clr)) == -1) {
474*2664Srica 			m_label_free(range->lower_bound);
475*2664Srica 			m_label_free(range->upper_bound);
476*2664Srica 			free(range);
477*2664Srica 			return (NULL);
478*2664Srica 		}
4791676Sjpk 	}
480*2664Srica 
4811676Sjpk 	return (range);
4821676Sjpk }
483