4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
33 #else /* !defined(_KERNEL) */
34 #include <sys/systm.h>
35 #endif /* !defined(_KERNEL) */
38 #include <sys/tsol/label_macro.h>
40 #include <sys/tsol/label.h>
45 #else /* !defined(_KERNEL) */
46 #include <util/strtolctype.h>
49 #define L_NO_CORRECTION 0x2
50 #endif /* !defined(_KERNEL) */
53 ((strncasecmp(s, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0) && \
54 (s[sizeof (ADMIN_LOW) - 1] == '\0'))
56 ((strncasecmp(s, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0) && \
57 (s[sizeof (ADMIN_HIGH) - 1] == '\0'))
58 #define IS_HEX(f, s) \
59 (((((f) == L_NO_CORRECTION)) || ((f) == L_DEFAULT)) && \
60 (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
63 unhex(const char **h
, uchar_t
*l
, int len
)
76 byte
= ch
- (isupper(ch
) ? 'A' - 10 : 'a' - 10);
84 byte
|= ch
- (isupper(ch
) ? 'A' - 10 : 'a' - 10);
93 * 0x + 4 class + 64 comps + end of string
94 * 0x + 4 class + '-' + ll + '-' + comps + end of string
95 * ll = number of words to fill out the entire comps field
96 * presumes trailing zero for comps
98 * So in the case of 256 comps (i.e., 8 compartment words):
100 * 0x + Classification + Compartments + end of string
105 htol(const char *s
, m_label_t
*l
)
107 const char *h
= &s
[2]; /* skip 0[xX] */
108 uchar_t
*lp
= (uchar_t
*)&(((_mac_label_impl_t
*)l
)->_lclass
);
109 size_t len
= sizeof (_mac_label_impl_t
) - 4;
112 /* unpack 16 bit signed classification */
113 if (!unhex(&h
, lp
, 2) || (LCLASS(l
) < 0)) {
116 lp
= (uchar_t
*)&(((_mac_label_impl_t
*)l
)->_comps
);
117 if (h
[0] == '-' && h
[3] == '-') {
120 /* length specified of internal text label */
122 if (!unhex(&h
, &size
, 1)) {
125 /* convert size from words to bytes */
126 if ((size
* sizeof (uint32_t)) > len
) {
128 * internal label greater than will fit in current
138 (bytes
*2 != strlen(h
)) ||
139 !unhex(&h
, lp
, bytes
)) {
146 * hexstr_to_label -- parse a string representing a hex label into a
147 * binary label. Only admin high/low and hex are
150 * Returns 0, success.
154 hexstr_to_label(const char *s
, m_label_t
*l
)
156 uint_t f
= L_DEFAULT
;
158 /* translate hex, admin_low and admin_high */
160 _LOW_LABEL(l
, SUN_MAC_ID
);
162 } else if (IS_HIGH(s
)) {
163 _HIGH_LABEL(l
, SUN_MAC_ID
);
165 } else if (IS_HEX(f
, s
)) {
166 _LOW_LABEL(l
, SUN_MAC_ID
);
174 #if !defined(_KERNEL)
176 convert_id(m_label_type_t t
)
182 return (SUN_UCLR_ID
);
189 * str_to_label -- parse a string into the requested label type.
191 * Entry s = string to parse.
192 * l = label to create or modify.
193 * t = label type (MAC_LABEL, USER_CLEAR).
196 * L_MODIFY_EXISTING, use the existing label as a basis for
198 * L_NO_CORRECTION, s must be correct and full by the
199 * label_encoding rules.
200 * L_CHECK_AR, for non-hex s, MAC_LABEL, check the l_e AR
202 * Exit l = parsed label value.
203 * e = index into string of error.
204 * = M_BAD_STRING (-3 L_BAD_LABEL) or could be zero,
205 * indicates entire string,
206 * e = M_BAD_LABEL (-2 L_BAD_CLASSIFICATION), problems with l
207 * e = M_OUTSIDE_AR (-4 unrelated to L_BAD_* return values)
209 * Returns 0, success.
211 * errno = ENOTSUP, the underlying label mechanism
212 * does not support label parsing.
213 * ENOMEM, unable to allocate memory for l.
214 * EINVAL, invalid argument, l != NULL or
215 * invalid label type for the underlying
218 #define _M_GOOD_LABEL -1 /* gfi L_GOOD_LABEL */
220 str_to_label(const char *str
, m_label_t
**l
, const m_label_type_t t
, uint_t f
,
223 char *s
= strdup(str
);
227 labeld_data_t
*callp
= &call
;
228 size_t bufsize
= sizeof (labeld_data_t
);
230 int err
= M_BAD_LABEL
;
231 int id
= convert_id(t
);
232 boolean_t
new = B_FALSE
;
233 uint_t lf
= (f
& ~L_CHECK_AR
); /* because L_DEFAULT == 0 */
240 if ((*l
= m_label_alloc(t
)) == NULL
) {
249 } else if (_MTYPE(*l
, SUN_INVALID_ID
) &&
250 ((lf
== L_NO_CORRECTION
) || (lf
== L_DEFAULT
))) {
253 } else if (!(_MTYPE(*l
, SUN_MAC_ID
) || _MTYPE(*l
, SUN_CLR_ID
))) {
257 if (new == B_FALSE
&& id
== -1) {
261 /* get to the beginning of the string to parse */
262 while (isspace(*s
)) {
266 /* accept a leading '[' and trailing ']' for old times sake */
270 while (isspace(*s
)) {
275 while (*p
!= '\0' && *p
!= ']') {
279 /* strip trailing spaces */
280 while (p
!= s
&& isspace(*(p
-1))) {
283 *p
= '\0'; /* end of string */
285 /* translate hex, admin_low and admin_high */
290 } else if (IS_HIGH(s
)) {
293 } else if (IS_HEX(lf
, s
)) {
294 if (htol(s
, *l
) != 0) {
295 /* whole string in error */
301 #define slcall callp->param.acall.cargs.sl_arg
302 #define slret callp->param.aret.rvals.sl_ret
303 /* now try label server */
305 datasize
= CALL_SIZE_STR(sl_call_t
, strlen(st
) + 1);
306 if (datasize
> bufsize
) {
307 if ((callp
= malloc(datasize
)) == NULL
) {
313 callp
->callop
= STOL
;
317 slcall
.flags
|= L_NEW_LABEL
;
318 (void) strcpy(slcall
.string
, st
);
320 * callp->reterr = L_GOOD_LABEL (-1) == OK;
321 * L_BAD_CLASSIFICATION (-2) == bad input
322 * classification: class
323 * L_BAD_LABEL (-3) == either string or input label bad
324 * M_OUTSIDE_AR (-4) == resultant MAC_LABEL is out
325 * l_e accreditation range
326 * O'E == offset in string 0 == entire string.
328 if (__call_labeld(&callp
, &bufsize
, &datasize
) == SUCCESS
) {
331 if (callp
!= &call
) {
332 /* free allocated buffer */
336 case _M_GOOD_LABEL
: /* L_GOOD_LABEL */
339 case M_BAD_LABEL
: /* L_BAD_CLASSIFICATION */
340 case M_BAD_STRING
: /* L_BAD_LABEL */
345 switch (callp
->reterr
) {
371 * m_label_alloc -- allocate a label structure
373 * Entry t = label type (MAC_LABEL, USER_CLEAR).
375 * Exit If error, NULL, errno set to ENOMEM
376 * Otherwise, pointer to m_label_t memory
381 m_label_alloc(const m_label_type_t t
)
388 if ((l
= malloc(sizeof (_mac_label_impl_t
))) == NULL
) {
391 _MSETTYPE(l
, SUN_INVALID_ID
);
401 * m_label_dup -- make a duplicate copy of the given label.
403 * Entry l = label to duplicate.
405 * Exit d = duplicate copy of l.
409 * errno = ENOTSUP, the underlying label mechanism
410 * does not support label duplication.
411 * ENOMEM, unable to allocate memory for d.
412 * EINVAL, invalid argument, l == NULL or
413 * invalid label type for the underlying
418 m_label_dup(m_label_t
**d
, const m_label_t
*l
)
420 if (d
== NULL
|| *d
!= NULL
) {
424 if ((*d
= malloc(sizeof (_mac_label_impl_t
))) == NULL
) {
429 (void) memcpy(*d
, l
, sizeof (_mac_label_impl_t
));
434 * m_label_free -- free label structure
436 * Entry l = label to free.
443 m_label_free(m_label_t
*l
)
448 #endif /* !defined(_KERNEL) */