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 * Label library contract private interfaces. 30 * 31 * Binary labels to String labels with dimming word lists. 32 * Dimming word list titles. 33 * Default user labels. 34 */ 35 36 #include <locale.h> 37 #include <stdlib.h> 38 #include <stdio.h> 39 #include <strings.h> 40 41 #include <sys/mman.h> 42 43 #include <tsol/label.h> 44 45 #include "clnt.h" 46 #include "labeld.h" 47 48 /* 49 * cvt memory: 50 * 51 * cvt: char *long_words[display_size]; Pointers to long words 52 * char *short_words[display_size]; Pointers to short words 53 * dim: char display[display_size]; Dim | Set 54 * 55 * strings associated with long and short words. 56 * 57 */ 58 59 /* 60 * Sensitivity Label words. 61 */ 62 63 static char *slcvt = NULL; 64 static int slcvtsize = 0; 65 static char *sldim; 66 67 static char *slstring = NULL; 68 static int slstringsize = 0; 69 static brange_t sbounds; 70 71 /* 72 * Clearance words. 73 */ 74 75 static char *clrcvt = NULL; 76 static int clrcvtsize = 0; 77 static char *clrdim; 78 79 static char *clrstring = NULL; 80 static int clrstringsize = 0; 81 static brange_t cbounds; 82 83 static 84 int 85 alloc_words(char **words, const size_t size) 86 { 87 if (*words == NULL) { 88 if ((*words = malloc(size)) == NULL) 89 return (0); 90 } else { 91 if ((*words = realloc(*words, size)) == NULL) { 92 return (0); 93 } 94 } 95 return (1); 96 } 97 98 /* 99 * build_strings - Build the static strings and dimming list for a 100 * converted label. 101 * 102 * Entry new_string = Newly converted string. 103 * new_words_size = Size of words associated with newly converted 104 * label. 105 * number_of_words = Number of words associated with newly 106 * converted label. 107 * full = 1, if static words lists to be updated. 108 * 0, if only string and dimming list to be updated. 109 * 110 * Exit static_string_size = Updated if needed. 111 * static_string = Updated to new label string. 112 * static_words_size = Updated if needed. 113 * static_words = Updated to new words list, if needed. 114 * static_dimming = Updated to new dimming state. 115 * long_words = Updated to new long words pointers, if needed. 116 * short_words = Updated to new short words pointers, if needed. 117 * 118 * 119 * Returns 0, If unable to allocate memory. 120 * 1, If successful. 121 * 122 * Calls alloc_string, alloc_words, memcpy, strcpy, strlen. 123 */ 124 125 static 126 int 127 build_strings(int *static_string_size, char **static_string, char *new_string, 128 int *static_words_size, int new_words_size, char **static_words, 129 char **static_dimming, int number_of_words, char *long_words, 130 char *short_words, char *dimming_list, int full) 131 { 132 char **l; 133 char **s; 134 char *w; 135 char *l_w = long_words; 136 char *s_w = short_words; 137 int i; 138 int len; 139 int newsize; 140 141 if (*static_string_size == 0) { /* Allocate string memory. */ 142 if ((*static_string_size = alloc_string(static_string, 143 *static_string_size, 'C')) == 0) 144 /* can't get string memory for string */ 145 return (0); 146 } 147 148 again: 149 if (*static_string_size < (int)strlen(new_string)+1) { 150 /* need longer string */ 151 if ((newsize = alloc_string(static_string, *static_string_size, 152 'C')) == 0) 153 /* can't get more string memory */ 154 return (0); 155 156 *static_string_size += newsize; 157 goto again; 158 } 159 bcopy(new_string, *static_string, strlen(new_string) + 1); 160 161 if (full) { 162 if (*static_words_size < new_words_size && 163 !alloc_words(static_words, new_words_size)) { 164 /* can't get more words memory */ 165 return (0); 166 } else { 167 *static_words_size = new_words_size; 168 } 169 /*LINTED*/ 170 l = (char **)*static_words; 171 s = l + number_of_words; 172 *static_dimming = (char *)(s + number_of_words); 173 w = *static_dimming + number_of_words; 174 for (i = 0; i < number_of_words; i++) { 175 *l = w; 176 (void) strcpy(w, l_w); 177 w += (len = strlen(l_w) + 1); 178 l_w += len; 179 if (*s_w == '\000') { 180 *s = NULL; 181 s_w++; 182 } else { 183 *s = w; 184 (void) strcpy(w, s_w); 185 w += (len = strlen(s_w) + 1); 186 s_w += len; 187 } 188 189 l++; 190 s++; 191 } /* for each word entry */ 192 } /* if (full) */ 193 194 bcopy(dimming_list, *static_dimming, number_of_words); 195 return (1); 196 } /* build_strings */ 197 198 #define bsfcall callp->param.acall.cargs.bslcvt_arg 199 #define bsfret callp->param.aret.rvals.bslcvt_ret 200 /* 201 * bslcvtfull - Convert Sensitivity Label and initialize static 202 * information. 203 * 204 * Entry label = Sensitivity Label to convert and get dimming list. 205 * This label should lie within the bounds or the 206 * results may not be meaningful. 207 * bounds = Lower and upper bounds for words lists. Must be 208 * dominated by clearance. 209 * flags = VIEW_INTERNAL, don't promote/demote admin low/high. 210 * VIEW_EXTERNAL, promote/demote admin low/high. 211 * 212 * Exit string = ASCII coded Sensitivity Label. 213 * long_words = Array of pointers to visible long word names. 214 * short_words = Array of pointers to visible short word names. 215 * display = Array of indicators as to whether the word is present 216 * in the converted label (CVT_SET), and/or changeable 217 * (CVT_DIM). 218 * first_compartment = Zero based index of first compartment. 219 * display_size = Number of entries in the display/words lists. 220 * 221 * Returns -1, If unable to access label encodings database, or 222 * invalid label. 223 * 0, If unable to allocate static memory. 224 * 1, If successful. 225 * 226 * Calls RPC - LABELS_BSLCONVERT, STTBLEVEL, SETBSLABEL, TCLNT, 227 * build_strings, clnt_call, clnt_perror. 228 * 229 * Uses sbounds, slrcvt, slrcvtsize, slrdim, slrstring, 230 * slrstringsize. 231 */ 232 233 int 234 bslcvtfull(const bslabel_t *label, const blrange_t *bounds, int flags, 235 char **string, char **long_words[], char **short_words[], char *display[], 236 int *first_compartment, int *display_size) 237 { 238 labeld_data_t call; 239 labeld_data_t *callp = &call; 240 size_t bufsize = sizeof (labeld_data_t); 241 size_t datasize = CALL_SIZE(bslcvt_call_t, 0); 242 int new_words_size; 243 int rval; 244 245 call.callop = BSLCVT; 246 bsfcall.label = *label; 247 bsfcall.bounds.upper_bound = *bounds->upper_bound; 248 bsfcall.bounds.lower_bound = *bounds->lower_bound; 249 bsfcall.flags = LABELS_FULL_CONVERT; 250 set_label_view(&bsfcall.flags, flags); 251 252 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { 253 #ifdef DEBUG 254 (void) fprintf(stderr, "No label server.\n"); 255 #endif /* DEBUG */ 256 return (-1); 257 } else if (rval != SUCCESS) { 258 return (-1); 259 } else { 260 if (callp->reterr != 0) 261 return (-1); 262 } 263 264 *first_compartment = bsfret.first_comp; 265 *display_size = bsfret.d_len; 266 267 new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len + 268 (2 * sizeof (char *)) * bsfret.d_len; 269 270 if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string], 271 &slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len, 272 &bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords], 273 &bsfret.buf[bsfret.dim], 1) != 1) { 274 if (callp != &call) 275 /* release return buffer */ 276 (void) munmap((void *)callp, bufsize); 277 return (0); 278 } 279 280 /* save for bslcvt call */ 281 sbounds.upper_bound = *bounds->upper_bound; 282 sbounds.lower_bound = *bounds->lower_bound; 283 284 *string = slstring; 285 *display = sldim; 286 /*LINTED*/ 287 *long_words = (char **)slcvt; 288 /*LINTED*/ 289 *short_words = (char **)(slcvt + *display_size * sizeof (char *)); 290 if (callp != &call) 291 /* release return buffer */ 292 (void) munmap((void *)callp, bufsize); 293 return (1); 294 } /* bslcvtfull */ 295 #undef bsfcall 296 #undef bsfret 297 298 #define bsccall callp->param.acall.cargs.bslcvt_arg 299 #define bscret callp->param.aret.rvals.bslcvt_ret 300 /* 301 * bslcvt - Convert Sensitivity Label and update dimming information. 302 * 303 * Entry label = Sensitivity Label to convert and get dimming list. 304 * This label should lie within the bounds of the 305 * corresponding bslcvtfull call or the results may 306 * not be meaningful. 307 * flags = VIEW_INTERNAL, don't promote/demote admin low/high. 308 * VIEW_EXTERNAL, promote/demote admin low/high. 309 * 310 * Exit string = ASCII coded Sensitivity Label. 311 * display = Array of indicators as to whether the word is present 312 * in the converted label (CVT_SET), and/or changeable 313 * (CVT_DIM). 314 * 315 * Returns -1, If unable to access label encodings database, or 316 * invalid label. 317 * 0, If unable to allocate static memory. 318 * 1, If successful. 319 * 320 * Calls RPC - LABELS_BSLCONVERT, SETBLEVEL, SETBSLABEL, build_strings 321 * clnt_call, clnt_perror. 322 * 323 * Uses sbounds, slrdim, slrstring. 324 */ 325 326 int 327 bslcvt(const bslabel_t *label, int flags, char **string, char *display[]) 328 { 329 labeld_data_t call; 330 labeld_data_t *callp = &call; 331 size_t bufsize = sizeof (labeld_data_t); 332 size_t datasize = CALL_SIZE(bslcvt_call_t, 0); 333 int rval; 334 335 if (slcvt == NULL) 336 return (-1); /* conversion not initialized */ 337 338 call.callop = BSLCVT; 339 bsccall.label = *label; 340 bsccall.bounds = sbounds; /* save from last bslcvtfull() call */ 341 bsccall.flags = 0; 342 set_label_view(&bsccall.flags, flags); 343 344 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { 345 #ifdef DEBUG 346 (void) fprintf(stderr, "No label server.\n"); 347 #endif /* DEBUG */ 348 return (-1); 349 } else if (rval != SUCCESS) { 350 return (-1); 351 } else { 352 if (callp->reterr != 0) 353 return (-1); 354 } 355 356 if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string], 357 &slcvtsize, 0, &slcvt, &sldim, bscret.d_len, 358 &bscret.buf[bscret.lwords], &bscret.buf[bscret.swords], 359 &bscret.buf[bscret.dim], 0) != 1) { 360 if (callp != &call) 361 /* release return buffer */ 362 (void) munmap((void *)callp, bufsize); 363 return (0); 364 } 365 366 *string = slstring; 367 *display = sldim; 368 if (callp != &call) 369 /* release return buffer */ 370 (void) munmap((void *)callp, bufsize); 371 return (1); 372 } /* bslcvt */ 373 #undef bsccall 374 #undef bscret 375 376 #define bcfcall callp->param.acall.cargs.bclearcvt_arg 377 #define bcfret callp->param.aret.rvals.bclearcvt_ret 378 /* 379 * bclearcvtfull - Convert Clearance and initialize static information. 380 * 381 * Entry clearance = Clearance to convert and get dimming list. 382 * This clearance should lie within the bounds or 383 * the results may not be meaningful. 384 * bounds = Lower and upper bounds for words lists. Must be 385 * dominated by clearance. 386 * flags = VIEW_INTERNAL, don't promote/demote admin low/high. 387 * VIEW_EXTERNAL, promote/demote admin low/high. 388 * 389 * Exit string = ASCII coded Clearance. 390 * long_words = Array of pointers to visible long word names. 391 * short_words = Array of pointers to visible short word names. 392 * display = Array of indicators as to whether the word is present 393 * in the converted label (CVT_SET), and/or changeable 394 * (CVT_DIM). 395 * first_compartment = Zero based index of first compartment. 396 * display_size = Number of entries in the display/words lists. 397 * 398 * Returns -1, If unable to access label encodings database, or 399 * invalid label. 400 * 0, If unable to allocate static memory. 401 * 1, If successful. 402 * 403 * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, TCLNT, 404 * build_strings, clnt_call, clnt_perror. 405 * 406 * Uses cbounds, clrcvt, clrcvtsize, clrdim, clrstring, 407 * clrstringsize. 408 */ 409 410 int 411 bclearcvtfull(const bclear_t *clearance, const blrange_t *bounds, 412 int flags, char **string, char **long_words[], char **short_words[], 413 char *display[], int *first_compartment, int *display_size) 414 { 415 labeld_data_t call; 416 labeld_data_t *callp = &call; 417 size_t bufsize = sizeof (labeld_data_t); 418 size_t datasize = CALL_SIZE(bclearcvt_call_t, 0); 419 int new_words_size; 420 int rval; 421 422 call.callop = BCLEARCVT; 423 bcfcall.clear = *clearance; 424 bcfcall.bounds.upper_bound = *bounds->upper_bound; 425 bcfcall.bounds.lower_bound = *bounds->lower_bound; 426 bcfcall.flags = LABELS_FULL_CONVERT; 427 set_label_view(&bcfcall.flags, flags); 428 429 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { 430 #ifdef DEBUG 431 (void) fprintf(stderr, "No label server.\n"); 432 #endif /* DEBUG */ 433 return (-1); 434 } else if (rval != SUCCESS) { 435 return (-1); 436 } else { 437 if (callp->reterr != 0) 438 return (-1); 439 } 440 441 *first_compartment = bcfret.first_comp; 442 *display_size = bcfret.d_len; 443 444 new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len + 445 (2 * sizeof (char *)) * bcfret.d_len; 446 447 if (build_strings(&clrstringsize, &clrstring, 448 &bcfret.buf[bcfret.string], 449 &clrcvtsize, new_words_size, &clrcvt, 450 &clrdim, bcfret.d_len, 451 &bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords], 452 &bcfret.buf[bcfret.dim], 1) != 1) { 453 if (callp != &call) 454 /* release return buffer */ 455 (void) munmap((void *)callp, bufsize); 456 return (0); 457 } 458 459 /* save for bclearcvt call */ 460 cbounds.upper_bound = *bounds->upper_bound; 461 cbounds.lower_bound = *bounds->lower_bound; 462 463 *string = clrstring; 464 *display = clrdim; 465 /*LINTED*/ 466 *long_words = (char **)clrcvt; 467 /*LINTED*/ 468 *short_words = (char **)(clrcvt + *display_size * sizeof (char *)); 469 if (callp != &call) 470 /* release return buffer */ 471 (void) munmap((void *)callp, bufsize); 472 return (1); 473 } /* bclearcvtfull */ 474 #undef bcfcall 475 #undef bcfret 476 477 #define bcccall callp->param.acall.cargs.bclearcvt_arg 478 #define bccret callp->param.aret.rvals.bclearcvt_ret 479 /* 480 * bclearcvt - Convert Clearance and update dimming inforamtion. 481 * 482 * Entry clearance = Clearance to convert and get dimming list. 483 * This clearance should lie within the bounds of the 484 * corresponding bclearcvtfull call or the results may 485 * not be meaningful. 486 * flags = VIEW_INTERNAL, don't promote/demote admin low/high. 487 * VIEW_EXTERNAL, promote/demote admin low/high. 488 * 489 * Exit string = ASCII coded Clearance. 490 * display = Array of indicators as to whether the word is present 491 * in the converted label (CVT_SET), and/or changeable 492 * (CVT_DIM). 493 * 494 * Returns -1, If unable to access label encodings database, or 495 * invalid label. 496 * 0, If unable to allocate static memory. 497 * 1, If successful. 498 * 499 * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, build_strings, 500 * clnt_call, clnt_perror. 501 * 502 * Uses cbounds, clrdim, clrstring. 503 */ 504 505 int 506 bclearcvt(const bclear_t *clearance, int flags, char **string, 507 char *display[]) 508 { 509 labeld_data_t call; 510 labeld_data_t *callp = &call; 511 size_t bufsize = sizeof (labeld_data_t); 512 size_t datasize = CALL_SIZE(bclearcvt_call_t, 0); 513 int rval; 514 515 if (clrcvt == NULL) 516 return (-1); /* conversion not initialized */ 517 518 call.callop = BCLEARCVT; 519 bcccall.clear = *clearance; 520 bcccall.bounds = cbounds; /* save from last bslcvtfull() call */ 521 bcccall.flags = 0; 522 set_label_view(&bcccall.flags, flags); 523 524 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { 525 #ifdef DEBUG 526 (void) fprintf(stderr, "No label server.\n"); 527 #endif /* DEBUG */ 528 return (-1); 529 } else if (rval != SUCCESS) { 530 return (-1); 531 } else { 532 if (callp->reterr != 0) 533 return (-1); 534 } 535 536 if (build_strings(&clrstringsize, &clrstring, 537 &bccret.buf[bccret.string], 538 &clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len, 539 &bccret.buf[bccret.lwords], &bccret.buf[bccret.swords], 540 &bccret.buf[bccret.dim], 0) != 1) { 541 if (callp != &call) 542 /* release return buffer */ 543 (void) munmap((void *)callp, bufsize); 544 return (0); 545 } 546 547 *string = clrstring; 548 *display = clrdim; 549 if (callp != &call) 550 /* release return buffer */ 551 (void) munmap((void *)callp, bufsize); 552 return (1); 553 } /* bclearcvt */ 554 #undef bcccall 555 #undef bccret 556 557 #define lfret callp->param.aret.rvals.fields_ret 558 /* 559 * labelfields - Return names for the label fields. 560 * 561 * Entry None 562 * 563 * Exit fields = Updated. 564 * 565 * Returns -1, If unable to access label encodings file, or 566 * labels server failure. 567 * 0, If unable to allocate memory. 568 * 1, If successful. 569 * 570 * Calls __call_labeld(LABELFIELDS). 571 */ 572 573 int 574 labelfields(struct name_fields *fields) 575 { 576 labeld_data_t call; 577 labeld_data_t *callp = &call; 578 size_t bufsize = sizeof (labeld_data_t); 579 size_t datasize = CALL_SIZE(fields_call_t, 0); 580 int rval; 581 582 call.callop = LABELFIELDS; 583 584 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { 585 586 if (callp != &call) 587 /* release return buffer */ 588 (void) munmap((void *)callp, bufsize); 589 return (-1); 590 } 591 592 /* unpack results */ 593 594 if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) { 595 if (callp != &call) 596 /* release return buffer */ 597 (void) munmap((void *)callp, bufsize); 598 return (0); 599 } 600 if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) { 601 free(fields->class_name); 602 if (callp != &call) 603 /* release return buffer */ 604 (void) munmap((void *)callp, bufsize); 605 return (0); 606 } 607 if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) { 608 free(fields->class_name); 609 free(fields->comps_name); 610 if (callp != &call) 611 /* release return buffer */ 612 (void) munmap((void *)callp, bufsize); 613 return (0); 614 } 615 616 if (callp != &call) 617 /* release return buffer */ 618 (void) munmap((void *)callp, bufsize); 619 return (rval); 620 } /* labelfields */ 621 #undef lfret 622 623 #define udret callp->param.aret.rvals.udefs_ret 624 /* 625 * userdefs - Get default user Sensitivity Label and/or Clearance. 626 * 627 * Entry None. 628 * 629 * Exit sl = default user Sensitivity Label. 630 * clear = default user Clearance. 631 * 632 * Returns -1, If unable to access label encodings file, or 633 * labels server failure. 634 * 1, If successful. 635 * 636 * Calls __call_labeld(UDEFS). 637 */ 638 639 int 640 userdefs(bslabel_t *sl, bclear_t *clear) 641 { 642 labeld_data_t call; 643 labeld_data_t *callp = &call; 644 size_t bufsize = sizeof (labeld_data_t); 645 size_t datasize = CALL_SIZE(udefs_call_t, 0); 646 int rval; 647 648 call.callop = UDEFS; 649 650 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { 651 /* process error */ 652 653 return (-1); 654 } 655 656 if (sl != NULL) 657 *sl = udret.sl; 658 if (clear != NULL) 659 *clear = udret.clear; 660 return (rval); 661 } /* userdefs */ 662 #undef udret 663