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*4201a95eSRic Aleshire * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2345916cd2Sjpk * Use is subject to license terms.
2445916cd2Sjpk */
2545916cd2Sjpk
26*4201a95eSRic Aleshire #if !defined(_KERNEL)
2745916cd2Sjpk #include <errno.h>
28*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
2945916cd2Sjpk
3045916cd2Sjpk #include <sys/types.h>
31*4201a95eSRic Aleshire #include <sys/mman.h>
3245916cd2Sjpk #include <sys/tsol/label_macro.h>
3345916cd2Sjpk
34*4201a95eSRic Aleshire #include <sys/tsol/label.h>
3545916cd2Sjpk
36*4201a95eSRic Aleshire #if !defined(_KERNEL)
3745916cd2Sjpk #include "clnt.h"
3845916cd2Sjpk #include "labeld.h"
39*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
40*4201a95eSRic Aleshire
41*4201a95eSRic Aleshire #if defined(_KERNEL)
42*4201a95eSRic Aleshire #include <sys/systm.h>
43*4201a95eSRic Aleshire #include <sys/sunddi.h>
44*4201a95eSRic Aleshire #else
45*4201a95eSRic Aleshire #include <stdlib.h>
46*4201a95eSRic Aleshire #include <string.h>
47*4201a95eSRic Aleshire #include <ctype.h>
48*4201a95eSRic Aleshire #endif
49*4201a95eSRic Aleshire
50*4201a95eSRic Aleshire
5145916cd2Sjpk
5245916cd2Sjpk static _mac_label_impl_t low;
5345916cd2Sjpk static _mac_label_impl_t high;
5445916cd2Sjpk static int inited = 0;
5545916cd2Sjpk
56*4201a95eSRic Aleshire #if defined(_KERNEL)
57*4201a95eSRic Aleshire #define malloc(l) kmem_alloc(l, KM_NOSLEEP)
58*4201a95eSRic Aleshire #define freeit(a, l) kmem_free(a, l)
59*4201a95eSRic Aleshire #else /* defined(_KERNEL) */
60*4201a95eSRic Aleshire #define freeit(a, l) free(a)
61*4201a95eSRic Aleshire #endif /* defined(_KERNEL) */
62*4201a95eSRic Aleshire
6345916cd2Sjpk /* 0x + Classification + '-' + ll + '-' + Compartments + end of string */
6445916cd2Sjpk #define _HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\
6545916cd2Sjpk (sizeof (Compartments_t)*2)+1
6645916cd2Sjpk
6745916cd2Sjpk /* 0x + Classification + '-' + ll + '-' + end of string */
6845916cd2Sjpk #define _MIN_HEX (2 + (sizeof (Classification_t)*2) + 4 + 1)
6945916cd2Sjpk
7045916cd2Sjpk static char digits[] = "0123456789abcdef";
7145916cd2Sjpk
7245916cd2Sjpk #define HEX(h, i, l, s) \
7345916cd2Sjpk for (; i < s; /* */) {\
7445916cd2Sjpk h[i++] = digits[(unsigned int)(*l >> 4)];\
7545916cd2Sjpk h[i++] = digits[(unsigned int)(*l++&0xF)]; }
7645916cd2Sjpk
7745916cd2Sjpk static int
__hex(char ** s,const m_label_t * l)7845916cd2Sjpk __hex(char **s, const m_label_t *l)
7945916cd2Sjpk {
8045916cd2Sjpk char *hex;
8145916cd2Sjpk int i = 0;
8245916cd2Sjpk uchar_t *hl;
8345916cd2Sjpk int hex_len;
8445916cd2Sjpk uchar_t *len;
8545916cd2Sjpk
8645916cd2Sjpk hl = (uchar_t *)&(((_mac_label_impl_t *)l)->_c_len);
8745916cd2Sjpk len = hl;
8845916cd2Sjpk
8945916cd2Sjpk if (*len == 0) {
9045916cd2Sjpk /* old binary label */
9145916cd2Sjpk hex_len = _HEX_SIZE;
9245916cd2Sjpk } else {
9345916cd2Sjpk hex_len = _MIN_HEX + (*len * sizeof (uint32_t) * 2);
9445916cd2Sjpk }
9545916cd2Sjpk
9645916cd2Sjpk if ((hex = malloc(hex_len)) == NULL) {
9745916cd2Sjpk return (-1);
9845916cd2Sjpk }
9945916cd2Sjpk
10045916cd2Sjpk /* header */
10145916cd2Sjpk
10245916cd2Sjpk hex[i++] = '0';
10345916cd2Sjpk hex[i++] = 'x';
10445916cd2Sjpk
10545916cd2Sjpk /* classification */
10645916cd2Sjpk
10745916cd2Sjpk hl++; /* start at classification */
10845916cd2Sjpk HEX(hex, i, hl, 6);
10945916cd2Sjpk
11045916cd2Sjpk /* Add compartments length */
11145916cd2Sjpk hex[i++] = '-';
11245916cd2Sjpk HEX(hex, i, len, 9);
11345916cd2Sjpk hex[i++] = '-';
11445916cd2Sjpk
11545916cd2Sjpk /* compartments */
11645916cd2Sjpk HEX(hex, i, hl, hex_len-1);
11745916cd2Sjpk hex[i] = '\0';
11845916cd2Sjpk
11945916cd2Sjpk /* truncate trailing zeros */
12045916cd2Sjpk
12145916cd2Sjpk while (hex[i-1] == '0' && hex[i-2] == '0') {
12245916cd2Sjpk i -= 2;
12345916cd2Sjpk }
12445916cd2Sjpk hex[i] = '\0';
12545916cd2Sjpk
12645916cd2Sjpk if ((*s = strdup(hex)) == NULL) {
127*4201a95eSRic Aleshire freeit(hex, hex_len);
12845916cd2Sjpk return (-1);
12945916cd2Sjpk }
13045916cd2Sjpk
131*4201a95eSRic Aleshire freeit(hex, hex_len);
13245916cd2Sjpk return (0);
13345916cd2Sjpk
13445916cd2Sjpk }
13545916cd2Sjpk
136*4201a95eSRic Aleshire int
l_to_str_internal(const m_label_t * l,char ** s)137*4201a95eSRic Aleshire l_to_str_internal(const m_label_t *l, char **s)
138*4201a95eSRic Aleshire {
139*4201a95eSRic Aleshire if (inited == 0) {
140*4201a95eSRic Aleshire inited = 1;
141*4201a95eSRic Aleshire _BSLLOW(&low);
142*4201a95eSRic Aleshire _BSLHIGH(&high);
143*4201a95eSRic Aleshire }
144*4201a95eSRic Aleshire
145*4201a95eSRic Aleshire if (!(_MTYPE(l, SUN_MAC_ID) || _MTYPE(l, SUN_UCLR_ID))) {
146*4201a95eSRic Aleshire #if !defined(_KERNEL)
147*4201a95eSRic Aleshire errno = EINVAL;
148*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
149*4201a95eSRic Aleshire *s = NULL;
150*4201a95eSRic Aleshire return (-1);
151*4201a95eSRic Aleshire }
152*4201a95eSRic Aleshire if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
153*4201a95eSRic Aleshire if ((*s = strdup(ADMIN_LOW)) == NULL) {
154*4201a95eSRic Aleshire return (-1);
155*4201a95eSRic Aleshire }
156*4201a95eSRic Aleshire return (0);
157*4201a95eSRic Aleshire }
158*4201a95eSRic Aleshire if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
159*4201a95eSRic Aleshire if ((*s = strdup(ADMIN_HIGH)) == NULL) {
160*4201a95eSRic Aleshire return (-1);
161*4201a95eSRic Aleshire }
162*4201a95eSRic Aleshire return (0);
163*4201a95eSRic Aleshire }
164*4201a95eSRic Aleshire
165*4201a95eSRic Aleshire return (__hex(s, l));
166*4201a95eSRic Aleshire }
167*4201a95eSRic Aleshire
168*4201a95eSRic Aleshire #if !defined(_KERNEL)
16945916cd2Sjpk /*
17045916cd2Sjpk * label_to_str -- convert a label to the requested type of string.
17145916cd2Sjpk *
17245916cd2Sjpk * Entry l = label to convert;
17345916cd2Sjpk * t = type of conversion;
17445916cd2Sjpk * f = flags for conversion type;
17545916cd2Sjpk *
17645916cd2Sjpk * Exit *s = allocated converted string;
17745916cd2Sjpk * Caller must call free() to free.
17845916cd2Sjpk *
17945916cd2Sjpk * Returns 0, success.
18045916cd2Sjpk * -1, error, errno set; *s = NULL.
18145916cd2Sjpk *
18245916cd2Sjpk * Calls labeld
18345916cd2Sjpk */
18445916cd2Sjpk
18545916cd2Sjpk int
label_to_str(const m_label_t * l,char ** s,const m_label_str_t t,uint_t f)18645916cd2Sjpk label_to_str(const m_label_t *l, char **s, const m_label_str_t t, uint_t f)
18745916cd2Sjpk {
18845916cd2Sjpk labeld_data_t call;
18945916cd2Sjpk labeld_data_t *callp = &call;
19045916cd2Sjpk size_t bufsize = sizeof (labeld_data_t);
19145916cd2Sjpk size_t datasize;
19245916cd2Sjpk int err;
1933851ea85Sgww int string_start = 0;
19445916cd2Sjpk
19545916cd2Sjpk if (inited == 0) {
19645916cd2Sjpk inited = 1;
19745916cd2Sjpk _BSLLOW(&low);
19845916cd2Sjpk _BSLHIGH(&high);
19945916cd2Sjpk }
20045916cd2Sjpk
20145916cd2Sjpk #define lscall callp->param.acall.cargs.ls_arg
20245916cd2Sjpk #define lsret callp->param.aret.rvals.ls_ret
20345916cd2Sjpk switch (t) {
20445916cd2Sjpk case M_LABEL:
20545916cd2Sjpk call.callop = LTOS;
20645916cd2Sjpk lscall.label = *l;
20745916cd2Sjpk lscall.flags = f;
20845916cd2Sjpk datasize = CALL_SIZE(ls_call_t, 0);
20945916cd2Sjpk if ((err = __call_labeld(&callp, &bufsize, &datasize)) ==
21045916cd2Sjpk SUCCESS) {
21145916cd2Sjpk if (callp->reterr != 0) {
21245916cd2Sjpk errno = EINVAL;
21345916cd2Sjpk *s = NULL;
21445916cd2Sjpk return (-1);
21545916cd2Sjpk }
2163851ea85Sgww *s = strdup(lsret.buf);
21745916cd2Sjpk if (callp != &call) {
21845916cd2Sjpk /* release returned buffer */
21945916cd2Sjpk (void) munmap((void *)callp, bufsize);
22045916cd2Sjpk }
2213851ea85Sgww if (*s == NULL) {
2223851ea85Sgww return (-1);
2233851ea85Sgww }
22445916cd2Sjpk return (0);
22545916cd2Sjpk }
22645916cd2Sjpk switch (err) {
22745916cd2Sjpk case NOSERVER:
22845916cd2Sjpk /* server not present */
22945916cd2Sjpk /* special case admin_low and admin_high */
23045916cd2Sjpk
23145916cd2Sjpk if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
23245916cd2Sjpk if ((*s = strdup(ADMIN_LOW)) == NULL) {
23345916cd2Sjpk return (-1);
23445916cd2Sjpk }
23545916cd2Sjpk return (0);
23645916cd2Sjpk } else if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
23745916cd2Sjpk if ((*s = strdup(ADMIN_HIGH)) == NULL) {
23845916cd2Sjpk return (-1);
23945916cd2Sjpk }
24045916cd2Sjpk return (0);
24145916cd2Sjpk }
24245916cd2Sjpk errno = ENOTSUP;
24345916cd2Sjpk break;
24445916cd2Sjpk default:
24545916cd2Sjpk errno = EINVAL;
24645916cd2Sjpk break;
24745916cd2Sjpk }
24845916cd2Sjpk *s = NULL;
24945916cd2Sjpk return (-1);
25045916cd2Sjpk #undef lscall
25145916cd2Sjpk #undef lsret
25245916cd2Sjpk
25345916cd2Sjpk case M_INTERNAL: {
254*4201a95eSRic Aleshire return (l_to_str_internal(l, s));
25545916cd2Sjpk }
25645916cd2Sjpk
25745916cd2Sjpk #define ccall callp->param.acall.cargs.color_arg
25845916cd2Sjpk #define cret callp->param.aret.rvals.color_ret
25945916cd2Sjpk case M_COLOR:
26045916cd2Sjpk datasize = CALL_SIZE(color_call_t, 0);
26145916cd2Sjpk call.callop = BLTOCOLOR;
26245916cd2Sjpk ccall.label = *l;
26345916cd2Sjpk
2643851ea85Sgww if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
2653851ea85Sgww if (callp->reterr != 0) {
2663851ea85Sgww errno = EINVAL;
2673851ea85Sgww *s = NULL;
2683851ea85Sgww return (-1);
2693851ea85Sgww }
2703851ea85Sgww *s = strdup(cret.color);
2713851ea85Sgww if (callp != &call) {
2723851ea85Sgww /* release returned buffer */
2733851ea85Sgww (void) munmap((void *)callp, bufsize);
2743851ea85Sgww }
2753851ea85Sgww if (*s == NULL) {
2763851ea85Sgww return (-1);
2773851ea85Sgww }
2783851ea85Sgww return (0);
2793851ea85Sgww } else {
28045916cd2Sjpk errno = ENOTSUP;
28145916cd2Sjpk *s = NULL;
28245916cd2Sjpk return (-1);
28345916cd2Sjpk }
28445916cd2Sjpk #undef ccall
28545916cd2Sjpk #undef cret
28645916cd2Sjpk
28745916cd2Sjpk #define prcall callp->param.acall.cargs.pr_arg
28845916cd2Sjpk #define prret callp->param.aret.rvals.pr_ret
28945916cd2Sjpk case PRINTER_TOP_BOTTOM:
29045916cd2Sjpk call.callop = PR_TOP;
29145916cd2Sjpk break;
29245916cd2Sjpk case PRINTER_LABEL:
29345916cd2Sjpk call.callop = PR_LABEL;
29445916cd2Sjpk break;
29545916cd2Sjpk case PRINTER_CAVEATS:
29645916cd2Sjpk call.callop = PR_CAVEATS;
2973851ea85Sgww string_start = 1; /* compensate for leading space */
29845916cd2Sjpk break;
29945916cd2Sjpk case PRINTER_CHANNELS:
30045916cd2Sjpk call.callop = PR_CHANNELS;
3013851ea85Sgww string_start = 1; /* compensate for leading space */
30245916cd2Sjpk break;
30345916cd2Sjpk default:
30445916cd2Sjpk errno = EINVAL;
30545916cd2Sjpk *s = NULL;
30645916cd2Sjpk return (-1);
30745916cd2Sjpk }
30845916cd2Sjpk /* do the common printer calls */
30945916cd2Sjpk datasize = CALL_SIZE(pr_call_t, 0);
31045916cd2Sjpk prcall.label = *l;
31145916cd2Sjpk prcall.flags = f;
3123851ea85Sgww if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
3133851ea85Sgww if (callp->reterr != 0) {
3143851ea85Sgww errno = EINVAL;
3153851ea85Sgww *s = NULL;
3163851ea85Sgww return (-1);
3173851ea85Sgww }
3183851ea85Sgww *s = strdup(&prret.buf[string_start]);
3193851ea85Sgww if (callp != &call) {
3203851ea85Sgww /* release returned buffer */
3213851ea85Sgww (void) munmap((void *)callp, bufsize);
3223851ea85Sgww }
3233851ea85Sgww if (*s == NULL) {
3243851ea85Sgww return (-1);
3253851ea85Sgww }
3263851ea85Sgww return (0);
3273851ea85Sgww } else {
32845916cd2Sjpk errno = ENOTSUP;
32945916cd2Sjpk *s = NULL;
33045916cd2Sjpk return (-1);
33145916cd2Sjpk }
33245916cd2Sjpk #undef prcall
33345916cd2Sjpk #undef prret
33445916cd2Sjpk }
335*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
336