xref: /titanic_53/usr/src/lib/libtsol/common/misc.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 /*
30*45916cd2Sjpk  *	Miscellaneous user interfaces to trusted label functions.
31*45916cd2Sjpk  *
32*45916cd2Sjpk  */
33*45916cd2Sjpk 
34*45916cd2Sjpk 
35*45916cd2Sjpk #include <ctype.h>
36*45916cd2Sjpk #include <stdlib.h>
37*45916cd2Sjpk #include <strings.h>
38*45916cd2Sjpk 
39*45916cd2Sjpk #include <sys/mman.h>
40*45916cd2Sjpk 
41*45916cd2Sjpk #include <tsol/label.h>
42*45916cd2Sjpk 
43*45916cd2Sjpk #include "labeld.h"
44*45916cd2Sjpk #include "clnt.h"
45*45916cd2Sjpk #include <sys/tsol/label_macro.h>
46*45916cd2Sjpk #include <secdb.h>
47*45916cd2Sjpk #include <user_attr.h>
48*45916cd2Sjpk 
49*45916cd2Sjpk static	bslabel_t slow, shigh;	/* static Admin Low and High SLs */
50*45916cd2Sjpk static	bclear_t  clow, chigh;	/* static Admin Low and High CLRs */
51*45916cd2Sjpk 
52*45916cd2Sjpk static char color[MAXCOLOR];
53*45916cd2Sjpk 
54*45916cd2Sjpk 
55*45916cd2Sjpk #define	incall callp->param.acall.cargs.inset_arg
56*45916cd2Sjpk #define	inret callp->param.aret.rvals.inset_ret
57*45916cd2Sjpk /*
58*45916cd2Sjpk  *	blinset - Check in a label set.
59*45916cd2Sjpk  *
60*45916cd2Sjpk  *	Entry	label = Sensitivity Label to check.
61*45916cd2Sjpk  *		id    = Label set identifier of set to check.
62*45916cd2Sjpk  *
63*45916cd2Sjpk  *	Exit	None.
64*45916cd2Sjpk  *
65*45916cd2Sjpk  *	Returns	-1, If label set unavailable, or server failure.
66*45916cd2Sjpk  *		 0, If label not in label set.
67*45916cd2Sjpk  *		 1, If label is in the label set.
68*45916cd2Sjpk  *
69*45916cd2Sjpk  *	Calls	__call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH.
70*45916cd2Sjpk  *
71*45916cd2Sjpk  *	Uses	slow, shigh.
72*45916cd2Sjpk  */
73*45916cd2Sjpk 
74*45916cd2Sjpk int
75*45916cd2Sjpk blinset(const bslabel_t *label, const set_id *id)
76*45916cd2Sjpk {
77*45916cd2Sjpk 	if (id->type == SYSTEM_ACCREDITATION_RANGE) {
78*45916cd2Sjpk 		if (!BLTYPE(&slow, SUN_SL_ID)) {
79*45916cd2Sjpk 			/* initialize static labels. */
80*45916cd2Sjpk 
81*45916cd2Sjpk 			BSLLOW(&slow);
82*45916cd2Sjpk 			BSLHIGH(&shigh);
83*45916cd2Sjpk 		}
84*45916cd2Sjpk 
85*45916cd2Sjpk 		if (BLTYPE(label, SUN_SL_ID) &&
86*45916cd2Sjpk 		    (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
87*45916cd2Sjpk 
88*45916cd2Sjpk 			return (1);
89*45916cd2Sjpk 	}
90*45916cd2Sjpk 	if (id->type == USER_ACCREDITATION_RANGE ||
91*45916cd2Sjpk 	    id->type == SYSTEM_ACCREDITATION_RANGE) {
92*45916cd2Sjpk 		labeld_data_t	call;
93*45916cd2Sjpk 		labeld_data_t	*callp = &call;
94*45916cd2Sjpk 		size_t	bufsize = sizeof (labeld_data_t);
95*45916cd2Sjpk 		size_t	datasize = CALL_SIZE(inset_call_t, 0);
96*45916cd2Sjpk 
97*45916cd2Sjpk 		call.callop = BLINSET;
98*45916cd2Sjpk 		incall.label = *label;
99*45916cd2Sjpk 		incall.type = id->type;
100*45916cd2Sjpk 
101*45916cd2Sjpk 		if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
102*45916cd2Sjpk 			/* process error */
103*45916cd2Sjpk 
104*45916cd2Sjpk 			return (-1);
105*45916cd2Sjpk 		}
106*45916cd2Sjpk 		return (inret.inset);
107*45916cd2Sjpk 	} else {
108*45916cd2Sjpk 		/*
109*45916cd2Sjpk 		 * Only System and User Accreditation Ranges presently
110*45916cd2Sjpk 		 * implemented.
111*45916cd2Sjpk 		 */
112*45916cd2Sjpk 		return (-1);
113*45916cd2Sjpk 	}
114*45916cd2Sjpk }
115*45916cd2Sjpk #undef	incall
116*45916cd2Sjpk #undef	inret
117*45916cd2Sjpk 
118*45916cd2Sjpk #define	slvcall callp->param.acall.cargs.slvalid_arg
119*45916cd2Sjpk #define	slvret callp->param.aret.rvals.slvalid_ret
120*45916cd2Sjpk /*
121*45916cd2Sjpk  *	bslvalid - Check Sensitivity Label for validity.
122*45916cd2Sjpk  *
123*45916cd2Sjpk  *	Entry	label = Sensitivity Label to check.
124*45916cd2Sjpk  *
125*45916cd2Sjpk  *	Exit	None.
126*45916cd2Sjpk  *
127*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
128*45916cd2Sjpk  *		 0, If label not valid.
129*45916cd2Sjpk  *		 1, If label is valid.
130*45916cd2Sjpk  *
131*45916cd2Sjpk  *	Calls	__call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH.
132*45916cd2Sjpk  *
133*45916cd2Sjpk  *	Uses	slow, shigh.
134*45916cd2Sjpk  *
135*45916cd2Sjpk  */
136*45916cd2Sjpk 
137*45916cd2Sjpk int
138*45916cd2Sjpk bslvalid(const bslabel_t *label)
139*45916cd2Sjpk {
140*45916cd2Sjpk 	labeld_data_t	call;
141*45916cd2Sjpk 	labeld_data_t	*callp = &call;
142*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
143*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(slvalid_call_t, 0);
144*45916cd2Sjpk 
145*45916cd2Sjpk 	if (!BLTYPE(&slow, SUN_SL_ID)) {
146*45916cd2Sjpk 		/* initialize static labels. */
147*45916cd2Sjpk 
148*45916cd2Sjpk 		BSLLOW(&slow);
149*45916cd2Sjpk 		BSLHIGH(&shigh);
150*45916cd2Sjpk 	}
151*45916cd2Sjpk 
152*45916cd2Sjpk 	if (BLTYPE(label, SUN_SL_ID) &&
153*45916cd2Sjpk 	    (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
154*45916cd2Sjpk 
155*45916cd2Sjpk 		return (1);
156*45916cd2Sjpk 	}
157*45916cd2Sjpk 
158*45916cd2Sjpk 	call.callop = BSLVALID;
159*45916cd2Sjpk 	slvcall.label = *label;
160*45916cd2Sjpk 
161*45916cd2Sjpk 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
162*45916cd2Sjpk 		/* process error */
163*45916cd2Sjpk 
164*45916cd2Sjpk 		return (-1);
165*45916cd2Sjpk 	}
166*45916cd2Sjpk 	return (slvret.valid);
167*45916cd2Sjpk }
168*45916cd2Sjpk #undef	slvcall
169*45916cd2Sjpk #undef	slvret
170*45916cd2Sjpk 
171*45916cd2Sjpk #define	clrvcall callp->param.acall.cargs.clrvalid_arg
172*45916cd2Sjpk #define	clrvret callp->param.aret.rvals.clrvalid_ret
173*45916cd2Sjpk /*
174*45916cd2Sjpk  *	bclearvalid - Check Clearance for validity.
175*45916cd2Sjpk  *
176*45916cd2Sjpk  *	Entry	clearance = Clearance to check.
177*45916cd2Sjpk  *
178*45916cd2Sjpk  *	Exit	None.
179*45916cd2Sjpk  *
180*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
181*45916cd2Sjpk  *		 0, If label not valid.
182*45916cd2Sjpk  *		 1, If label is valid.
183*45916cd2Sjpk  *
184*45916cd2Sjpk  *	Calls	__call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH.
185*45916cd2Sjpk  *
186*45916cd2Sjpk  *	Uses	clow, chigh.
187*45916cd2Sjpk  *
188*45916cd2Sjpk  */
189*45916cd2Sjpk 
190*45916cd2Sjpk int
191*45916cd2Sjpk bclearvalid(const bclear_t *clearance)
192*45916cd2Sjpk {
193*45916cd2Sjpk 	labeld_data_t	call;
194*45916cd2Sjpk 	labeld_data_t	*callp = &call;
195*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
196*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(clrvalid_call_t, 0);
197*45916cd2Sjpk 
198*45916cd2Sjpk 	if (!BLTYPE(&clow, SUN_CLR_ID)) {
199*45916cd2Sjpk 		/* initialize static labels. */
200*45916cd2Sjpk 
201*45916cd2Sjpk 		BCLEARLOW(&clow);
202*45916cd2Sjpk 		BCLEARHIGH(&chigh);
203*45916cd2Sjpk 	}
204*45916cd2Sjpk 
205*45916cd2Sjpk 	if (BLTYPE(clearance, SUN_CLR_ID) &&
206*45916cd2Sjpk 	    (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
207*45916cd2Sjpk 
208*45916cd2Sjpk 		return (1);
209*45916cd2Sjpk 	}
210*45916cd2Sjpk 
211*45916cd2Sjpk 	call.callop = BCLEARVALID;
212*45916cd2Sjpk 	clrvcall.clear = *clearance;
213*45916cd2Sjpk 
214*45916cd2Sjpk 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
215*45916cd2Sjpk 		/* process error */
216*45916cd2Sjpk 
217*45916cd2Sjpk 		return (-1);
218*45916cd2Sjpk 	}
219*45916cd2Sjpk 	return (clrvret.valid);
220*45916cd2Sjpk }
221*45916cd2Sjpk #undef	clrvcall
222*45916cd2Sjpk #undef	clrvret
223*45916cd2Sjpk 
224*45916cd2Sjpk #define	inforet callp->param.aret.rvals.info_ret
225*45916cd2Sjpk /*
226*45916cd2Sjpk  *	labelinfo - Get information about the label encodings file.
227*45916cd2Sjpk  *
228*45916cd2Sjpk  *	Entry	info = Address of label_info structure to update.
229*45916cd2Sjpk  *
230*45916cd2Sjpk  *	Exit	info = Updated.
231*45916cd2Sjpk  *
232*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
233*45916cd2Sjpk  *		 1, If successful.
234*45916cd2Sjpk  *
235*45916cd2Sjpk  *	Calls	__call_labeld(LABELINFO).
236*45916cd2Sjpk  */
237*45916cd2Sjpk 
238*45916cd2Sjpk int
239*45916cd2Sjpk labelinfo(struct label_info *info)
240*45916cd2Sjpk {
241*45916cd2Sjpk 	labeld_data_t	call;
242*45916cd2Sjpk 	labeld_data_t	*callp = &call;
243*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
244*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(info_call_t, 0);
245*45916cd2Sjpk 	int	rval;
246*45916cd2Sjpk 
247*45916cd2Sjpk 	call.callop = LABELINFO;
248*45916cd2Sjpk 
249*45916cd2Sjpk 	if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
250*45916cd2Sjpk 		/* process error */
251*45916cd2Sjpk 
252*45916cd2Sjpk 		return (-1);
253*45916cd2Sjpk 	}
254*45916cd2Sjpk 	*info = inforet.info;
255*45916cd2Sjpk 	return (rval);
256*45916cd2Sjpk }
257*45916cd2Sjpk #undef	inforet
258*45916cd2Sjpk 
259*45916cd2Sjpk #define	lvret callp->param.aret.rvals.vers_ret
260*45916cd2Sjpk /*
261*45916cd2Sjpk  *	labelvers - Get version string of the label encodings file.
262*45916cd2Sjpk  *
263*45916cd2Sjpk  *	Entry	version = Address of string pointer to return.
264*45916cd2Sjpk  *		len = Length of string if pre-allocated.
265*45916cd2Sjpk  *
266*45916cd2Sjpk  *	Exit	version = Updated.
267*45916cd2Sjpk  *
268*45916cd2Sjpk  *	Returns	-1, If unable to access label encodings file, or server failure.
269*45916cd2Sjpk  *		 0, If unable to allocate version string,
270*45916cd2Sjpk  *			or pre-allocated version string to short
271*45916cd2Sjpk  *			(and **version = '\0').
272*45916cd2Sjpk  *		length (including null) of version string, If successful.
273*45916cd2Sjpk  *
274*45916cd2Sjpk  *	Calls	__call_labeld(LABELVERS)
275*45916cd2Sjpk  *			malloc, strlen.
276*45916cd2Sjpk  */
277*45916cd2Sjpk 
278*45916cd2Sjpk ssize_t
279*45916cd2Sjpk labelvers(char **version, size_t len)
280*45916cd2Sjpk {
281*45916cd2Sjpk 	labeld_data_t	call;
282*45916cd2Sjpk 	labeld_data_t	*callp = &call;
283*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
284*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(vers_call_t, 0);
285*45916cd2Sjpk 	size_t	ver_len;
286*45916cd2Sjpk 
287*45916cd2Sjpk 	call.callop = LABELVERS;
288*45916cd2Sjpk 
289*45916cd2Sjpk 	if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
290*45916cd2Sjpk 
291*45916cd2Sjpk 		if (callp != &call)
292*45916cd2Sjpk 			/* release return buffer */
293*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
294*45916cd2Sjpk 		return (-1);
295*45916cd2Sjpk 	}
296*45916cd2Sjpk 
297*45916cd2Sjpk 	/* unpack length */
298*45916cd2Sjpk 
299*45916cd2Sjpk 	ver_len = strlen(lvret.vers) + 1;
300*45916cd2Sjpk 	if (*version == NULL) {
301*45916cd2Sjpk 		if ((*version = malloc(ver_len)) == NULL) {
302*45916cd2Sjpk 			if (callp != &call)
303*45916cd2Sjpk 				/* release return buffer */
304*45916cd2Sjpk 				(void) munmap((void *)callp, bufsize);
305*45916cd2Sjpk 			return (0);
306*45916cd2Sjpk 		}
307*45916cd2Sjpk 	} else if (ver_len > len) {
308*45916cd2Sjpk 		**version = '\0';
309*45916cd2Sjpk 		if (callp != &call)
310*45916cd2Sjpk 			/* release return buffer */
311*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
312*45916cd2Sjpk 		return (0);
313*45916cd2Sjpk 	}
314*45916cd2Sjpk 	(void) strcpy(*version, lvret.vers);
315*45916cd2Sjpk 
316*45916cd2Sjpk 	if (callp != &call)
317*45916cd2Sjpk 		/* release return buffer */
318*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
319*45916cd2Sjpk 	return (ver_len);
320*45916cd2Sjpk }  /* labelvers */
321*45916cd2Sjpk #undef	lvret
322*45916cd2Sjpk 
323*45916cd2Sjpk #define	ccall callp->param.acall.cargs.color_arg
324*45916cd2Sjpk #define	cret callp->param.aret.rvals.color_ret
325*45916cd2Sjpk /*
326*45916cd2Sjpk  *	bltocolor - get ASCII color name of label.
327*45916cd2Sjpk  *
328*45916cd2Sjpk  *	Entry	label = Sensitivity Level of color to get.
329*45916cd2Sjpk  *		size  = Size of the color_name array.
330*45916cd2Sjpk  *		color_name = Storage for ASCII color name string to be returned.
331*45916cd2Sjpk  *
332*45916cd2Sjpk  *	Exit	None.
333*45916cd2Sjpk  *
334*45916cd2Sjpk  *	Returns	NULL, If error (label encodings file not accessible,
335*45916cd2Sjpk  *			   invalid label, no color for this label).
336*45916cd2Sjpk  *		Address of color_name parameter containing ASCII color name
337*45916cd2Sjpk  *			defined for the label.
338*45916cd2Sjpk  *
339*45916cd2Sjpk  *	Calls	__call_labeld(BLTOCOLOR), strlen.
340*45916cd2Sjpk  */
341*45916cd2Sjpk 
342*45916cd2Sjpk char *
343*45916cd2Sjpk bltocolor_r(const blevel_t *label, size_t size, char *color_name)
344*45916cd2Sjpk {
345*45916cd2Sjpk 	labeld_data_t	call;
346*45916cd2Sjpk 	labeld_data_t	*callp = &call;
347*45916cd2Sjpk 	size_t	bufsize = sizeof (labeld_data_t);
348*45916cd2Sjpk 	size_t	datasize = CALL_SIZE(color_call_t, 0);
349*45916cd2Sjpk 	char	*colorp;
350*45916cd2Sjpk 
351*45916cd2Sjpk 	call.callop = BLTOCOLOR;
352*45916cd2Sjpk 	ccall.label = *label;
353*45916cd2Sjpk 
354*45916cd2Sjpk 	if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
355*45916cd2Sjpk 	    (callp->reterr != 0) ||
356*45916cd2Sjpk 	    (strlen(cret.color) >= size)) {
357*45916cd2Sjpk 
358*45916cd2Sjpk 		if (callp != &call)
359*45916cd2Sjpk 			/* release return buffer */
360*45916cd2Sjpk 			(void) munmap((void *)callp, bufsize);
361*45916cd2Sjpk 		return (NULL);
362*45916cd2Sjpk 	}
363*45916cd2Sjpk 
364*45916cd2Sjpk 	colorp = strcpy(color_name, cret.color);
365*45916cd2Sjpk 
366*45916cd2Sjpk 	if (callp != &call)
367*45916cd2Sjpk 		/* release return buffer */
368*45916cd2Sjpk 		(void) munmap((void *)callp, bufsize);
369*45916cd2Sjpk 	return (colorp);
370*45916cd2Sjpk }  /* bltocolor_r */
371*45916cd2Sjpk #undef	ccall
372*45916cd2Sjpk #undef	cret
373*45916cd2Sjpk 
374*45916cd2Sjpk /*
375*45916cd2Sjpk  *	bltocolor - get ASCII color name of label.
376*45916cd2Sjpk  *
377*45916cd2Sjpk  *	Entry	label = Sensitivity Level of color to get.
378*45916cd2Sjpk  *
379*45916cd2Sjpk  *	Exit	None.
380*45916cd2Sjpk  *
381*45916cd2Sjpk  *	Returns	NULL, If error (label encodings file not accessible,
382*45916cd2Sjpk  *			   invalid label, no color for this label).
383*45916cd2Sjpk  *		Address of statically allocated string containing ASCII
384*45916cd2Sjpk  *			color name defined for the classification contained
385*45916cd2Sjpk  *			in label.
386*45916cd2Sjpk  *
387*45916cd2Sjpk  *	Uses	color.
388*45916cd2Sjpk  *
389*45916cd2Sjpk  *	Calls	bltocolor_r.
390*45916cd2Sjpk  */
391*45916cd2Sjpk 
392*45916cd2Sjpk char *
393*45916cd2Sjpk bltocolor(const blevel_t *label)
394*45916cd2Sjpk {
395*45916cd2Sjpk 	return (bltocolor_r(label, sizeof (color), color));
396*45916cd2Sjpk }  /* bltocolor */
397*45916cd2Sjpk 
398*45916cd2Sjpk blevel_t *
399*45916cd2Sjpk blabel_alloc(void)
400*45916cd2Sjpk {
401*45916cd2Sjpk 	return (m_label_alloc(MAC_LABEL));
402*45916cd2Sjpk }
403*45916cd2Sjpk 
404*45916cd2Sjpk void
405*45916cd2Sjpk blabel_free(blevel_t *label_p)
406*45916cd2Sjpk {
407*45916cd2Sjpk 	free(label_p);
408*45916cd2Sjpk }
409*45916cd2Sjpk 
410*45916cd2Sjpk size_t
411*45916cd2Sjpk blabel_size(void)
412*45916cd2Sjpk {
413*45916cd2Sjpk 	return (sizeof (blevel_t));
414*45916cd2Sjpk }
415*45916cd2Sjpk 
416*45916cd2Sjpk /*
417*45916cd2Sjpk  *	getuserrange - get label range for user
418*45916cd2Sjpk  *
419*45916cd2Sjpk  *	Entry	username of user
420*45916cd2Sjpk  *
421*45916cd2Sjpk  *	Exit	None.
422*45916cd2Sjpk  *
423*45916cd2Sjpk  *	Returns	NULL, If memory allocation failure or userdefs failure.
424*45916cd2Sjpk  *		otherwise returns the allocates m_range_t with the
425*45916cd2Sjpk  *		user's min and max labels set.
426*45916cd2Sjpk  */
427*45916cd2Sjpk 
428*45916cd2Sjpk m_range_t *
429*45916cd2Sjpk getuserrange(const char *username)
430*45916cd2Sjpk {
431*45916cd2Sjpk 	char		*kv_str = NULL;
432*45916cd2Sjpk 	userattr_t 	*userp = NULL;
433*45916cd2Sjpk 	m_range_t 	*range;
434*45916cd2Sjpk 	int		err;
435*45916cd2Sjpk 
436*45916cd2Sjpk 	/*
437*45916cd2Sjpk 	 * Get some memory
438*45916cd2Sjpk 	 */
439*45916cd2Sjpk 
440*45916cd2Sjpk 	if ((range = malloc(sizeof (m_range_t))) == NULL) {
441*45916cd2Sjpk 		return (NULL);
442*45916cd2Sjpk 	}
443*45916cd2Sjpk 	if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
444*45916cd2Sjpk 		free(range);
445*45916cd2Sjpk 		return (NULL);
446*45916cd2Sjpk 	}
447*45916cd2Sjpk 	if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
448*45916cd2Sjpk 		m_label_free(range->lower_bound);
449*45916cd2Sjpk 		free(range);
450*45916cd2Sjpk 		return (NULL);
451*45916cd2Sjpk 	}
452*45916cd2Sjpk 	/*
453*45916cd2Sjpk 	 * Since user_attr entries are optional, start with
454*45916cd2Sjpk 	 * the system default values
455*45916cd2Sjpk 	 */
456*45916cd2Sjpk 	if ((userdefs(range->lower_bound, range->upper_bound)) == -1) {
457*45916cd2Sjpk 		m_label_free(range->lower_bound);
458*45916cd2Sjpk 		m_label_free(range->upper_bound);
459*45916cd2Sjpk 		free(range);
460*45916cd2Sjpk 		return (NULL);
461*45916cd2Sjpk 	}
462*45916cd2Sjpk 	/*
463*45916cd2Sjpk 	 * If the user has an explicit min_label or clearance,
464*45916cd2Sjpk 	 * then use it instead.
465*45916cd2Sjpk 	 */
466*45916cd2Sjpk 	if ((userp = getusernam(username)) == NULL) {
467*45916cd2Sjpk 		return (range);
468*45916cd2Sjpk 	}
469*45916cd2Sjpk 	if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) != NULL)
470*45916cd2Sjpk 		(void) stobsl(kv_str, range->lower_bound, NO_CORRECTION, &err);
471*45916cd2Sjpk 	if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE)) != NULL)
472*45916cd2Sjpk 		(void) stobclear(kv_str, range->upper_bound, NO_CORRECTION,
473*45916cd2Sjpk 		    &err);
474*45916cd2Sjpk 	free_userattr(userp);
475*45916cd2Sjpk 	return (range);
476*45916cd2Sjpk }
477