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 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 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 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 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 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 * 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 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 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