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
blinset(const bslabel_t * label,const set_id * id)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
bslvalid(const bslabel_t * label)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
bclearvalid(const bclear_t * clearance)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
labelinfo(struct label_info * info)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
labelvers(char ** version,size_t len)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 *
bltocolor_r(const blevel_t * label,size_t size,char * color_name)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 *
bltocolor(const blevel_t * label)3911676Sjpk bltocolor(const blevel_t *label)
3921676Sjpk {
3931676Sjpk return (bltocolor_r(label, sizeof (color), color));
3941676Sjpk } /* bltocolor */
3951676Sjpk
3961676Sjpk blevel_t *
blabel_alloc(void)3971676Sjpk blabel_alloc(void)
3981676Sjpk {
3991676Sjpk return (m_label_alloc(MAC_LABEL));
4001676Sjpk }
4011676Sjpk
4021676Sjpk void
blabel_free(blevel_t * label_p)4031676Sjpk blabel_free(blevel_t *label_p)
4041676Sjpk {
4051676Sjpk free(label_p);
4061676Sjpk }
4071676Sjpk
408*9112STon.Nguyen@Sun.COM size32_t
blabel_size(void)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 *
getuserrange(const char * username)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