| /* |
| * CDDL HEADER START |
| * |
| * The contents of this file are subject to the terms of the |
| * Common Development and Distribution License (the "License"). |
| * You may not use this file except in compliance with the License. |
| * |
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| * or http://www.opensolaris.org/os/licensing. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * |
| * When distributing Covered Code, include this CDDL HEADER in each |
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| * If applicable, add the following below this CDDL HEADER, with the |
| * fields enclosed by brackets "[]" replaced with your own identifying |
| * information: Portions Copyright [yyyy] [name of copyright owner] |
| * |
| * CDDL HEADER END |
| */ |
| /* |
| * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
| * Use is subject to license terms. |
| */ |
| |
| #pragma ident "%Z%%M% %I% %E% SMI" |
| |
| /* |
| * Label library contract private interfaces. |
| * |
| * Binary labels to String labels with dimming word lists. |
| * Dimming word list titles. |
| * Default user labels. |
| */ |
| |
| #include <locale.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <strings.h> |
| |
| #include <sys/mman.h> |
| |
| #include <tsol/label.h> |
| |
| #include "clnt.h" |
| #include "labeld.h" |
| |
| /* |
| * cvt memory: |
| * |
| * cvt: char *long_words[display_size]; Pointers to long words |
| * char *short_words[display_size]; Pointers to short words |
| * dim: char display[display_size]; Dim | Set |
| * |
| * strings associated with long and short words. |
| * |
| */ |
| |
| /* |
| * Sensitivity Label words. |
| */ |
| |
| static char *slcvt = NULL; |
| static int slcvtsize = 0; |
| static char *sldim; |
| |
| static char *slstring = NULL; |
| static int slstringsize = 0; |
| static brange_t sbounds; |
| |
| /* |
| * Clearance words. |
| */ |
| |
| static char *clrcvt = NULL; |
| static int clrcvtsize = 0; |
| static char *clrdim; |
| |
| static char *clrstring = NULL; |
| static int clrstringsize = 0; |
| static brange_t cbounds; |
| |
| static |
| int |
| alloc_words(char **words, const size_t size) |
| { |
| if (*words == NULL) { |
| if ((*words = malloc(size)) == NULL) |
| return (0); |
| } else { |
| if ((*words = realloc(*words, size)) == NULL) { |
| return (0); |
| } |
| } |
| return (1); |
| } |
| |
| /* |
| * build_strings - Build the static strings and dimming list for a |
| * converted label. |
| * |
| * Entry new_string = Newly converted string. |
| * new_words_size = Size of words associated with newly converted |
| * label. |
| * number_of_words = Number of words associated with newly |
| * converted label. |
| * full = 1, if static words lists to be updated. |
| * 0, if only string and dimming list to be updated. |
| * |
| * Exit static_string_size = Updated if needed. |
| * static_string = Updated to new label string. |
| * static_words_size = Updated if needed. |
| * static_words = Updated to new words list, if needed. |
| * static_dimming = Updated to new dimming state. |
| * long_words = Updated to new long words pointers, if needed. |
| * short_words = Updated to new short words pointers, if needed. |
| * |
| * |
| * Returns 0, If unable to allocate memory. |
| * 1, If successful. |
| * |
| * Calls alloc_string, alloc_words, memcpy, strcpy, strlen. |
| */ |
| |
| static |
| 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) |
| { |
| char **l; |
| char **s; |
| char *w; |
| char *l_w = long_words; |
| char *s_w = short_words; |
| int i; |
| int len; |
| int newsize; |
| |
| if (*static_string_size == 0) { /* Allocate string memory. */ |
| if ((*static_string_size = alloc_string(static_string, |
| *static_string_size, 'C')) == 0) |
| /* can't get string memory for string */ |
| return (0); |
| } |
| |
| again: |
| if (*static_string_size < (int)strlen(new_string)+1) { |
| /* need longer string */ |
| if ((newsize = alloc_string(static_string, *static_string_size, |
| 'C')) == 0) |
| /* can't get more string memory */ |
| return (0); |
| |
| *static_string_size += newsize; |
| goto again; |
| } |
| bcopy(new_string, *static_string, strlen(new_string) + 1); |
| |
| if (full) { |
| if (*static_words_size < new_words_size && |
| !alloc_words(static_words, new_words_size)) { |
| /* can't get more words memory */ |
| return (0); |
| } else { |
| *static_words_size = new_words_size; |
| } |
| /*LINTED*/ |
| l = (char **)*static_words; |
| s = l + number_of_words; |
| *static_dimming = (char *)(s + number_of_words); |
| w = *static_dimming + number_of_words; |
| for (i = 0; i < number_of_words; i++) { |
| *l = w; |
| (void) strcpy(w, l_w); |
| w += (len = strlen(l_w) + 1); |
| l_w += len; |
| if (*s_w == '\000') { |
| *s = NULL; |
| s_w++; |
| } else { |
| *s = w; |
| (void) strcpy(w, s_w); |
| w += (len = strlen(s_w) + 1); |
| s_w += len; |
| } |
| |
| l++; |
| s++; |
| } /* for each word entry */ |
| } /* if (full) */ |
| |
| bcopy(dimming_list, *static_dimming, number_of_words); |
| return (1); |
| } /* build_strings */ |
| |
| #define bsfcall callp->param.acall.cargs.bslcvt_arg |
| #define bsfret callp->param.aret.rvals.bslcvt_ret |
| /* |
| * bslcvtfull - Convert Sensitivity Label and initialize static |
| * information. |
| * |
| * Entry label = Sensitivity Label to convert and get dimming list. |
| * This label should lie within the bounds or the |
| * results may not be meaningful. |
| * bounds = Lower and upper bounds for words lists. Must be |
| * dominated by clearance. |
| * flags = VIEW_INTERNAL, don't promote/demote admin low/high. |
| * VIEW_EXTERNAL, promote/demote admin low/high. |
| * |
| * Exit string = ASCII coded Sensitivity Label. |
| * long_words = Array of pointers to visible long word names. |
| * short_words = Array of pointers to visible short word names. |
| * display = Array of indicators as to whether the word is present |
| * in the converted label (CVT_SET), and/or changeable |
| * (CVT_DIM). |
| * first_compartment = Zero based index of first compartment. |
| * display_size = Number of entries in the display/words lists. |
| * |
| * Returns -1, If unable to access label encodings database, or |
| * invalid label. |
| * 0, If unable to allocate static memory. |
| * 1, If successful. |
| * |
| * Calls RPC - LABELS_BSLCONVERT, STTBLEVEL, SETBSLABEL, TCLNT, |
| * build_strings, clnt_call, clnt_perror. |
| * |
| * Uses sbounds, slrcvt, slrcvtsize, slrdim, slrstring, |
| * slrstringsize. |
| */ |
| |
| 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) |
| { |
| labeld_data_t call; |
| labeld_data_t *callp = &call; |
| size_t bufsize = sizeof (labeld_data_t); |
| size_t datasize = CALL_SIZE(bslcvt_call_t, 0); |
| int new_words_size; |
| int rval; |
| |
| call.callop = BSLCVT; |
| bsfcall.label = *label; |
| bsfcall.bounds.upper_bound = *bounds->upper_bound; |
| bsfcall.bounds.lower_bound = *bounds->lower_bound; |
| bsfcall.flags = LABELS_FULL_CONVERT; |
| set_label_view(&bsfcall.flags, flags); |
| |
| if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { |
| #ifdef DEBUG |
| (void) fprintf(stderr, "No label server.\n"); |
| #endif /* DEBUG */ |
| return (-1); |
| } else if (rval != SUCCESS) { |
| return (-1); |
| } else { |
| if (callp->reterr != 0) |
| return (-1); |
| } |
| |
| *first_compartment = bsfret.first_comp; |
| *display_size = bsfret.d_len; |
| |
| new_words_size = bsfret.l_len + bsfret.s_len + bsfret.d_len + |
| (2 * sizeof (char *)) * bsfret.d_len; |
| |
| if (build_strings(&slstringsize, &slstring, &bsfret.buf[bsfret.string], |
| &slcvtsize, new_words_size, &slcvt, &sldim, bsfret.d_len, |
| &bsfret.buf[bsfret.lwords], &bsfret.buf[bsfret.swords], |
| &bsfret.buf[bsfret.dim], 1) != 1) { |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| |
| /* save for bslcvt call */ |
| sbounds.upper_bound = *bounds->upper_bound; |
| sbounds.lower_bound = *bounds->lower_bound; |
| |
| *string = slstring; |
| *display = sldim; |
| /*LINTED*/ |
| *long_words = (char **)slcvt; |
| /*LINTED*/ |
| *short_words = (char **)(slcvt + *display_size * sizeof (char *)); |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (1); |
| } /* bslcvtfull */ |
| #undef bsfcall |
| #undef bsfret |
| |
| #define bsccall callp->param.acall.cargs.bslcvt_arg |
| #define bscret callp->param.aret.rvals.bslcvt_ret |
| /* |
| * bslcvt - Convert Sensitivity Label and update dimming information. |
| * |
| * Entry label = Sensitivity Label to convert and get dimming list. |
| * This label should lie within the bounds of the |
| * corresponding bslcvtfull call or the results may |
| * not be meaningful. |
| * flags = VIEW_INTERNAL, don't promote/demote admin low/high. |
| * VIEW_EXTERNAL, promote/demote admin low/high. |
| * |
| * Exit string = ASCII coded Sensitivity Label. |
| * display = Array of indicators as to whether the word is present |
| * in the converted label (CVT_SET), and/or changeable |
| * (CVT_DIM). |
| * |
| * Returns -1, If unable to access label encodings database, or |
| * invalid label. |
| * 0, If unable to allocate static memory. |
| * 1, If successful. |
| * |
| * Calls RPC - LABELS_BSLCONVERT, SETBLEVEL, SETBSLABEL, build_strings |
| * clnt_call, clnt_perror. |
| * |
| * Uses sbounds, slrdim, slrstring. |
| */ |
| |
| int |
| bslcvt(const bslabel_t *label, int flags, char **string, char *display[]) |
| { |
| labeld_data_t call; |
| labeld_data_t *callp = &call; |
| size_t bufsize = sizeof (labeld_data_t); |
| size_t datasize = CALL_SIZE(bslcvt_call_t, 0); |
| int rval; |
| |
| if (slcvt == NULL) |
| return (-1); /* conversion not initialized */ |
| |
| call.callop = BSLCVT; |
| bsccall.label = *label; |
| bsccall.bounds = sbounds; /* save from last bslcvtfull() call */ |
| bsccall.flags = 0; |
| set_label_view(&bsccall.flags, flags); |
| |
| if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { |
| #ifdef DEBUG |
| (void) fprintf(stderr, "No label server.\n"); |
| #endif /* DEBUG */ |
| return (-1); |
| } else if (rval != SUCCESS) { |
| return (-1); |
| } else { |
| if (callp->reterr != 0) |
| return (-1); |
| } |
| |
| if (build_strings(&slstringsize, &slstring, &bscret.buf[bscret.string], |
| &slcvtsize, 0, &slcvt, &sldim, bscret.d_len, |
| &bscret.buf[bscret.lwords], &bscret.buf[bscret.swords], |
| &bscret.buf[bscret.dim], 0) != 1) { |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| |
| *string = slstring; |
| *display = sldim; |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (1); |
| } /* bslcvt */ |
| #undef bsccall |
| #undef bscret |
| |
| #define bcfcall callp->param.acall.cargs.bclearcvt_arg |
| #define bcfret callp->param.aret.rvals.bclearcvt_ret |
| /* |
| * bclearcvtfull - Convert Clearance and initialize static information. |
| * |
| * Entry clearance = Clearance to convert and get dimming list. |
| * This clearance should lie within the bounds or |
| * the results may not be meaningful. |
| * bounds = Lower and upper bounds for words lists. Must be |
| * dominated by clearance. |
| * flags = VIEW_INTERNAL, don't promote/demote admin low/high. |
| * VIEW_EXTERNAL, promote/demote admin low/high. |
| * |
| * Exit string = ASCII coded Clearance. |
| * long_words = Array of pointers to visible long word names. |
| * short_words = Array of pointers to visible short word names. |
| * display = Array of indicators as to whether the word is present |
| * in the converted label (CVT_SET), and/or changeable |
| * (CVT_DIM). |
| * first_compartment = Zero based index of first compartment. |
| * display_size = Number of entries in the display/words lists. |
| * |
| * Returns -1, If unable to access label encodings database, or |
| * invalid label. |
| * 0, If unable to allocate static memory. |
| * 1, If successful. |
| * |
| * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, TCLNT, |
| * build_strings, clnt_call, clnt_perror. |
| * |
| * Uses cbounds, clrcvt, clrcvtsize, clrdim, clrstring, |
| * clrstringsize. |
| */ |
| |
| 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) |
| { |
| labeld_data_t call; |
| labeld_data_t *callp = &call; |
| size_t bufsize = sizeof (labeld_data_t); |
| size_t datasize = CALL_SIZE(bclearcvt_call_t, 0); |
| int new_words_size; |
| int rval; |
| |
| call.callop = BCLEARCVT; |
| bcfcall.clear = *clearance; |
| bcfcall.bounds.upper_bound = *bounds->upper_bound; |
| bcfcall.bounds.lower_bound = *bounds->lower_bound; |
| bcfcall.flags = LABELS_FULL_CONVERT; |
| set_label_view(&bcfcall.flags, flags); |
| |
| if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { |
| #ifdef DEBUG |
| (void) fprintf(stderr, "No label server.\n"); |
| #endif /* DEBUG */ |
| return (-1); |
| } else if (rval != SUCCESS) { |
| return (-1); |
| } else { |
| if (callp->reterr != 0) |
| return (-1); |
| } |
| |
| *first_compartment = bcfret.first_comp; |
| *display_size = bcfret.d_len; |
| |
| new_words_size = bcfret.l_len + bcfret.s_len + bcfret.d_len + |
| (2 * sizeof (char *)) * bcfret.d_len; |
| |
| if (build_strings(&clrstringsize, &clrstring, |
| &bcfret.buf[bcfret.string], |
| &clrcvtsize, new_words_size, &clrcvt, |
| &clrdim, bcfret.d_len, |
| &bcfret.buf[bcfret.lwords], &bcfret.buf[bcfret.swords], |
| &bcfret.buf[bcfret.dim], 1) != 1) { |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| |
| /* save for bclearcvt call */ |
| cbounds.upper_bound = *bounds->upper_bound; |
| cbounds.lower_bound = *bounds->lower_bound; |
| |
| *string = clrstring; |
| *display = clrdim; |
| /*LINTED*/ |
| *long_words = (char **)clrcvt; |
| /*LINTED*/ |
| *short_words = (char **)(clrcvt + *display_size * sizeof (char *)); |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (1); |
| } /* bclearcvtfull */ |
| #undef bcfcall |
| #undef bcfret |
| |
| #define bcccall callp->param.acall.cargs.bclearcvt_arg |
| #define bccret callp->param.aret.rvals.bclearcvt_ret |
| /* |
| * bclearcvt - Convert Clearance and update dimming inforamtion. |
| * |
| * Entry clearance = Clearance to convert and get dimming list. |
| * This clearance should lie within the bounds of the |
| * corresponding bclearcvtfull call or the results may |
| * not be meaningful. |
| * flags = VIEW_INTERNAL, don't promote/demote admin low/high. |
| * VIEW_EXTERNAL, promote/demote admin low/high. |
| * |
| * Exit string = ASCII coded Clearance. |
| * display = Array of indicators as to whether the word is present |
| * in the converted label (CVT_SET), and/or changeable |
| * (CVT_DIM). |
| * |
| * Returns -1, If unable to access label encodings database, or |
| * invalid label. |
| * 0, If unable to allocate static memory. |
| * 1, If successful. |
| * |
| * Calls RPC - LABELS_BCLEARCONVERT, SETBCLEAR, SETBLEVEL, build_strings, |
| * clnt_call, clnt_perror. |
| * |
| * Uses cbounds, clrdim, clrstring. |
| */ |
| |
| int |
| bclearcvt(const bclear_t *clearance, int flags, char **string, |
| char *display[]) |
| { |
| labeld_data_t call; |
| labeld_data_t *callp = &call; |
| size_t bufsize = sizeof (labeld_data_t); |
| size_t datasize = CALL_SIZE(bclearcvt_call_t, 0); |
| int rval; |
| |
| if (clrcvt == NULL) |
| return (-1); /* conversion not initialized */ |
| |
| call.callop = BCLEARCVT; |
| bcccall.clear = *clearance; |
| bcccall.bounds = cbounds; /* save from last bslcvtfull() call */ |
| bcccall.flags = 0; |
| set_label_view(&bcccall.flags, flags); |
| |
| if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == NOSERVER) { |
| #ifdef DEBUG |
| (void) fprintf(stderr, "No label server.\n"); |
| #endif /* DEBUG */ |
| return (-1); |
| } else if (rval != SUCCESS) { |
| return (-1); |
| } else { |
| if (callp->reterr != 0) |
| return (-1); |
| } |
| |
| if (build_strings(&clrstringsize, &clrstring, |
| &bccret.buf[bccret.string], |
| &clrcvtsize, 0, &clrcvt, &clrdim, bccret.d_len, |
| &bccret.buf[bccret.lwords], &bccret.buf[bccret.swords], |
| &bccret.buf[bccret.dim], 0) != 1) { |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| |
| *string = clrstring; |
| *display = clrdim; |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (1); |
| } /* bclearcvt */ |
| #undef bcccall |
| #undef bccret |
| |
| #define lfret callp->param.aret.rvals.fields_ret |
| /* |
| * labelfields - Return names for the label fields. |
| * |
| * Entry None |
| * |
| * Exit fields = Updated. |
| * |
| * Returns -1, If unable to access label encodings file, or |
| * labels server failure. |
| * 0, If unable to allocate memory. |
| * 1, If successful. |
| * |
| * Calls __call_labeld(LABELFIELDS). |
| */ |
| |
| int |
| labelfields(struct name_fields *fields) |
| { |
| labeld_data_t call; |
| labeld_data_t *callp = &call; |
| size_t bufsize = sizeof (labeld_data_t); |
| size_t datasize = CALL_SIZE(fields_call_t, 0); |
| int rval; |
| |
| call.callop = LABELFIELDS; |
| |
| if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { |
| |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (-1); |
| } |
| |
| /* unpack results */ |
| |
| if ((fields->class_name = strdup(&lfret.buf[lfret.classi])) == NULL) { |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| if ((fields->comps_name = strdup(&lfret.buf[lfret.compsi])) == NULL) { |
| free(fields->class_name); |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| if ((fields->marks_name = strdup(&lfret.buf[lfret.marksi])) == NULL) { |
| free(fields->class_name); |
| free(fields->comps_name); |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (0); |
| } |
| |
| if (callp != &call) |
| /* release return buffer */ |
| (void) munmap((void *)callp, bufsize); |
| return (rval); |
| } /* labelfields */ |
| #undef lfret |
| |
| #define udret callp->param.aret.rvals.udefs_ret |
| /* |
| * userdefs - Get default user Sensitivity Label and Clearance. |
| * |
| * Entry None. |
| * |
| * Exit sl = default user Sensitivity Label. |
| * clear = default user Clearance. |
| * |
| * Returns -1, If unable to access label encodings file, or |
| * labels server failure. |
| * 1, If successful. |
| * |
| * Calls __call_labeld(UDEFS). |
| */ |
| |
| int |
| userdefs(bslabel_t *sl, bclear_t *clear) |
| { |
| labeld_data_t call; |
| labeld_data_t *callp = &call; |
| size_t bufsize = sizeof (labeld_data_t); |
| size_t datasize = CALL_SIZE(udefs_call_t, 0); |
| int rval; |
| |
| call.callop = UDEFS; |
| |
| if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { |
| /* process error */ |
| |
| return (-1); |
| } |
| |
| *sl = udret.sl; |
| *clear = udret.clear; |
| return (rval); |
| } /* userdefs */ |
| #undef udret |