1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * String to binary label translations.
28 */
29
30 #include <ctype.h>
31 #include <locale.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <strings.h>
35
36 #include <tsol/label.h>
37
38 #include "labeld.h"
39 #include <sys/tsol/label_macro.h>
40
41 #undef CALL_SIZE
42 #define CALL_SIZE(type, buf) (size_t)(sizeof (type) - BUFSIZE + sizeof (int)\
43 + (buf))
44
45 #if !defined(TEXT_DOMAIN) /* should be defined by Makefiles */
46 #define TEXT_DOMAIN "SYS_TEST"
47 #endif /* TEXT_DOMAIN */
48
49 /* short hands */
50
51 #define IS_ADMIN_LOW(sl) \
52 ((strncasecmp(sl, ADMIN_LOW, (sizeof (ADMIN_LOW) - 1)) == 0))
53
54 #define IS_ADMIN_HIGH(sh) \
55 ((strncasecmp(sh, ADMIN_HIGH, (sizeof (ADMIN_HIGH) - 1)) == 0))
56
57 #define ISHEX(f, s) \
58 (((((f) & NEW_LABEL) == ((f) | NEW_LABEL)) || \
59 (((f) & NO_CORRECTION) == ((f) | NO_CORRECTION))) && \
60 (((s)[0] == '0') && (((s)[1] == 'x') || ((s)[1] == 'X'))))
61
62 #define slcall callp->param.acall.cargs.stobsl_arg
63 #define slret callp->param.aret.rvals.stobsl_ret
64 /*
65 * stobsl - Translate Sensitivity Label string to a Binary Sensitivity
66 * Label.
67 *
68 * Entry string = Sensitivity Label string to be translated.
69 * label = Address of Binary Sensitivity Label to be initialized or
70 * updated.
71 * flags = Flags to control translation:
72 * NO_CORRECTION implies NEW_LABEL.
73 * NEW_LABEL, Initialize the label to a valid empty
74 * Sensitivity Label structure.
75 * NO_CORRECTION, Initialize the label to a valid
76 * empty Sensitivity Label structure.
77 * Prohibit correction to the Sensitivity Label.
78 * Other, pass existing Sensitivity Label through for
79 * modification.
80 *
81 * Exit label = Translated (updated) Binary Sensitivity Label.
82 * error = If error reported, the error indicator,
83 * -1, Unable to access label encodings file;
84 * 0, Invalid binary label passed;
85 * >0, Position after the first character in
86 * string of error, 1 indicates entire string.
87 * Otherwise, unchanged.
88 *
89 * Returns 0, If error.
90 * 1, If successful.
91 *
92 * Calls __call_labeld(STOBSL), ISHEX, htobsl, strlen,
93 * isspace,
94 * strncasecmp.
95 *
96 * Uses ADMIN_HIGH, ADMIN_LOW.
97 */
98
99 int
stobsl(const char * string,bslabel_t * label,int flags,int * error)100 stobsl(const char *string, bslabel_t *label, int flags, int *error)
101 {
102 labeld_data_t call;
103 labeld_data_t *callp = &call;
104 size_t bufsize = sizeof (labeld_data_t);
105 size_t datasize = CALL_SIZE(stobsl_call_t, strlen(string) + 1);
106 int rval;
107 char *s = (char *)string;
108
109 while (isspace(*s))
110 s++;
111 /* accept a leading '[' */
112 if (*s == '[') {
113 s++;
114 while (isspace(*s))
115 s++;
116 }
117 if (ISHEX(flags, s)) {
118 if (htobsl(s, label)) {
119 return (1);
120 } else {
121 if (error != NULL)
122 *error = 1;
123 return (0);
124 }
125 }
126
127 if (datasize > bufsize) {
128 if ((callp = malloc(datasize)) == NULL) {
129 if (error != NULL)
130 *error = -1;
131 return (0);
132 }
133 bufsize = datasize;
134 }
135 callp->callop = STOBSL;
136 slcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
137 slcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
138 slcall.label = *label;
139 (void) strcpy(slcall.string, string);
140
141 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
142 int err = callp->reterr;
143
144 if (callp != &call) {
145 /* free allocated buffer */
146 free(callp);
147 }
148 /*
149 * reterr == 0, OK,
150 * reterr < 0, invalid binary label,
151 * reterr > 0 error position, 1 == whole string
152 */
153 if (err == 0) {
154 *label = slret.label;
155 return (1);
156 } else if (err < 0) {
157 err = 0;
158 }
159 if (error != NULL)
160 *error = err;
161 return (0);
162 } else if (rval == NOSERVER) {
163 if (callp != &call) {
164 /* free allocated buffer */
165 free(callp);
166 }
167 /* server not present */
168 /* special case Admin High and Admin Low */
169 if (IS_ADMIN_LOW(s)) {
170 BSLLOW(label);
171 } else if (IS_ADMIN_HIGH(s)) {
172 BSLHIGH(label);
173 } else {
174 goto err1;
175 }
176 return (1);
177 }
178 if (callp != &call) {
179 /* free allocated buffer */
180 free(callp);
181 }
182 err1:
183 if (error != NULL)
184 *error = -1;
185 return (0);
186 } /* stobsl */
187 #undef slcall
188 #undef slret
189
190 #define clrcall callp->param.acall.cargs.stobclear_arg
191 #define clrret callp->param.aret.rvals.stobclear_ret
192 /*
193 * stobclear - Translate Clearance string to a Binary Clearance.
194 *
195 * Entry string = Clearance string to be translated.
196 * clearance = Address of Binary Clearance to be initialized or
197 * updated.
198 * flags = Flags to control translation:
199 * NO_CORRECTION implies NEW_LABEL.
200 * NEW_LABEL, Initialize the label to a valid empty
201 * Sensitivity Label structure.
202 * NO_CORRECTION, Initialize the label to a valid
203 * empty Sensitivity Label structure.
204 * Prohibit correction to the Sensitivity Label.
205 * Other, pass existing Sensitivity Label through for
206 * modification.
207 *
208 * Exit clearance = Translated (updated) Binary Clearance.
209 * error = If error reported, the error indicator,
210 * -1, Unable to access label encodings file;
211 * 0, Invalid binary label passed;
212 * >0, Position after the first character in
213 * string of error, 1 indicates entire string.
214 * Otherwise, unchanged.
215 *
216 * Returns 0, If error.
217 * 1, If successful.
218 *
219 * Calls __call_labeld(STOBCLEAR), ISHEX, htobsl, strlen,
220 * isspace,
221 * strncasecmp.
222 *
223 * Uses ADMIN_HIGH, ADMIN_LOW.
224 */
225
226 int
stobclear(const char * string,bclear_t * clearance,int flags,int * error)227 stobclear(const char *string, bclear_t *clearance, int flags, int *error)
228 {
229 labeld_data_t call;
230 labeld_data_t *callp = &call;
231 size_t bufsize = sizeof (labeld_data_t);
232 size_t datasize = CALL_SIZE(stobclear_call_t, strlen(string) + 1);
233 int rval;
234
235 if (ISHEX(flags, string)) {
236 if (htobclear(string, clearance)) {
237 return (1);
238 } else {
239 if (error != NULL)
240 *error = 1;
241 return (0);
242 }
243 }
244
245 if (datasize > bufsize) {
246 if ((callp = malloc(datasize)) == NULL) {
247 if (error != NULL)
248 *error = -1;
249 return (0);
250 }
251 bufsize = datasize;
252 }
253 callp->callop = STOBCLEAR;
254 clrcall.flags = (flags&NEW_LABEL) ? LABELS_NEW_LABEL : 0;
255 clrcall.flags |= (flags&NO_CORRECTION) ? LABELS_FULL_PARSE : 0;
256 clrcall.clear = *clearance;
257 (void) strcpy(clrcall.string, string);
258
259 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) == SUCCESS) {
260 int err = callp->reterr;
261
262 if (callp != &call) {
263 /* free allocated buffer */
264 free(callp);
265 }
266 /*
267 * reterr == 0, OK,
268 * reterr < 0, invalid binary label,
269 * reterr > 0 error position, 1 == whole string
270 */
271 if (err == 0) {
272 *clearance = clrret.clear;
273 return (1);
274 } else if (err < 0) {
275 err = 0;
276 }
277 if (error != NULL)
278 *error = err;
279 return (0);
280 } else if (rval == NOSERVER) {
281 char *s = (char *)string;
282
283 if (callp != &call) {
284 /* free allocated buffer */
285 free(callp);
286 }
287 /* server not present */
288 /* special case Admin High and Admin Low */
289 while (isspace(*s))
290 s++;
291 if (IS_ADMIN_LOW(s)) {
292 BCLEARLOW(clearance);
293 } else if (IS_ADMIN_HIGH(s)) {
294 BCLEARHIGH(clearance);
295 } else {
296 goto err1;
297 }
298 return (1);
299 }
300 if (callp != &call) {
301 /* free allocated buffer */
302 free(callp);
303 }
304 err1:
305 if (error != NULL)
306 *error = -1;
307 return (0);
308 } /* stobclear */
309 #undef clrcall
310 #undef clrret
311