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