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 #include <stdlib.h>
27*45916cd2Sjpk #include <strings.h>
28*45916cd2Sjpk #include <zone.h>
29*45916cd2Sjpk #include <errno.h>
30*45916cd2Sjpk #include <sys/types.h>
31*45916cd2Sjpk #include <sys/tsol/label_macro.h>
32*45916cd2Sjpk
33*45916cd2Sjpk /*
34*45916cd2Sjpk * Get label from zone name
35*45916cd2Sjpk */
36*45916cd2Sjpk m_label_t *
getzonelabelbyname(const char * zone)37*45916cd2Sjpk getzonelabelbyname(const char *zone)
38*45916cd2Sjpk {
39*45916cd2Sjpk zoneid_t zoneid;
40*45916cd2Sjpk
41*45916cd2Sjpk if ((zoneid = getzoneidbyname(zone)) == -1) {
42*45916cd2Sjpk errno = EINVAL;
43*45916cd2Sjpk return (NULL);
44*45916cd2Sjpk }
45*45916cd2Sjpk return (getzonelabelbyid(zoneid));
46*45916cd2Sjpk }
47*45916cd2Sjpk
48*45916cd2Sjpk /*
49*45916cd2Sjpk * Get label from zone id
50*45916cd2Sjpk */
51*45916cd2Sjpk m_label_t *
getzonelabelbyid(zoneid_t zoneid)52*45916cd2Sjpk getzonelabelbyid(zoneid_t zoneid)
53*45916cd2Sjpk {
54*45916cd2Sjpk m_label_t *slabel;
55*45916cd2Sjpk
56*45916cd2Sjpk if ((slabel = m_label_alloc(MAC_LABEL)) == NULL)
57*45916cd2Sjpk return (NULL);
58*45916cd2Sjpk
59*45916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_SLBL, slabel,
60*45916cd2Sjpk sizeof (m_label_t)) < 0) {
61*45916cd2Sjpk m_label_free(slabel);
62*45916cd2Sjpk errno = EINVAL;
63*45916cd2Sjpk return (NULL);
64*45916cd2Sjpk }
65*45916cd2Sjpk
66*45916cd2Sjpk return (slabel);
67*45916cd2Sjpk }
68*45916cd2Sjpk
69*45916cd2Sjpk /*
70*45916cd2Sjpk * Get zone id from label
71*45916cd2Sjpk */
72*45916cd2Sjpk
73*45916cd2Sjpk zoneid_t
getzoneidbylabel(const m_label_t * label)74*45916cd2Sjpk getzoneidbylabel(const m_label_t *label)
75*45916cd2Sjpk {
76*45916cd2Sjpk m_label_t admin_low;
77*45916cd2Sjpk m_label_t admin_high;
78*45916cd2Sjpk zoneid_t zoneid;
79*45916cd2Sjpk zoneid_t *zids;
80*45916cd2Sjpk uint_t nzents;
81*45916cd2Sjpk uint_t nzents_saved;
82*45916cd2Sjpk int i;
83*45916cd2Sjpk
84*45916cd2Sjpk bsllow(&admin_low);
85*45916cd2Sjpk bslhigh(&admin_high);
86*45916cd2Sjpk
87*45916cd2Sjpk /* Check for admin_low or admin_high; both are global zone */
88*45916cd2Sjpk if (blequal(label, &admin_low) || blequal(label, &admin_high))
89*45916cd2Sjpk return (GLOBAL_ZONEID);
90*45916cd2Sjpk
91*45916cd2Sjpk nzents = 0;
92*45916cd2Sjpk if (zone_list(NULL, &nzents) != 0)
93*45916cd2Sjpk return (-1);
94*45916cd2Sjpk
95*45916cd2Sjpk again:
96*45916cd2Sjpk if (nzents == 0) {
97*45916cd2Sjpk errno = EINVAL;
98*45916cd2Sjpk return (-1);
99*45916cd2Sjpk }
100*45916cd2Sjpk
101*45916cd2Sjpk /*
102*45916cd2Sjpk * Add a small amount of padding here to avoid spinning in a tight loop
103*45916cd2Sjpk * if there's a process running somewhere that's creating lots of zones
104*45916cd2Sjpk * all at once.
105*45916cd2Sjpk */
106*45916cd2Sjpk nzents += 8;
107*45916cd2Sjpk if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL)
108*45916cd2Sjpk return (-1);
109*45916cd2Sjpk nzents_saved = nzents;
110*45916cd2Sjpk
111*45916cd2Sjpk if (zone_list(zids, &nzents) != 0) {
112*45916cd2Sjpk free(zids);
113*45916cd2Sjpk return (-1);
114*45916cd2Sjpk }
115*45916cd2Sjpk if (nzents > nzents_saved) {
116*45916cd2Sjpk /* list changed, try again */
117*45916cd2Sjpk free(zids);
118*45916cd2Sjpk goto again;
119*45916cd2Sjpk }
120*45916cd2Sjpk
121*45916cd2Sjpk for (i = 0; i < nzents; i++) {
122*45916cd2Sjpk m_label_t test_sl;
123*45916cd2Sjpk
124*45916cd2Sjpk if (zids[i] == GLOBAL_ZONEID)
125*45916cd2Sjpk continue;
126*45916cd2Sjpk
127*45916cd2Sjpk if (zone_getattr(zids[i], ZONE_ATTR_SLBL, &test_sl,
128*45916cd2Sjpk sizeof (m_label_t)) < 0)
129*45916cd2Sjpk continue; /* Badly configured zone info */
130*45916cd2Sjpk
131*45916cd2Sjpk if (blequal(label, &test_sl) != 0) {
132*45916cd2Sjpk zoneid = zids[i];
133*45916cd2Sjpk free(zids);
134*45916cd2Sjpk return (zoneid);
135*45916cd2Sjpk }
136*45916cd2Sjpk }
137*45916cd2Sjpk free(zids);
138*45916cd2Sjpk errno = EINVAL;
139*45916cd2Sjpk return (-1);
140*45916cd2Sjpk }
141*45916cd2Sjpk
142*45916cd2Sjpk /*
143*45916cd2Sjpk * Get zoneroot for a zoneid
144*45916cd2Sjpk */
145*45916cd2Sjpk
146*45916cd2Sjpk char *
getzonerootbyid(zoneid_t zoneid)147*45916cd2Sjpk getzonerootbyid(zoneid_t zoneid)
148*45916cd2Sjpk {
149*45916cd2Sjpk char zoneroot[MAXPATHLEN];
150*45916cd2Sjpk
151*45916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot,
152*45916cd2Sjpk sizeof (zoneroot)) == -1) {
153*45916cd2Sjpk return (NULL);
154*45916cd2Sjpk }
155*45916cd2Sjpk
156*45916cd2Sjpk return (strdup(zoneroot));
157*45916cd2Sjpk }
158*45916cd2Sjpk
159*45916cd2Sjpk /*
160*45916cd2Sjpk * Get zoneroot for a zonename
161*45916cd2Sjpk */
162*45916cd2Sjpk
163*45916cd2Sjpk char *
getzonerootbyname(const char * zone)164*45916cd2Sjpk getzonerootbyname(const char *zone)
165*45916cd2Sjpk {
166*45916cd2Sjpk zoneid_t zoneid;
167*45916cd2Sjpk
168*45916cd2Sjpk if ((zoneid = getzoneidbyname(zone)) == -1)
169*45916cd2Sjpk return (NULL);
170*45916cd2Sjpk return (getzonerootbyid(zoneid));
171*45916cd2Sjpk }
172*45916cd2Sjpk
173*45916cd2Sjpk /*
174*45916cd2Sjpk * Get zoneroot for a label
175*45916cd2Sjpk */
176*45916cd2Sjpk
177*45916cd2Sjpk char *
getzonerootbylabel(const m_label_t * label)178*45916cd2Sjpk getzonerootbylabel(const m_label_t *label)
179*45916cd2Sjpk {
180*45916cd2Sjpk zoneid_t zoneid;
181*45916cd2Sjpk
182*45916cd2Sjpk if ((zoneid = getzoneidbylabel(label)) == -1)
183*45916cd2Sjpk return (NULL);
184*45916cd2Sjpk return (getzonerootbyid(zoneid));
185*45916cd2Sjpk }
186*45916cd2Sjpk
187*45916cd2Sjpk /*
188*45916cd2Sjpk * Get label of path relative to global zone
189*45916cd2Sjpk *
190*45916cd2Sjpk * This function must be called from the global zone
191*45916cd2Sjpk */
192*45916cd2Sjpk
193*45916cd2Sjpk m_label_t *
getlabelbypath(const char * path)194*45916cd2Sjpk getlabelbypath(const char *path)
195*45916cd2Sjpk {
196*45916cd2Sjpk m_label_t *slabel;
197*45916cd2Sjpk zoneid_t *zids;
198*45916cd2Sjpk uint_t nzents;
199*45916cd2Sjpk uint_t nzents_saved;
200*45916cd2Sjpk int i;
201*45916cd2Sjpk
202*45916cd2Sjpk if (getzoneid() != GLOBAL_ZONEID) {
203*45916cd2Sjpk errno = EINVAL;
204*45916cd2Sjpk return (NULL);
205*45916cd2Sjpk }
206*45916cd2Sjpk
207*45916cd2Sjpk nzents = 0;
208*45916cd2Sjpk if (zone_list(NULL, &nzents) != 0)
209*45916cd2Sjpk return (NULL);
210*45916cd2Sjpk
211*45916cd2Sjpk again:
212*45916cd2Sjpk /* Add a small amount of padding to avoid loops */
213*45916cd2Sjpk nzents += 8;
214*45916cd2Sjpk zids = malloc(nzents * sizeof (zoneid_t));
215*45916cd2Sjpk if (zids == NULL)
216*45916cd2Sjpk return (NULL);
217*45916cd2Sjpk
218*45916cd2Sjpk nzents_saved = nzents;
219*45916cd2Sjpk
220*45916cd2Sjpk if (zone_list(zids, &nzents) != 0) {
221*45916cd2Sjpk free(zids);
222*45916cd2Sjpk return (NULL);
223*45916cd2Sjpk }
224*45916cd2Sjpk if (nzents > nzents_saved) {
225*45916cd2Sjpk /* list changed, try again */
226*45916cd2Sjpk free(zids);
227*45916cd2Sjpk goto again;
228*45916cd2Sjpk }
229*45916cd2Sjpk
230*45916cd2Sjpk slabel = m_label_alloc(MAC_LABEL);
231*45916cd2Sjpk if (slabel == NULL) {
232*45916cd2Sjpk free(zids);
233*45916cd2Sjpk return (NULL);
234*45916cd2Sjpk }
235*45916cd2Sjpk
236*45916cd2Sjpk for (i = 0; i < nzents; i++) {
237*45916cd2Sjpk char zoneroot[MAXPATHLEN];
238*45916cd2Sjpk int zonerootlen;
239*45916cd2Sjpk
240*45916cd2Sjpk if (zids[i] == GLOBAL_ZONEID)
241*45916cd2Sjpk continue;
242*45916cd2Sjpk
243*45916cd2Sjpk if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zoneroot,
244*45916cd2Sjpk sizeof (zoneroot)) == -1)
245*45916cd2Sjpk continue; /* Badly configured zone info */
246*45916cd2Sjpk
247*45916cd2Sjpk /*
248*45916cd2Sjpk * Need to handle the case for the /dev directory which is
249*45916cd2Sjpk * parallel to the zone's root directory. So we back up
250*45916cd2Sjpk * 4 bytes - the strlen of "root".
251*45916cd2Sjpk */
252*45916cd2Sjpk if ((zonerootlen = strlen(zoneroot)) <= 4)
253*45916cd2Sjpk continue; /* Badly configured zone info */
254*45916cd2Sjpk if (strncmp(path, zoneroot, zonerootlen - 4) == 0) {
255*45916cd2Sjpk /*
256*45916cd2Sjpk * If we get a match, the file is in a labeled zone.
257*45916cd2Sjpk * Return the label of that zone.
258*45916cd2Sjpk */
259*45916cd2Sjpk if (zone_getattr(zids[i], ZONE_ATTR_SLBL, slabel,
260*45916cd2Sjpk sizeof (m_label_t)) < 0)
261*45916cd2Sjpk continue; /* Badly configured zone info */
262*45916cd2Sjpk
263*45916cd2Sjpk free(zids);
264*45916cd2Sjpk return (slabel);
265*45916cd2Sjpk }
266*45916cd2Sjpk }
267*45916cd2Sjpk free(zids);
268*45916cd2Sjpk bsllow(slabel);
269*45916cd2Sjpk return (slabel);
270*45916cd2Sjpk }
271