11676Sjpk /* 21676Sjpk * CDDL HEADER START 31676Sjpk * 41676Sjpk * The contents of this file are subject to the terms of the 51676Sjpk * Common Development and Distribution License (the "License"). 61676Sjpk * You may not use this file except in compliance with the License. 71676Sjpk * 81676Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91676Sjpk * or http://www.opensolaris.org/os/licensing. 101676Sjpk * See the License for the specific language governing permissions 111676Sjpk * and limitations under the License. 121676Sjpk * 131676Sjpk * When distributing Covered Code, include this CDDL HEADER in each 141676Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151676Sjpk * If applicable, add the following below this CDDL HEADER, with the 161676Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 171676Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 181676Sjpk * 191676Sjpk * CDDL HEADER END 201676Sjpk */ 211676Sjpk /* 221676Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 231676Sjpk * Use is subject to license terms. 241676Sjpk */ 251676Sjpk 261676Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 271676Sjpk 281676Sjpk 291676Sjpk /* 301676Sjpk * Miscellaneous user interfaces to trusted label functions. 311676Sjpk * 321676Sjpk */ 331676Sjpk 341676Sjpk 351676Sjpk #include <ctype.h> 361676Sjpk #include <stdlib.h> 371676Sjpk #include <strings.h> 381676Sjpk 391676Sjpk #include <sys/mman.h> 401676Sjpk 411676Sjpk #include <tsol/label.h> 421676Sjpk 431676Sjpk #include "labeld.h" 441676Sjpk #include "clnt.h" 451676Sjpk #include <sys/tsol/label_macro.h> 461676Sjpk #include <secdb.h> 471676Sjpk #include <user_attr.h> 481676Sjpk 491676Sjpk static bslabel_t slow, shigh; /* static Admin Low and High SLs */ 501676Sjpk static bclear_t clow, chigh; /* static Admin Low and High CLRs */ 511676Sjpk 521676Sjpk static char color[MAXCOLOR]; 531676Sjpk 541676Sjpk 551676Sjpk #define incall callp->param.acall.cargs.inset_arg 561676Sjpk #define inret callp->param.aret.rvals.inset_ret 571676Sjpk /* 581676Sjpk * blinset - Check in a label set. 591676Sjpk * 601676Sjpk * Entry label = Sensitivity Label to check. 611676Sjpk * id = Label set identifier of set to check. 621676Sjpk * 631676Sjpk * Exit None. 641676Sjpk * 651676Sjpk * Returns -1, If label set unavailable, or server failure. 661676Sjpk * 0, If label not in label set. 671676Sjpk * 1, If label is in the label set. 681676Sjpk * 691676Sjpk * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH. 701676Sjpk * 711676Sjpk * Uses slow, shigh. 721676Sjpk */ 731676Sjpk 741676Sjpk int 751676Sjpk blinset(const bslabel_t *label, const set_id *id) 761676Sjpk { 771676Sjpk if (id->type == SYSTEM_ACCREDITATION_RANGE) { 781676Sjpk if (!BLTYPE(&slow, SUN_SL_ID)) { 791676Sjpk /* initialize static labels. */ 801676Sjpk 811676Sjpk BSLLOW(&slow); 821676Sjpk BSLHIGH(&shigh); 831676Sjpk } 841676Sjpk 851676Sjpk if (BLTYPE(label, SUN_SL_ID) && 861676Sjpk (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) 871676Sjpk 881676Sjpk return (1); 891676Sjpk } 901676Sjpk if (id->type == USER_ACCREDITATION_RANGE || 911676Sjpk id->type == SYSTEM_ACCREDITATION_RANGE) { 921676Sjpk labeld_data_t call; 931676Sjpk labeld_data_t *callp = &call; 941676Sjpk size_t bufsize = sizeof (labeld_data_t); 951676Sjpk size_t datasize = CALL_SIZE(inset_call_t, 0); 961676Sjpk 971676Sjpk call.callop = BLINSET; 981676Sjpk incall.label = *label; 991676Sjpk incall.type = id->type; 1001676Sjpk 1011676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 1021676Sjpk /* process error */ 1031676Sjpk 1041676Sjpk return (-1); 1051676Sjpk } 1061676Sjpk return (inret.inset); 1071676Sjpk } else { 1081676Sjpk /* 1091676Sjpk * Only System and User Accreditation Ranges presently 1101676Sjpk * implemented. 1111676Sjpk */ 1121676Sjpk return (-1); 1131676Sjpk } 1141676Sjpk } 1151676Sjpk #undef incall 1161676Sjpk #undef inret 1171676Sjpk 1181676Sjpk #define slvcall callp->param.acall.cargs.slvalid_arg 1191676Sjpk #define slvret callp->param.aret.rvals.slvalid_ret 1201676Sjpk /* 1211676Sjpk * bslvalid - Check Sensitivity Label for validity. 1221676Sjpk * 1231676Sjpk * Entry label = Sensitivity Label to check. 1241676Sjpk * 1251676Sjpk * Exit None. 1261676Sjpk * 1271676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 1281676Sjpk * 0, If label not valid. 1291676Sjpk * 1, If label is valid. 1301676Sjpk * 1311676Sjpk * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH. 1321676Sjpk * 1331676Sjpk * Uses slow, shigh. 1341676Sjpk * 1351676Sjpk */ 1361676Sjpk 1371676Sjpk int 1381676Sjpk bslvalid(const bslabel_t *label) 1391676Sjpk { 1401676Sjpk labeld_data_t call; 1411676Sjpk labeld_data_t *callp = &call; 1421676Sjpk size_t bufsize = sizeof (labeld_data_t); 1431676Sjpk size_t datasize = CALL_SIZE(slvalid_call_t, 0); 1441676Sjpk 1451676Sjpk if (!BLTYPE(&slow, SUN_SL_ID)) { 1461676Sjpk /* initialize static labels. */ 1471676Sjpk 1481676Sjpk BSLLOW(&slow); 1491676Sjpk BSLHIGH(&shigh); 1501676Sjpk } 1511676Sjpk 1521676Sjpk if (BLTYPE(label, SUN_SL_ID) && 1531676Sjpk (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) { 1541676Sjpk 1551676Sjpk return (1); 1561676Sjpk } 1571676Sjpk 1581676Sjpk call.callop = BSLVALID; 1591676Sjpk slvcall.label = *label; 1601676Sjpk 1611676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 1621676Sjpk /* process error */ 1631676Sjpk 1641676Sjpk return (-1); 1651676Sjpk } 1661676Sjpk return (slvret.valid); 1671676Sjpk } 1681676Sjpk #undef slvcall 1691676Sjpk #undef slvret 1701676Sjpk 1711676Sjpk #define clrvcall callp->param.acall.cargs.clrvalid_arg 1721676Sjpk #define clrvret callp->param.aret.rvals.clrvalid_ret 1731676Sjpk /* 1741676Sjpk * bclearvalid - Check Clearance for validity. 1751676Sjpk * 1761676Sjpk * Entry clearance = Clearance to check. 1771676Sjpk * 1781676Sjpk * Exit None. 1791676Sjpk * 1801676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 1811676Sjpk * 0, If label not valid. 1821676Sjpk * 1, If label is valid. 1831676Sjpk * 1841676Sjpk * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH. 1851676Sjpk * 1861676Sjpk * Uses clow, chigh. 1871676Sjpk * 1881676Sjpk */ 1891676Sjpk 1901676Sjpk int 1911676Sjpk bclearvalid(const bclear_t *clearance) 1921676Sjpk { 1931676Sjpk labeld_data_t call; 1941676Sjpk labeld_data_t *callp = &call; 1951676Sjpk size_t bufsize = sizeof (labeld_data_t); 1961676Sjpk size_t datasize = CALL_SIZE(clrvalid_call_t, 0); 1971676Sjpk 1981676Sjpk if (!BLTYPE(&clow, SUN_CLR_ID)) { 1991676Sjpk /* initialize static labels. */ 2001676Sjpk 2011676Sjpk BCLEARLOW(&clow); 2021676Sjpk BCLEARHIGH(&chigh); 2031676Sjpk } 2041676Sjpk 2051676Sjpk if (BLTYPE(clearance, SUN_CLR_ID) && 2061676Sjpk (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) { 2071676Sjpk 2081676Sjpk return (1); 2091676Sjpk } 2101676Sjpk 2111676Sjpk call.callop = BCLEARVALID; 2121676Sjpk clrvcall.clear = *clearance; 2131676Sjpk 2141676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 2151676Sjpk /* process error */ 2161676Sjpk 2171676Sjpk return (-1); 2181676Sjpk } 2191676Sjpk return (clrvret.valid); 2201676Sjpk } 2211676Sjpk #undef clrvcall 2221676Sjpk #undef clrvret 2231676Sjpk 2241676Sjpk #define inforet callp->param.aret.rvals.info_ret 2251676Sjpk /* 2261676Sjpk * labelinfo - Get information about the label encodings file. 2271676Sjpk * 2281676Sjpk * Entry info = Address of label_info structure to update. 2291676Sjpk * 2301676Sjpk * Exit info = Updated. 2311676Sjpk * 2321676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 2331676Sjpk * 1, If successful. 2341676Sjpk * 2351676Sjpk * Calls __call_labeld(LABELINFO). 2361676Sjpk */ 2371676Sjpk 2381676Sjpk int 2391676Sjpk labelinfo(struct label_info *info) 2401676Sjpk { 2411676Sjpk labeld_data_t call; 2421676Sjpk labeld_data_t *callp = &call; 2431676Sjpk size_t bufsize = sizeof (labeld_data_t); 2441676Sjpk size_t datasize = CALL_SIZE(info_call_t, 0); 2451676Sjpk int rval; 2461676Sjpk 2471676Sjpk call.callop = LABELINFO; 2481676Sjpk 2491676Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) { 2501676Sjpk /* process error */ 2511676Sjpk 2521676Sjpk return (-1); 2531676Sjpk } 2541676Sjpk *info = inforet.info; 2551676Sjpk return (rval); 2561676Sjpk } 2571676Sjpk #undef inforet 2581676Sjpk 2591676Sjpk #define lvret callp->param.aret.rvals.vers_ret 2601676Sjpk /* 2611676Sjpk * labelvers - Get version string of the label encodings file. 2621676Sjpk * 2631676Sjpk * Entry version = Address of string pointer to return. 2641676Sjpk * len = Length of string if pre-allocated. 2651676Sjpk * 2661676Sjpk * Exit version = Updated. 2671676Sjpk * 2681676Sjpk * Returns -1, If unable to access label encodings file, or server failure. 2691676Sjpk * 0, If unable to allocate version string, 2701676Sjpk * or pre-allocated version string to short 2711676Sjpk * (and **version = '\0'). 2721676Sjpk * length (including null) of version string, If successful. 2731676Sjpk * 2741676Sjpk * Calls __call_labeld(LABELVERS) 2751676Sjpk * malloc, strlen. 2761676Sjpk */ 2771676Sjpk 2781676Sjpk ssize_t 2791676Sjpk labelvers(char **version, size_t len) 2801676Sjpk { 2811676Sjpk labeld_data_t call; 2821676Sjpk labeld_data_t *callp = &call; 2831676Sjpk size_t bufsize = sizeof (labeld_data_t); 2841676Sjpk size_t datasize = CALL_SIZE(vers_call_t, 0); 2851676Sjpk size_t ver_len; 2861676Sjpk 2871676Sjpk call.callop = LABELVERS; 2881676Sjpk 2891676Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) { 2901676Sjpk 2911676Sjpk if (callp != &call) 2921676Sjpk /* release return buffer */ 2931676Sjpk (void) munmap((void *)callp, bufsize); 2941676Sjpk return (-1); 2951676Sjpk } 2961676Sjpk 2971676Sjpk /* unpack length */ 2981676Sjpk 2991676Sjpk ver_len = strlen(lvret.vers) + 1; 3001676Sjpk if (*version == NULL) { 3011676Sjpk if ((*version = malloc(ver_len)) == NULL) { 3021676Sjpk if (callp != &call) 3031676Sjpk /* release return buffer */ 3041676Sjpk (void) munmap((void *)callp, bufsize); 3051676Sjpk return (0); 3061676Sjpk } 3071676Sjpk } else if (ver_len > len) { 3081676Sjpk **version = '\0'; 3091676Sjpk if (callp != &call) 3101676Sjpk /* release return buffer */ 3111676Sjpk (void) munmap((void *)callp, bufsize); 3121676Sjpk return (0); 3131676Sjpk } 3141676Sjpk (void) strcpy(*version, lvret.vers); 3151676Sjpk 3161676Sjpk if (callp != &call) 3171676Sjpk /* release return buffer */ 3181676Sjpk (void) munmap((void *)callp, bufsize); 3191676Sjpk return (ver_len); 3201676Sjpk } /* labelvers */ 3211676Sjpk #undef lvret 3221676Sjpk 3231676Sjpk #define ccall callp->param.acall.cargs.color_arg 3241676Sjpk #define cret callp->param.aret.rvals.color_ret 3251676Sjpk /* 3261676Sjpk * bltocolor - get ASCII color name of label. 3271676Sjpk * 3281676Sjpk * Entry label = Sensitivity Level of color to get. 3291676Sjpk * size = Size of the color_name array. 3301676Sjpk * color_name = Storage for ASCII color name string to be returned. 3311676Sjpk * 3321676Sjpk * Exit None. 3331676Sjpk * 3341676Sjpk * Returns NULL, If error (label encodings file not accessible, 3351676Sjpk * invalid label, no color for this label). 3361676Sjpk * Address of color_name parameter containing ASCII color name 3371676Sjpk * defined for the label. 3381676Sjpk * 3391676Sjpk * Calls __call_labeld(BLTOCOLOR), strlen. 3401676Sjpk */ 3411676Sjpk 3421676Sjpk char * 3431676Sjpk bltocolor_r(const blevel_t *label, size_t size, char *color_name) 3441676Sjpk { 3451676Sjpk labeld_data_t call; 3461676Sjpk labeld_data_t *callp = &call; 3471676Sjpk size_t bufsize = sizeof (labeld_data_t); 3481676Sjpk size_t datasize = CALL_SIZE(color_call_t, 0); 3491676Sjpk char *colorp; 3501676Sjpk 3511676Sjpk call.callop = BLTOCOLOR; 3521676Sjpk ccall.label = *label; 3531676Sjpk 3541676Sjpk if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) || 3551676Sjpk (callp->reterr != 0) || 3561676Sjpk (strlen(cret.color) >= size)) { 3571676Sjpk 3581676Sjpk if (callp != &call) 3591676Sjpk /* release return buffer */ 3601676Sjpk (void) munmap((void *)callp, bufsize); 3611676Sjpk return (NULL); 3621676Sjpk } 3631676Sjpk 3641676Sjpk colorp = strcpy(color_name, cret.color); 3651676Sjpk 3661676Sjpk if (callp != &call) 3671676Sjpk /* release return buffer */ 3681676Sjpk (void) munmap((void *)callp, bufsize); 3691676Sjpk return (colorp); 3701676Sjpk } /* bltocolor_r */ 3711676Sjpk #undef ccall 3721676Sjpk #undef cret 3731676Sjpk 3741676Sjpk /* 3751676Sjpk * bltocolor - get ASCII color name of label. 3761676Sjpk * 3771676Sjpk * Entry label = Sensitivity Level of color to get. 3781676Sjpk * 3791676Sjpk * Exit None. 3801676Sjpk * 3811676Sjpk * Returns NULL, If error (label encodings file not accessible, 3821676Sjpk * invalid label, no color for this label). 3831676Sjpk * Address of statically allocated string containing ASCII 3841676Sjpk * color name defined for the classification contained 3851676Sjpk * in label. 3861676Sjpk * 3871676Sjpk * Uses color. 3881676Sjpk * 3891676Sjpk * Calls bltocolor_r. 3901676Sjpk */ 3911676Sjpk 3921676Sjpk char * 3931676Sjpk bltocolor(const blevel_t *label) 3941676Sjpk { 3951676Sjpk return (bltocolor_r(label, sizeof (color), color)); 3961676Sjpk } /* bltocolor */ 3971676Sjpk 3981676Sjpk blevel_t * 3991676Sjpk blabel_alloc(void) 4001676Sjpk { 4011676Sjpk return (m_label_alloc(MAC_LABEL)); 4021676Sjpk } 4031676Sjpk 4041676Sjpk void 4051676Sjpk blabel_free(blevel_t *label_p) 4061676Sjpk { 4071676Sjpk free(label_p); 4081676Sjpk } 4091676Sjpk 4101676Sjpk size_t 4111676Sjpk blabel_size(void) 4121676Sjpk { 4131676Sjpk return (sizeof (blevel_t)); 4141676Sjpk } 4151676Sjpk 4161676Sjpk /* 4171676Sjpk * getuserrange - get label range for user 4181676Sjpk * 4191676Sjpk * Entry username of user 4201676Sjpk * 4211676Sjpk * Exit None. 4221676Sjpk * 4231676Sjpk * Returns NULL, If memory allocation failure or userdefs failure. 4241676Sjpk * otherwise returns the allocates m_range_t with the 4251676Sjpk * user's min and max labels set. 4261676Sjpk */ 4271676Sjpk 4281676Sjpk m_range_t * 4291676Sjpk getuserrange(const char *username) 4301676Sjpk { 4311676Sjpk char *kv_str = NULL; 4321676Sjpk userattr_t *userp = NULL; 4331676Sjpk m_range_t *range; 434*2664Srica m_label_t *def_min, *def_clr; 4351676Sjpk 4361676Sjpk /* 4371676Sjpk * Get some memory 4381676Sjpk */ 4391676Sjpk 4401676Sjpk if ((range = malloc(sizeof (m_range_t))) == NULL) { 4411676Sjpk return (NULL); 4421676Sjpk } 4431676Sjpk if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) { 4441676Sjpk free(range); 4451676Sjpk return (NULL); 4461676Sjpk } 447*2664Srica def_min = range->lower_bound; 4481676Sjpk if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) { 4491676Sjpk m_label_free(range->lower_bound); 4501676Sjpk free(range); 4511676Sjpk return (NULL); 4521676Sjpk } 453*2664Srica def_clr = range->upper_bound; 454*2664Srica 455*2664Srica /* If the user has an explicit min_label or clearance, use it. */ 456*2664Srica if ((userp = getusernam(username)) != NULL) { 457*2664Srica if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL)) 458*2664Srica != NULL) { 459*2664Srica (void) str_to_label(kv_str, &range->lower_bound, 460*2664Srica MAC_LABEL, L_NO_CORRECTION, NULL); 461*2664Srica def_min = NULL; /* don't get default later */ 462*2664Srica } 463*2664Srica if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE)) 464*2664Srica != NULL) { 465*2664Srica (void) str_to_label(kv_str, &range->upper_bound, 466*2664Srica USER_CLEAR, L_NO_CORRECTION, NULL); 467*2664Srica def_clr = NULL; /* don't get default later */ 468*2664Srica } 469*2664Srica free_userattr(userp); 4701676Sjpk } 471*2664Srica if (def_min || def_clr) { 472*2664Srica /* Need to use system default clearance and/or min_label */ 473*2664Srica if ((userdefs(def_min, def_clr)) == -1) { 474*2664Srica m_label_free(range->lower_bound); 475*2664Srica m_label_free(range->upper_bound); 476*2664Srica free(range); 477*2664Srica return (NULL); 478*2664Srica } 4791676Sjpk } 480*2664Srica 4811676Sjpk return (range); 4821676Sjpk } 483