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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * Miscellaneous user interfaces to trusted label functions. 29 * 30 */ 31 32 33 #include <ctype.h> 34 #include <stdlib.h> 35 #include <strings.h> 36 37 #include <sys/mman.h> 38 39 #include <tsol/label.h> 40 41 #include "labeld.h" 42 #include "clnt.h" 43 #include <sys/tsol/label_macro.h> 44 #include <secdb.h> 45 #include <user_attr.h> 46 47 static bslabel_t slow, shigh; /* static Admin Low and High SLs */ 48 static bclear_t clow, chigh; /* static Admin Low and High CLRs */ 49 50 static char color[MAXCOLOR]; 51 52 53 #define incall callp->param.acall.cargs.inset_arg 54 #define inret callp->param.aret.rvals.inset_ret 55 /* 56 * blinset - Check in a label set. 57 * 58 * Entry label = Sensitivity Label to check. 59 * id = Label set identifier of set to check. 60 * 61 * Exit None. 62 * 63 * Returns -1, If label set unavailable, or server failure. 64 * 0, If label not in label set. 65 * 1, If label is in the label set. 66 * 67 * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH. 68 * 69 * Uses slow, shigh. 70 */ 71 72 int 73 blinset(const bslabel_t *label, const set_id *id) 74 { 75 if (id->type == SYSTEM_ACCREDITATION_RANGE) { 76 if (!BLTYPE(&slow, SUN_SL_ID)) { 77 /* initialize static labels. */ 78 79 BSLLOW(&slow); 80 BSLHIGH(&shigh); 81 } 82 83 if (BLTYPE(label, SUN_SL_ID) && 84 (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) 85 86 return (1); 87 } 88 if (id->type == USER_ACCREDITATION_RANGE || 89 id->type == SYSTEM_ACCREDITATION_RANGE) { 90 labeld_data_t call; 91 labeld_data_t *callp = &call; 92 size_t bufsize = sizeof (labeld_data_t); 93 size_t datasize = CALL_SIZE(inset_call_t, 0); 94 95 call.callop = BLINSET; 96 incall.label = *label; 97 incall.type = id->type; 98 99 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 100 /* process error */ 101 102 return (-1); 103 } 104 return (inret.inset); 105 } else { 106 /* 107 * Only System and User Accreditation Ranges presently 108 * implemented. 109 */ 110 return (-1); 111 } 112 } 113 #undef incall 114 #undef inret 115 116 #define slvcall callp->param.acall.cargs.slvalid_arg 117 #define slvret callp->param.aret.rvals.slvalid_ret 118 /* 119 * bslvalid - Check Sensitivity Label for validity. 120 * 121 * Entry label = Sensitivity Label to check. 122 * 123 * Exit None. 124 * 125 * Returns -1, If unable to access label encodings file, or server failure. 126 * 0, If label not valid. 127 * 1, If label is valid. 128 * 129 * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH. 130 * 131 * Uses slow, shigh. 132 * 133 */ 134 135 int 136 bslvalid(const bslabel_t *label) 137 { 138 labeld_data_t call; 139 labeld_data_t *callp = &call; 140 size_t bufsize = sizeof (labeld_data_t); 141 size_t datasize = CALL_SIZE(slvalid_call_t, 0); 142 143 if (!BLTYPE(&slow, SUN_SL_ID)) { 144 /* initialize static labels. */ 145 146 BSLLOW(&slow); 147 BSLHIGH(&shigh); 148 } 149 150 if (BLTYPE(label, SUN_SL_ID) && 151 (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) { 152 153 return (1); 154 } 155 156 call.callop = BSLVALID; 157 slvcall.label = *label; 158 159 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 160 /* process error */ 161 162 return (-1); 163 } 164 return (slvret.valid); 165 } 166 #undef slvcall 167 #undef slvret 168 169 #define clrvcall callp->param.acall.cargs.clrvalid_arg 170 #define clrvret callp->param.aret.rvals.clrvalid_ret 171 /* 172 * bclearvalid - Check Clearance for validity. 173 * 174 * Entry clearance = Clearance to check. 175 * 176 * Exit None. 177 * 178 * Returns -1, If unable to access label encodings file, or server failure. 179 * 0, If label not valid. 180 * 1, If label is valid. 181 * 182 * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH. 183 * 184 * Uses clow, chigh. 185 * 186 */ 187 188 int 189 bclearvalid(const bclear_t *clearance) 190 { 191 labeld_data_t call; 192 labeld_data_t *callp = &call; 193 size_t bufsize = sizeof (labeld_data_t); 194 size_t datasize = CALL_SIZE(clrvalid_call_t, 0); 195 196 if (!BLTYPE(&clow, SUN_CLR_ID)) { 197 /* initialize static labels. */ 198 199 BCLEARLOW(&clow); 200 BCLEARHIGH(&chigh); 201 } 202 203 if (BLTYPE(clearance, SUN_CLR_ID) && 204 (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) { 205 206 return (1); 207 } 208 209 call.callop = BCLEARVALID; 210 clrvcall.clear = *clearance; 211 212 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 213 /* process error */ 214 215 return (-1); 216 } 217 return (clrvret.valid); 218 } 219 #undef clrvcall 220 #undef clrvret 221 222 #define inforet callp->param.aret.rvals.info_ret 223 /* 224 * labelinfo - Get information about the label encodings file. 225 * 226 * Entry info = Address of label_info structure to update. 227 * 228 * Exit info = Updated. 229 * 230 * Returns -1, If unable to access label encodings file, or server failure. 231 * 1, If successful. 232 * 233 * Calls __call_labeld(LABELINFO). 234 */ 235 236 int 237 labelinfo(struct label_info *info) 238 { 239 labeld_data_t call; 240 labeld_data_t *callp = &call; 241 size_t bufsize = sizeof (labeld_data_t); 242 size_t datasize = CALL_SIZE(info_call_t, 0); 243 int rval; 244 245 call.callop = LABELINFO; 246 247 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { 248 /* process error */ 249 250 return (-1); 251 } 252 *info = inforet.info; 253 return (rval); 254 } 255 #undef inforet 256 257 #define lvret callp->param.aret.rvals.vers_ret 258 /* 259 * labelvers - Get version string of the label encodings file. 260 * 261 * Entry version = Address of string pointer to return. 262 * len = Length of string if pre-allocated. 263 * 264 * Exit version = Updated. 265 * 266 * Returns -1, If unable to access label encodings file, or server failure. 267 * 0, If unable to allocate version string, 268 * or pre-allocated version string to short 269 * (and **version = '\0'). 270 * length (including null) of version string, If successful. 271 * 272 * Calls __call_labeld(LABELVERS) 273 * malloc, strlen. 274 */ 275 276 ssize_t 277 labelvers(char **version, size_t len) 278 { 279 labeld_data_t call; 280 labeld_data_t *callp = &call; 281 size_t bufsize = sizeof (labeld_data_t); 282 size_t datasize = CALL_SIZE(vers_call_t, 0); 283 size_t ver_len; 284 285 call.callop = LABELVERS; 286 287 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 288 289 if (callp != &call) 290 /* release return buffer */ 291 (void) munmap((void *)callp, bufsize); 292 return (-1); 293 } 294 295 /* unpack length */ 296 297 ver_len = strlen(lvret.vers) + 1; 298 if (*version == NULL) { 299 if ((*version = malloc(ver_len)) == NULL) { 300 if (callp != &call) 301 /* release return buffer */ 302 (void) munmap((void *)callp, bufsize); 303 return (0); 304 } 305 } else if (ver_len > len) { 306 **version = '\0'; 307 if (callp != &call) 308 /* release return buffer */ 309 (void) munmap((void *)callp, bufsize); 310 return (0); 311 } 312 (void) strcpy(*version, lvret.vers); 313 314 if (callp != &call) 315 /* release return buffer */ 316 (void) munmap((void *)callp, bufsize); 317 return (ver_len); 318 } /* labelvers */ 319 #undef lvret 320 321 #define ccall callp->param.acall.cargs.color_arg 322 #define cret callp->param.aret.rvals.color_ret 323 /* 324 * bltocolor - get ASCII color name of label. 325 * 326 * Entry label = Sensitivity Level of color to get. 327 * size = Size of the color_name array. 328 * color_name = Storage for ASCII color name string to be returned. 329 * 330 * Exit None. 331 * 332 * Returns NULL, If error (label encodings file not accessible, 333 * invalid label, no color for this label). 334 * Address of color_name parameter containing ASCII color name 335 * defined for the label. 336 * 337 * Calls __call_labeld(BLTOCOLOR), strlen. 338 */ 339 340 char * 341 bltocolor_r(const blevel_t *label, size_t size, char *color_name) 342 { 343 labeld_data_t call; 344 labeld_data_t *callp = &call; 345 size_t bufsize = sizeof (labeld_data_t); 346 size_t datasize = CALL_SIZE(color_call_t, 0); 347 char *colorp; 348 349 call.callop = BLTOCOLOR; 350 ccall.label = *label; 351 352 if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) || 353 (callp->reterr != 0) || 354 (strlen(cret.color) >= size)) { 355 356 if (callp != &call) 357 /* release return buffer */ 358 (void) munmap((void *)callp, bufsize); 359 return (NULL); 360 } 361 362 colorp = strcpy(color_name, cret.color); 363 364 if (callp != &call) 365 /* release return buffer */ 366 (void) munmap((void *)callp, bufsize); 367 return (colorp); 368 } /* bltocolor_r */ 369 #undef ccall 370 #undef cret 371 372 /* 373 * bltocolor - get ASCII color name of label. 374 * 375 * Entry label = Sensitivity Level of color to get. 376 * 377 * Exit None. 378 * 379 * Returns NULL, If error (label encodings file not accessible, 380 * invalid label, no color for this label). 381 * Address of statically allocated string containing ASCII 382 * color name defined for the classification contained 383 * in label. 384 * 385 * Uses color. 386 * 387 * Calls bltocolor_r. 388 */ 389 390 char * 391 bltocolor(const blevel_t *label) 392 { 393 return (bltocolor_r(label, sizeof (color), color)); 394 } /* bltocolor */ 395 396 blevel_t * 397 blabel_alloc(void) 398 { 399 return (m_label_alloc(MAC_LABEL)); 400 } 401 402 void 403 blabel_free(blevel_t *label_p) 404 { 405 free(label_p); 406 } 407 408 size32_t 409 blabel_size(void) 410 { 411 return (sizeof (blevel_t)); 412 } 413 414 /* 415 * getuserrange - get label range for user 416 * 417 * Entry username of user 418 * 419 * Exit None. 420 * 421 * Returns NULL, If memory allocation failure or userdefs failure. 422 * otherwise returns the allocates m_range_t with the 423 * user's min and max labels set. 424 */ 425 426 m_range_t * 427 getuserrange(const char *username) 428 { 429 char *kv_str = NULL; 430 userattr_t *userp = NULL; 431 m_range_t *range; 432 m_label_t *def_min, *def_clr; 433 434 /* 435 * Get some memory 436 */ 437 438 if ((range = malloc(sizeof (m_range_t))) == NULL) { 439 return (NULL); 440 } 441 if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) { 442 free(range); 443 return (NULL); 444 } 445 def_min = range->lower_bound; 446 if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) { 447 m_label_free(range->lower_bound); 448 free(range); 449 return (NULL); 450 } 451 def_clr = range->upper_bound; 452 453 /* If the user has an explicit min_label or clearance, use it. */ 454 if ((userp = getusernam(username)) != NULL) { 455 if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) 456 != NULL) { 457 (void) str_to_label(kv_str, &range->lower_bound, 458 MAC_LABEL, L_NO_CORRECTION, NULL); 459 def_min = NULL; /* don't get default later */ 460 } 461 if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE)) 462 != NULL) { 463 (void) str_to_label(kv_str, &range->upper_bound, 464 USER_CLEAR, L_NO_CORRECTION, NULL); 465 def_clr = NULL; /* don't get default later */ 466 } 467 free_userattr(userp); 468 } 469 if (def_min || def_clr) { 470 /* Need to use system default clearance and/or min_label */ 471 if ((userdefs(def_min, def_clr)) == -1) { 472 m_label_free(range->lower_bound); 473 m_label_free(range->upper_bound); 474 free(range); 475 return (NULL); 476 } 477 } 478 479 return (range); 480 } 481