/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#if !defined(_KERNEL)
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <strings.h>
#else /* !defined(_KERNEL) */
#endif /* !defined(_KERNEL) */
#if !defined(_KERNEL)
#include "clnt.h"
#include "labeld.h"
#else /* !defined(_KERNEL) */
#include <util/strtolctype.h>
#endif /* !defined(_KERNEL) */
#define IS_LOW(s) \
#define IS_HIGH(s) \
#define IS_HEX(f, s) \
(((((f) == L_NO_CORRECTION)) || ((f) == L_DEFAULT)) && \
(((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
static boolean_t
{
const char *hx = *h;
char ch;
for (; len--; ) {
return (B_FALSE);
else
byte <<= 4;
return (B_FALSE);
else
*l++ = byte;
}
*h = hx;
return (B_TRUE);
}
/*
* Formats accepted:
* 0x + 4 class + 64 comps + end of string
* 0x + 4 class + '-' + ll + '-' + comps + end of string
* ll = number of words to fill out the entire comps field
* presumes trailing zero for comps
*
* So in the case of 256 comps (i.e., 8 compartment words):
* 0x0006-08-7ff3f
* 0x + Classification + Compartments + end of string
* 0[xX]hhh...
*/
static int
{
const char *h = &s[2]; /* skip 0[xX] */
int bytes;
/* unpack 16 bit signed classification */
return (-1);
}
if (h[0] == '-' && h[3] == '-') {
/* length specified of internal text label */
h++; /* skip '-' */
return (-1);
}
/* convert size from words to bytes */
/*
* internal label greater than will fit in current
* binary.
*/
return (-1);
}
h++; /* skip '-' */
}
return (-1);
}
return (0);
}
/*
* hexstr_to_label -- parse a string representing a hex label into a
* accepted.
*
* Returns 0, success.
* -1, failure
*/
int
{
/* translate hex, admin_low and admin_high */
if (IS_LOW(s)) {
_LOW_LABEL(l, SUN_MAC_ID);
return (0);
} else if (IS_HIGH(s)) {
_HIGH_LABEL(l, SUN_MAC_ID);
return (0);
} else if (IS_HEX(f, s)) {
_LOW_LABEL(l, SUN_MAC_ID);
if (htol(s, l) == 0)
return (0);
}
return (-1);
}
#if !defined(_KERNEL)
static int
{
switch (t) {
case MAC_LABEL:
return (SUN_MAC_ID);
case USER_CLEAR:
return (SUN_UCLR_ID);
default:
return (-1);
}
}
/*
* str_to_label -- parse a string into the requested label type.
*
* Entry s = string to parse.
* l = label to create or modify.
* t = label type (MAC_LABEL, USER_CLEAR).
* f = flags
* L_DEFAULT,
* L_MODIFY_EXISTING, use the existing label as a basis for
* the parse string.
* L_NO_CORRECTION, s must be correct and full by the
* label_encoding rules.
* L_CHECK_AR, for non-hex s, MAC_LABEL, check the l_e AR
*
* Exit l = parsed label value.
* e = index into string of error.
* = M_BAD_STRING (-3 L_BAD_LABEL) or could be zero,
* indicates entire string,
* e = M_BAD_LABEL (-2 L_BAD_CLASSIFICATION), problems with l
* e = M_OUTSIDE_AR (-4 unrelated to L_BAD_* return values)
*
* Returns 0, success.
* -1, failure
* errno = ENOTSUP, the underlying label mechanism
* does not support label parsing.
* ENOMEM, unable to allocate memory for l.
* EINVAL, invalid argument, l != NULL or
* invalid label type for the underlying
* label mechanism.
*/
int
int *e)
{
char *st = s;
char *p;
return (-1);
}
if (*l == NULL) {
if ((*l = m_label_alloc(t)) == NULL) {
return (-1);
}
if (id == -1) {
goto badlabel;
}
_LOW_LABEL(*l, id);
} else if (_MTYPE(*l, SUN_INVALID_ID) &&
_LOW_LABEL(*l, id);
goto badlabel;
}
goto badlabel;
}
/* get to the beginning of the string to parse */
while (isspace(*s)) {
s++;
}
/* accept a leading '[' and trailing ']' for old times sake */
if (*s == '[') {
*s = ' ';
s++;
while (isspace(*s)) {
s++;
}
}
p = s;
while (*p != '\0' && *p != ']') {
p++;
}
/* strip trailing spaces */
while (p != s && isspace(*(p-1))) {
--p;
}
*p = '\0'; /* end of string */
/* translate hex, admin_low and admin_high */
if (IS_LOW(s)) {
_LOW_LABEL(*l, id);
goto goodlabel;
} else if (IS_HIGH(s)) {
_HIGH_LABEL(*l, id);
goto goodlabel;
if (htol(s, *l) != 0) {
/* whole string in error */
err = 0;
goto badlabel;
}
goto goodlabel;
}
/* now try label server */
return (-1);
}
}
if (new)
/*
* callp->reterr = L_GOOD_LABEL (-1) == OK;
* L_BAD_CLASSIFICATION (-2) == bad input
* classification: class
* L_BAD_LABEL (-3) == either string or input label bad
* M_OUTSIDE_AR (-4) == resultant MAC_LABEL is out
* l_e accreditation range
* O'E == offset in string 0 == entire string.
*/
/* free allocated buffer */
}
switch (err) {
case _M_GOOD_LABEL: /* L_GOOD_LABEL */
goto goodlabel;
case M_BAD_LABEL: /* L_BAD_CLASSIFICATION */
case M_BAD_STRING: /* L_BAD_LABEL */
default:
goto badlabel;
}
}
case NOSERVER:
break;
default:
break;
}
return (-1);
if (e != NULL)
*e = err;
return (-1);
return (0);
}
/*
* m_label_alloc -- allocate a label structure
*
* Entry t = label type (MAC_LABEL, USER_CLEAR).
*
* Exit If error, NULL, errno set to ENOMEM
* Otherwise, pointer to m_label_t memory
*/
/* ARGUSED */
{
m_label_t *l;
switch (t) {
case MAC_LABEL:
case USER_CLEAR:
return (NULL);
}
_MSETTYPE(l, SUN_INVALID_ID);
break;
default:
return (NULL);
}
return (l);
}
/*
* m_label_dup -- make a duplicate copy of the given label.
*
* Entry l = label to duplicate.
*
* Exit d = duplicate copy of l.
*
* Returns 0, success
* -1, if error.
* errno = ENOTSUP, the underlying label mechanism
* does not support label duplication.
* ENOMEM, unable to allocate memory for d.
* EINVAL, invalid argument, l == NULL or
* invalid label type for the underlying
* label mechanism.
*/
int
{
return (-1);
}
return (-1);
}
(void) memcpy(*d, l, sizeof (_mac_label_impl_t));
return (0);
}
/*
* m_label_free -- free label structure
*
* Entry l = label to free.
*
* Exit memory freed.
*
*/
void
{
if (l)
free(l);
}
#endif /* !defined(_KERNEL) */