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