#include <stdlib.h>
#include <strings.h>
#include <zone.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/tsol/label_macro.h>
m_label_t *
getzonelabelbyname(const char *zone)
{
zoneid_t zoneid;
if ((zoneid = getzoneidbyname(zone)) == -1) {
errno = EINVAL;
return (NULL);
}
return (getzonelabelbyid(zoneid));
}
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);
}
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);
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);
}
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) {
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;
if (blequal(label, &test_sl) != 0) {
zoneid = zids[i];
free(zids);
return (zoneid);
}
}
free(zids);
errno = EINVAL;
return (-1);
}
char *
getzonerootbyid(zoneid_t zoneid)
{
char zoneroot[MAXPATHLEN];
if (zone_getattr(zoneid, ZONE_ATTR_ROOT, zoneroot,
sizeof (zoneroot)) == -1) {
return (NULL);
}
return (strdup(zoneroot));
}
char *
getzonerootbyname(const char *zone)
{
zoneid_t zoneid;
if ((zoneid = getzoneidbyname(zone)) == -1)
return (NULL);
return (getzonerootbyid(zoneid));
}
char *
getzonerootbylabel(const m_label_t *label)
{
zoneid_t zoneid;
if ((zoneid = getzoneidbylabel(label)) == -1)
return (NULL);
return (getzonerootbyid(zoneid));
}
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:
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) {
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;
if ((zonerootlen = strlen(zoneroot)) <= 4)
continue;
if (strncmp(path, zoneroot, zonerootlen - 4) == 0) {
if (zone_getattr(zids[i], ZONE_ATTR_SLBL, slabel,
sizeof (m_label_t)) < 0)
continue;
free(zids);
return (slabel);
}
}
free(zids);
bsllow(slabel);
return (slabel);
}