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