xref: /titanic_44/usr/src/common/tsol/stol.c (revision 4201a95e0468170d576f82c3aa63afecf718497a)
1*4201a95eSRic Aleshire /*
2*4201a95eSRic Aleshire  * CDDL HEADER START
3*4201a95eSRic Aleshire  *
4*4201a95eSRic Aleshire  * The contents of this file are subject to the terms of the
5*4201a95eSRic Aleshire  * Common Development and Distribution License (the "License").
6*4201a95eSRic Aleshire  * You may not use this file except in compliance with the License.
7*4201a95eSRic Aleshire  *
8*4201a95eSRic Aleshire  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4201a95eSRic Aleshire  * or http://www.opensolaris.org/os/licensing.
10*4201a95eSRic Aleshire  * See the License for the specific language governing permissions
11*4201a95eSRic Aleshire  * and limitations under the License.
12*4201a95eSRic Aleshire  *
13*4201a95eSRic Aleshire  * When distributing Covered Code, include this CDDL HEADER in each
14*4201a95eSRic Aleshire  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4201a95eSRic Aleshire  * If applicable, add the following below this CDDL HEADER, with the
16*4201a95eSRic Aleshire  * fields enclosed by brackets "[]" replaced with your own identifying
17*4201a95eSRic Aleshire  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4201a95eSRic Aleshire  *
19*4201a95eSRic Aleshire  * CDDL HEADER END
20*4201a95eSRic Aleshire  */
21*4201a95eSRic Aleshire /*
22*4201a95eSRic Aleshire  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*4201a95eSRic Aleshire  * Use is subject to license terms.
24*4201a95eSRic Aleshire  */
25*4201a95eSRic Aleshire 
26*4201a95eSRic Aleshire #if !defined(_KERNEL)
27*4201a95eSRic Aleshire #include <errno.h>
28*4201a95eSRic Aleshire #include <stdio.h>
29*4201a95eSRic Aleshire #include <stdlib.h>
30*4201a95eSRic Aleshire #include <string.h>
31*4201a95eSRic Aleshire #include <ctype.h>
32*4201a95eSRic Aleshire #include <strings.h>
33*4201a95eSRic Aleshire #else /* !defined(_KERNEL) */
34*4201a95eSRic Aleshire #include <sys/systm.h>
35*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
36*4201a95eSRic Aleshire 
37*4201a95eSRic Aleshire #include <sys/mman.h>
38*4201a95eSRic Aleshire #include <sys/tsol/label_macro.h>
39*4201a95eSRic Aleshire 
40*4201a95eSRic Aleshire #include <sys/tsol/label.h>
41*4201a95eSRic Aleshire 
42*4201a95eSRic Aleshire #if !defined(_KERNEL)
43*4201a95eSRic Aleshire #include "clnt.h"
44*4201a95eSRic Aleshire #include "labeld.h"
45*4201a95eSRic Aleshire #else /* !defined(_KERNEL) */
46*4201a95eSRic Aleshire #include <util/strtolctype.h>
47*4201a95eSRic Aleshire 
48*4201a95eSRic Aleshire #define	L_DEFAULT	0x0
49*4201a95eSRic Aleshire #define	L_NO_CORRECTION	0x2
50*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
51*4201a95eSRic Aleshire 
52*4201a95eSRic Aleshire #define	IS_LOW(s) \
53*4201a95eSRic Aleshire 	((strncasecmp(s, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0) && \
54*4201a95eSRic Aleshire 	(s[sizeof (ADMIN_LOW) - 1] == '\0'))
55*4201a95eSRic Aleshire #define	IS_HIGH(s) \
56*4201a95eSRic Aleshire 	((strncasecmp(s, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0) && \
57*4201a95eSRic Aleshire 	(s[sizeof (ADMIN_HIGH) - 1] == '\0'))
58*4201a95eSRic Aleshire #define	IS_HEX(f, s) \
59*4201a95eSRic Aleshire 	(((((f) == L_NO_CORRECTION)) || ((f) == L_DEFAULT)) && \
60*4201a95eSRic Aleshire 	(((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
61*4201a95eSRic Aleshire 
62*4201a95eSRic Aleshire static boolean_t
unhex(const char ** h,uchar_t * l,int len)63*4201a95eSRic Aleshire unhex(const char **h, uchar_t *l, int len)
64*4201a95eSRic Aleshire {
65*4201a95eSRic Aleshire 	const char	*hx = *h;
66*4201a95eSRic Aleshire 	char	ch;
67*4201a95eSRic Aleshire 	uchar_t	byte;
68*4201a95eSRic Aleshire 
69*4201a95eSRic Aleshire 	for (; len--; ) {
70*4201a95eSRic Aleshire 		ch = *hx++;
71*4201a95eSRic Aleshire 		if (!isxdigit(ch))
72*4201a95eSRic Aleshire 			return (B_FALSE);
73*4201a95eSRic Aleshire 		if (isdigit(ch))
74*4201a95eSRic Aleshire 			byte = ch - '0';
75*4201a95eSRic Aleshire 		else
76*4201a95eSRic Aleshire 			byte = ch - (isupper(ch) ? 'A' - 10 : 'a' - 10);
77*4201a95eSRic Aleshire 		byte <<= 4;
78*4201a95eSRic Aleshire 		ch = *hx++;
79*4201a95eSRic Aleshire 		if (!isxdigit(ch))
80*4201a95eSRic Aleshire 			return (B_FALSE);
81*4201a95eSRic Aleshire 		if (isdigit(ch))
82*4201a95eSRic Aleshire 			byte |= ch - '0';
83*4201a95eSRic Aleshire 		else
84*4201a95eSRic Aleshire 			byte |= ch - (isupper(ch) ? 'A' - 10 : 'a' - 10);
85*4201a95eSRic Aleshire 		*l++ = byte;
86*4201a95eSRic Aleshire 	}
87*4201a95eSRic Aleshire 	*h = hx;
88*4201a95eSRic Aleshire 	return (B_TRUE);
89*4201a95eSRic Aleshire }
90*4201a95eSRic Aleshire 
91*4201a95eSRic Aleshire /*
92*4201a95eSRic Aleshire  * Formats accepted:
93*4201a95eSRic Aleshire  * 0x + 4 class + 64 comps + end of string
94*4201a95eSRic Aleshire  * 0x + 4 class + '-' + ll + '-' + comps + end of string
95*4201a95eSRic Aleshire  * ll = number of words to fill out the entire comps field
96*4201a95eSRic Aleshire  *      presumes trailing zero for comps
97*4201a95eSRic Aleshire  *
98*4201a95eSRic Aleshire  * So in the case of 256 comps (i.e., 8 compartment words):
99*4201a95eSRic Aleshire  * 0x0006-08-7ff3f
100*4201a95eSRic Aleshire  * 0x + Classification + Compartments + end of string
101*4201a95eSRic Aleshire  * 0[xX]hhh...
102*4201a95eSRic Aleshire  */
103*4201a95eSRic Aleshire 
104*4201a95eSRic Aleshire static int
htol(const char * s,m_label_t * l)105*4201a95eSRic Aleshire htol(const char *s, m_label_t *l)
106*4201a95eSRic Aleshire {
107*4201a95eSRic Aleshire 	const char	*h = &s[2];	/* skip 0[xX] */
108*4201a95eSRic Aleshire 	uchar_t *lp = (uchar_t *)&(((_mac_label_impl_t *)l)->_lclass);
109*4201a95eSRic Aleshire 	size_t	len = sizeof (_mac_label_impl_t) - 4;
110*4201a95eSRic Aleshire 	int	bytes;
111*4201a95eSRic Aleshire 
112*4201a95eSRic Aleshire 	/* unpack 16 bit signed classification */
113*4201a95eSRic Aleshire 	if (!unhex(&h, lp, 2) || (LCLASS(l) < 0)) {
114*4201a95eSRic Aleshire 		return (-1);
115*4201a95eSRic Aleshire 	}
116*4201a95eSRic Aleshire 	lp = (uchar_t *)&(((_mac_label_impl_t *)l)->_comps);
117*4201a95eSRic Aleshire 	if (h[0] == '-' && h[3] == '-') {
118*4201a95eSRic Aleshire 		uchar_t size;
119*4201a95eSRic Aleshire 
120*4201a95eSRic Aleshire 		/* length specified of internal text label */
121*4201a95eSRic Aleshire 		h++;	/* skip '-' */
122*4201a95eSRic Aleshire 		if (!unhex(&h, &size, 1)) {
123*4201a95eSRic Aleshire 			return (-1);
124*4201a95eSRic Aleshire 		}
125*4201a95eSRic Aleshire 		/* convert size from words to bytes */
126*4201a95eSRic Aleshire 		if ((size * sizeof (uint32_t)) > len) {
127*4201a95eSRic Aleshire 			/*
128*4201a95eSRic Aleshire 			 * internal label greater than will fit in current
129*4201a95eSRic Aleshire 			 * binary.
130*4201a95eSRic Aleshire 			 */
131*4201a95eSRic Aleshire 			return (-1);
132*4201a95eSRic Aleshire 		}
133*4201a95eSRic Aleshire 		bzero(lp, len);
134*4201a95eSRic Aleshire 		h++;	/* skip '-' */
135*4201a95eSRic Aleshire 	}
136*4201a95eSRic Aleshire 	bytes = strlen(h)/2;
137*4201a95eSRic Aleshire 	if ((bytes > len) ||
138*4201a95eSRic Aleshire 	    (bytes*2 != strlen(h)) ||
139*4201a95eSRic Aleshire 	    !unhex(&h, lp, bytes)) {
140*4201a95eSRic Aleshire 		return (-1);
141*4201a95eSRic Aleshire 	}
142*4201a95eSRic Aleshire 	return (0);
143*4201a95eSRic Aleshire }
144*4201a95eSRic Aleshire 
145*4201a95eSRic Aleshire /*
146*4201a95eSRic Aleshire  * hexstr_to_label -- parse a string representing a hex label into a
147*4201a95eSRic Aleshire  *			binary label.  Only admin high/low and hex are
148*4201a95eSRic Aleshire  *			accepted.
149*4201a95eSRic Aleshire  *
150*4201a95eSRic Aleshire  *	Returns	 0, success.
151*4201a95eSRic Aleshire  *		-1, failure
152*4201a95eSRic Aleshire  */
153*4201a95eSRic Aleshire int
hexstr_to_label(const char * s,m_label_t * l)154*4201a95eSRic Aleshire hexstr_to_label(const char *s, m_label_t *l)
155*4201a95eSRic Aleshire {
156*4201a95eSRic Aleshire 	uint_t	f = L_DEFAULT;
157*4201a95eSRic Aleshire 
158*4201a95eSRic Aleshire 	/* translate hex, admin_low and admin_high */
159*4201a95eSRic Aleshire 	if (IS_LOW(s)) {
160*4201a95eSRic Aleshire 		_LOW_LABEL(l, SUN_MAC_ID);
161*4201a95eSRic Aleshire 		return (0);
162*4201a95eSRic Aleshire 	} else if (IS_HIGH(s)) {
163*4201a95eSRic Aleshire 		_HIGH_LABEL(l, SUN_MAC_ID);
164*4201a95eSRic Aleshire 		return (0);
165*4201a95eSRic Aleshire 	} else if (IS_HEX(f, s)) {
166*4201a95eSRic Aleshire 		_LOW_LABEL(l, SUN_MAC_ID);
167*4201a95eSRic Aleshire 		if (htol(s, l) == 0)
168*4201a95eSRic Aleshire 			return (0);
169*4201a95eSRic Aleshire 	}
170*4201a95eSRic Aleshire 
171*4201a95eSRic Aleshire 	return (-1);
172*4201a95eSRic Aleshire }
173*4201a95eSRic Aleshire 
174*4201a95eSRic Aleshire #if !defined(_KERNEL)
175*4201a95eSRic Aleshire static int
convert_id(m_label_type_t t)176*4201a95eSRic Aleshire convert_id(m_label_type_t t)
177*4201a95eSRic Aleshire {
178*4201a95eSRic Aleshire 	switch (t) {
179*4201a95eSRic Aleshire 	case MAC_LABEL:
180*4201a95eSRic Aleshire 		return (SUN_MAC_ID);
181*4201a95eSRic Aleshire 	case USER_CLEAR:
182*4201a95eSRic Aleshire 		return (SUN_UCLR_ID);
183*4201a95eSRic Aleshire 	default:
184*4201a95eSRic Aleshire 		return (-1);
185*4201a95eSRic Aleshire 	}
186*4201a95eSRic Aleshire }
187*4201a95eSRic Aleshire 
188*4201a95eSRic Aleshire /*
189*4201a95eSRic Aleshire  * str_to_label -- parse a string into the requested label type.
190*4201a95eSRic Aleshire  *
191*4201a95eSRic Aleshire  *	Entry	s = string to parse.
192*4201a95eSRic Aleshire  *		l = label to create or modify.
193*4201a95eSRic Aleshire  *		t = label type (MAC_LABEL, USER_CLEAR).
194*4201a95eSRic Aleshire  *		f = flags
195*4201a95eSRic Aleshire  *			L_DEFAULT,
196*4201a95eSRic Aleshire  *			L_MODIFY_EXISTING, use the existing label as a basis for
197*4201a95eSRic Aleshire  *				the parse string.
198*4201a95eSRic Aleshire  *			L_NO_CORRECTION, s must be correct and full by the
199*4201a95eSRic Aleshire  *				label_encoding rules.
200*4201a95eSRic Aleshire  *			L_CHECK_AR, for non-hex s, MAC_LABEL, check the l_e AR
201*4201a95eSRic Aleshire  *
202*4201a95eSRic Aleshire  *	Exit	l = parsed label value.
203*4201a95eSRic Aleshire  *		e = index into string of error.
204*4201a95eSRic Aleshire  *		  = M_BAD_STRING (-3 L_BAD_LABEL) or could be zero,
205*4201a95eSRic Aleshire  *		    indicates entire string,
206*4201a95eSRic Aleshire  *	        e = M_BAD_LABEL (-2 L_BAD_CLASSIFICATION), problems with l
207*4201a95eSRic Aleshire  *		e = M_OUTSIDE_AR (-4 unrelated to L_BAD_* return values)
208*4201a95eSRic Aleshire  *
209*4201a95eSRic Aleshire  *	Returns	 0, success.
210*4201a95eSRic Aleshire  *		-1, failure
211*4201a95eSRic Aleshire  *			errno = ENOTSUP, the underlying label mechanism
212*4201a95eSRic Aleshire  *				does not support label parsing.
213*4201a95eSRic Aleshire  *				ENOMEM, unable to allocate memory for l.
214*4201a95eSRic Aleshire  *				EINVAL, invalid argument, l != NULL or
215*4201a95eSRic Aleshire  *				invalid label type for the underlying
216*4201a95eSRic Aleshire  *				label mechanism.
217*4201a95eSRic Aleshire  */
218*4201a95eSRic Aleshire #define	_M_GOOD_LABEL	-1	/* gfi L_GOOD_LABEL */
219*4201a95eSRic Aleshire int
str_to_label(const char * str,m_label_t ** l,const m_label_type_t t,uint_t f,int * e)220*4201a95eSRic Aleshire str_to_label(const char *str, m_label_t **l, const m_label_type_t t, uint_t f,
221*4201a95eSRic Aleshire     int *e)
222*4201a95eSRic Aleshire {
223*4201a95eSRic Aleshire 	char		*s = strdup(str);
224*4201a95eSRic Aleshire 	char		*st = s;
225*4201a95eSRic Aleshire 	char		*p;
226*4201a95eSRic Aleshire 	labeld_data_t	call;
227*4201a95eSRic Aleshire 	labeld_data_t	*callp = &call;
228*4201a95eSRic Aleshire 	size_t		bufsize = sizeof (labeld_data_t);
229*4201a95eSRic Aleshire 	size_t		datasize;
230*4201a95eSRic Aleshire 	int		err = M_BAD_LABEL;
231*4201a95eSRic Aleshire 	int		id = convert_id(t);
232*4201a95eSRic Aleshire 	boolean_t	new = B_FALSE;
233*4201a95eSRic Aleshire 	uint_t		lf = (f & ~L_CHECK_AR);	/* because L_DEFAULT == 0 */
234*4201a95eSRic Aleshire 
235*4201a95eSRic Aleshire 	if (st == NULL) {
236*4201a95eSRic Aleshire 		errno = ENOMEM;
237*4201a95eSRic Aleshire 		return (-1);
238*4201a95eSRic Aleshire 	}
239*4201a95eSRic Aleshire 	if (*l == NULL) {
240*4201a95eSRic Aleshire 		if ((*l = m_label_alloc(t)) == NULL) {
241*4201a95eSRic Aleshire 			free(st);
242*4201a95eSRic Aleshire 			return (-1);
243*4201a95eSRic Aleshire 		}
244*4201a95eSRic Aleshire 		if (id == -1) {
245*4201a95eSRic Aleshire 			goto badlabel;
246*4201a95eSRic Aleshire 		}
247*4201a95eSRic Aleshire 		_LOW_LABEL(*l, id);
248*4201a95eSRic Aleshire 		new = B_TRUE;
249*4201a95eSRic Aleshire 	} else if (_MTYPE(*l, SUN_INVALID_ID) &&
250*4201a95eSRic Aleshire 	    ((lf == L_NO_CORRECTION) || (lf == L_DEFAULT))) {
251*4201a95eSRic Aleshire 		_LOW_LABEL(*l, id);
252*4201a95eSRic Aleshire 		new = B_TRUE;
253*4201a95eSRic Aleshire 	} else if (!(_MTYPE(*l, SUN_MAC_ID) || _MTYPE(*l, SUN_CLR_ID))) {
254*4201a95eSRic Aleshire 		goto badlabel;
255*4201a95eSRic Aleshire 	}
256*4201a95eSRic Aleshire 
257*4201a95eSRic Aleshire 	if (new == B_FALSE && id == -1) {
258*4201a95eSRic Aleshire 		goto badlabel;
259*4201a95eSRic Aleshire 	}
260*4201a95eSRic Aleshire 
261*4201a95eSRic Aleshire 	/* get to the beginning of the string to parse */
262*4201a95eSRic Aleshire 	while (isspace(*s)) {
263*4201a95eSRic Aleshire 		s++;
264*4201a95eSRic Aleshire 	}
265*4201a95eSRic Aleshire 
266*4201a95eSRic Aleshire 	/* accept a leading '[' and trailing ']' for old times sake */
267*4201a95eSRic Aleshire 	if (*s == '[') {
268*4201a95eSRic Aleshire 		*s = ' ';
269*4201a95eSRic Aleshire 		s++;
270*4201a95eSRic Aleshire 		while (isspace(*s)) {
271*4201a95eSRic Aleshire 			s++;
272*4201a95eSRic Aleshire 		}
273*4201a95eSRic Aleshire 	}
274*4201a95eSRic Aleshire 	p = s;
275*4201a95eSRic Aleshire 	while (*p != '\0' && *p != ']') {
276*4201a95eSRic Aleshire 		p++;
277*4201a95eSRic Aleshire 	}
278*4201a95eSRic Aleshire 
279*4201a95eSRic Aleshire 	/* strip trailing spaces */
280*4201a95eSRic Aleshire 	while (p != s && isspace(*(p-1))) {
281*4201a95eSRic Aleshire 		--p;
282*4201a95eSRic Aleshire 	}
283*4201a95eSRic Aleshire 	*p = '\0';	/* end of string */
284*4201a95eSRic Aleshire 
285*4201a95eSRic Aleshire 	/* translate hex, admin_low and admin_high */
286*4201a95eSRic Aleshire 	id = _MGETTYPE(*l);
287*4201a95eSRic Aleshire 	if (IS_LOW(s)) {
288*4201a95eSRic Aleshire 		_LOW_LABEL(*l, id);
289*4201a95eSRic Aleshire 		goto goodlabel;
290*4201a95eSRic Aleshire 	} else if (IS_HIGH(s)) {
291*4201a95eSRic Aleshire 		_HIGH_LABEL(*l, id);
292*4201a95eSRic Aleshire 		goto goodlabel;
293*4201a95eSRic Aleshire 	} else if (IS_HEX(lf, s)) {
294*4201a95eSRic Aleshire 		if (htol(s, *l) != 0) {
295*4201a95eSRic Aleshire 			/* whole string in error */
296*4201a95eSRic Aleshire 			err = 0;
297*4201a95eSRic Aleshire 			goto badlabel;
298*4201a95eSRic Aleshire 		}
299*4201a95eSRic Aleshire 		goto goodlabel;
300*4201a95eSRic Aleshire 	}
301*4201a95eSRic Aleshire #define	slcall callp->param.acall.cargs.sl_arg
302*4201a95eSRic Aleshire #define	slret callp->param.aret.rvals.sl_ret
303*4201a95eSRic Aleshire 	/* now try label server */
304*4201a95eSRic Aleshire 
305*4201a95eSRic Aleshire 	datasize = CALL_SIZE_STR(sl_call_t, strlen(st) + 1);
306*4201a95eSRic Aleshire 	if (datasize > bufsize) {
307*4201a95eSRic Aleshire 		if ((callp = malloc(datasize)) == NULL) {
308*4201a95eSRic Aleshire 			free(st);
309*4201a95eSRic Aleshire 			return (-1);
310*4201a95eSRic Aleshire 		}
311*4201a95eSRic Aleshire 		bufsize = datasize;
312*4201a95eSRic Aleshire 	}
313*4201a95eSRic Aleshire 	callp->callop = STOL;
314*4201a95eSRic Aleshire 	slcall.label = **l;
315*4201a95eSRic Aleshire 	slcall.flags = f;
316*4201a95eSRic Aleshire 	if (new)
317*4201a95eSRic Aleshire 		slcall.flags |= L_NEW_LABEL;
318*4201a95eSRic Aleshire 	(void) strcpy(slcall.string, st);
319*4201a95eSRic Aleshire 	/*
320*4201a95eSRic Aleshire 	 * callp->reterr = L_GOOD_LABEL (-1) == OK;
321*4201a95eSRic Aleshire 	 *		   L_BAD_CLASSIFICATION (-2) == bad input
322*4201a95eSRic Aleshire 	 *			classification: class
323*4201a95eSRic Aleshire 	 *		   L_BAD_LABEL (-3) == either string or input label bad
324*4201a95eSRic Aleshire 	 *		   M_OUTSIDE_AR (-4) == resultant MAC_LABEL is out
325*4201a95eSRic Aleshire 	 *			l_e accreditation range
326*4201a95eSRic Aleshire 	 *		   O'E == offset in string 0 == entire string.
327*4201a95eSRic Aleshire 	 */
328*4201a95eSRic Aleshire 	if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
329*4201a95eSRic Aleshire 
330*4201a95eSRic Aleshire 		err = callp->reterr;
331*4201a95eSRic Aleshire 		if (callp != &call) {
332*4201a95eSRic Aleshire 			/* free allocated buffer */
333*4201a95eSRic Aleshire 			free(callp);
334*4201a95eSRic Aleshire 		}
335*4201a95eSRic Aleshire 		switch (err) {
336*4201a95eSRic Aleshire 		case _M_GOOD_LABEL:	/* L_GOOD_LABEL */
337*4201a95eSRic Aleshire 			**l = slret.label;
338*4201a95eSRic Aleshire 			goto goodlabel;
339*4201a95eSRic Aleshire 		case M_BAD_LABEL:	/* L_BAD_CLASSIFICATION */
340*4201a95eSRic Aleshire 		case M_BAD_STRING:	/* L_BAD_LABEL */
341*4201a95eSRic Aleshire 		default:
342*4201a95eSRic Aleshire 			goto badlabel;
343*4201a95eSRic Aleshire 		}
344*4201a95eSRic Aleshire 	}
345*4201a95eSRic Aleshire 	switch (callp->reterr) {
346*4201a95eSRic Aleshire 	case NOSERVER:
347*4201a95eSRic Aleshire 		errno = ENOTSUP;
348*4201a95eSRic Aleshire 		break;
349*4201a95eSRic Aleshire 	default:
350*4201a95eSRic Aleshire 		errno = EINVAL;
351*4201a95eSRic Aleshire 		break;
352*4201a95eSRic Aleshire 	}
353*4201a95eSRic Aleshire 	free(st);
354*4201a95eSRic Aleshire 	return (-1);
355*4201a95eSRic Aleshire 
356*4201a95eSRic Aleshire badlabel:
357*4201a95eSRic Aleshire 	errno = EINVAL;
358*4201a95eSRic Aleshire 	free(st);
359*4201a95eSRic Aleshire 	if (e != NULL)
360*4201a95eSRic Aleshire 		*e = err;
361*4201a95eSRic Aleshire 	return (-1);
362*4201a95eSRic Aleshire 
363*4201a95eSRic Aleshire goodlabel:
364*4201a95eSRic Aleshire 	free(st);
365*4201a95eSRic Aleshire 	return (0);
366*4201a95eSRic Aleshire }
367*4201a95eSRic Aleshire #undef	slcall
368*4201a95eSRic Aleshire #undef	slret
369*4201a95eSRic Aleshire 
370*4201a95eSRic Aleshire /*
371*4201a95eSRic Aleshire  * m_label_alloc -- allocate a label structure
372*4201a95eSRic Aleshire  *
373*4201a95eSRic Aleshire  *	Entry	t = label type (MAC_LABEL, USER_CLEAR).
374*4201a95eSRic Aleshire  *
375*4201a95eSRic Aleshire  *	Exit	If error, NULL, errno set to ENOMEM
376*4201a95eSRic Aleshire  *		Otherwise, pointer to m_label_t memory
377*4201a95eSRic Aleshire  */
378*4201a95eSRic Aleshire 
379*4201a95eSRic Aleshire /* ARGUSED */
380*4201a95eSRic Aleshire m_label_t *
m_label_alloc(const m_label_type_t t)381*4201a95eSRic Aleshire m_label_alloc(const m_label_type_t t)
382*4201a95eSRic Aleshire {
383*4201a95eSRic Aleshire 	m_label_t *l;
384*4201a95eSRic Aleshire 
385*4201a95eSRic Aleshire 	switch (t) {
386*4201a95eSRic Aleshire 	case MAC_LABEL:
387*4201a95eSRic Aleshire 	case USER_CLEAR:
388*4201a95eSRic Aleshire 		if ((l = malloc(sizeof (_mac_label_impl_t))) == NULL) {
389*4201a95eSRic Aleshire 			return (NULL);
390*4201a95eSRic Aleshire 		}
391*4201a95eSRic Aleshire 		_MSETTYPE(l, SUN_INVALID_ID);
392*4201a95eSRic Aleshire 		break;
393*4201a95eSRic Aleshire 	default:
394*4201a95eSRic Aleshire 		errno = EINVAL;
395*4201a95eSRic Aleshire 		return (NULL);
396*4201a95eSRic Aleshire 	}
397*4201a95eSRic Aleshire 	return (l);
398*4201a95eSRic Aleshire }
399*4201a95eSRic Aleshire 
400*4201a95eSRic Aleshire /*
401*4201a95eSRic Aleshire  * m_label_dup -- make a duplicate copy of the given label.
402*4201a95eSRic Aleshire  *
403*4201a95eSRic Aleshire  *	Entry	l = label to duplicate.
404*4201a95eSRic Aleshire  *
405*4201a95eSRic Aleshire  *	Exit	d = duplicate copy of l.
406*4201a95eSRic Aleshire  *
407*4201a95eSRic Aleshire  *	Returns	 0, success
408*4201a95eSRic Aleshire  *		-1, if error.
409*4201a95eSRic Aleshire  *			errno = ENOTSUP, the underlying label mechanism
410*4201a95eSRic Aleshire  *				does not support label duplication.
411*4201a95eSRic Aleshire  *				ENOMEM, unable to allocate memory for d.
412*4201a95eSRic Aleshire  *				EINVAL, invalid argument, l == NULL or
413*4201a95eSRic Aleshire  *				invalid label type for the underlying
414*4201a95eSRic Aleshire  *				label mechanism.
415*4201a95eSRic Aleshire  */
416*4201a95eSRic Aleshire 
417*4201a95eSRic Aleshire int
m_label_dup(m_label_t ** d,const m_label_t * l)418*4201a95eSRic Aleshire m_label_dup(m_label_t **d, const m_label_t *l)
419*4201a95eSRic Aleshire {
420*4201a95eSRic Aleshire 	if (d == NULL || *d != NULL) {
421*4201a95eSRic Aleshire 		errno = EINVAL;
422*4201a95eSRic Aleshire 		return (-1);
423*4201a95eSRic Aleshire 	}
424*4201a95eSRic Aleshire 	if ((*d = malloc(sizeof (_mac_label_impl_t))) == NULL) {
425*4201a95eSRic Aleshire 		errno = ENOMEM;
426*4201a95eSRic Aleshire 		return (-1);
427*4201a95eSRic Aleshire 	}
428*4201a95eSRic Aleshire 
429*4201a95eSRic Aleshire 	(void) memcpy(*d, l, sizeof (_mac_label_impl_t));
430*4201a95eSRic Aleshire 	return (0);
431*4201a95eSRic Aleshire }
432*4201a95eSRic Aleshire 
433*4201a95eSRic Aleshire /*
434*4201a95eSRic Aleshire  * m_label_free -- free label structure
435*4201a95eSRic Aleshire  *
436*4201a95eSRic Aleshire  *	Entry	l = label to free.
437*4201a95eSRic Aleshire  *
438*4201a95eSRic Aleshire  *	Exit	memory freed.
439*4201a95eSRic Aleshire  *
440*4201a95eSRic Aleshire  */
441*4201a95eSRic Aleshire 
442*4201a95eSRic Aleshire void
m_label_free(m_label_t * l)443*4201a95eSRic Aleshire m_label_free(m_label_t *l)
444*4201a95eSRic Aleshire {
445*4201a95eSRic Aleshire 	if (l)
446*4201a95eSRic Aleshire 		free(l);
447*4201a95eSRic Aleshire }
448*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
449