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