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