#include <ctype.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/mman.h>
#include <tsol/label.h>
#include "labeld.h"
#include "clnt.h"
#include <sys/tsol/label_macro.h>
#include <secdb.h>
#include <user_attr.h>
static bslabel_t slow, shigh;
static bclear_t clow, chigh;
static char color[MAXCOLOR];
#define incall callp->param.acall.cargs.inset_arg
#define inret callp->param.aret.rvals.inset_ret
int
blinset(const bslabel_t *label, const set_id *id)
{
if (id->type == SYSTEM_ACCREDITATION_RANGE) {
if (!BLTYPE(&slow, SUN_SL_ID)) {
BSLLOW(&slow);
BSLHIGH(&shigh);
}
if (BLTYPE(label, SUN_SL_ID) &&
(BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
return (1);
}
if (id->type == USER_ACCREDITATION_RANGE ||
id->type == SYSTEM_ACCREDITATION_RANGE) {
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(inset_call_t, 0);
call.callop = BLINSET;
incall.label = *label;
incall.type = id->type;
if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
return (-1);
}
return (inret.inset);
} else {
return (-1);
}
}
#undef incall
#undef inret
#define slvcall callp->param.acall.cargs.slvalid_arg
#define slvret callp->param.aret.rvals.slvalid_ret
int
bslvalid(const bslabel_t *label)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(slvalid_call_t, 0);
if (!BLTYPE(&slow, SUN_SL_ID)) {
BSLLOW(&slow);
BSLHIGH(&shigh);
}
if (BLTYPE(label, SUN_SL_ID) &&
(BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
return (1);
}
call.callop = BSLVALID;
slvcall.label = *label;
if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
return (-1);
}
return (slvret.valid);
}
#undef slvcall
#undef slvret
#define clrvcall callp->param.acall.cargs.clrvalid_arg
#define clrvret callp->param.aret.rvals.clrvalid_ret
int
bclearvalid(const bclear_t *clearance)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(clrvalid_call_t, 0);
if (!BLTYPE(&clow, SUN_CLR_ID)) {
BCLEARLOW(&clow);
BCLEARHIGH(&chigh);
}
if (BLTYPE(clearance, SUN_CLR_ID) &&
(BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
return (1);
}
call.callop = BCLEARVALID;
clrvcall.clear = *clearance;
if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
return (-1);
}
return (clrvret.valid);
}
#undef clrvcall
#undef clrvret
#define inforet callp->param.aret.rvals.info_ret
int
labelinfo(struct label_info *info)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(info_call_t, 0);
int rval;
call.callop = LABELINFO;
if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
return (-1);
}
*info = inforet.info;
return (rval);
}
#undef inforet
#define lvret callp->param.aret.rvals.vers_ret
ssize_t
labelvers(char **version, size_t len)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(vers_call_t, 0);
size_t ver_len;
call.callop = LABELVERS;
if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (-1);
}
ver_len = strlen(lvret.vers) + 1;
if (*version == NULL) {
if ((*version = malloc(ver_len)) == NULL) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
} else if (ver_len > len) {
**version = '\0';
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (0);
}
(void) strcpy(*version, lvret.vers);
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (ver_len);
}
#undef lvret
#define ccall callp->param.acall.cargs.color_arg
#define cret callp->param.aret.rvals.color_ret
char *
bltocolor_r(const blevel_t *label, size_t size, char *color_name)
{
labeld_data_t call;
labeld_data_t *callp = &call;
size_t bufsize = sizeof (labeld_data_t);
size_t datasize = CALL_SIZE(color_call_t, 0);
char *colorp;
call.callop = BLTOCOLOR;
ccall.label = *label;
if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
(callp->reterr != 0) ||
(strlen(cret.color) >= size)) {
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (NULL);
}
colorp = strcpy(color_name, cret.color);
if (callp != &call)
(void) munmap((void *)callp, bufsize);
return (colorp);
}
#undef ccall
#undef cret
char *
bltocolor(const blevel_t *label)
{
return (bltocolor_r(label, sizeof (color), color));
}
blevel_t *
blabel_alloc(void)
{
return (m_label_alloc(MAC_LABEL));
}
void
blabel_free(blevel_t *label_p)
{
free(label_p);
}
size32_t
blabel_size(void)
{
return (sizeof (blevel_t));
}
m_range_t *
getuserrange(const char *username)
{
char *kv_str = NULL;
userattr_t *userp = NULL;
m_range_t *range;
m_label_t *def_min, *def_clr;
if ((range = malloc(sizeof (m_range_t))) == NULL) {
return (NULL);
}
if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
free(range);
return (NULL);
}
def_min = range->lower_bound;
if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
m_label_free(range->lower_bound);
free(range);
return (NULL);
}
def_clr = range->upper_bound;
if ((userp = getusernam(username)) != NULL) {
if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL))
!= NULL) {
(void) str_to_label(kv_str, &range->lower_bound,
MAC_LABEL, L_NO_CORRECTION, NULL);
def_min = NULL;
}
if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE))
!= NULL) {
(void) str_to_label(kv_str, &range->upper_bound,
USER_CLEAR, L_NO_CORRECTION, NULL);
def_clr = NULL;
}
free_userattr(userp);
}
if (def_min || def_clr) {
if ((userdefs(def_min, def_clr)) == -1) {
m_label_free(range->lower_bound);
m_label_free(range->upper_bound);
free(range);
return (NULL);
}
}
return (range);
}