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 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 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