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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26
27 /*
28 * Miscellaneous user interfaces to trusted label functions.
29 *
30 */
31
32
33 #include <ctype.h>
34 #include <stdlib.h>
35 #include <strings.h>
36
37 #include <sys/mman.h>
38
39 #include <tsol/label.h>
40
41 #include "labeld.h"
42 #include "clnt.h"
43 #include <sys/tsol/label_macro.h>
44 #include <secdb.h>
45 #include <user_attr.h>
46
47 static bslabel_t slow, shigh; /* static Admin Low and High SLs */
48 static bclear_t clow, chigh; /* static Admin Low and High CLRs */
49
50 static char color[MAXCOLOR];
51
52
53 #define incall callp->param.acall.cargs.inset_arg
54 #define inret callp->param.aret.rvals.inset_ret
55 /*
56 * blinset - Check in a label set.
57 *
58 * Entry label = Sensitivity Label to check.
59 * id = Label set identifier of set to check.
60 *
61 * Exit None.
62 *
63 * Returns -1, If label set unavailable, or server failure.
64 * 0, If label not in label set.
65 * 1, If label is in the label set.
66 *
67 * Calls __call_labeld(BLINSET), BLTYPE, BSLLOW, BSLHIGH.
68 *
69 * Uses slow, shigh.
70 */
71
72 int
blinset(const bslabel_t * label,const set_id * id)73 blinset(const bslabel_t *label, const set_id *id)
74 {
75 if (id->type == SYSTEM_ACCREDITATION_RANGE) {
76 if (!BLTYPE(&slow, SUN_SL_ID)) {
77 /* initialize static labels. */
78
79 BSLLOW(&slow);
80 BSLHIGH(&shigh);
81 }
82
83 if (BLTYPE(label, SUN_SL_ID) &&
84 (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh)))
85
86 return (1);
87 }
88 if (id->type == USER_ACCREDITATION_RANGE ||
89 id->type == SYSTEM_ACCREDITATION_RANGE) {
90 labeld_data_t call;
91 labeld_data_t *callp = &call;
92 size_t bufsize = sizeof (labeld_data_t);
93 size_t datasize = CALL_SIZE(inset_call_t, 0);
94
95 call.callop = BLINSET;
96 incall.label = *label;
97 incall.type = id->type;
98
99 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
100 /* process error */
101
102 return (-1);
103 }
104 return (inret.inset);
105 } else {
106 /*
107 * Only System and User Accreditation Ranges presently
108 * implemented.
109 */
110 return (-1);
111 }
112 }
113 #undef incall
114 #undef inret
115
116 #define slvcall callp->param.acall.cargs.slvalid_arg
117 #define slvret callp->param.aret.rvals.slvalid_ret
118 /*
119 * bslvalid - Check Sensitivity Label for validity.
120 *
121 * Entry label = Sensitivity Label to check.
122 *
123 * Exit None.
124 *
125 * Returns -1, If unable to access label encodings file, or server failure.
126 * 0, If label not valid.
127 * 1, If label is valid.
128 *
129 * Calls __call_labeld(BSLVALID), BLTYPE, BSLLOW, BSLHIGH.
130 *
131 * Uses slow, shigh.
132 *
133 */
134
135 int
bslvalid(const bslabel_t * label)136 bslvalid(const bslabel_t *label)
137 {
138 labeld_data_t call;
139 labeld_data_t *callp = &call;
140 size_t bufsize = sizeof (labeld_data_t);
141 size_t datasize = CALL_SIZE(slvalid_call_t, 0);
142
143 if (!BLTYPE(&slow, SUN_SL_ID)) {
144 /* initialize static labels. */
145
146 BSLLOW(&slow);
147 BSLHIGH(&shigh);
148 }
149
150 if (BLTYPE(label, SUN_SL_ID) &&
151 (BLEQUAL(label, &slow) || BLEQUAL(label, &shigh))) {
152
153 return (1);
154 }
155
156 call.callop = BSLVALID;
157 slvcall.label = *label;
158
159 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
160 /* process error */
161
162 return (-1);
163 }
164 return (slvret.valid);
165 }
166 #undef slvcall
167 #undef slvret
168
169 #define clrvcall callp->param.acall.cargs.clrvalid_arg
170 #define clrvret callp->param.aret.rvals.clrvalid_ret
171 /*
172 * bclearvalid - Check Clearance for validity.
173 *
174 * Entry clearance = Clearance to check.
175 *
176 * Exit None.
177 *
178 * Returns -1, If unable to access label encodings file, or server failure.
179 * 0, If label not valid.
180 * 1, If label is valid.
181 *
182 * Calls __call_labeld(BCLEARVALID), BLTYPE, BCLEARLOW, BCLEARHIGH.
183 *
184 * Uses clow, chigh.
185 *
186 */
187
188 int
bclearvalid(const bclear_t * clearance)189 bclearvalid(const bclear_t *clearance)
190 {
191 labeld_data_t call;
192 labeld_data_t *callp = &call;
193 size_t bufsize = sizeof (labeld_data_t);
194 size_t datasize = CALL_SIZE(clrvalid_call_t, 0);
195
196 if (!BLTYPE(&clow, SUN_CLR_ID)) {
197 /* initialize static labels. */
198
199 BCLEARLOW(&clow);
200 BCLEARHIGH(&chigh);
201 }
202
203 if (BLTYPE(clearance, SUN_CLR_ID) &&
204 (BLEQUAL(clearance, &clow) || BLEQUAL(clearance, &chigh))) {
205
206 return (1);
207 }
208
209 call.callop = BCLEARVALID;
210 clrvcall.clear = *clearance;
211
212 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
213 /* process error */
214
215 return (-1);
216 }
217 return (clrvret.valid);
218 }
219 #undef clrvcall
220 #undef clrvret
221
222 #define inforet callp->param.aret.rvals.info_ret
223 /*
224 * labelinfo - Get information about the label encodings file.
225 *
226 * Entry info = Address of label_info structure to update.
227 *
228 * Exit info = Updated.
229 *
230 * Returns -1, If unable to access label encodings file, or server failure.
231 * 1, If successful.
232 *
233 * Calls __call_labeld(LABELINFO).
234 */
235
236 int
labelinfo(struct label_info * info)237 labelinfo(struct label_info *info)
238 {
239 labeld_data_t call;
240 labeld_data_t *callp = &call;
241 size_t bufsize = sizeof (labeld_data_t);
242 size_t datasize = CALL_SIZE(info_call_t, 0);
243 int rval;
244
245 call.callop = LABELINFO;
246
247 if ((rval = __call_labeld(&callp, &bufsize, &datasize)) != SUCCESS) {
248 /* process error */
249
250 return (-1);
251 }
252 *info = inforet.info;
253 return (rval);
254 }
255 #undef inforet
256
257 #define lvret callp->param.aret.rvals.vers_ret
258 /*
259 * labelvers - Get version string of the label encodings file.
260 *
261 * Entry version = Address of string pointer to return.
262 * len = Length of string if pre-allocated.
263 *
264 * Exit version = Updated.
265 *
266 * Returns -1, If unable to access label encodings file, or server failure.
267 * 0, If unable to allocate version string,
268 * or pre-allocated version string to short
269 * (and **version = '\0').
270 * length (including null) of version string, If successful.
271 *
272 * Calls __call_labeld(LABELVERS)
273 * malloc, strlen.
274 */
275
276 ssize_t
labelvers(char ** version,size_t len)277 labelvers(char **version, size_t len)
278 {
279 labeld_data_t call;
280 labeld_data_t *callp = &call;
281 size_t bufsize = sizeof (labeld_data_t);
282 size_t datasize = CALL_SIZE(vers_call_t, 0);
283 size_t ver_len;
284
285 call.callop = LABELVERS;
286
287 if (__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) {
288
289 if (callp != &call)
290 /* release return buffer */
291 (void) munmap((void *)callp, bufsize);
292 return (-1);
293 }
294
295 /* unpack length */
296
297 ver_len = strlen(lvret.vers) + 1;
298 if (*version == NULL) {
299 if ((*version = malloc(ver_len)) == NULL) {
300 if (callp != &call)
301 /* release return buffer */
302 (void) munmap((void *)callp, bufsize);
303 return (0);
304 }
305 } else if (ver_len > len) {
306 **version = '\0';
307 if (callp != &call)
308 /* release return buffer */
309 (void) munmap((void *)callp, bufsize);
310 return (0);
311 }
312 (void) strcpy(*version, lvret.vers);
313
314 if (callp != &call)
315 /* release return buffer */
316 (void) munmap((void *)callp, bufsize);
317 return (ver_len);
318 } /* labelvers */
319 #undef lvret
320
321 #define ccall callp->param.acall.cargs.color_arg
322 #define cret callp->param.aret.rvals.color_ret
323 /*
324 * bltocolor - get ASCII color name of label.
325 *
326 * Entry label = Sensitivity Level of color to get.
327 * size = Size of the color_name array.
328 * color_name = Storage for ASCII color name string to be returned.
329 *
330 * Exit None.
331 *
332 * Returns NULL, If error (label encodings file not accessible,
333 * invalid label, no color for this label).
334 * Address of color_name parameter containing ASCII color name
335 * defined for the label.
336 *
337 * Calls __call_labeld(BLTOCOLOR), strlen.
338 */
339
340 char *
bltocolor_r(const blevel_t * label,size_t size,char * color_name)341 bltocolor_r(const blevel_t *label, size_t size, char *color_name)
342 {
343 labeld_data_t call;
344 labeld_data_t *callp = &call;
345 size_t bufsize = sizeof (labeld_data_t);
346 size_t datasize = CALL_SIZE(color_call_t, 0);
347 char *colorp;
348
349 call.callop = BLTOCOLOR;
350 ccall.label = *label;
351
352 if ((__call_labeld(&callp, &bufsize, &datasize) != SUCCESS) ||
353 (callp->reterr != 0) ||
354 (strlen(cret.color) >= size)) {
355
356 if (callp != &call)
357 /* release return buffer */
358 (void) munmap((void *)callp, bufsize);
359 return (NULL);
360 }
361
362 colorp = strcpy(color_name, cret.color);
363
364 if (callp != &call)
365 /* release return buffer */
366 (void) munmap((void *)callp, bufsize);
367 return (colorp);
368 } /* bltocolor_r */
369 #undef ccall
370 #undef cret
371
372 /*
373 * bltocolor - get ASCII color name of label.
374 *
375 * Entry label = Sensitivity Level of color to get.
376 *
377 * Exit None.
378 *
379 * Returns NULL, If error (label encodings file not accessible,
380 * invalid label, no color for this label).
381 * Address of statically allocated string containing ASCII
382 * color name defined for the classification contained
383 * in label.
384 *
385 * Uses color.
386 *
387 * Calls bltocolor_r.
388 */
389
390 char *
bltocolor(const blevel_t * label)391 bltocolor(const blevel_t *label)
392 {
393 return (bltocolor_r(label, sizeof (color), color));
394 } /* bltocolor */
395
396 blevel_t *
blabel_alloc(void)397 blabel_alloc(void)
398 {
399 return (m_label_alloc(MAC_LABEL));
400 }
401
402 void
blabel_free(blevel_t * label_p)403 blabel_free(blevel_t *label_p)
404 {
405 free(label_p);
406 }
407
408 size32_t
blabel_size(void)409 blabel_size(void)
410 {
411 return (sizeof (blevel_t));
412 }
413
414 /*
415 * getuserrange - get label range for user
416 *
417 * Entry username of user
418 *
419 * Exit None.
420 *
421 * Returns NULL, If memory allocation failure or userdefs failure.
422 * otherwise returns the allocates m_range_t with the
423 * user's min and max labels set.
424 */
425
426 m_range_t *
getuserrange(const char * username)427 getuserrange(const char *username)
428 {
429 char *kv_str = NULL;
430 userattr_t *userp = NULL;
431 m_range_t *range;
432 m_label_t *def_min, *def_clr;
433
434 /*
435 * Get some memory
436 */
437
438 if ((range = malloc(sizeof (m_range_t))) == NULL) {
439 return (NULL);
440 }
441 if ((range->lower_bound = m_label_alloc(MAC_LABEL)) == NULL) {
442 free(range);
443 return (NULL);
444 }
445 def_min = range->lower_bound;
446 if ((range->upper_bound = m_label_alloc(USER_CLEAR)) == NULL) {
447 m_label_free(range->lower_bound);
448 free(range);
449 return (NULL);
450 }
451 def_clr = range->upper_bound;
452
453 /* If the user has an explicit min_label or clearance, use it. */
454 if ((userp = getusernam(username)) != NULL) {
455 if ((kv_str = kva_match(userp->attr, USERATTR_MINLABEL))
456 != NULL) {
457 (void) str_to_label(kv_str, &range->lower_bound,
458 MAC_LABEL, L_NO_CORRECTION, NULL);
459 def_min = NULL; /* don't get default later */
460 }
461 if ((kv_str = kva_match(userp->attr, USERATTR_CLEARANCE))
462 != NULL) {
463 (void) str_to_label(kv_str, &range->upper_bound,
464 USER_CLEAR, L_NO_CORRECTION, NULL);
465 def_clr = NULL; /* don't get default later */
466 }
467 free_userattr(userp);
468 }
469 if (def_min || def_clr) {
470 /* Need to use system default clearance and/or min_label */
471 if ((userdefs(def_min, def_clr)) == -1) {
472 m_label_free(range->lower_bound);
473 m_label_free(range->upper_bound);
474 free(range);
475 return (NULL);
476 }
477 }
478
479 return (range);
480 }
481