xref: /titanic_51/usr/src/lib/libtsol/common/private.c (revision 45916cd2fec6e79bca5dee0421bd39e3c2910d1e)
1*45916cd2Sjpk /*
2*45916cd2Sjpk  * CDDL HEADER START
3*45916cd2Sjpk  *
4*45916cd2Sjpk  * The contents of this file are subject to the terms of the
5*45916cd2Sjpk  * Common Development and Distribution License (the "License").
6*45916cd2Sjpk  * You may not use this file except in compliance with the License.
7*45916cd2Sjpk  *
8*45916cd2Sjpk  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*45916cd2Sjpk  * or http://www.opensolaris.org/os/licensing.
10*45916cd2Sjpk  * See the License for the specific language governing permissions
11*45916cd2Sjpk  * and limitations under the License.
12*45916cd2Sjpk  *
13*45916cd2Sjpk  * When distributing Covered Code, include this CDDL HEADER in each
14*45916cd2Sjpk  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*45916cd2Sjpk  * If applicable, add the following below this CDDL HEADER, with the
16*45916cd2Sjpk  * fields enclosed by brackets "[]" replaced with your own identifying
17*45916cd2Sjpk  * information: Portions Copyright [yyyy] [name of copyright owner]
18*45916cd2Sjpk  *
19*45916cd2Sjpk  * CDDL HEADER END
20*45916cd2Sjpk  */
21*45916cd2Sjpk /*
22*45916cd2Sjpk  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*45916cd2Sjpk  * Use is subject to license terms.
24*45916cd2Sjpk  */
25*45916cd2Sjpk 
26*45916cd2Sjpk #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*45916cd2Sjpk 
28*45916cd2Sjpk /*
29*45916cd2Sjpk  *	Label library contract private interfaces.
30*45916cd2Sjpk  *
31*45916cd2Sjpk  *	Binary labels to String labels with dimming word lists.
32*45916cd2Sjpk  *	Dimming word list titles.
33*45916cd2Sjpk  *	Default user labels.
34*45916cd2Sjpk  */
35*45916cd2Sjpk 
36*45916cd2Sjpk #include <locale.h>
37*45916cd2Sjpk #include <stdlib.h>
38*45916cd2Sjpk #include <stdio.h>
39*45916cd2Sjpk #include <strings.h>
40*45916cd2Sjpk 
41*45916cd2Sjpk #include <sys/mman.h>
42*45916cd2Sjpk 
43*45916cd2Sjpk #include <tsol/label.h>
44*45916cd2Sjpk 
45*45916cd2Sjpk #include "clnt.h"
46*45916cd2Sjpk #include "labeld.h"
47*45916cd2Sjpk 
48*45916cd2Sjpk /*
49*45916cd2Sjpk  *	cvt memory:
50*45916cd2Sjpk  *
51*45916cd2Sjpk  * cvt:	char	*long_words[display_size];	Pointers to long words
52*45916cd2Sjpk  *	char	*short_words[display_size];	Pointers to short words
53*45916cd2Sjpk  * dim:	char	display[display_size];		Dim | Set
54*45916cd2Sjpk  *
55*45916cd2Sjpk  *	    strings associated with long and short words.
56*45916cd2Sjpk  *
57*45916cd2Sjpk  */
58*45916cd2Sjpk 
59*45916cd2Sjpk /*
60*45916cd2Sjpk  *	Sensitivity Label words.
61*45916cd2Sjpk  */
62*45916cd2Sjpk 
63*45916cd2Sjpk static	char *slcvt = NULL;
64*45916cd2Sjpk static	int   slcvtsize = 0;
65*45916cd2Sjpk static	char *sldim;
66*45916cd2Sjpk 
67*45916cd2Sjpk static	char *slstring = NULL;
68*45916cd2Sjpk static	int   slstringsize = 0;
69*45916cd2Sjpk static	brange_t sbounds;
70*45916cd2Sjpk 
71*45916cd2Sjpk /*
72*45916cd2Sjpk  *	Clearance words.
73*45916cd2Sjpk  */
74*45916cd2Sjpk 
75*45916cd2Sjpk static	char *clrcvt = NULL;
76*45916cd2Sjpk static	int   clrcvtsize = 0;
77*45916cd2Sjpk static	char *clrdim;
78*45916cd2Sjpk 
79*45916cd2Sjpk static	char *clrstring = NULL;
80*45916cd2Sjpk static	int   clrstringsize = 0;
81*45916cd2Sjpk static	brange_t cbounds;
82*45916cd2Sjpk 
83*45916cd2Sjpk static
84*45916cd2Sjpk int
85*45916cd2Sjpk alloc_words(char **words, const size_t size)
86*45916cd2Sjpk {
87*45916cd2Sjpk 	if (*words == NULL) {
88*45916cd2Sjpk 		if ((*words = malloc(size)) == NULL)
89*45916cd2Sjpk 			return (0);
90*45916cd2Sjpk 	} else {
91*45916cd2Sjpk 		if ((*words = realloc(*words, size)) == NULL) {
92*45916cd2Sjpk 			return (0);
93*45916cd2Sjpk 		}
94*45916cd2Sjpk 	}
95*45916cd2Sjpk 	return (1);
96*45916cd2Sjpk }
97*45916cd2Sjpk 
98*45916cd2Sjpk /*
99*45916cd2Sjpk  *	build_strings - Build the static strings and dimming list for a
100*45916cd2Sjpk  *			converted label.
101*45916cd2Sjpk  *
102*45916cd2Sjpk  *	Entry	new_string = Newly converted string.
103*45916cd2Sjpk  *		new_words_size = Size of words associated with newly converted
104*45916cd2Sjpk  *				 label.
105*45916cd2Sjpk  *		number_of_words = Number of words associated with newly
106*45916cd2Sjpk  *				  converted label.
107*45916cd2Sjpk  *		full =	1, if static words lists to be updated.
108*45916cd2Sjpk  *			0, if only string and dimming list to be updated.
109*45916cd2Sjpk  *
110*45916cd2Sjpk  *	Exit	static_string_size = Updated if needed.
111*45916cd2Sjpk  *		static_string = Updated to new label string.
112*45916cd2Sjpk  *		static_words_size = Updated if needed.
113*45916cd2Sjpk  *		static_words = Updated to new words list, if needed.
114*45916cd2Sjpk  *		static_dimming = Updated to new dimming state.
115*45916cd2Sjpk  *		long_words = Updated to new long words pointers, if needed.
116*45916cd2Sjpk  *		short_words = Updated to new short words pointers, if needed.
117*45916cd2Sjpk  *
118*45916cd2Sjpk  *
119*45916cd2Sjpk  *	Returns	0, If unable to allocate memory.
120*45916cd2Sjpk  *		1, If successful.
121*45916cd2Sjpk  *
122*45916cd2Sjpk  *	Calls	alloc_string, alloc_words, memcpy, strcpy, strlen.
123*45916cd2Sjpk  */
124*45916cd2Sjpk 
125*45916cd2Sjpk static
126*45916cd2Sjpk int
127*45916cd2Sjpk build_strings(int *static_string_size, char **static_string, char *new_string,
128*45916cd2Sjpk     int *static_words_size, int new_words_size, char **static_words,
129*45916cd2Sjpk     char **static_dimming, int number_of_words, char *long_words,
130*45916cd2Sjpk     char *short_words, char *dimming_list, int full)
131*45916cd2Sjpk {
132*45916cd2Sjpk 	char	**l;
133*45916cd2Sjpk 	char	**s;
134*45916cd2Sjpk 	char	*w;
135*45916cd2Sjpk 	char	*l_w = long_words;
136*45916cd2Sjpk 	char	*s_w = short_words;
137*45916cd2Sjpk 	int	i;
138*45916cd2Sjpk 	int	len;
139*45916cd2Sjpk 	int	newsize;
140*45916cd2Sjpk 
141*45916cd2Sjpk 	if (*static_string_size == 0) { /* Allocate string memory. */
142*45916cd2Sjpk 		if ((*static_string_size = alloc_string(static_string,
143*45916cd2Sjpk 		    *static_string_size, 'C')) == 0)
144*45916cd2Sjpk 			/* can't get string memory for string */
145*45916cd2Sjpk 			return (0);
146*45916cd2Sjpk 	}
147*45916cd2Sjpk 
148*45916cd2Sjpk again:
149*45916cd2Sjpk 	if (*static_string_size < (int)strlen(new_string)+1) {
150*45916cd2Sjpk 		/* need longer string */
151*45916cd2Sjpk 		if ((newsize = alloc_string(static_string, *static_string_size,
152*45916cd2Sjpk 		    'C')) == 0)
153*45916cd2Sjpk 			/* can't get more string memory */
154*45916cd2Sjpk 			return (0);
155*45916cd2Sjpk 
156*45916cd2Sjpk 		*static_string_size += newsize;
157*45916cd2Sjpk 		goto again;
158*45916cd2Sjpk 	}
159*45916cd2Sjpk 	bcopy(new_string, *static_string, strlen(new_string) + 1);
160*45916cd2Sjpk 
161*45916cd2Sjpk 	if (full) {
162*45916cd2Sjpk 		if (*static_words_size < new_words_size &&
163*45916cd2Sjpk 		    !alloc_words(static_words, new_words_size)) {
164*45916cd2Sjpk 			/* can't get more words memory */
165*45916cd2Sjpk 			return (0);
166*45916cd2Sjpk 		} else {
167*45916cd2Sjpk 			*static_words_size = new_words_size;
168*45916cd2Sjpk 		}
169*45916cd2Sjpk 		/*LINTED*/
170*45916cd2Sjpk 		l = (char **)*static_words;
171*45916cd2Sjpk 		s = l + number_of_words;
172*45916cd2Sjpk 		*static_dimming = (char *)(s + number_of_words);
173*45916cd2Sjpk 		w = *static_dimming + number_of_words;
174*45916cd2Sjpk 		for (i = 0; i < number_of_words; i++) {
175*45916cd2Sjpk 			*l = w;
176*45916cd2Sjpk 			(void) strcpy(w, l_w);
177*45916cd2Sjpk 			w += (len = strlen(l_w) + 1);
178*45916cd2Sjpk 			l_w += len;
179*45916cd2Sjpk 			if (*s_w == '\000') {
180*45916cd2Sjpk 				*s = NULL;
181*45916cd2Sjpk 				s_w++;
182*45916cd2Sjpk 			} else {
183*45916cd2Sjpk 				*s = w;
184*45916cd2Sjpk 				(void) strcpy(w, s_w);
185*45916cd2Sjpk 				w += (len = strlen(s_w) + 1);
186*45916cd2Sjpk 				s_w += len;
187*45916cd2Sjpk 			}
188*45916cd2Sjpk 
189*45916cd2Sjpk 			l++;
190*45916cd2Sjpk 			s++;
191*45916cd2Sjpk 		}  /* for each word entry */
192*45916cd2Sjpk 	}  /* if (full) */
193*45916cd2Sjpk 
194*45916cd2Sjpk 	bcopy(dimming_list, *static_dimming, number_of_words);
195*45916cd2Sjpk 	return (1);
196*45916cd2Sjpk }  /* build_strings */
197*45916cd2Sjpk 
198*45916cd2Sjpk #define	bsfcall callp->param.acall.cargs.bslcvt_arg
199*45916cd2Sjpk #define	bsfret callp->param.aret.rvals.bslcvt_ret
200*45916cd2Sjpk /*
201*45916cd2Sjpk  *	bslcvtfull - Convert Sensitivity Label and initialize static
202*45916cd2Sjpk  *			information.
203*45916cd2Sjpk  *
204*45916cd2Sjpk  *	Entry	label = Sensitivity Label to convert and get dimming list.
205*45916cd2Sjpk  *			This label should lie within the bounds or the
206*45916cd2Sjpk  *			results may not be meaningful.
207*45916cd2Sjpk  *		bounds = Lower and upper bounds for words lists. Must be
208*45916cd2Sjpk  *			dominated by clearance.
209*45916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
210*45916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
211*45916cd2Sjpk  *
212*45916cd2Sjpk  *	Exit	string = ASCII coded Sensitivity Label.
213*45916cd2Sjpk  *		long_words = Array of pointers to visible long word names.
214*45916cd2Sjpk  *		short_words = Array of pointers to visible short word names.
215*45916cd2Sjpk  *		display = Array of indicators as to whether the word is present
216*45916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
217*45916cd2Sjpk  *			  (CVT_DIM).
218*45916cd2Sjpk  *		first_compartment = Zero based index of first compartment.
219*45916cd2Sjpk  *		display_size = Number of entries in the display/words lists.
220*45916cd2Sjpk  *
221*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
222*45916cd2Sjpk  *			invalid label.
223*45916cd2Sjpk  *		 0, If unable to allocate static memory.
224*45916cd2Sjpk  *		 1, If successful.
225*45916cd2Sjpk  *
226*45916cd2Sjpk  *	Calls	RPC - LABELS_BSLCONVERT, STTBLEVEL, SETBSLABEL, TCLNT,
227*45916cd2Sjpk  *			build_strings, clnt_call, clnt_perror.
228*45916cd2Sjpk  *
229*45916cd2Sjpk  *	Uses	sbounds, slrcvt, slrcvtsize, slrdim, slrstring,
230*45916cd2Sjpk  *			slrstringsize.
231*45916cd2Sjpk  */
232*45916cd2Sjpk 
233*45916cd2Sjpk int
234*45916cd2Sjpk bslcvtfull(const bslabel_t *label, const blrange_t *bounds, int flags,
235*45916cd2Sjpk     char **string, char **long_words[], char **short_words[], char *display[],
236*45916cd2Sjpk     int *first_compartment, int *display_size)
237*45916cd2Sjpk {
238*45916cd2Sjpk 	labeld_data_t	call;
239*45916cd2Sjpk 	labeld_data_t	*callp = &call;
240*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
241*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(bslcvt_call_t, 0);
242*45916cd2Sjpk 	int	new_words_size;
243*45916cd2Sjpk 	int	rval;
244*45916cd2Sjpk 
245*45916cd2Sjpk 	call.callop = BSLCVT;
246*45916cd2Sjpk 	bsfcall.label = *label;
247*45916cd2Sjpk 	bsfcall.bounds.upper_bound = *bounds->upper_bound;
248*45916cd2Sjpk 	bsfcall.bounds.lower_bound = *bounds->lower_bound;
249*45916cd2Sjpk 	bsfcall.flags = LABELS_FULL_CONVERT;
250*45916cd2Sjpk 	set_label_view(&bsfcall.flags, flags);
251*45916cd2Sjpk 
252*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
253*45916cd2Sjpk #ifdef	DEBUG
254*45916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
255*45916cd2Sjpk #endif	/* DEBUG */
256*45916cd2Sjpk 		return (-1);
257*45916cd2Sjpk 	} else if (rval != SUCCESS) {
258*45916cd2Sjpk 		return (-1);
259*45916cd2Sjpk 	} else {
260*45916cd2Sjpk 		if (callp->reterr != 0)
261*45916cd2Sjpk 			return (-1);
262*45916cd2Sjpk 	}
263*45916cd2Sjpk 
264*45916cd2Sjpk 	*first_compartment = bsfret.first_comp;
265*45916cd2Sjpk 	*display_size = bsfret.d_len;
266*45916cd2Sjpk 
267*45916cd2Sjpk 	new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len +
268*45916cd2Sjpk 	    (2 * sizeof (char *)) * bsfret.d_len;
269*45916cd2Sjpk 
270*45916cd2Sjpk 	if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string],
271*45916cd2Sjpk 	    &slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len,
272*45916cd2Sjpk 	    &bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords],
273*45916cd2Sjpk 	    &bsfret.buf[bsfret.dim], 1) != 1) {
274*45916cd2Sjpk 		if (callp != &call)
275*45916cd2Sjpk 			/* release return buffer */
276*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
277*45916cd2Sjpk 		return (0);
278*45916cd2Sjpk 	}
279*45916cd2Sjpk 
280*45916cd2Sjpk 	/* save for bslcvt call */
281*45916cd2Sjpk 	sbounds.upper_bound = *bounds->upper_bound;
282*45916cd2Sjpk 	sbounds.lower_bound = *bounds->lower_bound;
283*45916cd2Sjpk 
284*45916cd2Sjpk 	*string = slstring;
285*45916cd2Sjpk 	*display = sldim;
286*45916cd2Sjpk 	/*LINTED*/
287*45916cd2Sjpk 	*long_words = (char **)slcvt;
288*45916cd2Sjpk 	/*LINTED*/
289*45916cd2Sjpk 	*short_words = (char **)(slcvt + *display_size * sizeof (char *));
290*45916cd2Sjpk 	if (callp != &call)
291*45916cd2Sjpk 		/* release return buffer */
292*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
293*45916cd2Sjpk 	return (1);
294*45916cd2Sjpk }  /* bslcvtfull */
295*45916cd2Sjpk #undef	bsfcall
296*45916cd2Sjpk #undef	bsfret
297*45916cd2Sjpk 
298*45916cd2Sjpk #define	bsccall callp->param.acall.cargs.bslcvt_arg
299*45916cd2Sjpk #define	bscret callp->param.aret.rvals.bslcvt_ret
300*45916cd2Sjpk /*
301*45916cd2Sjpk  *	bslcvt - Convert Sensitivity Label and update dimming information.
302*45916cd2Sjpk  *
303*45916cd2Sjpk  *	Entry	label = Sensitivity Label to convert and get dimming list.
304*45916cd2Sjpk  *			This label should lie within the bounds of the
305*45916cd2Sjpk  *			corresponding bslcvtfull call or the results may
306*45916cd2Sjpk  *			not be meaningful.
307*45916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
308*45916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
309*45916cd2Sjpk  *
310*45916cd2Sjpk  *	Exit	string = ASCII coded Sensitivity Label.
311*45916cd2Sjpk  *		display = Array of indicators as to whether the word is present
312*45916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
313*45916cd2Sjpk  *			  (CVT_DIM).
314*45916cd2Sjpk  *
315*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
316*45916cd2Sjpk  *			invalid label.
317*45916cd2Sjpk  *		 0, If unable to allocate static memory.
318*45916cd2Sjpk  *		 1, If successful.
319*45916cd2Sjpk  *
320*45916cd2Sjpk  *	Calls	RPC - LABELS_BSLCONVERT, SETBLEVEL, SETBSLABEL, build_strings
321*45916cd2Sjpk  *			clnt_call, clnt_perror.
322*45916cd2Sjpk  *
323*45916cd2Sjpk  *	Uses	sbounds, slrdim, slrstring.
324*45916cd2Sjpk  */
325*45916cd2Sjpk 
326*45916cd2Sjpk int
327*45916cd2Sjpk bslcvt(const bslabel_t *label, int flags, char **string, char *display[])
328*45916cd2Sjpk {
329*45916cd2Sjpk 	labeld_data_t	call;
330*45916cd2Sjpk 	labeld_data_t	*callp = &call;
331*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
332*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(bslcvt_call_t, 0);
333*45916cd2Sjpk 	int	rval;
334*45916cd2Sjpk 
335*45916cd2Sjpk 	if (slcvt == NULL)
336*45916cd2Sjpk 		return (-1);	/* conversion not initialized */
337*45916cd2Sjpk 
338*45916cd2Sjpk 	call.callop = BSLCVT;
339*45916cd2Sjpk 	bsccall.label = *label;
340*45916cd2Sjpk 	bsccall.bounds = sbounds;	/* save from last bslcvtfull() call */
341*45916cd2Sjpk 	bsccall.flags = 0;
342*45916cd2Sjpk 	set_label_view(&bsccall.flags, flags);
343*45916cd2Sjpk 
344*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
345*45916cd2Sjpk #ifdef	DEBUG
346*45916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
347*45916cd2Sjpk #endif	/* DEBUG */
348*45916cd2Sjpk 		return (-1);
349*45916cd2Sjpk 	} else if (rval != SUCCESS) {
350*45916cd2Sjpk 		return (-1);
351*45916cd2Sjpk 	} else {
352*45916cd2Sjpk 		if (callp->reterr != 0)
353*45916cd2Sjpk 			return (-1);
354*45916cd2Sjpk 	}
355*45916cd2Sjpk 
356*45916cd2Sjpk 	if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string],
357*45916cd2Sjpk 	    &slcvtsize, 0, &slcvt, &sldim, bscret.d_len,
358*45916cd2Sjpk 	    &bscret.buf[bscret.lwords], &bscret.buf[bscret.swords],
359*45916cd2Sjpk 	    &bscret.buf[bscret.dim], 0) != 1) {
360*45916cd2Sjpk 		if (callp != &call)
361*45916cd2Sjpk 			/* release return buffer */
362*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
363*45916cd2Sjpk 		return (0);
364*45916cd2Sjpk 	}
365*45916cd2Sjpk 
366*45916cd2Sjpk 	*string = slstring;
367*45916cd2Sjpk 	*display = sldim;
368*45916cd2Sjpk 	if (callp != &call)
369*45916cd2Sjpk 		/* release return buffer */
370*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
371*45916cd2Sjpk 	return (1);
372*45916cd2Sjpk }  /* bslcvt */
373*45916cd2Sjpk #undef	bsccall
374*45916cd2Sjpk #undef	bscret
375*45916cd2Sjpk 
376*45916cd2Sjpk #define	bcfcall callp->param.acall.cargs.bclearcvt_arg
377*45916cd2Sjpk #define	bcfret callp->param.aret.rvals.bclearcvt_ret
378*45916cd2Sjpk /*
379*45916cd2Sjpk  *	bclearcvtfull - Convert Clearance and initialize static information.
380*45916cd2Sjpk  *
381*45916cd2Sjpk  *	Entry	clearance = Clearance to convert and get dimming list.
382*45916cd2Sjpk  *			    This clearance should lie within the bounds or
383*45916cd2Sjpk  *			    the results may not be meaningful.
384*45916cd2Sjpk  *		bounds = Lower and upper bounds for words lists. Must be
385*45916cd2Sjpk  *			dominated by clearance.
386*45916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
387*45916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
388*45916cd2Sjpk  *
389*45916cd2Sjpk  *	Exit	string = ASCII coded Clearance.
390*45916cd2Sjpk  *		long_words = Array of pointers to visible long word names.
391*45916cd2Sjpk  *		short_words = Array of pointers to visible short word names.
392*45916cd2Sjpk  *		display = Array of indicators as to whether the word is present
393*45916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
394*45916cd2Sjpk  *			  (CVT_DIM).
395*45916cd2Sjpk  *		first_compartment = Zero based index of first compartment.
396*45916cd2Sjpk  *		display_size = Number of entries in the display/words lists.
397*45916cd2Sjpk  *
398*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
399*45916cd2Sjpk  *			invalid label.
400*45916cd2Sjpk  *		 0, If unable to allocate static memory.
401*45916cd2Sjpk  *		 1, If successful.
402*45916cd2Sjpk  *
403*45916cd2Sjpk  *	Calls	RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, TCLNT,
404*45916cd2Sjpk  *			build_strings, clnt_call, clnt_perror.
405*45916cd2Sjpk  *
406*45916cd2Sjpk  *	Uses	cbounds, clrcvt, clrcvtsize, clrdim, clrstring,
407*45916cd2Sjpk  *			clrstringsize.
408*45916cd2Sjpk  */
409*45916cd2Sjpk 
410*45916cd2Sjpk int
411*45916cd2Sjpk bclearcvtfull(const bclear_t *clearance, const blrange_t *bounds,
412*45916cd2Sjpk     int flags, char **string, char **long_words[], char **short_words[],
413*45916cd2Sjpk     char *display[], int *first_compartment, int *display_size)
414*45916cd2Sjpk {
415*45916cd2Sjpk 	labeld_data_t	call;
416*45916cd2Sjpk 	labeld_data_t	*callp = &call;
417*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
418*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(bclearcvt_call_t, 0);
419*45916cd2Sjpk 	int	new_words_size;
420*45916cd2Sjpk 	int	rval;
421*45916cd2Sjpk 
422*45916cd2Sjpk 	call.callop = BCLEARCVT;
423*45916cd2Sjpk 	bcfcall.clear = *clearance;
424*45916cd2Sjpk 	bcfcall.bounds.upper_bound = *bounds->upper_bound;
425*45916cd2Sjpk 	bcfcall.bounds.lower_bound = *bounds->lower_bound;
426*45916cd2Sjpk 	bcfcall.flags = LABELS_FULL_CONVERT;
427*45916cd2Sjpk 	set_label_view(&bcfcall.flags, flags);
428*45916cd2Sjpk 
429*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
430*45916cd2Sjpk #ifdef	DEBUG
431*45916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
432*45916cd2Sjpk #endif	/* DEBUG */
433*45916cd2Sjpk 		return (-1);
434*45916cd2Sjpk 	} else if (rval != SUCCESS) {
435*45916cd2Sjpk 		return (-1);
436*45916cd2Sjpk 	} else {
437*45916cd2Sjpk 		if (callp->reterr != 0)
438*45916cd2Sjpk 			return (-1);
439*45916cd2Sjpk 	}
440*45916cd2Sjpk 
441*45916cd2Sjpk 	*first_compartment = bcfret.first_comp;
442*45916cd2Sjpk 	*display_size = bcfret.d_len;
443*45916cd2Sjpk 
444*45916cd2Sjpk 	new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len +
445*45916cd2Sjpk 	    (2 * sizeof (char *)) * bcfret.d_len;
446*45916cd2Sjpk 
447*45916cd2Sjpk 	if (build_strings(&clrstringsize, &clrstring,
448*45916cd2Sjpk 	    &bcfret.buf[bcfret.string],
449*45916cd2Sjpk 	    &clrcvtsize, new_words_size, &clrcvt,
450*45916cd2Sjpk 	    &clrdim, bcfret.d_len,
451*45916cd2Sjpk 	    &bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords],
452*45916cd2Sjpk 	    &bcfret.buf[bcfret.dim], 1) != 1) {
453*45916cd2Sjpk 		if (callp != &call)
454*45916cd2Sjpk 			/* release return buffer */
455*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
456*45916cd2Sjpk 		return (0);
457*45916cd2Sjpk 	}
458*45916cd2Sjpk 
459*45916cd2Sjpk 	/* save for bclearcvt call */
460*45916cd2Sjpk 	cbounds.upper_bound = *bounds->upper_bound;
461*45916cd2Sjpk 	cbounds.lower_bound = *bounds->lower_bound;
462*45916cd2Sjpk 
463*45916cd2Sjpk 	*string = clrstring;
464*45916cd2Sjpk 	*display = clrdim;
465*45916cd2Sjpk 	/*LINTED*/
466*45916cd2Sjpk 	*long_words = (char **)clrcvt;
467*45916cd2Sjpk 	/*LINTED*/
468*45916cd2Sjpk 	*short_words = (char **)(clrcvt + *display_size * sizeof (char *));
469*45916cd2Sjpk 	if (callp != &call)
470*45916cd2Sjpk 		/* release return buffer */
471*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
472*45916cd2Sjpk 	return (1);
473*45916cd2Sjpk }  /* bclearcvtfull */
474*45916cd2Sjpk #undef	bcfcall
475*45916cd2Sjpk #undef	bcfret
476*45916cd2Sjpk 
477*45916cd2Sjpk #define	bcccall callp->param.acall.cargs.bclearcvt_arg
478*45916cd2Sjpk #define	bccret callp->param.aret.rvals.bclearcvt_ret
479*45916cd2Sjpk /*
480*45916cd2Sjpk  *	bclearcvt - Convert Clearance and update dimming inforamtion.
481*45916cd2Sjpk  *
482*45916cd2Sjpk  *	Entry	clearance = Clearance to convert and get dimming list.
483*45916cd2Sjpk  *			    This clearance should lie within the bounds of the
484*45916cd2Sjpk  *			    corresponding bclearcvtfull call or the results may
485*45916cd2Sjpk  *			    not be meaningful.
486*45916cd2Sjpk  *		flags = VIEW_INTERNAL, don't promote/demote admin low/high.
487*45916cd2Sjpk  *			VIEW_EXTERNAL, promote/demote admin low/high.
488*45916cd2Sjpk  *
489*45916cd2Sjpk  *	Exit	string = ASCII coded Clearance.
490*45916cd2Sjpk  *		display = Array of indicators as to whether the word is present
491*45916cd2Sjpk  *			  in the converted label (CVT_SET), and/or changeable
492*45916cd2Sjpk  *			  (CVT_DIM).
493*45916cd2Sjpk  *
494*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings database, or
495*45916cd2Sjpk  *			invalid label.
496*45916cd2Sjpk  *		 0, If unable to allocate static memory.
497*45916cd2Sjpk  *		 1, If successful.
498*45916cd2Sjpk  *
499*45916cd2Sjpk  *	Calls	RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, build_strings,
500*45916cd2Sjpk  *			clnt_call, clnt_perror.
501*45916cd2Sjpk  *
502*45916cd2Sjpk  *	Uses	cbounds, clrdim, clrstring.
503*45916cd2Sjpk  */
504*45916cd2Sjpk 
505*45916cd2Sjpk int
506*45916cd2Sjpk bclearcvt(const bclear_t *clearance, int flags, char **string,
507*45916cd2Sjpk     char *display[])
508*45916cd2Sjpk {
509*45916cd2Sjpk 	labeld_data_t	call;
510*45916cd2Sjpk 	labeld_data_t	*callp = &call;
511*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
512*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(bclearcvt_call_t, 0);
513*45916cd2Sjpk 	int	rval;
514*45916cd2Sjpk 
515*45916cd2Sjpk 	if (clrcvt == NULL)
516*45916cd2Sjpk 		return (-1);	/* conversion not initialized */
517*45916cd2Sjpk 
518*45916cd2Sjpk 	call.callop = BCLEARCVT;
519*45916cd2Sjpk 	bcccall.clear = *clearance;
520*45916cd2Sjpk 	bcccall.bounds = cbounds;	/* save from last bslcvtfull() call */
521*45916cd2Sjpk 	bcccall.flags = 0;
522*45916cd2Sjpk 	set_label_view(&bcccall.flags, flags);
523*45916cd2Sjpk 
524*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) {
525*45916cd2Sjpk #ifdef	DEBUG
526*45916cd2Sjpk 		(void) fprintf(stderr, "No label server.\n");
527*45916cd2Sjpk #endif	/* DEBUG */
528*45916cd2Sjpk 		return (-1);
529*45916cd2Sjpk 	} else if (rval != SUCCESS) {
530*45916cd2Sjpk 		return (-1);
531*45916cd2Sjpk 	} else {
532*45916cd2Sjpk 		if (callp->reterr != 0)
533*45916cd2Sjpk 			return (-1);
534*45916cd2Sjpk 	}
535*45916cd2Sjpk 
536*45916cd2Sjpk 	if (build_strings(&clrstringsize, &clrstring,
537*45916cd2Sjpk 	    &bccret.buf[bccret.string],
538*45916cd2Sjpk 	    &clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len,
539*45916cd2Sjpk 	    &bccret.buf[bccret.lwords], &bccret.buf[bccret.swords],
540*45916cd2Sjpk 	    &bccret.buf[bccret.dim], 0) != 1) {
541*45916cd2Sjpk 		if (callp != &call)
542*45916cd2Sjpk 			/* release return buffer */
543*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
544*45916cd2Sjpk 		return (0);
545*45916cd2Sjpk 	}
546*45916cd2Sjpk 
547*45916cd2Sjpk 	*string = clrstring;
548*45916cd2Sjpk 	*display = clrdim;
549*45916cd2Sjpk 	if (callp != &call)
550*45916cd2Sjpk 		/* release return buffer */
551*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
552*45916cd2Sjpk 	return (1);
553*45916cd2Sjpk }  /* bclearcvt */
554*45916cd2Sjpk #undef	bcccall
555*45916cd2Sjpk #undef	bccret
556*45916cd2Sjpk 
557*45916cd2Sjpk #define	lfret callp->param.aret.rvals.fields_ret
558*45916cd2Sjpk /*
559*45916cd2Sjpk  *	labelfields - Return names for the label fields.
560*45916cd2Sjpk  *
561*45916cd2Sjpk  *	Entry	None
562*45916cd2Sjpk  *
563*45916cd2Sjpk  *	Exit	fields = Updated.
564*45916cd2Sjpk  *
565*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings file, or
566*45916cd2Sjpk  *			labels server failure.
567*45916cd2Sjpk  *		 0, If unable to allocate memory.
568*45916cd2Sjpk  *		 1, If successful.
569*45916cd2Sjpk  *
570*45916cd2Sjpk  *	Calls __call_labeld(LABELFIELDS).
571*45916cd2Sjpk  */
572*45916cd2Sjpk 
573*45916cd2Sjpk int
574*45916cd2Sjpk labelfields(struct name_fields *fields)
575*45916cd2Sjpk {
576*45916cd2Sjpk 	labeld_data_t	call;
577*45916cd2Sjpk 	labeld_data_t	*callp = &call;
578*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
579*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(fields_call_t, 0);
580*45916cd2Sjpk 	int	rval;
581*45916cd2Sjpk 
582*45916cd2Sjpk 	call.callop = LABELFIELDS;
583*45916cd2Sjpk 
584*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
585*45916cd2Sjpk 
586*45916cd2Sjpk 		if (callp != &call)
587*45916cd2Sjpk 			/* release return buffer */
588*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
589*45916cd2Sjpk 		return (-1);
590*45916cd2Sjpk 	}
591*45916cd2Sjpk 
592*45916cd2Sjpk 	/* unpack results */
593*45916cd2Sjpk 
594*45916cd2Sjpk 	if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) {
595*45916cd2Sjpk 		if (callp != &call)
596*45916cd2Sjpk 			/* release return buffer */
597*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
598*45916cd2Sjpk 		return (0);
599*45916cd2Sjpk 	}
600*45916cd2Sjpk 	if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) {
601*45916cd2Sjpk 		free(fields->class_name);
602*45916cd2Sjpk 		if (callp != &call)
603*45916cd2Sjpk 			/* release return buffer */
604*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
605*45916cd2Sjpk 		return (0);
606*45916cd2Sjpk 	}
607*45916cd2Sjpk 	if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) {
608*45916cd2Sjpk 		free(fields->class_name);
609*45916cd2Sjpk 		free(fields->comps_name);
610*45916cd2Sjpk 		if (callp != &call)
611*45916cd2Sjpk 			/* release return buffer */
612*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
613*45916cd2Sjpk 		return (0);
614*45916cd2Sjpk 	}
615*45916cd2Sjpk 
616*45916cd2Sjpk 	if (callp != &call)
617*45916cd2Sjpk 		/* release return buffer */
618*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
619*45916cd2Sjpk 	return (rval);
620*45916cd2Sjpk }  /* labelfields */
621*45916cd2Sjpk #undef	lfret
622*45916cd2Sjpk 
623*45916cd2Sjpk #define	udret callp->param.aret.rvals.udefs_ret
624*45916cd2Sjpk /*
625*45916cd2Sjpk  *	userdefs - Get default user Sensitivity Label and Clearance.
626*45916cd2Sjpk  *
627*45916cd2Sjpk  *	Entry   None.
628*45916cd2Sjpk  *
629*45916cd2Sjpk  *	Exit	sl = default user Sensitivity Label.
630*45916cd2Sjpk  *		clear = default user Clearance.
631*45916cd2Sjpk  *
632*45916cd2Sjpk  *	Returns -1, If unable to access label encodings file, or
633*45916cd2Sjpk  *			labels server failure.
634*45916cd2Sjpk  *		1, If successful.
635*45916cd2Sjpk  *
636*45916cd2Sjpk  *	Calls	__call_labeld(UDEFS).
637*45916cd2Sjpk  */
638*45916cd2Sjpk 
639*45916cd2Sjpk int
640*45916cd2Sjpk userdefs(bslabel_t *sl, bclear_t *clear)
641*45916cd2Sjpk {
642*45916cd2Sjpk 	labeld_data_t	call;
643*45916cd2Sjpk 	labeld_data_t	*callp = &call;
644*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
645*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(udefs_call_t, 0);
646*45916cd2Sjpk 	int	rval;
647*45916cd2Sjpk 
648*45916cd2Sjpk 	call.callop = UDEFS;
649*45916cd2Sjpk 
650*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
651*45916cd2Sjpk 		/* process error */
652*45916cd2Sjpk 
653*45916cd2Sjpk 		return (-1);
654*45916cd2Sjpk 	}
655*45916cd2Sjpk 
656*45916cd2Sjpk 	*sl = udret.sl;
657*45916cd2Sjpk 	*clear = udret.clear;
658*45916cd2Sjpk 	return (rval);
659*45916cd2Sjpk }  /* userdefs */
660*45916cd2Sjpk #undef	udret
661