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 #endif /* !defined(_KERNEL) */ 29*4201a95eSRic Aleshire 30*4201a95eSRic Aleshire #include <sys/types.h> 31*4201a95eSRic Aleshire #include <sys/mman.h> 32*4201a95eSRic Aleshire #include <sys/tsol/label_macro.h> 33*4201a95eSRic Aleshire 34*4201a95eSRic Aleshire #include <sys/tsol/label.h> 35*4201a95eSRic Aleshire 36*4201a95eSRic Aleshire #if !defined(_KERNEL) 37*4201a95eSRic Aleshire #include "clnt.h" 38*4201a95eSRic Aleshire #include "labeld.h" 39*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */ 40*4201a95eSRic Aleshire 41*4201a95eSRic Aleshire #if defined(_KERNEL) 42*4201a95eSRic Aleshire #include <sys/systm.h> 43*4201a95eSRic Aleshire #include <sys/sunddi.h> 44*4201a95eSRic Aleshire #else 45*4201a95eSRic Aleshire #include <stdlib.h> 46*4201a95eSRic Aleshire #include <string.h> 47*4201a95eSRic Aleshire #include <ctype.h> 48*4201a95eSRic Aleshire #endif 49*4201a95eSRic Aleshire 50*4201a95eSRic Aleshire 51*4201a95eSRic Aleshire 52*4201a95eSRic Aleshire static _mac_label_impl_t low; 53*4201a95eSRic Aleshire static _mac_label_impl_t high; 54*4201a95eSRic Aleshire static int inited = 0; 55*4201a95eSRic Aleshire 56*4201a95eSRic Aleshire #if defined(_KERNEL) 57*4201a95eSRic Aleshire #define malloc(l) kmem_alloc(l, KM_NOSLEEP) 58*4201a95eSRic Aleshire #define freeit(a, l) kmem_free(a, l) 59*4201a95eSRic Aleshire #else /* defined(_KERNEL) */ 60*4201a95eSRic Aleshire #define freeit(a, l) free(a) 61*4201a95eSRic Aleshire #endif /* defined(_KERNEL) */ 62*4201a95eSRic Aleshire 63*4201a95eSRic Aleshire /* 0x + Classification + '-' + ll + '-' + Compartments + end of string */ 64*4201a95eSRic Aleshire #define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\ 65*4201a95eSRic Aleshire (sizeof (Compartments_t)*2)+1 66*4201a95eSRic Aleshire 67*4201a95eSRic Aleshire /* 0x + Classification + '-' + ll + '-' + end of string */ 68*4201a95eSRic Aleshire #define _MIN_HEX (2 + (sizeof (Classification_t)*2) + 4 + 1) 69*4201a95eSRic Aleshire 70*4201a95eSRic Aleshire static char digits[] = "0123456789abcdef"; 71*4201a95eSRic Aleshire 72*4201a95eSRic Aleshire #define HEX(h, i, l, s) \ 73*4201a95eSRic Aleshire for (; i < s; /* */) {\ 74*4201a95eSRic Aleshire h[i++] = digits[(unsigned int)(*l >> 4)];\ 75*4201a95eSRic Aleshire h[i++] = digits[(unsigned int)(*l++&0xF)]; } 76*4201a95eSRic Aleshire 77*4201a95eSRic Aleshire static int 78*4201a95eSRic Aleshire __hex(char **s, const m_label_t *l) 79*4201a95eSRic Aleshire { 80*4201a95eSRic Aleshire char *hex; 81*4201a95eSRic Aleshire int i = 0; 82*4201a95eSRic Aleshire uchar_t *hl; 83*4201a95eSRic Aleshire int hex_len; 84*4201a95eSRic Aleshire uchar_t *len; 85*4201a95eSRic Aleshire 86*4201a95eSRic Aleshire hl = (uchar_t *)&(((_mac_label_impl_t *)l)->_c_len); 87*4201a95eSRic Aleshire len = hl; 88*4201a95eSRic Aleshire 89*4201a95eSRic Aleshire if (*len == 0) { 90*4201a95eSRic Aleshire /* old binary label */ 91*4201a95eSRic Aleshire hex_len = _HEX_SIZE; 92*4201a95eSRic Aleshire } else { 93*4201a95eSRic Aleshire hex_len = _MIN_HEX + (*len * sizeof (uint32_t) * 2); 94*4201a95eSRic Aleshire } 95*4201a95eSRic Aleshire 96*4201a95eSRic Aleshire if ((hex = malloc(hex_len)) == NULL) { 97*4201a95eSRic Aleshire return (-1); 98*4201a95eSRic Aleshire } 99*4201a95eSRic Aleshire 100*4201a95eSRic Aleshire /* header */ 101*4201a95eSRic Aleshire 102*4201a95eSRic Aleshire hex[i++] = '0'; 103*4201a95eSRic Aleshire hex[i++] = 'x'; 104*4201a95eSRic Aleshire 105*4201a95eSRic Aleshire /* classification */ 106*4201a95eSRic Aleshire 107*4201a95eSRic Aleshire hl++; /* start at classification */ 108*4201a95eSRic Aleshire HEX(hex, i, hl, 6); 109*4201a95eSRic Aleshire 110*4201a95eSRic Aleshire /* Add compartments length */ 111*4201a95eSRic Aleshire hex[i++] = '-'; 112*4201a95eSRic Aleshire HEX(hex, i, len, 9); 113*4201a95eSRic Aleshire hex[i++] = '-'; 114*4201a95eSRic Aleshire 115*4201a95eSRic Aleshire /* compartments */ 116*4201a95eSRic Aleshire HEX(hex, i, hl, hex_len-1); 117*4201a95eSRic Aleshire hex[i] = '\0'; 118*4201a95eSRic Aleshire 119*4201a95eSRic Aleshire /* truncate trailing zeros */ 120*4201a95eSRic Aleshire 121*4201a95eSRic Aleshire while (hex[i-1] == '0' && hex[i-2] == '0') { 122*4201a95eSRic Aleshire i -= 2; 123*4201a95eSRic Aleshire } 124*4201a95eSRic Aleshire hex[i] = '\0'; 125*4201a95eSRic Aleshire 126*4201a95eSRic Aleshire if ((*s = strdup(hex)) == NULL) { 127*4201a95eSRic Aleshire freeit(hex, hex_len); 128*4201a95eSRic Aleshire return (-1); 129*4201a95eSRic Aleshire } 130*4201a95eSRic Aleshire 131*4201a95eSRic Aleshire freeit(hex, hex_len); 132*4201a95eSRic Aleshire return (0); 133*4201a95eSRic Aleshire 134*4201a95eSRic Aleshire } 135*4201a95eSRic Aleshire 136*4201a95eSRic Aleshire int 137*4201a95eSRic Aleshire l_to_str_internal(const m_label_t *l, char **s) 138*4201a95eSRic Aleshire { 139*4201a95eSRic Aleshire if (inited == 0) { 140*4201a95eSRic Aleshire inited = 1; 141*4201a95eSRic Aleshire _BSLLOW(&low); 142*4201a95eSRic Aleshire _BSLHIGH(&high); 143*4201a95eSRic Aleshire } 144*4201a95eSRic Aleshire 145*4201a95eSRic Aleshire if (!(_MTYPE(l, SUN_MAC_ID) || _MTYPE(l, SUN_UCLR_ID))) { 146*4201a95eSRic Aleshire #if !defined(_KERNEL) 147*4201a95eSRic Aleshire errno = EINVAL; 148*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */ 149*4201a95eSRic Aleshire *s = NULL; 150*4201a95eSRic Aleshire return (-1); 151*4201a95eSRic Aleshire } 152*4201a95eSRic Aleshire if (_MEQUAL(&low, (_mac_label_impl_t *)l)) { 153*4201a95eSRic Aleshire if ((*s = strdup(ADMIN_LOW)) == NULL) { 154*4201a95eSRic Aleshire return (-1); 155*4201a95eSRic Aleshire } 156*4201a95eSRic Aleshire return (0); 157*4201a95eSRic Aleshire } 158*4201a95eSRic Aleshire if (_MEQUAL(&high, (_mac_label_impl_t *)l)) { 159*4201a95eSRic Aleshire if ((*s = strdup(ADMIN_HIGH)) == NULL) { 160*4201a95eSRic Aleshire return (-1); 161*4201a95eSRic Aleshire } 162*4201a95eSRic Aleshire return (0); 163*4201a95eSRic Aleshire } 164*4201a95eSRic Aleshire 165*4201a95eSRic Aleshire return (__hex(s, l)); 166*4201a95eSRic Aleshire } 167*4201a95eSRic Aleshire 168*4201a95eSRic Aleshire #if !defined(_KERNEL) 169*4201a95eSRic Aleshire /* 170*4201a95eSRic Aleshire * label_to_str -- convert a label to the requested type of string. 171*4201a95eSRic Aleshire * 172*4201a95eSRic Aleshire * Entry l = label to convert; 173*4201a95eSRic Aleshire * t = type of conversion; 174*4201a95eSRic Aleshire * f = flags for conversion type; 175*4201a95eSRic Aleshire * 176*4201a95eSRic Aleshire * Exit *s = allocated converted string; 177*4201a95eSRic Aleshire * Caller must call free() to free. 178*4201a95eSRic Aleshire * 179*4201a95eSRic Aleshire * Returns 0, success. 180*4201a95eSRic Aleshire * -1, error, errno set; *s = NULL. 181*4201a95eSRic Aleshire * 182*4201a95eSRic Aleshire * Calls labeld 183*4201a95eSRic Aleshire */ 184*4201a95eSRic Aleshire 185*4201a95eSRic Aleshire int 186*4201a95eSRic Aleshire label_to_str(const m_label_t *l, char **s, const m_label_str_t t, uint_t f) 187*4201a95eSRic Aleshire { 188*4201a95eSRic Aleshire labeld_data_t call; 189*4201a95eSRic Aleshire labeld_data_t *callp = &call; 190*4201a95eSRic Aleshire size_t bufsize = sizeof (labeld_data_t); 191*4201a95eSRic Aleshire size_t datasize; 192*4201a95eSRic Aleshire int err; 193*4201a95eSRic Aleshire int string_start = 0; 194*4201a95eSRic Aleshire 195*4201a95eSRic Aleshire if (inited == 0) { 196*4201a95eSRic Aleshire inited = 1; 197*4201a95eSRic Aleshire _BSLLOW(&low); 198*4201a95eSRic Aleshire _BSLHIGH(&high); 199*4201a95eSRic Aleshire } 200*4201a95eSRic Aleshire 201*4201a95eSRic Aleshire #define lscall callp->param.acall.cargs.ls_arg 202*4201a95eSRic Aleshire #define lsret callp->param.aret.rvals.ls_ret 203*4201a95eSRic Aleshire switch (t) { 204*4201a95eSRic Aleshire case M_LABEL: 205*4201a95eSRic Aleshire call.callop = LTOS; 206*4201a95eSRic Aleshire lscall.label = *l; 207*4201a95eSRic Aleshire lscall.flags = f; 208*4201a95eSRic Aleshire datasize = CALL_SIZE(ls_call_t, 0); 209*4201a95eSRic Aleshire if ((err = __call_labeld(&callp, &bufsize, &datasize)) == 210*4201a95eSRic Aleshire SUCCESS) { 211*4201a95eSRic Aleshire if (callp->reterr != 0) { 212*4201a95eSRic Aleshire errno = EINVAL; 213*4201a95eSRic Aleshire *s = NULL; 214*4201a95eSRic Aleshire return (-1); 215*4201a95eSRic Aleshire } 216*4201a95eSRic Aleshire *s = strdup(lsret.buf); 217*4201a95eSRic Aleshire if (callp != &call) { 218*4201a95eSRic Aleshire /* release returned buffer */ 219*4201a95eSRic Aleshire (void) munmap((void *)callp, bufsize); 220*4201a95eSRic Aleshire } 221*4201a95eSRic Aleshire if (*s == NULL) { 222*4201a95eSRic Aleshire return (-1); 223*4201a95eSRic Aleshire } 224*4201a95eSRic Aleshire return (0); 225*4201a95eSRic Aleshire } 226*4201a95eSRic Aleshire switch (err) { 227*4201a95eSRic Aleshire case NOSERVER: 228*4201a95eSRic Aleshire /* server not present */ 229*4201a95eSRic Aleshire /* special case admin_low and admin_high */ 230*4201a95eSRic Aleshire 231*4201a95eSRic Aleshire if (_MEQUAL(&low, (_mac_label_impl_t *)l)) { 232*4201a95eSRic Aleshire if ((*s = strdup(ADMIN_LOW)) == NULL) { 233*4201a95eSRic Aleshire return (-1); 234*4201a95eSRic Aleshire } 235*4201a95eSRic Aleshire return (0); 236*4201a95eSRic Aleshire } else if (_MEQUAL(&high, (_mac_label_impl_t *)l)) { 237*4201a95eSRic Aleshire if ((*s = strdup(ADMIN_HIGH)) == NULL) { 238*4201a95eSRic Aleshire return (-1); 239*4201a95eSRic Aleshire } 240*4201a95eSRic Aleshire return (0); 241*4201a95eSRic Aleshire } 242*4201a95eSRic Aleshire errno = ENOTSUP; 243*4201a95eSRic Aleshire break; 244*4201a95eSRic Aleshire default: 245*4201a95eSRic Aleshire errno = EINVAL; 246*4201a95eSRic Aleshire break; 247*4201a95eSRic Aleshire } 248*4201a95eSRic Aleshire *s = NULL; 249*4201a95eSRic Aleshire return (-1); 250*4201a95eSRic Aleshire #undef lscall 251*4201a95eSRic Aleshire #undef lsret 252*4201a95eSRic Aleshire 253*4201a95eSRic Aleshire case M_INTERNAL: { 254*4201a95eSRic Aleshire return (l_to_str_internal(l, s)); 255*4201a95eSRic Aleshire } 256*4201a95eSRic Aleshire 257*4201a95eSRic Aleshire #define ccall callp->param.acall.cargs.color_arg 258*4201a95eSRic Aleshire #define cret callp->param.aret.rvals.color_ret 259*4201a95eSRic Aleshire case M_COLOR: 260*4201a95eSRic Aleshire datasize = CALL_SIZE(color_call_t, 0); 261*4201a95eSRic Aleshire call.callop = BLTOCOLOR; 262*4201a95eSRic Aleshire ccall.label = *l; 263*4201a95eSRic Aleshire 264*4201a95eSRic Aleshire if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) { 265*4201a95eSRic Aleshire if (callp->reterr != 0) { 266*4201a95eSRic Aleshire errno = EINVAL; 267*4201a95eSRic Aleshire *s = NULL; 268*4201a95eSRic Aleshire return (-1); 269*4201a95eSRic Aleshire } 270*4201a95eSRic Aleshire *s = strdup(cret.color); 271*4201a95eSRic Aleshire if (callp != &call) { 272*4201a95eSRic Aleshire /* release returned buffer */ 273*4201a95eSRic Aleshire (void) munmap((void *)callp, bufsize); 274*4201a95eSRic Aleshire } 275*4201a95eSRic Aleshire if (*s == NULL) { 276*4201a95eSRic Aleshire return (-1); 277*4201a95eSRic Aleshire } 278*4201a95eSRic Aleshire return (0); 279*4201a95eSRic Aleshire } else { 280*4201a95eSRic Aleshire errno = ENOTSUP; 281*4201a95eSRic Aleshire *s = NULL; 282*4201a95eSRic Aleshire return (-1); 283*4201a95eSRic Aleshire } 284*4201a95eSRic Aleshire #undef ccall 285*4201a95eSRic Aleshire #undef cret 286*4201a95eSRic Aleshire 287*4201a95eSRic Aleshire #define prcall callp->param.acall.cargs.pr_arg 288*4201a95eSRic Aleshire #define prret callp->param.aret.rvals.pr_ret 289*4201a95eSRic Aleshire case PRINTER_TOP_BOTTOM: 290*4201a95eSRic Aleshire call.callop = PR_TOP; 291*4201a95eSRic Aleshire break; 292*4201a95eSRic Aleshire case PRINTER_LABEL: 293*4201a95eSRic Aleshire call.callop = PR_LABEL; 294*4201a95eSRic Aleshire break; 295*4201a95eSRic Aleshire case PRINTER_CAVEATS: 296*4201a95eSRic Aleshire call.callop = PR_CAVEATS; 297*4201a95eSRic Aleshire string_start = 1; /* compensate for leading space */ 298*4201a95eSRic Aleshire break; 299*4201a95eSRic Aleshire case PRINTER_CHANNELS: 300*4201a95eSRic Aleshire call.callop = PR_CHANNELS; 301*4201a95eSRic Aleshire string_start = 1; /* compensate for leading space */ 302*4201a95eSRic Aleshire break; 303*4201a95eSRic Aleshire default: 304*4201a95eSRic Aleshire errno = EINVAL; 305*4201a95eSRic Aleshire *s = NULL; 306*4201a95eSRic Aleshire return (-1); 307*4201a95eSRic Aleshire } 308*4201a95eSRic Aleshire /* do the common printer calls */ 309*4201a95eSRic Aleshire datasize = CALL_SIZE(pr_call_t, 0); 310*4201a95eSRic Aleshire prcall.label = *l; 311*4201a95eSRic Aleshire prcall.flags = f; 312*4201a95eSRic Aleshire if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) { 313*4201a95eSRic Aleshire if (callp->reterr != 0) { 314*4201a95eSRic Aleshire errno = EINVAL; 315*4201a95eSRic Aleshire *s = NULL; 316*4201a95eSRic Aleshire return (-1); 317*4201a95eSRic Aleshire } 318*4201a95eSRic Aleshire *s = strdup(&prret.buf[string_start]); 319*4201a95eSRic Aleshire if (callp != &call) { 320*4201a95eSRic Aleshire /* release returned buffer */ 321*4201a95eSRic Aleshire (void) munmap((void *)callp, bufsize); 322*4201a95eSRic Aleshire } 323*4201a95eSRic Aleshire if (*s == NULL) { 324*4201a95eSRic Aleshire return (-1); 325*4201a95eSRic Aleshire } 326*4201a95eSRic Aleshire return (0); 327*4201a95eSRic Aleshire } else { 328*4201a95eSRic Aleshire errno = ENOTSUP; 329*4201a95eSRic Aleshire *s = NULL; 330*4201a95eSRic Aleshire return (-1); 331*4201a95eSRic Aleshire } 332*4201a95eSRic Aleshire #undef prcall 333*4201a95eSRic Aleshire #undef prret 334*4201a95eSRic Aleshire } 335*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */ 336