145916cd2Sjpk /*
245916cd2Sjpk * CDDL HEADER START
345916cd2Sjpk *
445916cd2Sjpk * The contents of this file are subject to the terms of the
545916cd2Sjpk * Common Development and Distribution License (the "License").
645916cd2Sjpk * You may not use this file except in compliance with the License.
745916cd2Sjpk *
845916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
945916cd2Sjpk * or http://www.opensolaris.org/os/licensing.
1045916cd2Sjpk * See the License for the specific language governing permissions
1145916cd2Sjpk * and limitations under the License.
1245916cd2Sjpk *
1345916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each
1445916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1545916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the
1645916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying
1745916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner]
1845916cd2Sjpk *
1945916cd2Sjpk * CDDL HEADER END
2045916cd2Sjpk */
2145916cd2Sjpk /*
22*42096647STony Nguyen * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2345916cd2Sjpk * Use is subject to license terms.
2445916cd2Sjpk */
2545916cd2Sjpk
2645916cd2Sjpk
2745916cd2Sjpk /*
2845916cd2Sjpk * Miscellaneous user interfaces to trusted label functions.
2945916cd2Sjpk *
3045916cd2Sjpk */
3145916cd2Sjpk
3245916cd2Sjpk
3345916cd2Sjpk #include <ctype.h>
3445916cd2Sjpk #include <stdlib.h>
3545916cd2Sjpk #include <strings.h>
3645916cd2Sjpk
3745916cd2Sjpk #include <sys/mman.h>
3845916cd2Sjpk
3945916cd2Sjpk #include <tsol/label.h>
4045916cd2Sjpk
4145916cd2Sjpk #include "labeld.h"
4245916cd2Sjpk #include "clnt.h"
4345916cd2Sjpk #include <sys/tsol/label_macro.h>
4445916cd2Sjpk #include <secdb.h>
4545916cd2Sjpk #include <user_attr.h>
4645916cd2Sjpk
4745916cd2Sjpk static bslabel_t slow, shigh; /* static Admin Low and High SLs */
4845916cd2Sjpk static bclear_t clow, chigh; /* static Admin Low and High CLRs */
4945916cd2Sjpk
5045916cd2Sjpk static char color[MAXCOLOR];
5145916cd2Sjpk
5245916cd2Sjpk
5345916cd2Sjpk #define incall callp->param.acall.cargs.inset_arg
5445916cd2Sjpk #define inret callp->param.aret.rvals.inset_ret
5545916cd2Sjpk /*
5645916cd2Sjpk * blinset - Check in a label set.
5745916cd2Sjpk *
5845916cd2Sjpk * Entry label = Sensitivity Label to check.
5945916cd2Sjpk * id = Label set identifier of set to check.
6045916cd2Sjpk *
6145916cd2Sjpk * Exit None.
6245916cd2Sjpk *
6345916cd2Sjpk * Returns -1, If label set unavailable, or server failure.
6445916cd2Sjpk * 0, If label not in label set.
6545916cd2Sjpk * 1, If label is in the label set.
6645916cd2Sjpk *
6745916cd2Sjpk * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH.
6845916cd2Sjpk *
6945916cd2Sjpk * Uses slow, shigh.
7045916cd2Sjpk */
7145916cd2Sjpk
7245916cd2Sjpk int
blinset(const bslabel_t * label,const set_id * id)7345916cd2Sjpk blinset(const bslabel_t *label, const set_id *id)
7445916cd2Sjpk {
7545916cd2Sjpk if (id->type == SYSTEM_ACCREDITATION_RANGE) {
7645916cd2Sjpk if (!BLTYPE(&slow, SUN_SL_ID)) {
7745916cd2Sjpk /* initialize static labels. */
7845916cd2Sjpk
7945916cd2Sjpk BSLLOW(&slow);
8045916cd2Sjpk BSLHIGH(&shigh);
8145916cd2Sjpk }
8245916cd2Sjpk
8345916cd2Sjpk if (BLTYPE(label, SUN_SL_ID) &&
8445916cd2Sjpk (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
8545916cd2Sjpk
8645916cd2Sjpk return (1);
8745916cd2Sjpk }
8845916cd2Sjpk if (id->type == USER_ACCREDITATION_RANGE ||
8945916cd2Sjpk id->type == SYSTEM_ACCREDITATION_RANGE) {
9045916cd2Sjpk labeld_data_t call;
9145916cd2Sjpk labeld_data_t *callp = &call;
9245916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
9345916cd2Sjpk size_t datasize = CALL_SIZE(inset_call_t, 0);
9445916cd2Sjpk
9545916cd2Sjpk call.callop = BLINSET;
9645916cd2Sjpk incall.label = *label;
9745916cd2Sjpk incall.type = id->type;
9845916cd2Sjpk
9945916cd2Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
10045916cd2Sjpk /* process error */
10145916cd2Sjpk
10245916cd2Sjpk return (-1);
10345916cd2Sjpk }
10445916cd2Sjpk return (inret.inset);
10545916cd2Sjpk } else {
10645916cd2Sjpk /*
10745916cd2Sjpk * Only System and User Accreditation Ranges presently
10845916cd2Sjpk * implemented.
10945916cd2Sjpk */
11045916cd2Sjpk return (-1);
11145916cd2Sjpk }
11245916cd2Sjpk }
11345916cd2Sjpk #undef incall
11445916cd2Sjpk #undef inret
11545916cd2Sjpk
11645916cd2Sjpk #define slvcall callp->param.acall.cargs.slvalid_arg
11745916cd2Sjpk #define slvret callp->param.aret.rvals.slvalid_ret
11845916cd2Sjpk /*
11945916cd2Sjpk * bslvalid - Check Sensitivity Label for validity.
12045916cd2Sjpk *
12145916cd2Sjpk * Entry label = Sensitivity Label to check.
12245916cd2Sjpk *
12345916cd2Sjpk * Exit None.
12445916cd2Sjpk *
12545916cd2Sjpk * Returns -1, If unable to access label encodings file, or server failure.
12645916cd2Sjpk * 0, If label not valid.
12745916cd2Sjpk * 1, If label is valid.
12845916cd2Sjpk *
12945916cd2Sjpk * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH.
13045916cd2Sjpk *
13145916cd2Sjpk * Uses slow, shigh.
13245916cd2Sjpk *
13345916cd2Sjpk */
13445916cd2Sjpk
13545916cd2Sjpk int
bslvalid(const bslabel_t * label)13645916cd2Sjpk bslvalid(const bslabel_t *label)
13745916cd2Sjpk {
13845916cd2Sjpk labeld_data_t call;
13945916cd2Sjpk labeld_data_t *callp = &call;
14045916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
14145916cd2Sjpk size_t datasize = CALL_SIZE(slvalid_call_t, 0);
14245916cd2Sjpk
14345916cd2Sjpk if (!BLTYPE(&slow, SUN_SL_ID)) {
14445916cd2Sjpk /* initialize static labels. */
14545916cd2Sjpk
14645916cd2Sjpk BSLLOW(&slow);
14745916cd2Sjpk BSLHIGH(&shigh);
14845916cd2Sjpk }
14945916cd2Sjpk
15045916cd2Sjpk if (BLTYPE(label, SUN_SL_ID) &&
15145916cd2Sjpk (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
15245916cd2Sjpk
15345916cd2Sjpk return (1);
15445916cd2Sjpk }
15545916cd2Sjpk
15645916cd2Sjpk call.callop = BSLVALID;
15745916cd2Sjpk slvcall.label = *label;
15845916cd2Sjpk
15945916cd2Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
16045916cd2Sjpk /* process error */
16145916cd2Sjpk
16245916cd2Sjpk return (-1);
16345916cd2Sjpk }
16445916cd2Sjpk return (slvret.valid);
16545916cd2Sjpk }
16645916cd2Sjpk #undef slvcall
16745916cd2Sjpk #undef slvret
16845916cd2Sjpk
16945916cd2Sjpk #define clrvcall callp->param.acall.cargs.clrvalid_arg
17045916cd2Sjpk #define clrvret callp->param.aret.rvals.clrvalid_ret
17145916cd2Sjpk /*
17245916cd2Sjpk * bclearvalid - Check Clearance for validity.
17345916cd2Sjpk *
17445916cd2Sjpk * Entry clearance = Clearance to check.
17545916cd2Sjpk *
17645916cd2Sjpk * Exit None.
17745916cd2Sjpk *
17845916cd2Sjpk * Returns -1, If unable to access label encodings file, or server failure.
17945916cd2Sjpk * 0, If label not valid.
18045916cd2Sjpk * 1, If label is valid.
18145916cd2Sjpk *
18245916cd2Sjpk * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH.
18345916cd2Sjpk *
18445916cd2Sjpk * Uses clow, chigh.
18545916cd2Sjpk *
18645916cd2Sjpk */
18745916cd2Sjpk
18845916cd2Sjpk int
bclearvalid(const bclear_t * clearance)18945916cd2Sjpk bclearvalid(const bclear_t *clearance)
19045916cd2Sjpk {
19145916cd2Sjpk labeld_data_t call;
19245916cd2Sjpk labeld_data_t *callp = &call;
19345916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
19445916cd2Sjpk size_t datasize = CALL_SIZE(clrvalid_call_t, 0);
19545916cd2Sjpk
19645916cd2Sjpk if (!BLTYPE(&clow, SUN_CLR_ID)) {
19745916cd2Sjpk /* initialize static labels. */
19845916cd2Sjpk
19945916cd2Sjpk BCLEARLOW(&clow);
20045916cd2Sjpk BCLEARHIGH(&chigh);
20145916cd2Sjpk }
20245916cd2Sjpk
20345916cd2Sjpk if (BLTYPE(clearance, SUN_CLR_ID) &&
20445916cd2Sjpk (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
20545916cd2Sjpk
20645916cd2Sjpk return (1);
20745916cd2Sjpk }
20845916cd2Sjpk
20945916cd2Sjpk call.callop = BCLEARVALID;
21045916cd2Sjpk clrvcall.clear = *clearance;
21145916cd2Sjpk
21245916cd2Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
21345916cd2Sjpk /* process error */
21445916cd2Sjpk
21545916cd2Sjpk return (-1);
21645916cd2Sjpk }
21745916cd2Sjpk return (clrvret.valid);
21845916cd2Sjpk }
21945916cd2Sjpk #undef clrvcall
22045916cd2Sjpk #undef clrvret
22145916cd2Sjpk
22245916cd2Sjpk #define inforet callp->param.aret.rvals.info_ret
22345916cd2Sjpk /*
22445916cd2Sjpk * labelinfo - Get information about the label encodings file.
22545916cd2Sjpk *
22645916cd2Sjpk * Entry info = Address of label_info structure to update.
22745916cd2Sjpk *
22845916cd2Sjpk * Exit info = Updated.
22945916cd2Sjpk *
23045916cd2Sjpk * Returns -1, If unable to access label encodings file, or server failure.
23145916cd2Sjpk * 1, If successful.
23245916cd2Sjpk *
23345916cd2Sjpk * Calls __call_labeld(LABELINFO).
23445916cd2Sjpk */
23545916cd2Sjpk
23645916cd2Sjpk int
labelinfo(struct label_info * info)23745916cd2Sjpk labelinfo(struct label_info *info)
23845916cd2Sjpk {
23945916cd2Sjpk labeld_data_t call;
24045916cd2Sjpk labeld_data_t *callp = &call;
24145916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
24245916cd2Sjpk size_t datasize = CALL_SIZE(info_call_t, 0);
24345916cd2Sjpk int rval;
24445916cd2Sjpk
24545916cd2Sjpk call.callop = LABELINFO;
24645916cd2Sjpk
24745916cd2Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
24845916cd2Sjpk /* process error */
24945916cd2Sjpk
25045916cd2Sjpk return (-1);
25145916cd2Sjpk }
25245916cd2Sjpk *info = inforet.info;
25345916cd2Sjpk return (rval);
25445916cd2Sjpk }
25545916cd2Sjpk #undef inforet
25645916cd2Sjpk
25745916cd2Sjpk #define lvret callp->param.aret.rvals.vers_ret
25845916cd2Sjpk /*
25945916cd2Sjpk * labelvers - Get version string of the label encodings file.
26045916cd2Sjpk *
26145916cd2Sjpk * Entry version = Address of string pointer to return.
26245916cd2Sjpk * len = Length of string if pre-allocated.
26345916cd2Sjpk *
26445916cd2Sjpk * Exit version = Updated.
26545916cd2Sjpk *
26645916cd2Sjpk * Returns -1, If unable to access label encodings file, or server failure.
26745916cd2Sjpk * 0, If unable to allocate version string,
26845916cd2Sjpk * or pre-allocated version string to short
26945916cd2Sjpk * (and **version = '\0').
27045916cd2Sjpk * length (including null) of version string, If successful.
27145916cd2Sjpk *
27245916cd2Sjpk * Calls __call_labeld(LABELVERS)
27345916cd2Sjpk * malloc, strlen.
27445916cd2Sjpk */
27545916cd2Sjpk
27645916cd2Sjpk ssize_t
labelvers(char ** version,size_t len)27745916cd2Sjpk labelvers(char **version, size_t len)
27845916cd2Sjpk {
27945916cd2Sjpk labeld_data_t call;
28045916cd2Sjpk labeld_data_t *callp = &call;
28145916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
28245916cd2Sjpk size_t datasize = CALL_SIZE(vers_call_t, 0);
28345916cd2Sjpk size_t ver_len;
28445916cd2Sjpk
28545916cd2Sjpk call.callop = LABELVERS;
28645916cd2Sjpk
28745916cd2Sjpk if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
28845916cd2Sjpk
28945916cd2Sjpk if (callp != &call)
29045916cd2Sjpk /* release return buffer */
29145916cd2Sjpk (void) munmap((void *)callp, bufsize);
29245916cd2Sjpk return (-1);
29345916cd2Sjpk }
29445916cd2Sjpk
29545916cd2Sjpk /* unpack length */
29645916cd2Sjpk
29745916cd2Sjpk ver_len = strlen(lvret.vers) + 1;
29845916cd2Sjpk if (*version == NULL) {
29945916cd2Sjpk if ((*version = malloc(ver_len)) == NULL) {
30045916cd2Sjpk if (callp != &call)
30145916cd2Sjpk /* release return buffer */
30245916cd2Sjpk (void) munmap((void *)callp, bufsize);
30345916cd2Sjpk return (0);
30445916cd2Sjpk }
30545916cd2Sjpk } else if (ver_len > len) {
30645916cd2Sjpk **version = '\0';
30745916cd2Sjpk if (callp != &call)
30845916cd2Sjpk /* release return buffer */
30945916cd2Sjpk (void) munmap((void *)callp, bufsize);
31045916cd2Sjpk return (0);
31145916cd2Sjpk }
31245916cd2Sjpk (void) strcpy(*version, lvret.vers);
31345916cd2Sjpk
31445916cd2Sjpk if (callp != &call)
31545916cd2Sjpk /* release return buffer */
31645916cd2Sjpk (void) munmap((void *)callp, bufsize);
31745916cd2Sjpk return (ver_len);
31845916cd2Sjpk } /* labelvers */
31945916cd2Sjpk #undef lvret
32045916cd2Sjpk
32145916cd2Sjpk #define ccall callp->param.acall.cargs.color_arg
32245916cd2Sjpk #define cret callp->param.aret.rvals.color_ret
32345916cd2Sjpk /*
32445916cd2Sjpk * bltocolor - get ASCII color name of label.
32545916cd2Sjpk *
32645916cd2Sjpk * Entry label = Sensitivity Level of color to get.
32745916cd2Sjpk * size = Size of the color_name array.
32845916cd2Sjpk * color_name = Storage for ASCII color name string to be returned.
32945916cd2Sjpk *
33045916cd2Sjpk * Exit None.
33145916cd2Sjpk *
33245916cd2Sjpk * Returns NULL, If error (label encodings file not accessible,
33345916cd2Sjpk * invalid label, no color for this label).
33445916cd2Sjpk * Address of color_name parameter containing ASCII color name
33545916cd2Sjpk * defined for the label.
33645916cd2Sjpk *
33745916cd2Sjpk * Calls __call_labeld(BLTOCOLOR), strlen.
33845916cd2Sjpk */
33945916cd2Sjpk
34045916cd2Sjpk char *
bltocolor_r(const blevel_t * label,size_t size,char * color_name)34145916cd2Sjpk bltocolor_r(const blevel_t *label, size_t size, char *color_name)
34245916cd2Sjpk {
34345916cd2Sjpk labeld_data_t call;
34445916cd2Sjpk labeld_data_t *callp = &call;
34545916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
34645916cd2Sjpk size_t datasize = CALL_SIZE(color_call_t, 0);
34745916cd2Sjpk char *colorp;
34845916cd2Sjpk
34945916cd2Sjpk call.callop = BLTOCOLOR;
35045916cd2Sjpk ccall.label = *label;
35145916cd2Sjpk
35245916cd2Sjpk if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
35345916cd2Sjpk (callp->reterr != 0) ||
35445916cd2Sjpk (strlen(cret.color) >= size)) {
35545916cd2Sjpk
35645916cd2Sjpk if (callp != &call)
35745916cd2Sjpk /* release return buffer */
35845916cd2Sjpk (void) munmap((void *)callp, bufsize);
35945916cd2Sjpk return (NULL);
36045916cd2Sjpk }
36145916cd2Sjpk
36245916cd2Sjpk colorp = strcpy(color_name, cret.color);
36345916cd2Sjpk
36445916cd2Sjpk if (callp != &call)
36545916cd2Sjpk /* release return buffer */
36645916cd2Sjpk (void) munmap((void *)callp, bufsize);
36745916cd2Sjpk return (colorp);
36845916cd2Sjpk } /* bltocolor_r */
36945916cd2Sjpk #undef ccall
37045916cd2Sjpk #undef cret
37145916cd2Sjpk
37245916cd2Sjpk /*
37345916cd2Sjpk * bltocolor - get ASCII color name of label.
37445916cd2Sjpk *
37545916cd2Sjpk * Entry label = Sensitivity Level of color to get.
37645916cd2Sjpk *
37745916cd2Sjpk * Exit None.
37845916cd2Sjpk *
37945916cd2Sjpk * Returns NULL, If error (label encodings file not accessible,
38045916cd2Sjpk * invalid label, no color for this label).
38145916cd2Sjpk * Address of statically allocated string containing ASCII
38245916cd2Sjpk * color name defined for the classification contained
38345916cd2Sjpk * in label.
38445916cd2Sjpk *
38545916cd2Sjpk * Uses color.
38645916cd2Sjpk *
38745916cd2Sjpk * Calls bltocolor_r.
38845916cd2Sjpk */
38945916cd2Sjpk
39045916cd2Sjpk char *
bltocolor(const blevel_t * label)39145916cd2Sjpk bltocolor(const blevel_t *label)
39245916cd2Sjpk {
39345916cd2Sjpk return (bltocolor_r(label, sizeof (color), color));
39445916cd2Sjpk } /* bltocolor */
39545916cd2Sjpk
39645916cd2Sjpk blevel_t *
blabel_alloc(void)39745916cd2Sjpk blabel_alloc(void)
39845916cd2Sjpk {
39945916cd2Sjpk return (m_label_alloc(MAC_LABEL));
40045916cd2Sjpk }
40145916cd2Sjpk
40245916cd2Sjpk void
blabel_free(blevel_t * label_p)40345916cd2Sjpk blabel_free(blevel_t *label_p)
40445916cd2Sjpk {
40545916cd2Sjpk free(label_p);
40645916cd2Sjpk }
40745916cd2Sjpk
408*42096647STony Nguyen size32_t
blabel_size(void)40945916cd2Sjpk blabel_size(void)
41045916cd2Sjpk {
41145916cd2Sjpk return (sizeof (blevel_t));
41245916cd2Sjpk }
41345916cd2Sjpk
41445916cd2Sjpk /*
41545916cd2Sjpk * getuserrange - get label range for user
41645916cd2Sjpk *
41745916cd2Sjpk * Entry username of user
41845916cd2Sjpk *
41945916cd2Sjpk * Exit None.
42045916cd2Sjpk *
42145916cd2Sjpk * Returns NULL, If memory allocation failure or userdefs failure.
42245916cd2Sjpk * otherwise returns the allocates m_range_t with the
42345916cd2Sjpk * user's min and max labels set.
42445916cd2Sjpk */
42545916cd2Sjpk
42645916cd2Sjpk m_range_t *
getuserrange(const char * username)42745916cd2Sjpk getuserrange(const char *username)
42845916cd2Sjpk {
42945916cd2Sjpk char *kv_str = NULL;
43045916cd2Sjpk userattr_t *userp = NULL;
43145916cd2Sjpk m_range_t *range;
432aa2e15f6Srica m_label_t *def_min, *def_clr;
43345916cd2Sjpk
43445916cd2Sjpk /*
43545916cd2Sjpk * Get some memory
43645916cd2Sjpk */
43745916cd2Sjpk
43845916cd2Sjpk if ((range = malloc(sizeof (m_range_t))) == NULL) {
43945916cd2Sjpk return (NULL);
44045916cd2Sjpk }
44145916cd2Sjpk if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
44245916cd2Sjpk free(range);
44345916cd2Sjpk return (NULL);
44445916cd2Sjpk }
445aa2e15f6Srica def_min = range->lower_bound;
44645916cd2Sjpk if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
44745916cd2Sjpk m_label_free(range->lower_bound);
44845916cd2Sjpk free(range);
44945916cd2Sjpk return (NULL);
45045916cd2Sjpk }
451aa2e15f6Srica def_clr = range->upper_bound;
452aa2e15f6Srica
453aa2e15f6Srica /* If the user has an explicit min_label or clearance, use it. */
454aa2e15f6Srica if ((userp = getusernam(username)) != NULL) {
455aa2e15f6Srica if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL))
456aa2e15f6Srica != NULL) {
457aa2e15f6Srica (void) str_to_label(kv_str, &range->lower_bound,
458aa2e15f6Srica MAC_LABEL, L_NO_CORRECTION, NULL);
459aa2e15f6Srica def_min = NULL; /* don't get default later */
460aa2e15f6Srica }
461aa2e15f6Srica if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE))
462aa2e15f6Srica != NULL) {
463aa2e15f6Srica (void) str_to_label(kv_str, &range->upper_bound,
464aa2e15f6Srica USER_CLEAR, L_NO_CORRECTION, NULL);
465aa2e15f6Srica def_clr = NULL; /* don't get default later */
466aa2e15f6Srica }
467aa2e15f6Srica free_userattr(userp);
468aa2e15f6Srica }
469aa2e15f6Srica if (def_min || def_clr) {
470aa2e15f6Srica /* Need to use system default clearance and/or min_label */
471aa2e15f6Srica if ((userdefs(def_min, def_clr)) == -1) {
47245916cd2Sjpk m_label_free(range->lower_bound);
47345916cd2Sjpk m_label_free(range->upper_bound);
47445916cd2Sjpk free(range);
47545916cd2Sjpk return (NULL);
47645916cd2Sjpk }
47745916cd2Sjpk }
478aa2e15f6Srica
47945916cd2Sjpk return (range);
48045916cd2Sjpk }
481