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*4999Sgww * Copyright 2007 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 * String to binary label translations.
301676Sjpk */
311676Sjpk
321676Sjpk #include <ctype.h>
331676Sjpk #include <locale.h>
341676Sjpk #include <stdio.h>
351676Sjpk #include <stdlib.h>
361676Sjpk #include <strings.h>
371676Sjpk
381676Sjpk #include <tsol/label.h>
391676Sjpk
401676Sjpk #include "labeld.h"
411676Sjpk #include <sys/tsol/label_macro.h>
421676Sjpk
431676Sjpk #undef CALL_SIZE
441676Sjpk #define CALL_SIZE(type, buf) (size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
451676Sjpk + (buf))
461676Sjpk
471676Sjpk #if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */
481676Sjpk #define TEXT_DOMAIN "SYS_TEST"
491676Sjpk #endif /* TEXT_DOMAIN */
501676Sjpk
511676Sjpk /* short hands */
521676Sjpk
531676Sjpk #define IS_ADMIN_LOW(sl) \
541676Sjpk ((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
551676Sjpk
561676Sjpk #define IS_ADMIN_HIGH(sh) \
571676Sjpk ((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
581676Sjpk
591676Sjpk #define ISHEX(f, s) \
601676Sjpk (((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
611676Sjpk (((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
621676Sjpk (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
631676Sjpk
641676Sjpk #define slcall callp->param.acall.cargs.stobsl_arg
651676Sjpk #define slret callp->param.aret.rvals.stobsl_ret
661676Sjpk /*
671676Sjpk * stobsl - Translate Sensitivity Label string to a Binary Sensitivity
681676Sjpk * Label.
691676Sjpk *
701676Sjpk * Entry string = Sensitivity Label string to be translated.
711676Sjpk * label = Address of Binary Sensitivity Label to be initialized or
721676Sjpk * updated.
731676Sjpk * flags = Flags to control translation:
741676Sjpk * NO_CORRECTION implies NEW_LABEL.
751676Sjpk * NEW_LABEL, Initialize the label to a valid empty
761676Sjpk * Sensitivity Label structure.
771676Sjpk * NO_CORRECTION, Initialize the label to a valid
781676Sjpk * empty Sensitivity Label structure.
791676Sjpk * Prohibit correction to the Sensitivity Label.
801676Sjpk * Other, pass existing Sensitivity Label through for
811676Sjpk * modification.
821676Sjpk *
831676Sjpk * Exit label = Translated (updated) Binary Sensitivity Label.
841676Sjpk * error = If error reported, the error indicator,
851676Sjpk * -1, Unable to access label encodings file;
861676Sjpk * 0, Invalid binary label passed;
871676Sjpk * >0, Position after the first character in
881676Sjpk * string of error, 1 indicates entire string.
891676Sjpk * Otherwise, unchanged.
901676Sjpk *
911676Sjpk * Returns 0, If error.
921676Sjpk * 1, If successful.
931676Sjpk *
941676Sjpk * Calls __call_labeld(STOBSL), ISHEX, htobsl, strlen,
951676Sjpk * isspace,
961676Sjpk * strncasecmp.
971676Sjpk *
981676Sjpk * Uses ADMIN_HIGH, ADMIN_LOW.
991676Sjpk */
1001676Sjpk
1011676Sjpk int
stobsl(const char * string,bslabel_t * label,int flags,int * error)1021676Sjpk stobsl(const char *string, bslabel_t *label, int flags, int *error)
1031676Sjpk {
1041676Sjpk labeld_data_t call;
1051676Sjpk labeld_data_t *callp = &call;
1061676Sjpk size_t bufsize = sizeof (labeld_data_t);
1071676Sjpk size_t datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
1081676Sjpk int rval;
1091676Sjpk char *s = (char *)string;
1101676Sjpk
1111676Sjpk while (isspace(*s))
1121676Sjpk s++;
1131676Sjpk /* accept a leading '[' */
1141676Sjpk if (*s == '[') {
1151676Sjpk s++;
1161676Sjpk while (isspace(*s))
1171676Sjpk s++;
1181676Sjpk }
1191676Sjpk if (ISHEX(flags, s)) {
1201676Sjpk if (htobsl(s, label)) {
1211676Sjpk return (1);
1221676Sjpk } else {
1231676Sjpk if (error != NULL)
1241676Sjpk *error = 1;
1251676Sjpk return (0);
1261676Sjpk }
1271676Sjpk }
1281676Sjpk
1291676Sjpk if (datasize > bufsize) {
1301676Sjpk if ((callp = malloc(datasize)) == NULL) {
1311676Sjpk if (error != NULL)
1321676Sjpk *error = -1;
1331676Sjpk return (0);
1341676Sjpk }
1351676Sjpk bufsize = datasize;
1361676Sjpk }
1371676Sjpk callp->callop = STOBSL;
1381676Sjpk slcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
1391676Sjpk slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
1401676Sjpk slcall.label = *label;
1411676Sjpk (void) strcpy(slcall.string, string);
1421676Sjpk
1431676Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
1441676Sjpk int err = callp->reterr;
1451676Sjpk
1461676Sjpk if (callp != &call) {
1471676Sjpk /* free allocated buffer */
1481676Sjpk free(callp);
1491676Sjpk }
1501676Sjpk /*
1511676Sjpk * reterr == 0, OK,
1521676Sjpk * reterr < 0, invalid binary label,
1531676Sjpk * reterr > 0 error position, 1 == whole string
1541676Sjpk */
1551676Sjpk if (err == 0) {
1561676Sjpk *label = slret.label;
1571676Sjpk return (1);
1581676Sjpk } else if (err < 0) {
1591676Sjpk err = 0;
1601676Sjpk }
1611676Sjpk if (error != NULL)
1621676Sjpk *error = err;
1631676Sjpk return (0);
1641676Sjpk } else if (rval == NOSERVER) {
1651676Sjpk if (callp != &call) {
1661676Sjpk /* free allocated buffer */
1671676Sjpk free(callp);
1681676Sjpk }
1691676Sjpk /* server not present */
1701676Sjpk /* special case Admin High and Admin Low */
1711676Sjpk if (IS_ADMIN_LOW(s)) {
1721676Sjpk BSLLOW(label);
1731676Sjpk } else if (IS_ADMIN_HIGH(s)) {
1741676Sjpk BSLHIGH(label);
1751676Sjpk } else {
1761676Sjpk goto err1;
1771676Sjpk }
1781676Sjpk return (1);
1791676Sjpk }
1801676Sjpk if (callp != &call) {
1811676Sjpk /* free allocated buffer */
1821676Sjpk free(callp);
1831676Sjpk }
1841676Sjpk err1:
1851676Sjpk if (error != NULL)
1861676Sjpk *error = -1;
1871676Sjpk return (0);
1881676Sjpk } /* stobsl */
1891676Sjpk #undef slcall
1901676Sjpk #undef slret
1911676Sjpk
1921676Sjpk #define clrcall callp->param.acall.cargs.stobclear_arg
1931676Sjpk #define clrret callp->param.aret.rvals.stobclear_ret
1941676Sjpk /*
1951676Sjpk * stobclear - Translate Clearance string to a Binary Clearance.
1961676Sjpk *
1971676Sjpk * Entry string = Clearance string to be translated.
1981676Sjpk * clearance = Address of Binary Clearance to be initialized or
1991676Sjpk * updated.
2001676Sjpk * flags = Flags to control translation:
2011676Sjpk * NO_CORRECTION implies NEW_LABEL.
2021676Sjpk * NEW_LABEL, Initialize the label to a valid empty
2031676Sjpk * Sensitivity Label structure.
2041676Sjpk * NO_CORRECTION, Initialize the label to a valid
2051676Sjpk * empty Sensitivity Label structure.
2061676Sjpk * Prohibit correction to the Sensitivity Label.
2071676Sjpk * Other, pass existing Sensitivity Label through for
2081676Sjpk * modification.
2091676Sjpk *
2101676Sjpk * Exit clearance = Translated (updated) Binary Clearance.
2111676Sjpk * error = If error reported, the error indicator,
2121676Sjpk * -1, Unable to access label encodings file;
2131676Sjpk * 0, Invalid binary label passed;
2141676Sjpk * >0, Position after the first character in
2151676Sjpk * string of error, 1 indicates entire string.
2161676Sjpk * Otherwise, unchanged.
2171676Sjpk *
2181676Sjpk * Returns 0, If error.
2191676Sjpk * 1, If successful.
2201676Sjpk *
2211676Sjpk * Calls __call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
2221676Sjpk * isspace,
2231676Sjpk * strncasecmp.
2241676Sjpk *
2251676Sjpk * Uses ADMIN_HIGH, ADMIN_LOW.
2261676Sjpk */
2271676Sjpk
2281676Sjpk int
stobclear(const char * string,bclear_t * clearance,int flags,int * error)2291676Sjpk stobclear(const char *string, bclear_t *clearance, int flags, int *error)
2301676Sjpk {
2311676Sjpk labeld_data_t call;
2321676Sjpk labeld_data_t *callp = &call;
2331676Sjpk size_t bufsize = sizeof (labeld_data_t);
234*4999Sgww size_t datasize = CALL_SIZE(stobclear_call_t, strlen(string) + 1);
2351676Sjpk int rval;
2361676Sjpk
2371676Sjpk if (ISHEX(flags, string)) {
2381676Sjpk if (htobclear(string, clearance)) {
2391676Sjpk return (1);
2401676Sjpk } else {
2411676Sjpk if (error != NULL)
2421676Sjpk *error = 1;
2431676Sjpk return (0);
2441676Sjpk }
2451676Sjpk }
2461676Sjpk
2471676Sjpk if (datasize > bufsize) {
2481676Sjpk if ((callp = malloc(datasize)) == NULL) {
2491676Sjpk if (error != NULL)
2501676Sjpk *error = -1;
2511676Sjpk return (0);
2521676Sjpk }
2531676Sjpk bufsize = datasize;
2541676Sjpk }
2551676Sjpk callp->callop = STOBCLEAR;
2561676Sjpk clrcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
2571676Sjpk clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
2581676Sjpk clrcall.clear = *clearance;
2591676Sjpk (void) strcpy(clrcall.string, string);
2601676Sjpk
2611676Sjpk if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
2621676Sjpk int err = callp->reterr;
2631676Sjpk
2641676Sjpk if (callp != &call) {
2651676Sjpk /* free allocated buffer */
2661676Sjpk free(callp);
2671676Sjpk }
2681676Sjpk /*
2691676Sjpk * reterr == 0, OK,
2701676Sjpk * reterr < 0, invalid binary label,
2711676Sjpk * reterr > 0 error position, 1 == whole string
2721676Sjpk */
2731676Sjpk if (err == 0) {
2741676Sjpk *clearance = clrret.clear;
2751676Sjpk return (1);
2761676Sjpk } else if (err < 0) {
2771676Sjpk err = 0;
2781676Sjpk }
2791676Sjpk if (error != NULL)
2801676Sjpk *error = err;
2811676Sjpk return (0);
2821676Sjpk } else if (rval == NOSERVER) {
2831676Sjpk char *s = (char *)string;
2841676Sjpk
2851676Sjpk if (callp != &call) {
2861676Sjpk /* free allocated buffer */
2871676Sjpk free(callp);
2881676Sjpk }
2891676Sjpk /* server not present */
2901676Sjpk /* special case Admin High and Admin Low */
2911676Sjpk while (isspace(*s))
2921676Sjpk s++;
2931676Sjpk if (IS_ADMIN_LOW(s)) {
2941676Sjpk BCLEARLOW(clearance);
2951676Sjpk } else if (IS_ADMIN_HIGH(s)) {
2961676Sjpk BCLEARHIGH(clearance);
2971676Sjpk } else {
2981676Sjpk goto err1;
2991676Sjpk }
3001676Sjpk return (1);
3011676Sjpk }
3021676Sjpk if (callp != &call) {
3031676Sjpk /* free allocated buffer */
3041676Sjpk free(callp);
3051676Sjpk }
3061676Sjpk err1:
3071676Sjpk if (error != NULL)
3081676Sjpk *error = -1;
3091676Sjpk return (0);
3101676Sjpk } /* stobclear */
3111676Sjpk #undef clrcall
3121676Sjpk #undef clrret
313