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