/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include /* * Get label from zone name */ m_label_t * getzonelabelbyname(const char *zone) { zoneid_t zoneid; if ((zoneid = getzoneidbyname(zone)) == -1) { errno = EINVAL; return (NULL); } return (getzonelabelbyid(zoneid)); } /* * Get label from zone id */ m_label_t * getzonelabelbyid(zoneid_t zoneid) { m_label_t *slabel; if ((slabel = m_label_alloc(MAC_LABEL)) == NULL) return (NULL); if (zone_getattr(zoneid, ZONE_ATTR_SLBL, slabel, sizeof (m_label_t)) < 0) { m_label_free(slabel); errno = EINVAL; return (NULL); } return (slabel); } /* * Get zone id from label */ zoneid_t getzoneidbylabel(const m_label_t *label) { m_label_t admin_low; m_label_t admin_high; zoneid_t zoneid; zoneid_t *zids; uint_t nzents; uint_t nzents_saved; int i; bsllow(&admin_low); bslhigh(&admin_high); /* Check for admin_low or admin_high; both are global zone */ if (blequal(label, &admin_low) || blequal(label, &admin_high)) return (GLOBAL_ZONEID); nzents = 0; if (zone_list(NULL, &nzents) != 0) return (-1); again: if (nzents == 0) { errno = EINVAL; return (-1); } /* * Add a small amount of padding here to avoid spinning in a tight loop * if there's a process running somewhere that's creating lots of zones * all at once. */ nzents += 8; if ((zids = malloc(nzents * sizeof (zoneid_t))) == NULL) return (-1); nzents_saved = nzents; if (zone_list(zids, &nzents) != 0) { free(zids); return (-1); } if (nzents > nzents_saved) { /* list changed, try again */ free(zids); goto again; } for (i = 0; i < nzents; i++) { m_label_t test_sl; if (zids[i] == GLOBAL_ZONEID) continue; if (zone_getattr(zids[i], ZONE_ATTR_SLBL, &test_sl, sizeof (m_label_t)) < 0) continue; /* Badly configured zone info */ if (blequal(label, &test_sl) != 0) { zoneid = zids[i]; free(zids); return (zoneid); } } free(zids); errno = EINVAL; return (-1); } /* * Get zoneroot for a zoneid */ char * getzonerootbyid(zoneid_t zoneid) { char zoneroot[MAXPATHLEN]; if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot, sizeof (zoneroot)) == -1) { return (NULL); } return (strdup(zoneroot)); } /* * Get zoneroot for a zonename */ char * getzonerootbyname(const char *zone) { zoneid_t zoneid; if ((zoneid = getzoneidbyname(zone)) == -1) return (NULL); return (getzonerootbyid(zoneid)); } /* * Get zoneroot for a label */ char * getzonerootbylabel(const m_label_t *label) { zoneid_t zoneid; if ((zoneid = getzoneidbylabel(label)) == -1) return (NULL); return (getzonerootbyid(zoneid)); } /* * Get label of path relative to global zone * * This function must be called from the global zone */ m_label_t * getlabelbypath(const char *path) { m_label_t *slabel; zoneid_t *zids; uint_t nzents; uint_t nzents_saved; int i; if (getzoneid() != GLOBAL_ZONEID) { errno = EINVAL; return (NULL); } nzents = 0; if (zone_list(NULL, &nzents) != 0) return (NULL); again: /* Add a small amount of padding to avoid loops */ nzents += 8; zids = malloc(nzents * sizeof (zoneid_t)); if (zids == NULL) return (NULL); nzents_saved = nzents; if (zone_list(zids, &nzents) != 0) { free(zids); return (NULL); } if (nzents > nzents_saved) { /* list changed, try again */ free(zids); goto again; } slabel = m_label_alloc(MAC_LABEL); if (slabel == NULL) { free(zids); return (NULL); } for (i = 0; i < nzents; i++) { char zoneroot[MAXPATHLEN]; int zonerootlen; if (zids[i] == GLOBAL_ZONEID) continue; if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zoneroot, sizeof (zoneroot)) == -1) continue; /* Badly configured zone info */ /* * Need to handle the case for the /dev directory which is * parallel to the zone's root directory. So we back up * 4 bytes - the strlen of "root". */ if ((zonerootlen = strlen(zoneroot)) <= 4) continue; /* Badly configured zone info */ if (strncmp(path, zoneroot, zonerootlen - 4) == 0) { /* * If we get a match, the file is in a labeled zone. * Return the label of that zone. */ if (zone_getattr(zids[i], ZONE_ATTR_SLBL, slabel, sizeof (m_label_t)) < 0) continue; /* Badly configured zone info */ free(zids); return (slabel); } } free(zids); bsllow(slabel); return (slabel); }