1*45916cd2Sjpk /*
2*45916cd2Sjpk * CDDL HEADER START
3*45916cd2Sjpk *
4*45916cd2Sjpk * The contents of this file are subject to the terms of the
5*45916cd2Sjpk * Common Development and Distribution License (the "License").
6*45916cd2Sjpk * You may not use this file except in compliance with the License.
7*45916cd2Sjpk *
8*45916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*45916cd2Sjpk * or http://www.opensolaris.org/os/licensing.
10*45916cd2Sjpk * See the License for the specific language governing permissions
11*45916cd2Sjpk * and limitations under the License.
12*45916cd2Sjpk *
13*45916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each
14*45916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*45916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the
16*45916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying
17*45916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner]
18*45916cd2Sjpk *
19*45916cd2Sjpk * CDDL HEADER END
20*45916cd2Sjpk */
21*45916cd2Sjpk /*
22*45916cd2Sjpk * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23*45916cd2Sjpk * Use is subject to license terms.
24*45916cd2Sjpk */
25*45916cd2Sjpk
26*45916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI"
27*45916cd2Sjpk
28*45916cd2Sjpk #include <stdlib.h>
29*45916cd2Sjpk #include <strings.h>
30*45916cd2Sjpk #include <zone.h>
31*45916cd2Sjpk #include <errno.h>
32*45916cd2Sjpk #include <sys/types.h>
33*45916cd2Sjpk #include <sys/tsol/label_macro.h>
34*45916cd2Sjpk
35*45916cd2Sjpk /*
36*45916cd2Sjpk * Get label from zone name
37*45916cd2Sjpk */
38*45916cd2Sjpk m_label_t *
getzonelabelbyname(const char * zone)39*45916cd2Sjpk getzonelabelbyname(const char *zone)
40*45916cd2Sjpk {
41*45916cd2Sjpk zoneid_t zoneid;
42*45916cd2Sjpk
43*45916cd2Sjpk if ((zoneid = getzoneidbyname(zone)) == -1) {
44*45916cd2Sjpk errno = EINVAL;
45*45916cd2Sjpk return (NULL);
46*45916cd2Sjpk }
47*45916cd2Sjpk return (getzonelabelbyid(zoneid));
48*45916cd2Sjpk }
49*45916cd2Sjpk
50*45916cd2Sjpk /*
51*45916cd2Sjpk * Get label from zone id
52*45916cd2Sjpk */
53*45916cd2Sjpk m_label_t *
getzonelabelbyid(zoneid_t zoneid)54*45916cd2Sjpk getzonelabelbyid(zoneid_t zoneid)
55*45916cd2Sjpk {
56*45916cd2Sjpk m_label_t *slabel;
57*45916cd2Sjpk
58*45916cd2Sjpk if ((slabel = m_label_alloc(MAC_LABEL)) == NULL)
59*45916cd2Sjpk return (NULL);
60*45916cd2Sjpk
61*45916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_SLBL, slabel,
62*45916cd2Sjpk sizeof (m_label_t)) < 0) {
63*45916cd2Sjpk m_label_free(slabel);
64*45916cd2Sjpk errno = EINVAL;
65*45916cd2Sjpk return (NULL);
66*45916cd2Sjpk }
67*45916cd2Sjpk
68*45916cd2Sjpk return (slabel);
69*45916cd2Sjpk }
70*45916cd2Sjpk
71*45916cd2Sjpk /*
72*45916cd2Sjpk * Get zone id from label
73*45916cd2Sjpk */
74*45916cd2Sjpk
75*45916cd2Sjpk zoneid_t
getzoneidbylabel(const m_label_t * label)76*45916cd2Sjpk getzoneidbylabel(const m_label_t *label)
77*45916cd2Sjpk {
78*45916cd2Sjpk m_label_t admin_low;
79*45916cd2Sjpk m_label_t admin_high;
80*45916cd2Sjpk zoneid_t zoneid;
81*45916cd2Sjpk zoneid_t *zids;
82*45916cd2Sjpk uint_t nzents;
83*45916cd2Sjpk uint_t nzents_saved;
84*45916cd2Sjpk int i;
85*45916cd2Sjpk
86*45916cd2Sjpk bsllow(&admin_low);
87*45916cd2Sjpk bslhigh(&admin_high);
88*45916cd2Sjpk
89*45916cd2Sjpk /* Check for admin_low or admin_high; both are global zone */
90*45916cd2Sjpk if (blequal(label, &admin_low) || blequal(label, &admin_high))
91*45916cd2Sjpk return (GLOBAL_ZONEID);
92*45916cd2Sjpk
93*45916cd2Sjpk nzents = 0;
94*45916cd2Sjpk if (zone_list(NULL, &nzents) != 0)
95*45916cd2Sjpk return (-1);
96*45916cd2Sjpk
97*45916cd2Sjpk again:
98*45916cd2Sjpk if (nzents == 0) {
99*45916cd2Sjpk errno = EINVAL;
100*45916cd2Sjpk return (-1);
101*45916cd2Sjpk }
102*45916cd2Sjpk
103*45916cd2Sjpk /*
104*45916cd2Sjpk * Add a small amount of padding here to avoid spinning in a tight loop
105*45916cd2Sjpk * if there's a process running somewhere that's creating lots of zones
106*45916cd2Sjpk * all at once.
107*45916cd2Sjpk */
108*45916cd2Sjpk nzents += 8;
109*45916cd2Sjpk if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL)
110*45916cd2Sjpk return (-1);
111*45916cd2Sjpk nzents_saved = nzents;
112*45916cd2Sjpk
113*45916cd2Sjpk if (zone_list(zids, &nzents) != 0) {
114*45916cd2Sjpk free(zids);
115*45916cd2Sjpk return (-1);
116*45916cd2Sjpk }
117*45916cd2Sjpk if (nzents > nzents_saved) {
118*45916cd2Sjpk /* list changed, try again */
119*45916cd2Sjpk free(zids);
120*45916cd2Sjpk goto again;
121*45916cd2Sjpk }
122*45916cd2Sjpk
123*45916cd2Sjpk for (i = 0; i < nzents; i++) {
124*45916cd2Sjpk m_label_t test_sl;
125*45916cd2Sjpk
126*45916cd2Sjpk if (zids[i] == GLOBAL_ZONEID)
127*45916cd2Sjpk continue;
128*45916cd2Sjpk
129*45916cd2Sjpk if (zone_getattr(zids[i], ZONE_ATTR_SLBL, &test_sl,
130*45916cd2Sjpk sizeof (m_label_t)) < 0)
131*45916cd2Sjpk continue; /* Badly configured zone info */
132*45916cd2Sjpk
133*45916cd2Sjpk if (blequal(label, &test_sl) != 0) {
134*45916cd2Sjpk zoneid = zids[i];
135*45916cd2Sjpk free(zids);
136*45916cd2Sjpk return (zoneid);
137*45916cd2Sjpk }
138*45916cd2Sjpk }
139*45916cd2Sjpk free(zids);
140*45916cd2Sjpk errno = EINVAL;
141*45916cd2Sjpk return (-1);
142*45916cd2Sjpk }
143*45916cd2Sjpk
144*45916cd2Sjpk /*
145*45916cd2Sjpk * Get zoneroot for a zoneid
146*45916cd2Sjpk */
147*45916cd2Sjpk
148*45916cd2Sjpk char *
getzonerootbyid(zoneid_t zoneid)149*45916cd2Sjpk getzonerootbyid(zoneid_t zoneid)
150*45916cd2Sjpk {
151*45916cd2Sjpk char zoneroot[MAXPATHLEN];
152*45916cd2Sjpk
153*45916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot,
154*45916cd2Sjpk sizeof (zoneroot)) == -1) {
155*45916cd2Sjpk return (NULL);
156*45916cd2Sjpk }
157*45916cd2Sjpk
158*45916cd2Sjpk return (strdup(zoneroot));
159*45916cd2Sjpk }
160*45916cd2Sjpk
161*45916cd2Sjpk /*
162*45916cd2Sjpk * Get zoneroot for a zonename
163*45916cd2Sjpk */
164*45916cd2Sjpk
165*45916cd2Sjpk char *
getzonerootbyname(const char * zone)166*45916cd2Sjpk getzonerootbyname(const char *zone)
167*45916cd2Sjpk {
168*45916cd2Sjpk zoneid_t zoneid;
169*45916cd2Sjpk
170*45916cd2Sjpk if ((zoneid = getzoneidbyname(zone)) == -1)
171*45916cd2Sjpk return (NULL);
172*45916cd2Sjpk return (getzonerootbyid(zoneid));
173*45916cd2Sjpk }
174*45916cd2Sjpk
175*45916cd2Sjpk /*
176*45916cd2Sjpk * Get zoneroot for a label
177*45916cd2Sjpk */
178*45916cd2Sjpk
179*45916cd2Sjpk char *
getzonerootbylabel(const m_label_t * label)180*45916cd2Sjpk getzonerootbylabel(const m_label_t *label)
181*45916cd2Sjpk {
182*45916cd2Sjpk zoneid_t zoneid;
183*45916cd2Sjpk
184*45916cd2Sjpk if ((zoneid = getzoneidbylabel(label)) == -1)
185*45916cd2Sjpk return (NULL);
186*45916cd2Sjpk return (getzonerootbyid(zoneid));
187*45916cd2Sjpk }
188*45916cd2Sjpk
189*45916cd2Sjpk /*
190*45916cd2Sjpk * Get label of path relative to global zone
191*45916cd2Sjpk *
192*45916cd2Sjpk * This function must be called from the global zone
193*45916cd2Sjpk */
194*45916cd2Sjpk
195*45916cd2Sjpk m_label_t *
getlabelbypath(const char * path)196*45916cd2Sjpk getlabelbypath(const char *path)
197*45916cd2Sjpk {
198*45916cd2Sjpk m_label_t *slabel;
199*45916cd2Sjpk zoneid_t *zids;
200*45916cd2Sjpk uint_t nzents;
201*45916cd2Sjpk uint_t nzents_saved;
202*45916cd2Sjpk int i;
203*45916cd2Sjpk
204*45916cd2Sjpk if (getzoneid() != GLOBAL_ZONEID) {
205*45916cd2Sjpk errno = EINVAL;
206*45916cd2Sjpk return (NULL);
207*45916cd2Sjpk }
208*45916cd2Sjpk
209*45916cd2Sjpk nzents = 0;
210*45916cd2Sjpk if (zone_list(NULL, &nzents) != 0)
211*45916cd2Sjpk return (NULL);
212*45916cd2Sjpk
213*45916cd2Sjpk again:
214*45916cd2Sjpk /* Add a small amount of padding to avoid loops */
215*45916cd2Sjpk nzents += 8;
216*45916cd2Sjpk zids = malloc(nzents * sizeof (zoneid_t));
217*45916cd2Sjpk if (zids == NULL)
218*45916cd2Sjpk return (NULL);
219*45916cd2Sjpk
220*45916cd2Sjpk nzents_saved = nzents;
221*45916cd2Sjpk
222*45916cd2Sjpk if (zone_list(zids, &nzents) != 0) {
223*45916cd2Sjpk free(zids);
224*45916cd2Sjpk return (NULL);
225*45916cd2Sjpk }
226*45916cd2Sjpk if (nzents > nzents_saved) {
227*45916cd2Sjpk /* list changed, try again */
228*45916cd2Sjpk free(zids);
229*45916cd2Sjpk goto again;
230*45916cd2Sjpk }
231*45916cd2Sjpk
232*45916cd2Sjpk slabel = m_label_alloc(MAC_LABEL);
233*45916cd2Sjpk if (slabel == NULL) {
234*45916cd2Sjpk free(zids);
235*45916cd2Sjpk return (NULL);
236*45916cd2Sjpk }
237*45916cd2Sjpk
238*45916cd2Sjpk for (i = 0; i < nzents; i++) {
239*45916cd2Sjpk char zoneroot[MAXPATHLEN];
240*45916cd2Sjpk int zonerootlen;
241*45916cd2Sjpk
242*45916cd2Sjpk if (zids[i] == GLOBAL_ZONEID)
243*45916cd2Sjpk continue;
244*45916cd2Sjpk
245*45916cd2Sjpk if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zoneroot,
246*45916cd2Sjpk sizeof (zoneroot)) == -1)
247*45916cd2Sjpk continue; /* Badly configured zone info */
248*45916cd2Sjpk
249*45916cd2Sjpk /*
250*45916cd2Sjpk * Need to handle the case for the /dev directory which is
251*45916cd2Sjpk * parallel to the zone's root directory. So we back up
252*45916cd2Sjpk * 4 bytes - the strlen of "root".
253*45916cd2Sjpk */
254*45916cd2Sjpk if ((zonerootlen = strlen(zoneroot)) <= 4)
255*45916cd2Sjpk continue; /* Badly configured zone info */
256*45916cd2Sjpk if (strncmp(path, zoneroot, zonerootlen - 4) == 0) {
257*45916cd2Sjpk /*
258*45916cd2Sjpk * If we get a match, the file is in a labeled zone.
259*45916cd2Sjpk * Return the label of that zone.
260*45916cd2Sjpk */
261*45916cd2Sjpk if (zone_getattr(zids[i], ZONE_ATTR_SLBL, slabel,
262*45916cd2Sjpk sizeof (m_label_t)) < 0)
263*45916cd2Sjpk continue; /* Badly configured zone info */
264*45916cd2Sjpk
265*45916cd2Sjpk free(zids);
266*45916cd2Sjpk return (slabel);
267*45916cd2Sjpk }
268*45916cd2Sjpk }
269*45916cd2Sjpk free(zids);
270*45916cd2Sjpk bsllow(slabel);
271*45916cd2Sjpk return (slabel);
272*45916cd2Sjpk }
273