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
alloc_words(char ** words,const size_t size)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
build_strings(int * static_string_size,char ** static_string,char * new_string,int * static_words_size,int new_words_size,char ** static_words,char ** static_dimming,int number_of_words,char * long_words,char * short_words,char * dimming_list,int full)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
bslcvtfull(const bslabel_t * label,const blrange_t * bounds,int flags,char ** string,char ** long_words[],char ** short_words[],char * display[],int * first_compartment,int * display_size)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
bslcvt(const bslabel_t * label,int flags,char ** string,char * display[])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
bclearcvtfull(const bclear_t * clearance,const blrange_t * bounds,int flags,char ** string,char ** long_words[],char ** short_words[],char * display[],int * first_compartment,int * display_size)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
bclearcvt(const bclear_t * clearance,int flags,char ** string,char * display[])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
labelfields(struct name_fields * fields)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
userdefs(bslabel_t * sl,bclear_t * clear)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