1*1676Sjpk /* 2*1676Sjpk * CDDL HEADER START 3*1676Sjpk * 4*1676Sjpk * The contents of this file are subject to the terms of the 5*1676Sjpk * Common Development and Distribution License (the "License"). 6*1676Sjpk * You may not use this file except in compliance with the License. 7*1676Sjpk * 8*1676Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*1676Sjpk * or http://www.opensolaris.org/os/licensing. 10*1676Sjpk * See the License for the specific language governing permissions 11*1676Sjpk * and limitations under the License. 12*1676Sjpk * 13*1676Sjpk * When distributing Covered Code, include this CDDL HEADER in each 14*1676Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*1676Sjpk * If applicable, add the following below this CDDL HEADER, with the 16*1676Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 17*1676Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 18*1676Sjpk * 19*1676Sjpk * CDDL HEADER END 20*1676Sjpk */ 21*1676Sjpk /* 22*1676Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*1676Sjpk * Use is subject to license terms. 24*1676Sjpk */ 25*1676Sjpk 26*1676Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 27*1676Sjpk 28*1676Sjpk 29*1676Sjpk /* 30*1676Sjpk * Miscellaneous user interfaces to trusted label functions. 31*1676Sjpk * 32*1676Sjpk */ 33*1676Sjpk 34*1676Sjpk 35*1676Sjpk #include <ctype.h> 36*1676Sjpk #include <stdlib.h> 37*1676Sjpk #include <strings.h> 38*1676Sjpk 39*1676Sjpk #include <sys/mman.h> 40*1676Sjpk 41*1676Sjpk #include <tsol/label.h> 42*1676Sjpk 43*1676Sjpk #include "labeld.h" 44*1676Sjpk #include "clnt.h" 45*1676Sjpk #include <sys/tsol/label_macro.h> 46*1676Sjpk #include <secdb.h> 47*1676Sjpk #include <user_attr.h> 48*1676Sjpk 49*1676Sjpk static bslabel_t slow, shigh; /* static Admin Low and High SLs */ 50*1676Sjpk static bclear_t clow, chigh; /* static Admin Low and High CLRs */ 51*1676Sjpk 52*1676Sjpk static char color[MAXCOLOR]; 53*1676Sjpk 54*1676Sjpk 55*1676Sjpk #define incall callp->param.acall.cargs.inset_arg 56*1676Sjpk #define inret callp->param.aret.rvals.inset_ret 57*1676Sjpk /* 58*1676Sjpk * blinset - Check in a label set. 59*1676Sjpk * 60*1676Sjpk * Entry label = Sensitivity Label to check. 61*1676Sjpk * id = Label set identifier of set to check. 62*1676Sjpk * 63*1676Sjpk * Exit None. 64*1676Sjpk * 65*1676Sjpk * Returns -1, If label set unavailable, or server failure. 66*1676Sjpk * 0, If label not in label set. 67*1676Sjpk * 1, If label is in the label set. 68*1676Sjpk * 69*1676Sjpk * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH. 70*1676Sjpk * 71*1676Sjpk * Uses slow, shigh. 72*1676Sjpk */ 73*1676Sjpk 74*1676Sjpk int 75*1676Sjpk blinset(const bslabel_t *label, const set_id *id) 76*1676Sjpk { 77*1676Sjpk if (id->type == SYSTEM_ACCREDITATION_RANGE) { 78*1676Sjpk if (!BLTYPE(&slow, SUN_SL_ID)) { 79*1676Sjpk /* initialize static labels. */ 80*1676Sjpk 81*1676Sjpk BSLLOW(&slow); 82*1676Sjpk BSLHIGH(&shigh); 83*1676Sjpk } 84*1676Sjpk 85*1676Sjpk if (BLTYPE(label, SUN_SL_ID) && 86*1676Sjpk (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) 87*1676Sjpk 88*1676Sjpk return (1); 89*1676Sjpk } 90*1676Sjpk if (id->type == USER_ACCREDITATION_RANGE || 91*1676Sjpk id->type == SYSTEM_ACCREDITATION_RANGE) { 92*1676Sjpk labeld_data_t call; 93*1676Sjpk labeld_data_t *callp = &call; 94*1676Sjpk size_t bufsize = sizeof (labeld_data_t); 95*1676Sjpk size_t datasize = CALL_SIZE(inset_call_t, 0); 96*1676Sjpk 97*1676Sjpk call.callop = BLINSET; 98*1676Sjpk incall.label = *label; 99*1676Sjpk incall.type = id->type; 100*1676Sjpk 101*1676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 102*1676Sjpk /* process error */ 103*1676Sjpk 104*1676Sjpk return (-1); 105*1676Sjpk } 106*1676Sjpk return (inret.inset); 107*1676Sjpk } else { 108*1676Sjpk /* 109*1676Sjpk * Only System and User Accreditation Ranges presently 110*1676Sjpk * implemented. 111*1676Sjpk */ 112*1676Sjpk return (-1); 113*1676Sjpk } 114*1676Sjpk } 115*1676Sjpk #undef incall 116*1676Sjpk #undef inret 117*1676Sjpk 118*1676Sjpk #define slvcall callp->param.acall.cargs.slvalid_arg 119*1676Sjpk #define slvret callp->param.aret.rvals.slvalid_ret 120*1676Sjpk /* 121*1676Sjpk * bslvalid - Check Sensitivity Label for validity. 122*1676Sjpk * 123*1676Sjpk * Entry label = Sensitivity Label to check. 124*1676Sjpk * 125*1676Sjpk * Exit None. 126*1676Sjpk * 127*1676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 128*1676Sjpk * 0, If label not valid. 129*1676Sjpk * 1, If label is valid. 130*1676Sjpk * 131*1676Sjpk * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH. 132*1676Sjpk * 133*1676Sjpk * Uses slow, shigh. 134*1676Sjpk * 135*1676Sjpk */ 136*1676Sjpk 137*1676Sjpk int 138*1676Sjpk bslvalid(const bslabel_t *label) 139*1676Sjpk { 140*1676Sjpk labeld_data_t call; 141*1676Sjpk labeld_data_t *callp = &call; 142*1676Sjpk size_t bufsize = sizeof (labeld_data_t); 143*1676Sjpk size_t datasize = CALL_SIZE(slvalid_call_t, 0); 144*1676Sjpk 145*1676Sjpk if (!BLTYPE(&slow, SUN_SL_ID)) { 146*1676Sjpk /* initialize static labels. */ 147*1676Sjpk 148*1676Sjpk BSLLOW(&slow); 149*1676Sjpk BSLHIGH(&shigh); 150*1676Sjpk } 151*1676Sjpk 152*1676Sjpk if (BLTYPE(label, SUN_SL_ID) && 153*1676Sjpk (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) { 154*1676Sjpk 155*1676Sjpk return (1); 156*1676Sjpk } 157*1676Sjpk 158*1676Sjpk call.callop = BSLVALID; 159*1676Sjpk slvcall.label = *label; 160*1676Sjpk 161*1676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 162*1676Sjpk /* process error */ 163*1676Sjpk 164*1676Sjpk return (-1); 165*1676Sjpk } 166*1676Sjpk return (slvret.valid); 167*1676Sjpk } 168*1676Sjpk #undef slvcall 169*1676Sjpk #undef slvret 170*1676Sjpk 171*1676Sjpk #define clrvcall callp->param.acall.cargs.clrvalid_arg 172*1676Sjpk #define clrvret callp->param.aret.rvals.clrvalid_ret 173*1676Sjpk /* 174*1676Sjpk * bclearvalid - Check Clearance for validity. 175*1676Sjpk * 176*1676Sjpk * Entry clearance = Clearance to check. 177*1676Sjpk * 178*1676Sjpk * Exit None. 179*1676Sjpk * 180*1676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 181*1676Sjpk * 0, If label not valid. 182*1676Sjpk * 1, If label is valid. 183*1676Sjpk * 184*1676Sjpk * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH. 185*1676Sjpk * 186*1676Sjpk * Uses clow, chigh. 187*1676Sjpk * 188*1676Sjpk */ 189*1676Sjpk 190*1676Sjpk int 191*1676Sjpk bclearvalid(const bclear_t *clearance) 192*1676Sjpk { 193*1676Sjpk labeld_data_t call; 194*1676Sjpk labeld_data_t *callp = &call; 195*1676Sjpk size_t bufsize = sizeof (labeld_data_t); 196*1676Sjpk size_t datasize = CALL_SIZE(clrvalid_call_t, 0); 197*1676Sjpk 198*1676Sjpk if (!BLTYPE(&clow, SUN_CLR_ID)) { 199*1676Sjpk /* initialize static labels. */ 200*1676Sjpk 201*1676Sjpk BCLEARLOW(&clow); 202*1676Sjpk BCLEARHIGH(&chigh); 203*1676Sjpk } 204*1676Sjpk 205*1676Sjpk if (BLTYPE(clearance, SUN_CLR_ID) && 206*1676Sjpk (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) { 207*1676Sjpk 208*1676Sjpk return (1); 209*1676Sjpk } 210*1676Sjpk 211*1676Sjpk call.callop = BCLEARVALID; 212*1676Sjpk clrvcall.clear = *clearance; 213*1676Sjpk 214*1676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 215*1676Sjpk /* process error */ 216*1676Sjpk 217*1676Sjpk return (-1); 218*1676Sjpk } 219*1676Sjpk return (clrvret.valid); 220*1676Sjpk } 221*1676Sjpk #undef clrvcall 222*1676Sjpk #undef clrvret 223*1676Sjpk 224*1676Sjpk #define inforet callp->param.aret.rvals.info_ret 225*1676Sjpk /* 226*1676Sjpk * labelinfo - Get information about the label encodings file. 227*1676Sjpk * 228*1676Sjpk * Entry info = Address of label_info structure to update. 229*1676Sjpk * 230*1676Sjpk * Exit info = Updated. 231*1676Sjpk * 232*1676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 233*1676Sjpk * 1, If successful. 234*1676Sjpk * 235*1676Sjpk * Calls __call_labeld(LABELINFO). 236*1676Sjpk */ 237*1676Sjpk 238*1676Sjpk int 239*1676Sjpk labelinfo(struct label_info *info) 240*1676Sjpk { 241*1676Sjpk labeld_data_t call; 242*1676Sjpk labeld_data_t *callp = &call; 243*1676Sjpk size_t bufsize = sizeof (labeld_data_t); 244*1676Sjpk size_t datasize = CALL_SIZE(info_call_t, 0); 245*1676Sjpk int rval; 246*1676Sjpk 247*1676Sjpk call.callop = LABELINFO; 248*1676Sjpk 249*1676Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { 250*1676Sjpk /* process error */ 251*1676Sjpk 252*1676Sjpk return (-1); 253*1676Sjpk } 254*1676Sjpk *info = inforet.info; 255*1676Sjpk return (rval); 256*1676Sjpk } 257*1676Sjpk #undef inforet 258*1676Sjpk 259*1676Sjpk #define lvret callp->param.aret.rvals.vers_ret 260*1676Sjpk /* 261*1676Sjpk * labelvers - Get version string of the label encodings file. 262*1676Sjpk * 263*1676Sjpk * Entry version = Address of string pointer to return. 264*1676Sjpk * len = Length of string if pre-allocated. 265*1676Sjpk * 266*1676Sjpk * Exit version = Updated. 267*1676Sjpk * 268*1676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 269*1676Sjpk * 0, If unable to allocate version string, 270*1676Sjpk * or pre-allocated version string to short 271*1676Sjpk * (and **version = '\0'). 272*1676Sjpk * length (including null) of version string, If successful. 273*1676Sjpk * 274*1676Sjpk * Calls __call_labeld(LABELVERS) 275*1676Sjpk * malloc, strlen. 276*1676Sjpk */ 277*1676Sjpk 278*1676Sjpk ssize_t 279*1676Sjpk labelvers(char **version, size_t len) 280*1676Sjpk { 281*1676Sjpk labeld_data_t call; 282*1676Sjpk labeld_data_t *callp = &call; 283*1676Sjpk size_t bufsize = sizeof (labeld_data_t); 284*1676Sjpk size_t datasize = CALL_SIZE(vers_call_t, 0); 285*1676Sjpk size_t ver_len; 286*1676Sjpk 287*1676Sjpk call.callop = LABELVERS; 288*1676Sjpk 289*1676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 290*1676Sjpk 291*1676Sjpk if (callp != &call) 292*1676Sjpk /* release return buffer */ 293*1676Sjpk (void) munmap((void *)callp, bufsize); 294*1676Sjpk return (-1); 295*1676Sjpk } 296*1676Sjpk 297*1676Sjpk /* unpack length */ 298*1676Sjpk 299*1676Sjpk ver_len = strlen(lvret.vers) + 1; 300*1676Sjpk if (*version == NULL) { 301*1676Sjpk if ((*version = malloc(ver_len)) == NULL) { 302*1676Sjpk if (callp != &call) 303*1676Sjpk /* release return buffer */ 304*1676Sjpk (void) munmap((void *)callp, bufsize); 305*1676Sjpk return (0); 306*1676Sjpk } 307*1676Sjpk } else if (ver_len > len) { 308*1676Sjpk **version = '\0'; 309*1676Sjpk if (callp != &call) 310*1676Sjpk /* release return buffer */ 311*1676Sjpk (void) munmap((void *)callp, bufsize); 312*1676Sjpk return (0); 313*1676Sjpk } 314*1676Sjpk (void) strcpy(*version, lvret.vers); 315*1676Sjpk 316*1676Sjpk if (callp != &call) 317*1676Sjpk /* release return buffer */ 318*1676Sjpk (void) munmap((void *)callp, bufsize); 319*1676Sjpk return (ver_len); 320*1676Sjpk } /* labelvers */ 321*1676Sjpk #undef lvret 322*1676Sjpk 323*1676Sjpk #define ccall callp->param.acall.cargs.color_arg 324*1676Sjpk #define cret callp->param.aret.rvals.color_ret 325*1676Sjpk /* 326*1676Sjpk * bltocolor - get ASCII color name of label. 327*1676Sjpk * 328*1676Sjpk * Entry label = Sensitivity Level of color to get. 329*1676Sjpk * size = Size of the color_name array. 330*1676Sjpk * color_name = Storage for ASCII color name string to be returned. 331*1676Sjpk * 332*1676Sjpk * Exit None. 333*1676Sjpk * 334*1676Sjpk * Returns NULL, If error (label encodings file not accessible, 335*1676Sjpk * invalid label, no color for this label). 336*1676Sjpk * Address of color_name parameter containing ASCII color name 337*1676Sjpk * defined for the label. 338*1676Sjpk * 339*1676Sjpk * Calls __call_labeld(BLTOCOLOR), strlen. 340*1676Sjpk */ 341*1676Sjpk 342*1676Sjpk char * 343*1676Sjpk bltocolor_r(const blevel_t *label, size_t size, char *color_name) 344*1676Sjpk { 345*1676Sjpk labeld_data_t call; 346*1676Sjpk labeld_data_t *callp = &call; 347*1676Sjpk size_t bufsize = sizeof (labeld_data_t); 348*1676Sjpk size_t datasize = CALL_SIZE(color_call_t, 0); 349*1676Sjpk char *colorp; 350*1676Sjpk 351*1676Sjpk call.callop = BLTOCOLOR; 352*1676Sjpk ccall.label = *label; 353*1676Sjpk 354*1676Sjpk if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) || 355*1676Sjpk (callp->reterr != 0) || 356*1676Sjpk (strlen(cret.color) >= size)) { 357*1676Sjpk 358*1676Sjpk if (callp != &call) 359*1676Sjpk /* release return buffer */ 360*1676Sjpk (void) munmap((void *)callp, bufsize); 361*1676Sjpk return (NULL); 362*1676Sjpk } 363*1676Sjpk 364*1676Sjpk colorp = strcpy(color_name, cret.color); 365*1676Sjpk 366*1676Sjpk if (callp != &call) 367*1676Sjpk /* release return buffer */ 368*1676Sjpk (void) munmap((void *)callp, bufsize); 369*1676Sjpk return (colorp); 370*1676Sjpk } /* bltocolor_r */ 371*1676Sjpk #undef ccall 372*1676Sjpk #undef cret 373*1676Sjpk 374*1676Sjpk /* 375*1676Sjpk * bltocolor - get ASCII color name of label. 376*1676Sjpk * 377*1676Sjpk * Entry label = Sensitivity Level of color to get. 378*1676Sjpk * 379*1676Sjpk * Exit None. 380*1676Sjpk * 381*1676Sjpk * Returns NULL, If error (label encodings file not accessible, 382*1676Sjpk * invalid label, no color for this label). 383*1676Sjpk * Address of statically allocated string containing ASCII 384*1676Sjpk * color name defined for the classification contained 385*1676Sjpk * in label. 386*1676Sjpk * 387*1676Sjpk * Uses color. 388*1676Sjpk * 389*1676Sjpk * Calls bltocolor_r. 390*1676Sjpk */ 391*1676Sjpk 392*1676Sjpk char * 393*1676Sjpk bltocolor(const blevel_t *label) 394*1676Sjpk { 395*1676Sjpk return (bltocolor_r(label, sizeof (color), color)); 396*1676Sjpk } /* bltocolor */ 397*1676Sjpk 398*1676Sjpk blevel_t * 399*1676Sjpk blabel_alloc(void) 400*1676Sjpk { 401*1676Sjpk return (m_label_alloc(MAC_LABEL)); 402*1676Sjpk } 403*1676Sjpk 404*1676Sjpk void 405*1676Sjpk blabel_free(blevel_t *label_p) 406*1676Sjpk { 407*1676Sjpk free(label_p); 408*1676Sjpk } 409*1676Sjpk 410*1676Sjpk size_t 411*1676Sjpk blabel_size(void) 412*1676Sjpk { 413*1676Sjpk return (sizeof (blevel_t)); 414*1676Sjpk } 415*1676Sjpk 416*1676Sjpk /* 417*1676Sjpk * getuserrange - get label range for user 418*1676Sjpk * 419*1676Sjpk * Entry username of user 420*1676Sjpk * 421*1676Sjpk * Exit None. 422*1676Sjpk * 423*1676Sjpk * Returns NULL, If memory allocation failure or userdefs failure. 424*1676Sjpk * otherwise returns the allocates m_range_t with the 425*1676Sjpk * user's min and max labels set. 426*1676Sjpk */ 427*1676Sjpk 428*1676Sjpk m_range_t * 429*1676Sjpk getuserrange(const char *username) 430*1676Sjpk { 431*1676Sjpk char *kv_str = NULL; 432*1676Sjpk userattr_t *userp = NULL; 433*1676Sjpk m_range_t *range; 434*1676Sjpk int err; 435*1676Sjpk 436*1676Sjpk /* 437*1676Sjpk * Get some memory 438*1676Sjpk */ 439*1676Sjpk 440*1676Sjpk if ((range = malloc(sizeof (m_range_t))) == NULL) { 441*1676Sjpk return (NULL); 442*1676Sjpk } 443*1676Sjpk if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) { 444*1676Sjpk free(range); 445*1676Sjpk return (NULL); 446*1676Sjpk } 447*1676Sjpk if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) { 448*1676Sjpk m_label_free(range->lower_bound); 449*1676Sjpk free(range); 450*1676Sjpk return (NULL); 451*1676Sjpk } 452*1676Sjpk /* 453*1676Sjpk * Since user_attr entries are optional, start with 454*1676Sjpk * the system default values 455*1676Sjpk */ 456*1676Sjpk if ((userdefs(range->lower_bound, range->upper_bound)) == -1) { 457*1676Sjpk m_label_free(range->lower_bound); 458*1676Sjpk m_label_free(range->upper_bound); 459*1676Sjpk free(range); 460*1676Sjpk return (NULL); 461*1676Sjpk } 462*1676Sjpk /* 463*1676Sjpk * If the user has an explicit min_label or clearance, 464*1676Sjpk * then use it instead. 465*1676Sjpk */ 466*1676Sjpk if ((userp = getusernam(username)) == NULL) { 467*1676Sjpk return (range); 468*1676Sjpk } 469*1676Sjpk if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) != NULL) 470*1676Sjpk (void) stobsl(kv_str, range->lower_bound, NO_CORRECTION, &err); 471*1676Sjpk if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE)) != NULL) 472*1676Sjpk (void) stobclear(kv_str, range->upper_bound, NO_CORRECTION, 473*1676Sjpk &err); 474*1676Sjpk free_userattr(userp); 475*1676Sjpk return (range); 476*1676Sjpk } 477