1*45916cd2Sjpk /* 2*45916cd2Sjpk * CDDL HEADER START 3*45916cd2Sjpk * 4*45916cd2Sjpk * The contents of this file are subject to the terms of the 5*45916cd2Sjpk * Common Development and Distribution License (the "License"). 6*45916cd2Sjpk * You may not use this file except in compliance with the License. 7*45916cd2Sjpk * 8*45916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*45916cd2Sjpk * or http://www.opensolaris.org/os/licensing. 10*45916cd2Sjpk * See the License for the specific language governing permissions 11*45916cd2Sjpk * and limitations under the License. 12*45916cd2Sjpk * 13*45916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each 14*45916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*45916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the 16*45916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 17*45916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 18*45916cd2Sjpk * 19*45916cd2Sjpk * CDDL HEADER END 20*45916cd2Sjpk */ 21*45916cd2Sjpk /* 22*45916cd2Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*45916cd2Sjpk * Use is subject to license terms. 24*45916cd2Sjpk */ 25*45916cd2Sjpk 26*45916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 27*45916cd2Sjpk 28*45916cd2Sjpk /* 29*45916cd2Sjpk * String to binary label translations. 30*45916cd2Sjpk */ 31*45916cd2Sjpk 32*45916cd2Sjpk #include <ctype.h> 33*45916cd2Sjpk #include <locale.h> 34*45916cd2Sjpk #include <stdio.h> 35*45916cd2Sjpk #include <stdlib.h> 36*45916cd2Sjpk #include <strings.h> 37*45916cd2Sjpk 38*45916cd2Sjpk #include <tsol/label.h> 39*45916cd2Sjpk 40*45916cd2Sjpk #include "labeld.h" 41*45916cd2Sjpk #include <sys/tsol/label_macro.h> 42*45916cd2Sjpk 43*45916cd2Sjpk #undef CALL_SIZE 44*45916cd2Sjpk #define CALL_SIZE(type, buf) (size_t)(sizeof (type) - BUFSIZE + sizeof (int)\ 45*45916cd2Sjpk + (buf)) 46*45916cd2Sjpk 47*45916cd2Sjpk #if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */ 48*45916cd2Sjpk #define TEXT_DOMAIN "SYS_TEST" 49*45916cd2Sjpk #endif /* TEXT_DOMAIN */ 50*45916cd2Sjpk 51*45916cd2Sjpk /* short hands */ 52*45916cd2Sjpk 53*45916cd2Sjpk #define IS_ADMIN_LOW(sl) \ 54*45916cd2Sjpk ((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0)) 55*45916cd2Sjpk 56*45916cd2Sjpk #define IS_ADMIN_HIGH(sh) \ 57*45916cd2Sjpk ((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0)) 58*45916cd2Sjpk 59*45916cd2Sjpk #define ISHEX(f, s) \ 60*45916cd2Sjpk (((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \ 61*45916cd2Sjpk (((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \ 62*45916cd2Sjpk (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X')))) 63*45916cd2Sjpk 64*45916cd2Sjpk #define slcall callp->param.acall.cargs.stobsl_arg 65*45916cd2Sjpk #define slret callp->param.aret.rvals.stobsl_ret 66*45916cd2Sjpk /* 67*45916cd2Sjpk * stobsl - Translate Sensitivity Label string to a Binary Sensitivity 68*45916cd2Sjpk * Label. 69*45916cd2Sjpk * 70*45916cd2Sjpk * Entry string = Sensitivity Label string to be translated. 71*45916cd2Sjpk * label = Address of Binary Sensitivity Label to be initialized or 72*45916cd2Sjpk * updated. 73*45916cd2Sjpk * flags = Flags to control translation: 74*45916cd2Sjpk * NO_CORRECTION implies NEW_LABEL. 75*45916cd2Sjpk * NEW_LABEL, Initialize the label to a valid empty 76*45916cd2Sjpk * Sensitivity Label structure. 77*45916cd2Sjpk * NO_CORRECTION, Initialize the label to a valid 78*45916cd2Sjpk * empty Sensitivity Label structure. 79*45916cd2Sjpk * Prohibit correction to the Sensitivity Label. 80*45916cd2Sjpk * Other, pass existing Sensitivity Label through for 81*45916cd2Sjpk * modification. 82*45916cd2Sjpk * 83*45916cd2Sjpk * Exit label = Translated (updated) Binary Sensitivity Label. 84*45916cd2Sjpk * error = If error reported, the error indicator, 85*45916cd2Sjpk * -1, Unable to access label encodings file; 86*45916cd2Sjpk * 0, Invalid binary label passed; 87*45916cd2Sjpk * >0, Position after the first character in 88*45916cd2Sjpk * string of error, 1 indicates entire string. 89*45916cd2Sjpk * Otherwise, unchanged. 90*45916cd2Sjpk * 91*45916cd2Sjpk * Returns 0, If error. 92*45916cd2Sjpk * 1, If successful. 93*45916cd2Sjpk * 94*45916cd2Sjpk * Calls __call_labeld(STOBSL), ISHEX, htobsl, strlen, 95*45916cd2Sjpk * isspace, 96*45916cd2Sjpk * strncasecmp. 97*45916cd2Sjpk * 98*45916cd2Sjpk * Uses ADMIN_HIGH, ADMIN_LOW. 99*45916cd2Sjpk */ 100*45916cd2Sjpk 101*45916cd2Sjpk int 102*45916cd2Sjpk stobsl(const char *string, bslabel_t *label, int flags, int *error) 103*45916cd2Sjpk { 104*45916cd2Sjpk labeld_data_t call; 105*45916cd2Sjpk labeld_data_t *callp = &call; 106*45916cd2Sjpk size_t bufsize = sizeof (labeld_data_t); 107*45916cd2Sjpk size_t datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1); 108*45916cd2Sjpk int rval; 109*45916cd2Sjpk char *s = (char *)string; 110*45916cd2Sjpk 111*45916cd2Sjpk while (isspace(*s)) 112*45916cd2Sjpk s++; 113*45916cd2Sjpk /* accept a leading '[' */ 114*45916cd2Sjpk if (*s == '[') { 115*45916cd2Sjpk s++; 116*45916cd2Sjpk while (isspace(*s)) 117*45916cd2Sjpk s++; 118*45916cd2Sjpk } 119*45916cd2Sjpk if (ISHEX(flags, s)) { 120*45916cd2Sjpk if (htobsl(s, label)) { 121*45916cd2Sjpk return (1); 122*45916cd2Sjpk } else { 123*45916cd2Sjpk if (error != NULL) 124*45916cd2Sjpk *error = 1; 125*45916cd2Sjpk return (0); 126*45916cd2Sjpk } 127*45916cd2Sjpk } 128*45916cd2Sjpk 129*45916cd2Sjpk if (datasize > bufsize) { 130*45916cd2Sjpk if ((callp = malloc(datasize)) == NULL) { 131*45916cd2Sjpk if (error != NULL) 132*45916cd2Sjpk *error = -1; 133*45916cd2Sjpk return (0); 134*45916cd2Sjpk } 135*45916cd2Sjpk bufsize = datasize; 136*45916cd2Sjpk } 137*45916cd2Sjpk callp->callop = STOBSL; 138*45916cd2Sjpk slcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0; 139*45916cd2Sjpk slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0; 140*45916cd2Sjpk slcall.label = *label; 141*45916cd2Sjpk (void) strcpy(slcall.string, string); 142*45916cd2Sjpk 143*45916cd2Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) { 144*45916cd2Sjpk int err = callp->reterr; 145*45916cd2Sjpk 146*45916cd2Sjpk if (callp != &call) { 147*45916cd2Sjpk /* free allocated buffer */ 148*45916cd2Sjpk free(callp); 149*45916cd2Sjpk } 150*45916cd2Sjpk /* 151*45916cd2Sjpk * reterr == 0, OK, 152*45916cd2Sjpk * reterr < 0, invalid binary label, 153*45916cd2Sjpk * reterr > 0 error position, 1 == whole string 154*45916cd2Sjpk */ 155*45916cd2Sjpk if (err == 0) { 156*45916cd2Sjpk *label = slret.label; 157*45916cd2Sjpk return (1); 158*45916cd2Sjpk } else if (err < 0) { 159*45916cd2Sjpk err = 0; 160*45916cd2Sjpk } 161*45916cd2Sjpk if (error != NULL) 162*45916cd2Sjpk *error = err; 163*45916cd2Sjpk return (0); 164*45916cd2Sjpk } else if (rval == NOSERVER) { 165*45916cd2Sjpk if (callp != &call) { 166*45916cd2Sjpk /* free allocated buffer */ 167*45916cd2Sjpk free(callp); 168*45916cd2Sjpk } 169*45916cd2Sjpk /* server not present */ 170*45916cd2Sjpk /* special case Admin High and Admin Low */ 171*45916cd2Sjpk if (IS_ADMIN_LOW(s)) { 172*45916cd2Sjpk BSLLOW(label); 173*45916cd2Sjpk } else if (IS_ADMIN_HIGH(s)) { 174*45916cd2Sjpk BSLHIGH(label); 175*45916cd2Sjpk } else { 176*45916cd2Sjpk goto err1; 177*45916cd2Sjpk } 178*45916cd2Sjpk return (1); 179*45916cd2Sjpk } 180*45916cd2Sjpk if (callp != &call) { 181*45916cd2Sjpk /* free allocated buffer */ 182*45916cd2Sjpk free(callp); 183*45916cd2Sjpk } 184*45916cd2Sjpk err1: 185*45916cd2Sjpk if (error != NULL) 186*45916cd2Sjpk *error = -1; 187*45916cd2Sjpk return (0); 188*45916cd2Sjpk } /* stobsl */ 189*45916cd2Sjpk #undef slcall 190*45916cd2Sjpk #undef slret 191*45916cd2Sjpk 192*45916cd2Sjpk #define clrcall callp->param.acall.cargs.stobclear_arg 193*45916cd2Sjpk #define clrret callp->param.aret.rvals.stobclear_ret 194*45916cd2Sjpk /* 195*45916cd2Sjpk * stobclear - Translate Clearance string to a Binary Clearance. 196*45916cd2Sjpk * 197*45916cd2Sjpk * Entry string = Clearance string to be translated. 198*45916cd2Sjpk * clearance = Address of Binary Clearance to be initialized or 199*45916cd2Sjpk * updated. 200*45916cd2Sjpk * flags = Flags to control translation: 201*45916cd2Sjpk * NO_CORRECTION implies NEW_LABEL. 202*45916cd2Sjpk * NEW_LABEL, Initialize the label to a valid empty 203*45916cd2Sjpk * Sensitivity Label structure. 204*45916cd2Sjpk * NO_CORRECTION, Initialize the label to a valid 205*45916cd2Sjpk * empty Sensitivity Label structure. 206*45916cd2Sjpk * Prohibit correction to the Sensitivity Label. 207*45916cd2Sjpk * Other, pass existing Sensitivity Label through for 208*45916cd2Sjpk * modification. 209*45916cd2Sjpk * 210*45916cd2Sjpk * Exit clearance = Translated (updated) Binary Clearance. 211*45916cd2Sjpk * error = If error reported, the error indicator, 212*45916cd2Sjpk * -1, Unable to access label encodings file; 213*45916cd2Sjpk * 0, Invalid binary label passed; 214*45916cd2Sjpk * >0, Position after the first character in 215*45916cd2Sjpk * string of error, 1 indicates entire string. 216*45916cd2Sjpk * Otherwise, unchanged. 217*45916cd2Sjpk * 218*45916cd2Sjpk * Returns 0, If error. 219*45916cd2Sjpk * 1, If successful. 220*45916cd2Sjpk * 221*45916cd2Sjpk * Calls __call_labeld(STOBCLEAR), ISHEX, htobsl, strlen, 222*45916cd2Sjpk * isspace, 223*45916cd2Sjpk * strncasecmp. 224*45916cd2Sjpk * 225*45916cd2Sjpk * Uses ADMIN_HIGH, ADMIN_LOW. 226*45916cd2Sjpk */ 227*45916cd2Sjpk 228*45916cd2Sjpk int 229*45916cd2Sjpk stobclear(const char *string, bclear_t *clearance, int flags, int *error) 230*45916cd2Sjpk { 231*45916cd2Sjpk labeld_data_t call; 232*45916cd2Sjpk labeld_data_t *callp = &call; 233*45916cd2Sjpk size_t bufsize = sizeof (labeld_data_t); 234*45916cd2Sjpk size_t datasize = CALL_SIZE(callp->param.acall, strlen(string) + 1); 235*45916cd2Sjpk int rval; 236*45916cd2Sjpk 237*45916cd2Sjpk if (ISHEX(flags, string)) { 238*45916cd2Sjpk if (htobclear(string, clearance)) { 239*45916cd2Sjpk return (1); 240*45916cd2Sjpk } else { 241*45916cd2Sjpk if (error != NULL) 242*45916cd2Sjpk *error = 1; 243*45916cd2Sjpk return (0); 244*45916cd2Sjpk } 245*45916cd2Sjpk } 246*45916cd2Sjpk 247*45916cd2Sjpk if (datasize > bufsize) { 248*45916cd2Sjpk if ((callp = malloc(datasize)) == NULL) { 249*45916cd2Sjpk if (error != NULL) 250*45916cd2Sjpk *error = -1; 251*45916cd2Sjpk return (0); 252*45916cd2Sjpk } 253*45916cd2Sjpk bufsize = datasize; 254*45916cd2Sjpk } 255*45916cd2Sjpk callp->callop = STOBCLEAR; 256*45916cd2Sjpk clrcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0; 257*45916cd2Sjpk clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0; 258*45916cd2Sjpk clrcall.clear = *clearance; 259*45916cd2Sjpk (void) strcpy(clrcall.string, string); 260*45916cd2Sjpk 261*45916cd2Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) { 262*45916cd2Sjpk int err = callp->reterr; 263*45916cd2Sjpk 264*45916cd2Sjpk if (callp != &call) { 265*45916cd2Sjpk /* free allocated buffer */ 266*45916cd2Sjpk free(callp); 267*45916cd2Sjpk } 268*45916cd2Sjpk /* 269*45916cd2Sjpk * reterr == 0, OK, 270*45916cd2Sjpk * reterr < 0, invalid binary label, 271*45916cd2Sjpk * reterr > 0 error position, 1 == whole string 272*45916cd2Sjpk */ 273*45916cd2Sjpk if (err == 0) { 274*45916cd2Sjpk *clearance = clrret.clear; 275*45916cd2Sjpk return (1); 276*45916cd2Sjpk } else if (err < 0) { 277*45916cd2Sjpk err = 0; 278*45916cd2Sjpk } 279*45916cd2Sjpk if (error != NULL) 280*45916cd2Sjpk *error = err; 281*45916cd2Sjpk return (0); 282*45916cd2Sjpk } else if (rval == NOSERVER) { 283*45916cd2Sjpk char *s = (char *)string; 284*45916cd2Sjpk 285*45916cd2Sjpk if (callp != &call) { 286*45916cd2Sjpk /* free allocated buffer */ 287*45916cd2Sjpk free(callp); 288*45916cd2Sjpk } 289*45916cd2Sjpk /* server not present */ 290*45916cd2Sjpk /* special case Admin High and Admin Low */ 291*45916cd2Sjpk while (isspace(*s)) 292*45916cd2Sjpk s++; 293*45916cd2Sjpk if (IS_ADMIN_LOW(s)) { 294*45916cd2Sjpk BCLEARLOW(clearance); 295*45916cd2Sjpk } else if (IS_ADMIN_HIGH(s)) { 296*45916cd2Sjpk BCLEARHIGH(clearance); 297*45916cd2Sjpk } else { 298*45916cd2Sjpk goto err1; 299*45916cd2Sjpk } 300*45916cd2Sjpk return (1); 301*45916cd2Sjpk } 302*45916cd2Sjpk if (callp != &call) { 303*45916cd2Sjpk /* free allocated buffer */ 304*45916cd2Sjpk free(callp); 305*45916cd2Sjpk } 306*45916cd2Sjpk err1: 307*45916cd2Sjpk if (error != NULL) 308*45916cd2Sjpk *error = -1; 309*45916cd2Sjpk return (0); 310*45916cd2Sjpk } /* stobclear */ 311*45916cd2Sjpk #undef clrcall 312*45916cd2Sjpk #undef clrret 313