xref: /titanic_51/usr/src/lib/libtsol/common/private.c (revision aa2e15f6ec88d9bf4f2dee6bfbb3307b2da8adb4)
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 /*
2245916cd2Sjpk  * Copyright 2006 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  *	Label library contract private interfaces.
3045916cd2Sjpk  *
3145916cd2Sjpk  *	Binary labels to String labels with dimming word lists.
3245916cd2Sjpk  *	Dimming word list titles.
3345916cd2Sjpk  *	Default user labels.
3445916cd2Sjpk  */
3545916cd2Sjpk 
3645916cd2Sjpk #include <locale.h>
3745916cd2Sjpk #include <stdlib.h>
3845916cd2Sjpk #include <stdio.h>
3945916cd2Sjpk #include <strings.h>
4045916cd2Sjpk 
4145916cd2Sjpk #include <sys/mman.h>
4245916cd2Sjpk 
4345916cd2Sjpk #include <tsol/label.h>
4445916cd2Sjpk 
4545916cd2Sjpk #include "clnt.h"
4645916cd2Sjpk #include "labeld.h"
4745916cd2Sjpk 
4845916cd2Sjpk /*
4945916cd2Sjpk  *	cvt memory:
5045916cd2Sjpk  *
5145916cd2Sjpk  * cvt:	char	*long_words[display_size];	Pointers to long words
5245916cd2Sjpk  *	char	*short_words[display_size];	Pointers to short words
5345916cd2Sjpk  * dim:	char	display[display_size];		Dim | Set
5445916cd2Sjpk  *
5545916cd2Sjpk  *	    strings associated with long and short words.
5645916cd2Sjpk  *
5745916cd2Sjpk  */
5845916cd2Sjpk 
5945916cd2Sjpk /*
6045916cd2Sjpk  *	Sensitivity Label words.
6145916cd2Sjpk  */
6245916cd2Sjpk 
6345916cd2Sjpk static	char *slcvt = NULL;
6445916cd2Sjpk static	int   slcvtsize = 0;
6545916cd2Sjpk static	char *sldim;
6645916cd2Sjpk 
6745916cd2Sjpk static	char *slstring = NULL;
6845916cd2Sjpk static	int   slstringsize = 0;
6945916cd2Sjpk static	brange_t sbounds;
7045916cd2Sjpk 
7145916cd2Sjpk /*
7245916cd2Sjpk  *	Clearance words.
7345916cd2Sjpk  */
7445916cd2Sjpk 
7545916cd2Sjpk static	char *clrcvt = NULL;
7645916cd2Sjpk static	int   clrcvtsize = 0;
7745916cd2Sjpk static	char *clrdim;
7845916cd2Sjpk 
7945916cd2Sjpk static	char *clrstring = NULL;
8045916cd2Sjpk static	int   clrstringsize = 0;
8145916cd2Sjpk static	brange_t cbounds;
8245916cd2Sjpk 
8345916cd2Sjpk static
8445916cd2Sjpk int
8545916cd2Sjpk alloc_words(char **words, const size_t size)
8645916cd2Sjpk {
8745916cd2Sjpk 	if (*words == NULL) {
8845916cd2Sjpk 		if ((*words = malloc(size)) == NULL)
8945916cd2Sjpk 			return (0);
9045916cd2Sjpk 	} else {
9145916cd2Sjpk 		if ((*words = realloc(*words, size)) == NULL) {
9245916cd2Sjpk 			return (0);
9345916cd2Sjpk 		}
9445916cd2Sjpk 	}
9545916cd2Sjpk 	return (1);
9645916cd2Sjpk }
9745916cd2Sjpk 
9845916cd2Sjpk /*
9945916cd2Sjpk  *	build_strings - Build the static strings and dimming list for a
10045916cd2Sjpk  *			converted label.
10145916cd2Sjpk  *
10245916cd2Sjpk  *	Entry	new_string = Newly converted string.
10345916cd2Sjpk  *		new_words_size = Size of words associated with newly converted
10445916cd2Sjpk  *				 label.
10545916cd2Sjpk  *		number_of_words = Number of words associated with newly
10645916cd2Sjpk  *				  converted label.
10745916cd2Sjpk  *		full =	1, if static words lists to be updated.
10845916cd2Sjpk  *			0, if only string and dimming list to be updated.
10945916cd2Sjpk  *
11045916cd2Sjpk  *	Exit	static_string_size = Updated if needed.
11145916cd2Sjpk  *		static_string = Updated to new label string.
11245916cd2Sjpk  *		static_words_size = Updated if needed.
11345916cd2Sjpk  *		static_words = Updated to new words list, if needed.
11445916cd2Sjpk  *		static_dimming = Updated to new dimming state.
11545916cd2Sjpk  *		long_words = Updated to new long words pointers, if needed.
11645916cd2Sjpk  *		short_words = Updated to new short words pointers, if needed.
11745916cd2Sjpk  *
11845916cd2Sjpk  *
11945916cd2Sjpk  *	Returns	0, If unable to allocate memory.
12045916cd2Sjpk  *		1, If successful.
12145916cd2Sjpk  *
12245916cd2Sjpk  *	Calls	alloc_string, alloc_words, memcpy, strcpy, strlen.
12345916cd2Sjpk  */
12445916cd2Sjpk 
12545916cd2Sjpk static
12645916cd2Sjpk int
12745916cd2Sjpk build_strings(int *static_string_size, char **static_string, char *new_string,
12845916cd2Sjpk     int *static_words_size, int new_words_size, char **static_words,
12945916cd2Sjpk     char **static_dimming, int number_of_words, char *long_words,
13045916cd2Sjpk     char *short_words, char *dimming_list, int full)
13145916cd2Sjpk {
13245916cd2Sjpk 	char	**l;
13345916cd2Sjpk 	char	**s;
13445916cd2Sjpk 	char	*w;
13545916cd2Sjpk 	char	*l_w = long_words;
13645916cd2Sjpk 	char	*s_w = short_words;
13745916cd2Sjpk 	int	i;
13845916cd2Sjpk 	int	len;
13945916cd2Sjpk 	int	newsize;
14045916cd2Sjpk 
14145916cd2Sjpk 	if (*static_string_size == 0) { /* Allocate string memory. */
14245916cd2Sjpk 		if ((*static_string_size = alloc_string(static_string,
14345916cd2Sjpk 		    *static_string_size, 'C')) == 0)
14445916cd2Sjpk 			/* can't get string memory for string */
14545916cd2Sjpk 			return (0);
14645916cd2Sjpk 	}
14745916cd2Sjpk 
14845916cd2Sjpk again:
14945916cd2Sjpk 	if (*static_string_size < (int)strlen(new_string)+1) {
15045916cd2Sjpk 		/* need longer string */
15145916cd2Sjpk 		if ((newsize = alloc_string(static_string, *static_string_size,
15245916cd2Sjpk 		    'C')) == 0)
15345916cd2Sjpk 			/* can't get more string memory */
15445916cd2Sjpk 			return (0);
15545916cd2Sjpk 
15645916cd2Sjpk 		*static_string_size += newsize;
15745916cd2Sjpk 		goto again;
15845916cd2Sjpk 	}
15945916cd2Sjpk 	bcopy(new_string, *static_string, strlen(new_string) + 1);
16045916cd2Sjpk 
16145916cd2Sjpk 	if (full) {
16245916cd2Sjpk 		if (*static_words_size < new_words_size &&
16345916cd2Sjpk 		    !alloc_words(static_words, new_words_size)) {
16445916cd2Sjpk 			/* can't get more words memory */
16545916cd2Sjpk 			return (0);
16645916cd2Sjpk 		} else {
16745916cd2Sjpk 			*static_words_size = new_words_size;
16845916cd2Sjpk 		}
16945916cd2Sjpk 		/*LINTED*/
17045916cd2Sjpk 		l = (char **)*static_words;
17145916cd2Sjpk 		s = l + number_of_words;
17245916cd2Sjpk 		*static_dimming = (char *)(s + number_of_words);
17345916cd2Sjpk 		w = *static_dimming + number_of_words;
17445916cd2Sjpk 		for (i = 0; i < number_of_words; i++) {
17545916cd2Sjpk 			*l = w;
17645916cd2Sjpk 			(void) strcpy(w, l_w);
17745916cd2Sjpk 			w += (len = strlen(l_w) + 1);
17845916cd2Sjpk 			l_w += len;
17945916cd2Sjpk 			if (*s_w == '\000') {
18045916cd2Sjpk 				*s = NULL;
18145916cd2Sjpk 				s_w++;
18245916cd2Sjpk 			} else {
18345916cd2Sjpk 				*s = w;
18445916cd2Sjpk 				(void) strcpy(w, s_w);
18545916cd2Sjpk 				w += (len = strlen(s_w) + 1);
18645916cd2Sjpk 				s_w += len;
18745916cd2Sjpk 			}
18845916cd2Sjpk 
18945916cd2Sjpk 			l++;
19045916cd2Sjpk 			s++;
19145916cd2Sjpk 		}  /* for each word entry */
19245916cd2Sjpk 	}  /* if (full) */
19345916cd2Sjpk 
19445916cd2Sjpk 	bcopy(dimming_list, *static_dimming, number_of_words);
19545916cd2Sjpk 	return (1);
19645916cd2Sjpk }  /* build_strings */
19745916cd2Sjpk 
19845916cd2Sjpk #define	bsfcall callp->param.acall.cargs.bslcvt_arg
19945916cd2Sjpk #define	bsfret callp->param.aret.rvals.bslcvt_ret
20045916cd2Sjpk /*
20145916cd2Sjpk  *	bslcvtfull - Convert Sensitivity Label and initialize static
20245916cd2Sjpk  *			information.
20345916cd2Sjpk  *
20445916cd2Sjpk  *	Entry	label = Sensitivity Label to convert and get dimming list.
20545916cd2Sjpk  *			This label should lie within the bounds or the
20645916cd2Sjpk  *			results may not be meaningful.
20745916cd2Sjpk  *		bounds = Lower and upper bounds for words lists. Must be
20845916cd2Sjpk  *			dominated by clearance.
20945916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
21045916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
21145916cd2Sjpk  *
21245916cd2Sjpk  *	Exit	string = ASCII coded Sensitivity Label.
21345916cd2Sjpk  *		long_words = Array of pointers to visible long word names.
21445916cd2Sjpk  *		short_words = Array of pointers to visible short word names.
21545916cd2Sjpk  *		display = Array of indicators as to whether the word is present
21645916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
21745916cd2Sjpk  *			  (CVT_DIM).
21845916cd2Sjpk  *		first_compartment = Zero based index of first compartment.
21945916cd2Sjpk  *		display_size = Number of entries in the display/words lists.
22045916cd2Sjpk  *
22145916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
22245916cd2Sjpk  *			invalid label.
22345916cd2Sjpk  *		 0, If unable to allocate static memory.
22445916cd2Sjpk  *		 1, If successful.
22545916cd2Sjpk  *
22645916cd2Sjpk  *	Calls	RPC - LABELS_BSLCONVERT, STTBLEVEL, SETBSLABEL, TCLNT,
22745916cd2Sjpk  *			build_strings, clnt_call, clnt_perror.
22845916cd2Sjpk  *
22945916cd2Sjpk  *	Uses	sbounds, slrcvt, slrcvtsize, slrdim, slrstring,
23045916cd2Sjpk  *			slrstringsize.
23145916cd2Sjpk  */
23245916cd2Sjpk 
23345916cd2Sjpk int
23445916cd2Sjpk bslcvtfull(const bslabel_t *label, const blrange_t *bounds, int flags,
23545916cd2Sjpk     char **string, char **long_words[], char **short_words[], char *display[],
23645916cd2Sjpk     int *first_compartment, int *display_size)
23745916cd2Sjpk {
23845916cd2Sjpk 	labeld_data_t	call;
23945916cd2Sjpk 	labeld_data_t	*callp = &call;
24045916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
24145916cd2Sjpk 	size_t	datasize = CALL_SIZE(bslcvt_call_t, 0);
24245916cd2Sjpk 	int	new_words_size;
24345916cd2Sjpk 	int	rval;
24445916cd2Sjpk 
24545916cd2Sjpk 	call.callop = BSLCVT;
24645916cd2Sjpk 	bsfcall.label = *label;
24745916cd2Sjpk 	bsfcall.bounds.upper_bound = *bounds->upper_bound;
24845916cd2Sjpk 	bsfcall.bounds.lower_bound = *bounds->lower_bound;
24945916cd2Sjpk 	bsfcall.flags = LABELS_FULL_CONVERT;
25045916cd2Sjpk 	set_label_view(&bsfcall.flags, flags);
25145916cd2Sjpk 
25245916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
25345916cd2Sjpk #ifdef	DEBUG
25445916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
25545916cd2Sjpk #endif	/* DEBUG */
25645916cd2Sjpk 		return (-1);
25745916cd2Sjpk 	} else if (rval != SUCCESS) {
25845916cd2Sjpk 		return (-1);
25945916cd2Sjpk 	} else {
26045916cd2Sjpk 		if (callp->reterr != 0)
26145916cd2Sjpk 			return (-1);
26245916cd2Sjpk 	}
26345916cd2Sjpk 
26445916cd2Sjpk 	*first_compartment = bsfret.first_comp;
26545916cd2Sjpk 	*display_size = bsfret.d_len;
26645916cd2Sjpk 
26745916cd2Sjpk 	new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len +
26845916cd2Sjpk 	    (2 * sizeof (char *)) * bsfret.d_len;
26945916cd2Sjpk 
27045916cd2Sjpk 	if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string],
27145916cd2Sjpk 	    &slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len,
27245916cd2Sjpk 	    &bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords],
27345916cd2Sjpk 	    &bsfret.buf[bsfret.dim], 1) != 1) {
27445916cd2Sjpk 		if (callp != &call)
27545916cd2Sjpk 			/* release return buffer */
27645916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
27745916cd2Sjpk 		return (0);
27845916cd2Sjpk 	}
27945916cd2Sjpk 
28045916cd2Sjpk 	/* save for bslcvt call */
28145916cd2Sjpk 	sbounds.upper_bound = *bounds->upper_bound;
28245916cd2Sjpk 	sbounds.lower_bound = *bounds->lower_bound;
28345916cd2Sjpk 
28445916cd2Sjpk 	*string = slstring;
28545916cd2Sjpk 	*display = sldim;
28645916cd2Sjpk 	/*LINTED*/
28745916cd2Sjpk 	*long_words = (char **)slcvt;
28845916cd2Sjpk 	/*LINTED*/
28945916cd2Sjpk 	*short_words = (char **)(slcvt + *display_size * sizeof (char *));
29045916cd2Sjpk 	if (callp != &call)
29145916cd2Sjpk 		/* release return buffer */
29245916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
29345916cd2Sjpk 	return (1);
29445916cd2Sjpk }  /* bslcvtfull */
29545916cd2Sjpk #undef	bsfcall
29645916cd2Sjpk #undef	bsfret
29745916cd2Sjpk 
29845916cd2Sjpk #define	bsccall callp->param.acall.cargs.bslcvt_arg
29945916cd2Sjpk #define	bscret callp->param.aret.rvals.bslcvt_ret
30045916cd2Sjpk /*
30145916cd2Sjpk  *	bslcvt - Convert Sensitivity Label and update dimming information.
30245916cd2Sjpk  *
30345916cd2Sjpk  *	Entry	label = Sensitivity Label to convert and get dimming list.
30445916cd2Sjpk  *			This label should lie within the bounds of the
30545916cd2Sjpk  *			corresponding bslcvtfull call or the results may
30645916cd2Sjpk  *			not be meaningful.
30745916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
30845916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
30945916cd2Sjpk  *
31045916cd2Sjpk  *	Exit	string = ASCII coded Sensitivity Label.
31145916cd2Sjpk  *		display = Array of indicators as to whether the word is present
31245916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
31345916cd2Sjpk  *			  (CVT_DIM).
31445916cd2Sjpk  *
31545916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
31645916cd2Sjpk  *			invalid label.
31745916cd2Sjpk  *		 0, If unable to allocate static memory.
31845916cd2Sjpk  *		 1, If successful.
31945916cd2Sjpk  *
32045916cd2Sjpk  *	Calls	RPC - LABELS_BSLCONVERT, SETBLEVEL, SETBSLABEL, build_strings
32145916cd2Sjpk  *			clnt_call, clnt_perror.
32245916cd2Sjpk  *
32345916cd2Sjpk  *	Uses	sbounds, slrdim, slrstring.
32445916cd2Sjpk  */
32545916cd2Sjpk 
32645916cd2Sjpk int
32745916cd2Sjpk bslcvt(const bslabel_t *label, int flags, char **string, char *display[])
32845916cd2Sjpk {
32945916cd2Sjpk 	labeld_data_t	call;
33045916cd2Sjpk 	labeld_data_t	*callp = &call;
33145916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
33245916cd2Sjpk 	size_t	datasize = CALL_SIZE(bslcvt_call_t, 0);
33345916cd2Sjpk 	int	rval;
33445916cd2Sjpk 
33545916cd2Sjpk 	if (slcvt == NULL)
33645916cd2Sjpk 		return (-1);	/* conversion not initialized */
33745916cd2Sjpk 
33845916cd2Sjpk 	call.callop = BSLCVT;
33945916cd2Sjpk 	bsccall.label = *label;
34045916cd2Sjpk 	bsccall.bounds = sbounds;	/* save from last bslcvtfull() call */
34145916cd2Sjpk 	bsccall.flags = 0;
34245916cd2Sjpk 	set_label_view(&bsccall.flags, flags);
34345916cd2Sjpk 
34445916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
34545916cd2Sjpk #ifdef	DEBUG
34645916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
34745916cd2Sjpk #endif	/* DEBUG */
34845916cd2Sjpk 		return (-1);
34945916cd2Sjpk 	} else if (rval != SUCCESS) {
35045916cd2Sjpk 		return (-1);
35145916cd2Sjpk 	} else {
35245916cd2Sjpk 		if (callp->reterr != 0)
35345916cd2Sjpk 			return (-1);
35445916cd2Sjpk 	}
35545916cd2Sjpk 
35645916cd2Sjpk 	if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string],
35745916cd2Sjpk 	    &slcvtsize, 0, &slcvt, &sldim, bscret.d_len,
35845916cd2Sjpk 	    &bscret.buf[bscret.lwords], &bscret.buf[bscret.swords],
35945916cd2Sjpk 	    &bscret.buf[bscret.dim], 0) != 1) {
36045916cd2Sjpk 		if (callp != &call)
36145916cd2Sjpk 			/* release return buffer */
36245916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
36345916cd2Sjpk 		return (0);
36445916cd2Sjpk 	}
36545916cd2Sjpk 
36645916cd2Sjpk 	*string = slstring;
36745916cd2Sjpk 	*display = sldim;
36845916cd2Sjpk 	if (callp != &call)
36945916cd2Sjpk 		/* release return buffer */
37045916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
37145916cd2Sjpk 	return (1);
37245916cd2Sjpk }  /* bslcvt */
37345916cd2Sjpk #undef	bsccall
37445916cd2Sjpk #undef	bscret
37545916cd2Sjpk 
37645916cd2Sjpk #define	bcfcall callp->param.acall.cargs.bclearcvt_arg
37745916cd2Sjpk #define	bcfret callp->param.aret.rvals.bclearcvt_ret
37845916cd2Sjpk /*
37945916cd2Sjpk  *	bclearcvtfull - Convert Clearance and initialize static information.
38045916cd2Sjpk  *
38145916cd2Sjpk  *	Entry	clearance = Clearance to convert and get dimming list.
38245916cd2Sjpk  *			    This clearance should lie within the bounds or
38345916cd2Sjpk  *			    the results may not be meaningful.
38445916cd2Sjpk  *		bounds = Lower and upper bounds for words lists. Must be
38545916cd2Sjpk  *			dominated by clearance.
38645916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
38745916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
38845916cd2Sjpk  *
38945916cd2Sjpk  *	Exit	string = ASCII coded Clearance.
39045916cd2Sjpk  *		long_words = Array of pointers to visible long word names.
39145916cd2Sjpk  *		short_words = Array of pointers to visible short word names.
39245916cd2Sjpk  *		display = Array of indicators as to whether the word is present
39345916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
39445916cd2Sjpk  *			  (CVT_DIM).
39545916cd2Sjpk  *		first_compartment = Zero based index of first compartment.
39645916cd2Sjpk  *		display_size = Number of entries in the display/words lists.
39745916cd2Sjpk  *
39845916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
39945916cd2Sjpk  *			invalid label.
40045916cd2Sjpk  *		 0, If unable to allocate static memory.
40145916cd2Sjpk  *		 1, If successful.
40245916cd2Sjpk  *
40345916cd2Sjpk  *	Calls	RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, TCLNT,
40445916cd2Sjpk  *			build_strings, clnt_call, clnt_perror.
40545916cd2Sjpk  *
40645916cd2Sjpk  *	Uses	cbounds, clrcvt, clrcvtsize, clrdim, clrstring,
40745916cd2Sjpk  *			clrstringsize.
40845916cd2Sjpk  */
40945916cd2Sjpk 
41045916cd2Sjpk int
41145916cd2Sjpk bclearcvtfull(const bclear_t *clearance, const blrange_t *bounds,
41245916cd2Sjpk     int flags, char **string, char **long_words[], char **short_words[],
41345916cd2Sjpk     char *display[], int *first_compartment, int *display_size)
41445916cd2Sjpk {
41545916cd2Sjpk 	labeld_data_t	call;
41645916cd2Sjpk 	labeld_data_t	*callp = &call;
41745916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
41845916cd2Sjpk 	size_t	datasize = CALL_SIZE(bclearcvt_call_t, 0);
41945916cd2Sjpk 	int	new_words_size;
42045916cd2Sjpk 	int	rval;
42145916cd2Sjpk 
42245916cd2Sjpk 	call.callop = BCLEARCVT;
42345916cd2Sjpk 	bcfcall.clear = *clearance;
42445916cd2Sjpk 	bcfcall.bounds.upper_bound = *bounds->upper_bound;
42545916cd2Sjpk 	bcfcall.bounds.lower_bound = *bounds->lower_bound;
42645916cd2Sjpk 	bcfcall.flags = LABELS_FULL_CONVERT;
42745916cd2Sjpk 	set_label_view(&bcfcall.flags, flags);
42845916cd2Sjpk 
42945916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
43045916cd2Sjpk #ifdef	DEBUG
43145916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
43245916cd2Sjpk #endif	/* DEBUG */
43345916cd2Sjpk 		return (-1);
43445916cd2Sjpk 	} else if (rval != SUCCESS) {
43545916cd2Sjpk 		return (-1);
43645916cd2Sjpk 	} else {
43745916cd2Sjpk 		if (callp->reterr != 0)
43845916cd2Sjpk 			return (-1);
43945916cd2Sjpk 	}
44045916cd2Sjpk 
44145916cd2Sjpk 	*first_compartment = bcfret.first_comp;
44245916cd2Sjpk 	*display_size = bcfret.d_len;
44345916cd2Sjpk 
44445916cd2Sjpk 	new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len +
44545916cd2Sjpk 	    (2 * sizeof (char *)) * bcfret.d_len;
44645916cd2Sjpk 
44745916cd2Sjpk 	if (build_strings(&clrstringsize, &clrstring,
44845916cd2Sjpk 	    &bcfret.buf[bcfret.string],
44945916cd2Sjpk 	    &clrcvtsize, new_words_size, &clrcvt,
45045916cd2Sjpk 	    &clrdim, bcfret.d_len,
45145916cd2Sjpk 	    &bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords],
45245916cd2Sjpk 	    &bcfret.buf[bcfret.dim], 1) != 1) {
45345916cd2Sjpk 		if (callp != &call)
45445916cd2Sjpk 			/* release return buffer */
45545916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
45645916cd2Sjpk 		return (0);
45745916cd2Sjpk 	}
45845916cd2Sjpk 
45945916cd2Sjpk 	/* save for bclearcvt call */
46045916cd2Sjpk 	cbounds.upper_bound = *bounds->upper_bound;
46145916cd2Sjpk 	cbounds.lower_bound = *bounds->lower_bound;
46245916cd2Sjpk 
46345916cd2Sjpk 	*string = clrstring;
46445916cd2Sjpk 	*display = clrdim;
46545916cd2Sjpk 	/*LINTED*/
46645916cd2Sjpk 	*long_words = (char **)clrcvt;
46745916cd2Sjpk 	/*LINTED*/
46845916cd2Sjpk 	*short_words = (char **)(clrcvt + *display_size * sizeof (char *));
46945916cd2Sjpk 	if (callp != &call)
47045916cd2Sjpk 		/* release return buffer */
47145916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
47245916cd2Sjpk 	return (1);
47345916cd2Sjpk }  /* bclearcvtfull */
47445916cd2Sjpk #undef	bcfcall
47545916cd2Sjpk #undef	bcfret
47645916cd2Sjpk 
47745916cd2Sjpk #define	bcccall callp->param.acall.cargs.bclearcvt_arg
47845916cd2Sjpk #define	bccret callp->param.aret.rvals.bclearcvt_ret
47945916cd2Sjpk /*
48045916cd2Sjpk  *	bclearcvt - Convert Clearance and update dimming inforamtion.
48145916cd2Sjpk  *
48245916cd2Sjpk  *	Entry	clearance = Clearance to convert and get dimming list.
48345916cd2Sjpk  *			    This clearance should lie within the bounds of the
48445916cd2Sjpk  *			    corresponding bclearcvtfull call or the results may
48545916cd2Sjpk  *			    not be meaningful.
48645916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
48745916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
48845916cd2Sjpk  *
48945916cd2Sjpk  *	Exit	string = ASCII coded Clearance.
49045916cd2Sjpk  *		display = Array of indicators as to whether the word is present
49145916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
49245916cd2Sjpk  *			  (CVT_DIM).
49345916cd2Sjpk  *
49445916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
49545916cd2Sjpk  *			invalid label.
49645916cd2Sjpk  *		 0, If unable to allocate static memory.
49745916cd2Sjpk  *		 1, If successful.
49845916cd2Sjpk  *
49945916cd2Sjpk  *	Calls	RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, build_strings,
50045916cd2Sjpk  *			clnt_call, clnt_perror.
50145916cd2Sjpk  *
50245916cd2Sjpk  *	Uses	cbounds, clrdim, clrstring.
50345916cd2Sjpk  */
50445916cd2Sjpk 
50545916cd2Sjpk int
50645916cd2Sjpk bclearcvt(const bclear_t *clearance, int flags, char **string,
50745916cd2Sjpk     char *display[])
50845916cd2Sjpk {
50945916cd2Sjpk 	labeld_data_t	call;
51045916cd2Sjpk 	labeld_data_t	*callp = &call;
51145916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
51245916cd2Sjpk 	size_t	datasize = CALL_SIZE(bclearcvt_call_t, 0);
51345916cd2Sjpk 	int	rval;
51445916cd2Sjpk 
51545916cd2Sjpk 	if (clrcvt == NULL)
51645916cd2Sjpk 		return (-1);	/* conversion not initialized */
51745916cd2Sjpk 
51845916cd2Sjpk 	call.callop = BCLEARCVT;
51945916cd2Sjpk 	bcccall.clear = *clearance;
52045916cd2Sjpk 	bcccall.bounds = cbounds;	/* save from last bslcvtfull() call */
52145916cd2Sjpk 	bcccall.flags = 0;
52245916cd2Sjpk 	set_label_view(&bcccall.flags, flags);
52345916cd2Sjpk 
52445916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
52545916cd2Sjpk #ifdef	DEBUG
52645916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
52745916cd2Sjpk #endif	/* DEBUG */
52845916cd2Sjpk 		return (-1);
52945916cd2Sjpk 	} else if (rval != SUCCESS) {
53045916cd2Sjpk 		return (-1);
53145916cd2Sjpk 	} else {
53245916cd2Sjpk 		if (callp->reterr != 0)
53345916cd2Sjpk 			return (-1);
53445916cd2Sjpk 	}
53545916cd2Sjpk 
53645916cd2Sjpk 	if (build_strings(&clrstringsize, &clrstring,
53745916cd2Sjpk 	    &bccret.buf[bccret.string],
53845916cd2Sjpk 	    &clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len,
53945916cd2Sjpk 	    &bccret.buf[bccret.lwords], &bccret.buf[bccret.swords],
54045916cd2Sjpk 	    &bccret.buf[bccret.dim], 0) != 1) {
54145916cd2Sjpk 		if (callp != &call)
54245916cd2Sjpk 			/* release return buffer */
54345916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
54445916cd2Sjpk 		return (0);
54545916cd2Sjpk 	}
54645916cd2Sjpk 
54745916cd2Sjpk 	*string = clrstring;
54845916cd2Sjpk 	*display = clrdim;
54945916cd2Sjpk 	if (callp != &call)
55045916cd2Sjpk 		/* release return buffer */
55145916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
55245916cd2Sjpk 	return (1);
55345916cd2Sjpk }  /* bclearcvt */
55445916cd2Sjpk #undef	bcccall
55545916cd2Sjpk #undef	bccret
55645916cd2Sjpk 
55745916cd2Sjpk #define	lfret callp->param.aret.rvals.fields_ret
55845916cd2Sjpk /*
55945916cd2Sjpk  *	labelfields - Return names for the label fields.
56045916cd2Sjpk  *
56145916cd2Sjpk  *	Entry	None
56245916cd2Sjpk  *
56345916cd2Sjpk  *	Exit	fields = Updated.
56445916cd2Sjpk  *
56545916cd2Sjpk  *	Returns	-1, If unable to access label encodings file, or
56645916cd2Sjpk  *			labels server failure.
56745916cd2Sjpk  *		 0, If unable to allocate memory.
56845916cd2Sjpk  *		 1, If successful.
56945916cd2Sjpk  *
57045916cd2Sjpk  *	Calls __call_labeld(LABELFIELDS).
57145916cd2Sjpk  */
57245916cd2Sjpk 
57345916cd2Sjpk int
57445916cd2Sjpk labelfields(struct name_fields *fields)
57545916cd2Sjpk {
57645916cd2Sjpk 	labeld_data_t	call;
57745916cd2Sjpk 	labeld_data_t	*callp = &call;
57845916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
57945916cd2Sjpk 	size_t	datasize = CALL_SIZE(fields_call_t, 0);
58045916cd2Sjpk 	int	rval;
58145916cd2Sjpk 
58245916cd2Sjpk 	call.callop = LABELFIELDS;
58345916cd2Sjpk 
58445916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
58545916cd2Sjpk 
58645916cd2Sjpk 		if (callp != &call)
58745916cd2Sjpk 			/* release return buffer */
58845916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
58945916cd2Sjpk 		return (-1);
59045916cd2Sjpk 	}
59145916cd2Sjpk 
59245916cd2Sjpk 	/* unpack results */
59345916cd2Sjpk 
59445916cd2Sjpk 	if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) {
59545916cd2Sjpk 		if (callp != &call)
59645916cd2Sjpk 			/* release return buffer */
59745916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
59845916cd2Sjpk 		return (0);
59945916cd2Sjpk 	}
60045916cd2Sjpk 	if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) {
60145916cd2Sjpk 		free(fields->class_name);
60245916cd2Sjpk 		if (callp != &call)
60345916cd2Sjpk 			/* release return buffer */
60445916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
60545916cd2Sjpk 		return (0);
60645916cd2Sjpk 	}
60745916cd2Sjpk 	if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) {
60845916cd2Sjpk 		free(fields->class_name);
60945916cd2Sjpk 		free(fields->comps_name);
61045916cd2Sjpk 		if (callp != &call)
61145916cd2Sjpk 			/* release return buffer */
61245916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
61345916cd2Sjpk 		return (0);
61445916cd2Sjpk 	}
61545916cd2Sjpk 
61645916cd2Sjpk 	if (callp != &call)
61745916cd2Sjpk 		/* release return buffer */
61845916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
61945916cd2Sjpk 	return (rval);
62045916cd2Sjpk }  /* labelfields */
62145916cd2Sjpk #undef	lfret
62245916cd2Sjpk 
62345916cd2Sjpk #define	udret callp->param.aret.rvals.udefs_ret
62445916cd2Sjpk /*
625*aa2e15f6Srica  *	userdefs - Get default user Sensitivity Label and/or Clearance.
62645916cd2Sjpk  *
62745916cd2Sjpk  *	Entry   None.
62845916cd2Sjpk  *
62945916cd2Sjpk  *	Exit	sl = default user Sensitivity Label.
63045916cd2Sjpk  *		clear = default user Clearance.
63145916cd2Sjpk  *
63245916cd2Sjpk  *	Returns -1, If unable to access label encodings file, or
63345916cd2Sjpk  *			labels server failure.
63445916cd2Sjpk  *		1, If successful.
63545916cd2Sjpk  *
63645916cd2Sjpk  *	Calls	__call_labeld(UDEFS).
63745916cd2Sjpk  */
63845916cd2Sjpk 
63945916cd2Sjpk int
64045916cd2Sjpk userdefs(bslabel_t *sl, bclear_t *clear)
64145916cd2Sjpk {
64245916cd2Sjpk 	labeld_data_t	call;
64345916cd2Sjpk 	labeld_data_t	*callp = &call;
64445916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
64545916cd2Sjpk 	size_t	datasize = CALL_SIZE(udefs_call_t, 0);
64645916cd2Sjpk 	int	rval;
64745916cd2Sjpk 
64845916cd2Sjpk 	call.callop = UDEFS;
64945916cd2Sjpk 
65045916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
65145916cd2Sjpk 		/* process error */
65245916cd2Sjpk 
65345916cd2Sjpk 		return (-1);
65445916cd2Sjpk 	}
65545916cd2Sjpk 
656*aa2e15f6Srica 	if (sl != NULL)
65745916cd2Sjpk 		*sl = udret.sl;
658*aa2e15f6Srica 	if (clear != NULL)
65945916cd2Sjpk 		*clear = udret.clear;
66045916cd2Sjpk 	return (rval);
66145916cd2Sjpk }  /* userdefs */
66245916cd2Sjpk #undef	udret
663