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
alloc_words(char ** words,const size_t size)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
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)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
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)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
bslcvt(const bslabel_t * label,int flags,char ** string,char * display[])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
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)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
bclearcvt(const bclear_t * clearance,int flags,char ** string,char * display[])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
labelfields(struct name_fields * fields)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
userdefs(bslabel_t * sl,bclear_t * clear)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