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*a6080eb5Sgww * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
2345916cd2Sjpk * Use is subject to license terms.
2445916cd2Sjpk */
2545916cd2Sjpk
2645916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI"
2745916cd2Sjpk
2845916cd2Sjpk /*
2945916cd2Sjpk * String to binary label translations.
3045916cd2Sjpk */
3145916cd2Sjpk
3245916cd2Sjpk #include <ctype.h>
3345916cd2Sjpk #include <locale.h>
3445916cd2Sjpk #include <stdio.h>
3545916cd2Sjpk #include <stdlib.h>
3645916cd2Sjpk #include <strings.h>
3745916cd2Sjpk
3845916cd2Sjpk #include <tsol/label.h>
3945916cd2Sjpk
4045916cd2Sjpk #include "labeld.h"
4145916cd2Sjpk #include <sys/tsol/label_macro.h>
4245916cd2Sjpk
4345916cd2Sjpk #undef CALL_SIZE
4445916cd2Sjpk #define CALL_SIZE(type, buf) (size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
4545916cd2Sjpk + (buf))
4645916cd2Sjpk
4745916cd2Sjpk #if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */
4845916cd2Sjpk #define TEXT_DOMAIN "SYS_TEST"
4945916cd2Sjpk #endif /* TEXT_DOMAIN */
5045916cd2Sjpk
5145916cd2Sjpk /* short hands */
5245916cd2Sjpk
5345916cd2Sjpk #define IS_ADMIN_LOW(sl) \
5445916cd2Sjpk ((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
5545916cd2Sjpk
5645916cd2Sjpk #define IS_ADMIN_HIGH(sh) \
5745916cd2Sjpk ((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
5845916cd2Sjpk
5945916cd2Sjpk #define ISHEX(f, s) \
6045916cd2Sjpk (((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
6145916cd2Sjpk (((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
6245916cd2Sjpk (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
6345916cd2Sjpk
6445916cd2Sjpk #define slcall callp->param.acall.cargs.stobsl_arg
6545916cd2Sjpk #define slret callp->param.aret.rvals.stobsl_ret
6645916cd2Sjpk /*
6745916cd2Sjpk * stobsl - Translate Sensitivity Label string to a Binary Sensitivity
6845916cd2Sjpk * Label.
6945916cd2Sjpk *
7045916cd2Sjpk * Entry string = Sensitivity Label string to be translated.
7145916cd2Sjpk * label = Address of Binary Sensitivity Label to be initialized or
7245916cd2Sjpk * updated.
7345916cd2Sjpk * flags = Flags to control translation:
7445916cd2Sjpk * NO_CORRECTION implies NEW_LABEL.
7545916cd2Sjpk * NEW_LABEL, Initialize the label to a valid empty
7645916cd2Sjpk * Sensitivity Label structure.
7745916cd2Sjpk * NO_CORRECTION, Initialize the label to a valid
7845916cd2Sjpk * empty Sensitivity Label structure.
7945916cd2Sjpk * Prohibit correction to the Sensitivity Label.
8045916cd2Sjpk * Other, pass existing Sensitivity Label through for
8145916cd2Sjpk * modification.
8245916cd2Sjpk *
8345916cd2Sjpk * Exit label = Translated (updated) Binary Sensitivity Label.
8445916cd2Sjpk * error = If error reported, the error indicator,
8545916cd2Sjpk * -1, Unable to access label encodings file;
8645916cd2Sjpk * 0, Invalid binary label passed;
8745916cd2Sjpk * >0, Position after the first character in
8845916cd2Sjpk * string of error, 1 indicates entire string.
8945916cd2Sjpk * Otherwise, unchanged.
9045916cd2Sjpk *
9145916cd2Sjpk * Returns 0, If error.
9245916cd2Sjpk * 1, If successful.
9345916cd2Sjpk *
9445916cd2Sjpk * Calls __call_labeld(STOBSL), ISHEX, htobsl, strlen,
9545916cd2Sjpk * isspace,
9645916cd2Sjpk * strncasecmp.
9745916cd2Sjpk *
9845916cd2Sjpk * Uses ADMIN_HIGH, ADMIN_LOW.
9945916cd2Sjpk */
10045916cd2Sjpk
10145916cd2Sjpk int
stobsl(const char * string,bslabel_t * label,int flags,int * error)10245916cd2Sjpk stobsl(const char *string, bslabel_t *label, int flags, int *error)
10345916cd2Sjpk {
10445916cd2Sjpk labeld_data_t call;
10545916cd2Sjpk labeld_data_t *callp = &call;
10645916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
10745916cd2Sjpk size_t datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
10845916cd2Sjpk int rval;
10945916cd2Sjpk char *s = (char *)string;
11045916cd2Sjpk
11145916cd2Sjpk while (isspace(*s))
11245916cd2Sjpk s++;
11345916cd2Sjpk /* accept a leading '[' */
11445916cd2Sjpk if (*s == '[') {
11545916cd2Sjpk s++;
11645916cd2Sjpk while (isspace(*s))
11745916cd2Sjpk s++;
11845916cd2Sjpk }
11945916cd2Sjpk if (ISHEX(flags, s)) {
12045916cd2Sjpk if (htobsl(s, label)) {
12145916cd2Sjpk return (1);
12245916cd2Sjpk } else {
12345916cd2Sjpk if (error != NULL)
12445916cd2Sjpk *error = 1;
12545916cd2Sjpk return (0);
12645916cd2Sjpk }
12745916cd2Sjpk }
12845916cd2Sjpk
12945916cd2Sjpk if (datasize > bufsize) {
13045916cd2Sjpk if ((callp = malloc(datasize)) == NULL) {
13145916cd2Sjpk if (error != NULL)
13245916cd2Sjpk *error = -1;
13345916cd2Sjpk return (0);
13445916cd2Sjpk }
13545916cd2Sjpk bufsize = datasize;
13645916cd2Sjpk }
13745916cd2Sjpk callp->callop = STOBSL;
13845916cd2Sjpk slcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
13945916cd2Sjpk slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
14045916cd2Sjpk slcall.label = *label;
14145916cd2Sjpk (void) strcpy(slcall.string, string);
14245916cd2Sjpk
14345916cd2Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
14445916cd2Sjpk int err = callp->reterr;
14545916cd2Sjpk
14645916cd2Sjpk if (callp != &call) {
14745916cd2Sjpk /* free allocated buffer */
14845916cd2Sjpk free(callp);
14945916cd2Sjpk }
15045916cd2Sjpk /*
15145916cd2Sjpk * reterr == 0, OK,
15245916cd2Sjpk * reterr < 0, invalid binary label,
15345916cd2Sjpk * reterr > 0 error position, 1 == whole string
15445916cd2Sjpk */
15545916cd2Sjpk if (err == 0) {
15645916cd2Sjpk *label = slret.label;
15745916cd2Sjpk return (1);
15845916cd2Sjpk } else if (err < 0) {
15945916cd2Sjpk err = 0;
16045916cd2Sjpk }
16145916cd2Sjpk if (error != NULL)
16245916cd2Sjpk *error = err;
16345916cd2Sjpk return (0);
16445916cd2Sjpk } else if (rval == NOSERVER) {
16545916cd2Sjpk if (callp != &call) {
16645916cd2Sjpk /* free allocated buffer */
16745916cd2Sjpk free(callp);
16845916cd2Sjpk }
16945916cd2Sjpk /* server not present */
17045916cd2Sjpk /* special case Admin High and Admin Low */
17145916cd2Sjpk if (IS_ADMIN_LOW(s)) {
17245916cd2Sjpk BSLLOW(label);
17345916cd2Sjpk } else if (IS_ADMIN_HIGH(s)) {
17445916cd2Sjpk BSLHIGH(label);
17545916cd2Sjpk } else {
17645916cd2Sjpk goto err1;
17745916cd2Sjpk }
17845916cd2Sjpk return (1);
17945916cd2Sjpk }
18045916cd2Sjpk if (callp != &call) {
18145916cd2Sjpk /* free allocated buffer */
18245916cd2Sjpk free(callp);
18345916cd2Sjpk }
18445916cd2Sjpk err1:
18545916cd2Sjpk if (error != NULL)
18645916cd2Sjpk *error = -1;
18745916cd2Sjpk return (0);
18845916cd2Sjpk } /* stobsl */
18945916cd2Sjpk #undef slcall
19045916cd2Sjpk #undef slret
19145916cd2Sjpk
19245916cd2Sjpk #define clrcall callp->param.acall.cargs.stobclear_arg
19345916cd2Sjpk #define clrret callp->param.aret.rvals.stobclear_ret
19445916cd2Sjpk /*
19545916cd2Sjpk * stobclear - Translate Clearance string to a Binary Clearance.
19645916cd2Sjpk *
19745916cd2Sjpk * Entry string = Clearance string to be translated.
19845916cd2Sjpk * clearance = Address of Binary Clearance to be initialized or
19945916cd2Sjpk * updated.
20045916cd2Sjpk * flags = Flags to control translation:
20145916cd2Sjpk * NO_CORRECTION implies NEW_LABEL.
20245916cd2Sjpk * NEW_LABEL, Initialize the label to a valid empty
20345916cd2Sjpk * Sensitivity Label structure.
20445916cd2Sjpk * NO_CORRECTION, Initialize the label to a valid
20545916cd2Sjpk * empty Sensitivity Label structure.
20645916cd2Sjpk * Prohibit correction to the Sensitivity Label.
20745916cd2Sjpk * Other, pass existing Sensitivity Label through for
20845916cd2Sjpk * modification.
20945916cd2Sjpk *
21045916cd2Sjpk * Exit clearance = Translated (updated) Binary Clearance.
21145916cd2Sjpk * error = If error reported, the error indicator,
21245916cd2Sjpk * -1, Unable to access label encodings file;
21345916cd2Sjpk * 0, Invalid binary label passed;
21445916cd2Sjpk * >0, Position after the first character in
21545916cd2Sjpk * string of error, 1 indicates entire string.
21645916cd2Sjpk * Otherwise, unchanged.
21745916cd2Sjpk *
21845916cd2Sjpk * Returns 0, If error.
21945916cd2Sjpk * 1, If successful.
22045916cd2Sjpk *
22145916cd2Sjpk * Calls __call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
22245916cd2Sjpk * isspace,
22345916cd2Sjpk * strncasecmp.
22445916cd2Sjpk *
22545916cd2Sjpk * Uses ADMIN_HIGH, ADMIN_LOW.
22645916cd2Sjpk */
22745916cd2Sjpk
22845916cd2Sjpk int
stobclear(const char * string,bclear_t * clearance,int flags,int * error)22945916cd2Sjpk stobclear(const char *string, bclear_t *clearance, int flags, int *error)
23045916cd2Sjpk {
23145916cd2Sjpk labeld_data_t call;
23245916cd2Sjpk labeld_data_t *callp = &call;
23345916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
234*a6080eb5Sgww size_t datasize = CALL_SIZE(stobclear_call_t, strlen(string) + 1);
23545916cd2Sjpk int rval;
23645916cd2Sjpk
23745916cd2Sjpk if (ISHEX(flags, string)) {
23845916cd2Sjpk if (htobclear(string, clearance)) {
23945916cd2Sjpk return (1);
24045916cd2Sjpk } else {
24145916cd2Sjpk if (error != NULL)
24245916cd2Sjpk *error = 1;
24345916cd2Sjpk return (0);
24445916cd2Sjpk }
24545916cd2Sjpk }
24645916cd2Sjpk
24745916cd2Sjpk if (datasize > bufsize) {
24845916cd2Sjpk if ((callp = malloc(datasize)) == NULL) {
24945916cd2Sjpk if (error != NULL)
25045916cd2Sjpk *error = -1;
25145916cd2Sjpk return (0);
25245916cd2Sjpk }
25345916cd2Sjpk bufsize = datasize;
25445916cd2Sjpk }
25545916cd2Sjpk callp->callop = STOBCLEAR;
25645916cd2Sjpk clrcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
25745916cd2Sjpk clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
25845916cd2Sjpk clrcall.clear = *clearance;
25945916cd2Sjpk (void) strcpy(clrcall.string, string);
26045916cd2Sjpk
26145916cd2Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
26245916cd2Sjpk int err = callp->reterr;
26345916cd2Sjpk
26445916cd2Sjpk if (callp != &call) {
26545916cd2Sjpk /* free allocated buffer */
26645916cd2Sjpk free(callp);
26745916cd2Sjpk }
26845916cd2Sjpk /*
26945916cd2Sjpk * reterr == 0, OK,
27045916cd2Sjpk * reterr < 0, invalid binary label,
27145916cd2Sjpk * reterr > 0 error position, 1 == whole string
27245916cd2Sjpk */
27345916cd2Sjpk if (err == 0) {
27445916cd2Sjpk *clearance = clrret.clear;
27545916cd2Sjpk return (1);
27645916cd2Sjpk } else if (err < 0) {
27745916cd2Sjpk err = 0;
27845916cd2Sjpk }
27945916cd2Sjpk if (error != NULL)
28045916cd2Sjpk *error = err;
28145916cd2Sjpk return (0);
28245916cd2Sjpk } else if (rval == NOSERVER) {
28345916cd2Sjpk char *s = (char *)string;
28445916cd2Sjpk
28545916cd2Sjpk if (callp != &call) {
28645916cd2Sjpk /* free allocated buffer */
28745916cd2Sjpk free(callp);
28845916cd2Sjpk }
28945916cd2Sjpk /* server not present */
29045916cd2Sjpk /* special case Admin High and Admin Low */
29145916cd2Sjpk while (isspace(*s))
29245916cd2Sjpk s++;
29345916cd2Sjpk if (IS_ADMIN_LOW(s)) {
29445916cd2Sjpk BCLEARLOW(clearance);
29545916cd2Sjpk } else if (IS_ADMIN_HIGH(s)) {
29645916cd2Sjpk BCLEARHIGH(clearance);
29745916cd2Sjpk } else {
29845916cd2Sjpk goto err1;
29945916cd2Sjpk }
30045916cd2Sjpk return (1);
30145916cd2Sjpk }
30245916cd2Sjpk if (callp != &call) {
30345916cd2Sjpk /* free allocated buffer */
30445916cd2Sjpk free(callp);
30545916cd2Sjpk }
30645916cd2Sjpk err1:
30745916cd2Sjpk if (error != NULL)
30845916cd2Sjpk *error = -1;
30945916cd2Sjpk return (0);
31045916cd2Sjpk } /* stobclear */
31145916cd2Sjpk #undef clrcall
31245916cd2Sjpk #undef clrret
313