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