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