2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * Binary label to label string translations.
2N/A */
2N/A
2N/A#include <locale.h>
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <strings.h>
2N/A#include <wchar.h>
2N/A
2N/A#include <sys/mman.h>
2N/A
2N/A#include <tsol/label.h>
2N/A
2N/A#include "clnt.h"
2N/A#include "labeld.h"
2N/A#include <sys/tsol/label_macro.h>
2N/A
2N/A#if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */
2N/A#define TEXT_DOMAIN "SYS_TEST"
2N/A#endif /* TEXT_DOMAIN */
2N/A
2N/Astatic bslabel_t slow; /* static admin_low high sensitivity label */
2N/Astatic bslabel_t shigh; /* static admin_high sensitivity label */
2N/Astatic bclear_t clrlow, clrhigh; /* static admin_low and admin_high Clearance */
2N/A
2N/Astatic char *sstring; /* return string for sb*tos */
2N/Astatic size_t ssize; /* current size of return string */
2N/A
2N/Astatic int
2N/Areturn_string(char **string, int str_len, char *val)
2N/A{
2N/A char *cpyptr;
2N/A size_t val_len = strlen(val) + 1;
2N/A
2N/A if (*string == NULL) {
2N/A if ((*string = malloc(val_len)) == NULL)
2N/A return (0);
2N/A } else if (val_len > str_len) {
2N/A **string = '\0';
2N/A return (0);
2N/A }
2N/A
2N/A cpyptr = *string;
2N/A bcopy(val, cpyptr, val_len);
2N/A
2N/A return (val_len);
2N/A}
2N/A
2N/Avoid
2N/Aset_label_view(uint_t *callflags, uint_t flags)
2N/A{
2N/A if (flags&VIEW_INTERNAL) {
2N/A *callflags |= LABELS_VIEW_INTERNAL;
2N/A } else if (flags&VIEW_EXTERNAL) {
2N/A *callflags |= LABELS_VIEW_EXTERNAL;
2N/A }
2N/A}
2N/A
2N/Aint
2N/Aalloc_string(char **string, size_t size, char val)
2N/A{
2N/A if (*string == NULL) {
2N/A if ((*string = malloc(ALLOC_CHUNK)) == NULL)
2N/A return (0);
2N/A } else {
2N/A if ((*string = realloc(*string, size + ALLOC_CHUNK)) == NULL) {
2N/A **string = val;
2N/A return (0);
2N/A }
2N/A }
2N/A **string = val;
2N/A return (ALLOC_CHUNK);
2N/A}
2N/A
2N/A#define slcall callp->param.acall.cargs.bsltos_arg
2N/A#define slret callp->param.aret.rvals.bsltos_ret
2N/A/*
2N/A * bsltos - Convert Binary Sensitivity Label to Sensitivity Label string.
2N/A *
2N/A * Entry label = Binary Sensitivity Label to be converted.
2N/A * string = NULL ((char *) 0), if memory to be allocated,
2N/A * otherwise, pointer to preallocated memory.
2N/A * str_len = Length of preallocated memory, else ignored.
2N/A * flags = Logical sum of:
2N/A * LONG_CLASSIFICATION or SHORT_CLASSIFICATION,
2N/A * LONG_WORDS or SHORT_WORDS,
2N/A * VIEW_INTERNAL or VIEW_EXTERNAL, and
2N/A * NO_CLASSIFICATION.
2N/A * LONG_CLASSIFICATION, use long classification names.
2N/A * SHORT_CLASSIFICATION, use short classification
2N/A * names (default).
2N/A * NO_CLASSIFICATION, don't translate classification.
2N/A * LONG_WORDS, use the long form of words (default).
2N/A * SHORTWORDS, use the short form of words where available.
2N/A * VIEW_INTERNAL, don't promote/demote admin low/high.
2N/A * VIEW_EXTERNAL, promote/demote admin low/high.
2N/A *
2N/A * Exit string = Sensitivity Label string, or empty string if
2N/A * not enough preallocated memory.
2N/A *
2N/A * Returns -1, If unable to access label encodings database.
2N/A * 0, If unable to allocate string,
2N/A * or allocated string to short
2N/A * (and **string = '\0').
2N/A * length (including null) of Sensitivity Label string,
2N/A * If successful.
2N/A *
2N/A * Calls RPC - LABELS_BSLTOS, BCLHIGH, BCLLOW, BCLTOSL, BLEQUAL,
2N/A * BLTYPE, SETBSLABEL, UCLNT, memcpy, clnt_call,
2N/A * clnt_perror, malloc, strcat, strlen.
2N/A *
2N/A * Uses ADMIN_HIGH, ADMIN_LOW, shigh, slow.
2N/A */
2N/A
2N/Assize_t
2N/Absltos(const bslabel_t *label, char **string, size_t str_len,
2N/A int flags)
2N/A{
2N/A labeld_data_t call;
2N/A labeld_data_t *callp = &call;
2N/A size_t bufsize = sizeof (labeld_data_t);
2N/A size_t datasize = CALL_SIZE(bsltos_call_t, 0);
2N/A int rval;
2N/A
2N/A if (!BLTYPE(label, SUN_SL_ID)) {
2N/A return (-1);
2N/A }
2N/A
2N/A call.callop = BSLTOS;
2N/A slcall.label = *label;
2N/A slcall.flags = (flags&NO_CLASSIFICATION) ? LABELS_NO_CLASS : 0;
2N/A slcall.flags |= (flags&SHORT_CLASSIFICATION ||
2N/A !(flags&LONG_CLASSIFICATION)) ? LABELS_SHORT_CLASS : 0;
2N/A slcall.flags |= (flags&SHORT_WORDS && !(flags&LONG_WORDS)) ?
2N/A LABELS_SHORT_WORDS : 0;
2N/A set_label_view(&slcall.flags, flags);
2N/A
2N/A if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
2N/A
2N/A if (callp->reterr != 0)
2N/A return (-1);
2N/A
2N/A /* unpack Sensitivity Label */
2N/A
2N/A rval = return_string(string, str_len, slret.slabel);
2N/A
2N/A if (callp != &call)
2N/A (void) munmap((void *)callp, bufsize);
2N/A return (rval);
2N/A } else if (rval == NOSERVER) {
2N/A /* server not present */
2N/A /* special case admin_high and admin_low */
2N/A
2N/A if (!BLTYPE(&slow, SUN_SL_ID)) {
2N/A /* initialize static labels */
2N/A
2N/A BSLLOW(&slow);
2N/A BSLHIGH(&shigh);
2N/A }
2N/A
2N/A if (BLEQUAL(label, &slow)) {
2N/A return (return_string(string, str_len, ADMIN_LOW));
2N/A } else if (BLEQUAL(label, &shigh)) {
2N/A return (return_string(string, str_len, ADMIN_HIGH));
2N/A }
2N/A }
2N/A return (-1);
2N/A} /* bsltos */
2N/A#undef slcall
2N/A#undef slret
2N/A
2N/A#define clrcall callp->param.acall.cargs.bcleartos_arg
2N/A#define clrret callp->param.aret.rvals.bcleartos_ret
2N/A/*
2N/A * bcleartos - Convert Binary Clearance to Clearance string.
2N/A *
2N/A * Entry clearance = Binary Clearance to be converted.
2N/A * string = NULL ((char *) 0), if memory to be allocated,
2N/A * otherwise, pointer to preallocated memory.
2N/A * str_len = Length of preallocated memory, else ignored.
2N/A * flags = Logical sum of:
2N/A * LONG_CLASSIFICATION or SHORT_CLASSIFICATION,
2N/A * LONG_WORDS or SHORT_WORDS,
2N/A * VIEW_INTERNAL or VIEW_EXTERNAL.
2N/A * LONG_CLASSIFICATION, use long classification names.
2N/A * SHORT_CLASSIFICATION, use short classification
2N/A * names (default).
2N/A * LONG_WORDS, use the long form of words (default).
2N/A * SHORTWORDS, use the short form of words where available.
2N/A * VIEW_INTERNAL, don't promote/demote admin low/high.
2N/A * VIEW_EXTERNAL, promote/demote admin low/high.
2N/A *
2N/A * Exit string = Clearance string, or empty string if not
2N/A * enough preallocated memory.
2N/A *
2N/A * Returns -1, If unable to access label encodings database.
2N/A * 0, If unable to allocate string,
2N/A * or allocated string to short
2N/A * (and **string = '\0').
2N/A * length (including null) of Clearance string,
2N/A * If successful.
2N/A *
2N/A * Calls RPC - LABELS_BSLTOS, BCLHIGH, BCLLOW, BCLTOSL, BLEQUAL,
2N/A * BLTYPE, SETBSLABEL, UCLNT, memcpy, clnt_call,
2N/A * clnt_perror, malloc, strcat, strlen.
2N/A *
2N/A * Uses ADMIN_HIGH, ADMIN_LOW, clrhigh, clrlow.
2N/A */
2N/A
2N/Assize_t
2N/Abcleartos(const bclear_t *clearance, char **string, size_t str_len,
2N/A int flags)
2N/A{
2N/A labeld_data_t call;
2N/A labeld_data_t *callp = &call;
2N/A size_t bufsize = sizeof (labeld_data_t);
2N/A size_t datasize = CALL_SIZE(bcleartos_call_t, 0);
2N/A int rval;
2N/A
2N/A if (!BLTYPE(clearance, SUN_CLR_ID)) {
2N/A return (-1);
2N/A }
2N/A
2N/A call.callop = BCLEARTOS;
2N/A clrcall.clear = *clearance;
2N/A clrcall.flags = (flags&SHORT_CLASSIFICATION ||
2N/A !(flags&LONG_CLASSIFICATION)) ? LABELS_SHORT_CLASS : 0;
2N/A clrcall.flags |= (flags&SHORT_WORDS && !(flags&LONG_WORDS)) ?
2N/A LABELS_SHORT_WORDS : 0;
2N/A set_label_view(&clrcall.flags, flags);
2N/A
2N/A if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
2N/A
2N/A if (callp->reterr != 0)
2N/A return (-1);
2N/A
2N/A /* unpack Clearance */
2N/A
2N/A rval = return_string(string, str_len, clrret.cslabel);
2N/A
2N/A if (callp != &call)
2N/A /* release return buffer */
2N/A (void) munmap((void *)callp, bufsize);
2N/A return (rval);
2N/A } else if (rval == NOSERVER) {
2N/A /* server not present */
2N/A /* special case admin_high and admin_low */
2N/A
2N/A if (!BLTYPE(&clrlow, SUN_CLR_ID)) {
2N/A /* initialize static labels */
2N/A
2N/A BCLEARLOW(&clrlow);
2N/A BCLEARHIGH(&clrhigh);
2N/A }
2N/A if (BLEQUAL(clearance, &clrlow)) {
2N/A return (return_string(string, str_len, ADMIN_LOW));
2N/A } else if (BLEQUAL(clearance, &clrhigh)) {
2N/A return (return_string(string, str_len, ADMIN_HIGH));
2N/A }
2N/A }
2N/A return (-1);
2N/A} /* bcleartos */
2N/A#undef clrcall
2N/A#undef clrret
2N/A
2N/A/*
2N/A * sbsltos - Convert Sensitivity Label to canonical clipped form.
2N/A *
2N/A * Entry label = Sensitivity Label to be converted.
2N/A * len = Maximum length of translated string, excluding NULL.
2N/A * 0, full string.
2N/A * sstring = address of string to translate into.
2N/A * ssize = size of memory currently allocated to sstring.
2N/A *
2N/A * Exit sstring = Newly translated string.
2N/A * ssize = Updated if more memory pre-allocated.
2N/A *
2N/A * Returns NULL, If error, len too small, unable to translate, or get
2N/A * memory for string.
2N/A * Address of string containing converted value.
2N/A *
2N/A * Calls alloc_string, bsltos, strcpy.
2N/A *
2N/A * Uses ssize, sstring.
2N/A */
2N/A
2N/Achar *
2N/Asbsltos(const bslabel_t *label, size_t len)
2N/A{
2N/A ssize_t slen; /* length including NULL */
2N/A wchar_t *wstring;
2N/A int wccount;
2N/A
2N/A if (ssize == 0) {
2N/A /* Allocate string memory. */
2N/A if ((ssize = alloc_string(&sstring, ssize, 's')) == 0)
2N/A /* can't get initial memory for string */
2N/A return (NULL);
2N/A }
2N/A
2N/Aagain:
2N/A if ((slen = bsltos(label, &sstring, ssize,
2N/A (SHORT_CLASSIFICATION | LONG_WORDS))) <= 0) {
2N/A /* error in translation */
2N/A if (slen == 0) {
2N/A if (*sstring == '\0') {
2N/A int newsize;
2N/A /* sstring not long enough */
2N/A if ((newsize = alloc_string(&sstring, ssize,
2N/A 's')) == 0) {
2N/A /* Can't get more memory */
2N/A return (NULL);
2N/A }
2N/A ssize += newsize;
2N/A goto again;
2N/A }
2N/A }
2N/A return (NULL);
2N/A }
2N/A if (len == 0) {
2N/A return (sstring);
2N/A } else if (len < MIN_SL_LEN) {
2N/A return (NULL);
2N/A }
2N/A if ((wstring = malloc(slen * sizeof (wchar_t))) == NULL)
2N/A return (NULL);
2N/A if ((wccount = mbstowcs(wstring, sstring, slen - 1)) == -1) {
2N/A free(wstring);
2N/A return (NULL);
2N/A }
2N/A if (wccount > len) {
2N/A wchar_t *clipp = wstring + (len - 2);
2N/A
2N/A /* Adjust string size to desired length */
2N/A
2N/A clipp[0] = L'<';
2N/A clipp[1] = L'-';
2N/A clipp[2] = L'\0';
2N/A
2N/A while (wcstombs(NULL, wstring, 0) >= ssize) {
2N/A int newsize;
2N/A
2N/A /* sstring not long enough */
2N/A if ((newsize = alloc_string(&sstring, ssize, 's')) ==
2N/A 0) {
2N/A /* Can't get more memory */
2N/A return (NULL);
2N/A }
2N/A ssize += newsize;
2N/A }
2N/A
2N/A if ((wccount = wcstombs(sstring, wstring, ssize)) == -1) {
2N/A free(wstring);
2N/A return (NULL);
2N/A }
2N/A }
2N/A free(wstring);
2N/A
2N/A return (sstring);
2N/A} /* sbsltos */
2N/A
2N/A/*
2N/A * sbcleartos - Convert Clearance to canonical clipped form.
2N/A *
2N/A * Entry clearance = Clearance to be converted.
2N/A * len = Maximum length of translated string, excluding NULL.
2N/A * 0, full string.
2N/A * sstring = address of string to translate into.
2N/A * ssize = size of memory currently allocated to sstring.
2N/A *
2N/A * Exit sstring = Newly translated string.
2N/A * ssize = Updated if more memory pre-allocated.
2N/A *
2N/A * Returns NULL, If error, len too small, unable to translate, or get
2N/A * memory for string.
2N/A * Address of string containing converted value.
2N/A *
2N/A * Calls alloc_string, bcleartos, strcpy.
2N/A *
2N/A * Uses ssize, sstring.
2N/A */
2N/A
2N/Achar *
2N/Asbcleartos(const bclear_t *clearance, size_t len)
2N/A{
2N/A ssize_t slen; /* length including NULL */
2N/A wchar_t *wstring;
2N/A int wccount;
2N/A
2N/A if (ssize == 0) {
2N/A /* Allocate string memory. */
2N/A if ((ssize = alloc_string(&sstring, ssize, 'c')) == 0)
2N/A /* can't get initial memory for string */
2N/A return (NULL);
2N/A }
2N/A
2N/Aagain:
2N/A if ((slen = bcleartos(clearance, &sstring, ssize,
2N/A (SHORT_CLASSIFICATION | LONG_WORDS))) <= 0) {
2N/A /* error in translation */
2N/A if (slen == 0) {
2N/A if (*sstring == '\0') {
2N/A int newsize;
2N/A /* sstring not long enough */
2N/A if ((newsize = alloc_string(&sstring, ssize,
2N/A 'c')) == 0) {
2N/A /* Can't get more memory */
2N/A return (NULL);
2N/A }
2N/A ssize += newsize;
2N/A goto again;
2N/A }
2N/A }
2N/A return (NULL);
2N/A }
2N/A if (len == 0) {
2N/A return (sstring);
2N/A } else if (len < MIN_CLR_LEN) {
2N/A return (NULL);
2N/A }
2N/A if ((wstring = malloc(slen * sizeof (wchar_t))) == NULL)
2N/A return (NULL);
2N/A if ((wccount = mbstowcs(wstring, sstring, slen - 1)) == -1) {
2N/A free(wstring);
2N/A return (NULL);
2N/A }
2N/A if (wccount > len) {
2N/A wchar_t *clipp = wstring + (len - 2);
2N/A
2N/A /* Adjust string size to desired length */
2N/A
2N/A clipp[0] = L'<';
2N/A clipp[1] = L'-';
2N/A clipp[2] = L'\0';
2N/A
2N/A while (wcstombs(NULL, wstring, 0) >= ssize) {
2N/A int newsize;
2N/A
2N/A /* sstring not long enough */
2N/A if ((newsize = alloc_string(&sstring, ssize, 'c')) ==
2N/A 0) {
2N/A /* Can't get more memory */
2N/A free(wstring);
2N/A return (NULL);
2N/A }
2N/A ssize += newsize;
2N/A }
2N/A if ((wccount = wcstombs(sstring, wstring, ssize)) == -1) {
2N/A free(wstring);
2N/A return (NULL);
2N/A }
2N/A }
2N/A free(wstring);
2N/A
2N/A return (sstring);
2N/A} /* sbcleartos */