xref: /titanic_50/usr/src/common/tsol/ltos.c (revision 4201a95e0468170d576f82c3aa63afecf718497a)
1*4201a95eSRic Aleshire /*
2*4201a95eSRic Aleshire  * CDDL HEADER START
3*4201a95eSRic Aleshire  *
4*4201a95eSRic Aleshire  * The contents of this file are subject to the terms of the
5*4201a95eSRic Aleshire  * Common Development and Distribution License (the "License").
6*4201a95eSRic Aleshire  * You may not use this file except in compliance with the License.
7*4201a95eSRic Aleshire  *
8*4201a95eSRic Aleshire  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4201a95eSRic Aleshire  * or http://www.opensolaris.org/os/licensing.
10*4201a95eSRic Aleshire  * See the License for the specific language governing permissions
11*4201a95eSRic Aleshire  * and limitations under the License.
12*4201a95eSRic Aleshire  *
13*4201a95eSRic Aleshire  * When distributing Covered Code, include this CDDL HEADER in each
14*4201a95eSRic Aleshire  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4201a95eSRic Aleshire  * If applicable, add the following below this CDDL HEADER, with the
16*4201a95eSRic Aleshire  * fields enclosed by brackets "[]" replaced with your own identifying
17*4201a95eSRic Aleshire  * information: Portions Copyright [yyyy] [name of copyright owner]
18*4201a95eSRic Aleshire  *
19*4201a95eSRic Aleshire  * CDDL HEADER END
20*4201a95eSRic Aleshire  */
21*4201a95eSRic Aleshire /*
22*4201a95eSRic Aleshire  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
23*4201a95eSRic Aleshire  * Use is subject to license terms.
24*4201a95eSRic Aleshire  */
25*4201a95eSRic Aleshire 
26*4201a95eSRic Aleshire #if !defined(_KERNEL)
27*4201a95eSRic Aleshire #include <errno.h>
28*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
29*4201a95eSRic Aleshire 
30*4201a95eSRic Aleshire #include <sys/types.h>
31*4201a95eSRic Aleshire #include <sys/mman.h>
32*4201a95eSRic Aleshire #include <sys/tsol/label_macro.h>
33*4201a95eSRic Aleshire 
34*4201a95eSRic Aleshire #include <sys/tsol/label.h>
35*4201a95eSRic Aleshire 
36*4201a95eSRic Aleshire #if !defined(_KERNEL)
37*4201a95eSRic Aleshire #include "clnt.h"
38*4201a95eSRic Aleshire #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 
51*4201a95eSRic Aleshire 
52*4201a95eSRic Aleshire static _mac_label_impl_t low;
53*4201a95eSRic Aleshire static _mac_label_impl_t high;
54*4201a95eSRic Aleshire static int	inited = 0;
55*4201a95eSRic Aleshire 
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 
63*4201a95eSRic Aleshire /* 0x + Classification + '-' + ll + '-' + Compartments + end of string */
64*4201a95eSRic Aleshire #define	_HEX_SIZE 2+(sizeof (Classification_t)*2)+4+\
65*4201a95eSRic Aleshire 	(sizeof (Compartments_t)*2)+1
66*4201a95eSRic Aleshire 
67*4201a95eSRic Aleshire /* 0x + Classification + '-' + ll + '-' + end of string */
68*4201a95eSRic Aleshire #define	_MIN_HEX (2 + (sizeof (Classification_t)*2) + 4 + 1)
69*4201a95eSRic Aleshire 
70*4201a95eSRic Aleshire static char digits[] = "0123456789abcdef";
71*4201a95eSRic Aleshire 
72*4201a95eSRic Aleshire #define	HEX(h, i, l, s) \
73*4201a95eSRic Aleshire 	for (; i < s; /* */) {\
74*4201a95eSRic Aleshire 	h[i++] = digits[(unsigned int)(*l >> 4)];\
75*4201a95eSRic Aleshire 	h[i++] = digits[(unsigned int)(*l++&0xF)]; }
76*4201a95eSRic Aleshire 
77*4201a95eSRic Aleshire static int
__hex(char ** s,const m_label_t * l)78*4201a95eSRic Aleshire __hex(char **s, const m_label_t *l)
79*4201a95eSRic Aleshire {
80*4201a95eSRic Aleshire 	char	*hex;
81*4201a95eSRic Aleshire 	int	i = 0;
82*4201a95eSRic Aleshire 	uchar_t *hl;
83*4201a95eSRic Aleshire 	int	hex_len;
84*4201a95eSRic Aleshire 	uchar_t *len;
85*4201a95eSRic Aleshire 
86*4201a95eSRic Aleshire 	hl = (uchar_t  *)&(((_mac_label_impl_t *)l)->_c_len);
87*4201a95eSRic Aleshire 	len = hl;
88*4201a95eSRic Aleshire 
89*4201a95eSRic Aleshire 	if (*len == 0) {
90*4201a95eSRic Aleshire 		/* old binary label */
91*4201a95eSRic Aleshire 		hex_len = _HEX_SIZE;
92*4201a95eSRic Aleshire 	} else {
93*4201a95eSRic Aleshire 		hex_len = _MIN_HEX + (*len * sizeof (uint32_t) * 2);
94*4201a95eSRic Aleshire 	}
95*4201a95eSRic Aleshire 
96*4201a95eSRic Aleshire 	if ((hex = malloc(hex_len)) == NULL) {
97*4201a95eSRic Aleshire 		return (-1);
98*4201a95eSRic Aleshire 	}
99*4201a95eSRic Aleshire 
100*4201a95eSRic Aleshire 	/* header */
101*4201a95eSRic Aleshire 
102*4201a95eSRic Aleshire 	hex[i++] = '0';
103*4201a95eSRic Aleshire 	hex[i++] = 'x';
104*4201a95eSRic Aleshire 
105*4201a95eSRic Aleshire 	/* classification */
106*4201a95eSRic Aleshire 
107*4201a95eSRic Aleshire 	hl++;		/* start at classification */
108*4201a95eSRic Aleshire 	HEX(hex, i, hl, 6);
109*4201a95eSRic Aleshire 
110*4201a95eSRic Aleshire 	/* Add compartments length */
111*4201a95eSRic Aleshire 	hex[i++] = '-';
112*4201a95eSRic Aleshire 	HEX(hex, i, len, 9);
113*4201a95eSRic Aleshire 	hex[i++] = '-';
114*4201a95eSRic Aleshire 
115*4201a95eSRic Aleshire 	/* compartments */
116*4201a95eSRic Aleshire 	HEX(hex, i, hl, hex_len-1);
117*4201a95eSRic Aleshire 	hex[i] = '\0';
118*4201a95eSRic Aleshire 
119*4201a95eSRic Aleshire 	/* truncate trailing zeros */
120*4201a95eSRic Aleshire 
121*4201a95eSRic Aleshire 	while (hex[i-1] == '0' && hex[i-2] == '0') {
122*4201a95eSRic Aleshire 		i -= 2;
123*4201a95eSRic Aleshire 	}
124*4201a95eSRic Aleshire 	hex[i] = '\0';
125*4201a95eSRic Aleshire 
126*4201a95eSRic Aleshire 	if ((*s = strdup(hex)) == NULL) {
127*4201a95eSRic Aleshire 		freeit(hex, hex_len);
128*4201a95eSRic Aleshire 		return (-1);
129*4201a95eSRic Aleshire 	}
130*4201a95eSRic Aleshire 
131*4201a95eSRic Aleshire 	freeit(hex, hex_len);
132*4201a95eSRic Aleshire 	return (0);
133*4201a95eSRic Aleshire 
134*4201a95eSRic Aleshire }
135*4201a95eSRic Aleshire 
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)
169*4201a95eSRic Aleshire /*
170*4201a95eSRic Aleshire  * label_to_str -- convert a label to the requested type of string.
171*4201a95eSRic Aleshire  *
172*4201a95eSRic Aleshire  *	Entry	l = label to convert;
173*4201a95eSRic Aleshire  *		t = type of conversion;
174*4201a95eSRic Aleshire  *		f = flags for conversion type;
175*4201a95eSRic Aleshire  *
176*4201a95eSRic Aleshire  *	Exit	*s = allocated converted string;
177*4201a95eSRic Aleshire  *		     Caller must call free() to free.
178*4201a95eSRic Aleshire  *
179*4201a95eSRic Aleshire  *	Returns	0, success.
180*4201a95eSRic Aleshire  *		-1, error, errno set; *s = NULL.
181*4201a95eSRic Aleshire  *
182*4201a95eSRic Aleshire  *	Calls	labeld
183*4201a95eSRic Aleshire  */
184*4201a95eSRic Aleshire 
185*4201a95eSRic Aleshire int
label_to_str(const m_label_t * l,char ** s,const m_label_str_t t,uint_t f)186*4201a95eSRic Aleshire label_to_str(const m_label_t *l, char **s, const m_label_str_t t, uint_t f)
187*4201a95eSRic Aleshire {
188*4201a95eSRic Aleshire 	labeld_data_t	call;
189*4201a95eSRic Aleshire 	labeld_data_t	*callp = &call;
190*4201a95eSRic Aleshire 	size_t	bufsize = sizeof (labeld_data_t);
191*4201a95eSRic Aleshire 	size_t	datasize;
192*4201a95eSRic Aleshire 	int	err;
193*4201a95eSRic Aleshire 	int	string_start = 0;
194*4201a95eSRic Aleshire 
195*4201a95eSRic Aleshire 	if (inited == 0) {
196*4201a95eSRic Aleshire 		inited = 1;
197*4201a95eSRic Aleshire 		_BSLLOW(&low);
198*4201a95eSRic Aleshire 		_BSLHIGH(&high);
199*4201a95eSRic Aleshire 	}
200*4201a95eSRic Aleshire 
201*4201a95eSRic Aleshire #define	lscall callp->param.acall.cargs.ls_arg
202*4201a95eSRic Aleshire #define	lsret callp->param.aret.rvals.ls_ret
203*4201a95eSRic Aleshire 	switch (t) {
204*4201a95eSRic Aleshire 	case M_LABEL:
205*4201a95eSRic Aleshire 		call.callop = LTOS;
206*4201a95eSRic Aleshire 		lscall.label = *l;
207*4201a95eSRic Aleshire 		lscall.flags = f;
208*4201a95eSRic Aleshire 		datasize = CALL_SIZE(ls_call_t, 0);
209*4201a95eSRic Aleshire 		if ((err = __call_labeld(&callp, &bufsize, &datasize)) ==
210*4201a95eSRic Aleshire 		    SUCCESS) {
211*4201a95eSRic Aleshire 			if (callp->reterr != 0) {
212*4201a95eSRic Aleshire 				errno = EINVAL;
213*4201a95eSRic Aleshire 				*s = NULL;
214*4201a95eSRic Aleshire 				return (-1);
215*4201a95eSRic Aleshire 			}
216*4201a95eSRic Aleshire 			*s = strdup(lsret.buf);
217*4201a95eSRic Aleshire 			if (callp != &call) {
218*4201a95eSRic Aleshire 				/* release returned buffer */
219*4201a95eSRic Aleshire 				(void) munmap((void *)callp, bufsize);
220*4201a95eSRic Aleshire 			}
221*4201a95eSRic Aleshire 			if (*s == NULL) {
222*4201a95eSRic Aleshire 				return (-1);
223*4201a95eSRic Aleshire 			}
224*4201a95eSRic Aleshire 			return (0);
225*4201a95eSRic Aleshire 		}
226*4201a95eSRic Aleshire 		switch (err) {
227*4201a95eSRic Aleshire 		case NOSERVER:
228*4201a95eSRic Aleshire 			/* server not present */
229*4201a95eSRic Aleshire 			/* special case admin_low and admin_high */
230*4201a95eSRic Aleshire 
231*4201a95eSRic Aleshire 			if (_MEQUAL(&low, (_mac_label_impl_t *)l)) {
232*4201a95eSRic Aleshire 				if ((*s = strdup(ADMIN_LOW)) == NULL) {
233*4201a95eSRic Aleshire 					return (-1);
234*4201a95eSRic Aleshire 				}
235*4201a95eSRic Aleshire 				return (0);
236*4201a95eSRic Aleshire 			} else if (_MEQUAL(&high, (_mac_label_impl_t *)l)) {
237*4201a95eSRic Aleshire 				if ((*s = strdup(ADMIN_HIGH)) == NULL) {
238*4201a95eSRic Aleshire 					return (-1);
239*4201a95eSRic Aleshire 				}
240*4201a95eSRic Aleshire 				return (0);
241*4201a95eSRic Aleshire 			}
242*4201a95eSRic Aleshire 			errno = ENOTSUP;
243*4201a95eSRic Aleshire 			break;
244*4201a95eSRic Aleshire 		default:
245*4201a95eSRic Aleshire 			errno = EINVAL;
246*4201a95eSRic Aleshire 			break;
247*4201a95eSRic Aleshire 		}
248*4201a95eSRic Aleshire 		*s = NULL;
249*4201a95eSRic Aleshire 		return (-1);
250*4201a95eSRic Aleshire #undef	lscall
251*4201a95eSRic Aleshire #undef	lsret
252*4201a95eSRic Aleshire 
253*4201a95eSRic Aleshire 	case M_INTERNAL: {
254*4201a95eSRic Aleshire 		return (l_to_str_internal(l, s));
255*4201a95eSRic Aleshire 	}
256*4201a95eSRic Aleshire 
257*4201a95eSRic Aleshire #define	ccall callp->param.acall.cargs.color_arg
258*4201a95eSRic Aleshire #define	cret callp->param.aret.rvals.color_ret
259*4201a95eSRic Aleshire 	case M_COLOR:
260*4201a95eSRic Aleshire 		datasize = CALL_SIZE(color_call_t, 0);
261*4201a95eSRic Aleshire 		call.callop = BLTOCOLOR;
262*4201a95eSRic Aleshire 		ccall.label = *l;
263*4201a95eSRic Aleshire 
264*4201a95eSRic Aleshire 		if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
265*4201a95eSRic Aleshire 			if (callp->reterr != 0) {
266*4201a95eSRic Aleshire 				errno = EINVAL;
267*4201a95eSRic Aleshire 				*s = NULL;
268*4201a95eSRic Aleshire 				return (-1);
269*4201a95eSRic Aleshire 			}
270*4201a95eSRic Aleshire 			*s = strdup(cret.color);
271*4201a95eSRic Aleshire 			if (callp != &call) {
272*4201a95eSRic Aleshire 				/* release returned buffer */
273*4201a95eSRic Aleshire 				(void) munmap((void *)callp, bufsize);
274*4201a95eSRic Aleshire 			}
275*4201a95eSRic Aleshire 			if (*s == NULL) {
276*4201a95eSRic Aleshire 				return (-1);
277*4201a95eSRic Aleshire 			}
278*4201a95eSRic Aleshire 			return (0);
279*4201a95eSRic Aleshire 		} else {
280*4201a95eSRic Aleshire 			errno = ENOTSUP;
281*4201a95eSRic Aleshire 			*s = NULL;
282*4201a95eSRic Aleshire 			return (-1);
283*4201a95eSRic Aleshire 		}
284*4201a95eSRic Aleshire #undef	ccall
285*4201a95eSRic Aleshire #undef	cret
286*4201a95eSRic Aleshire 
287*4201a95eSRic Aleshire #define	prcall	callp->param.acall.cargs.pr_arg
288*4201a95eSRic Aleshire #define	prret	callp->param.aret.rvals.pr_ret
289*4201a95eSRic Aleshire 	case PRINTER_TOP_BOTTOM:
290*4201a95eSRic Aleshire 		call.callop = PR_TOP;
291*4201a95eSRic Aleshire 		break;
292*4201a95eSRic Aleshire 	case PRINTER_LABEL:
293*4201a95eSRic Aleshire 		call.callop = PR_LABEL;
294*4201a95eSRic Aleshire 		break;
295*4201a95eSRic Aleshire 	case PRINTER_CAVEATS:
296*4201a95eSRic Aleshire 		call.callop = PR_CAVEATS;
297*4201a95eSRic Aleshire 		string_start = 1;	/* compensate for leading space */
298*4201a95eSRic Aleshire 		break;
299*4201a95eSRic Aleshire 	case PRINTER_CHANNELS:
300*4201a95eSRic Aleshire 		call.callop = PR_CHANNELS;
301*4201a95eSRic Aleshire 		string_start = 1;	/* compensate for leading space */
302*4201a95eSRic Aleshire 		break;
303*4201a95eSRic Aleshire 	default:
304*4201a95eSRic Aleshire 		errno = EINVAL;
305*4201a95eSRic Aleshire 		*s = NULL;
306*4201a95eSRic Aleshire 		return (-1);
307*4201a95eSRic Aleshire 	}
308*4201a95eSRic Aleshire 	/* do the common printer calls */
309*4201a95eSRic Aleshire 	datasize = CALL_SIZE(pr_call_t, 0);
310*4201a95eSRic Aleshire 	prcall.label = *l;
311*4201a95eSRic Aleshire 	prcall.flags = f;
312*4201a95eSRic Aleshire 	if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
313*4201a95eSRic Aleshire 		if (callp->reterr != 0) {
314*4201a95eSRic Aleshire 			errno = EINVAL;
315*4201a95eSRic Aleshire 			*s = NULL;
316*4201a95eSRic Aleshire 			return (-1);
317*4201a95eSRic Aleshire 		}
318*4201a95eSRic Aleshire 		*s = strdup(&prret.buf[string_start]);
319*4201a95eSRic Aleshire 		if (callp != &call) {
320*4201a95eSRic Aleshire 			/* release returned buffer */
321*4201a95eSRic Aleshire 			(void) munmap((void *)callp, bufsize);
322*4201a95eSRic Aleshire 		}
323*4201a95eSRic Aleshire 		if (*s == NULL) {
324*4201a95eSRic Aleshire 			return (-1);
325*4201a95eSRic Aleshire 		}
326*4201a95eSRic Aleshire 		return (0);
327*4201a95eSRic Aleshire 	} else {
328*4201a95eSRic Aleshire 		errno = ENOTSUP;
329*4201a95eSRic Aleshire 		*s = NULL;
330*4201a95eSRic Aleshire 		return (-1);
331*4201a95eSRic Aleshire 	}
332*4201a95eSRic Aleshire #undef	prcall
333*4201a95eSRic Aleshire #undef	prret
334*4201a95eSRic Aleshire }
335*4201a95eSRic Aleshire #endif /* !defined(_KERNEL) */
336