145916cd2Sjpk /* 245916cd2Sjpk * CDDL HEADER START 345916cd2Sjpk * 445916cd2Sjpk * The contents of this file are subject to the terms of the 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * You may not use this file except in compliance with the License. 745916cd2Sjpk * 845916cd2Sjpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 945916cd2Sjpk * or http://www.opensolaris.org/os/licensing. 1045916cd2Sjpk * See the License for the specific language governing permissions 1145916cd2Sjpk * and limitations under the License. 1245916cd2Sjpk * 1345916cd2Sjpk * When distributing Covered Code, include this CDDL HEADER in each 1445916cd2Sjpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1545916cd2Sjpk * If applicable, add the following below this CDDL HEADER, with the 1645916cd2Sjpk * fields enclosed by brackets "[]" replaced with your own identifying 1745916cd2Sjpk * information: Portions Copyright [yyyy] [name of copyright owner] 1845916cd2Sjpk * 1945916cd2Sjpk * CDDL HEADER END 2045916cd2Sjpk */ 2145916cd2Sjpk /* 22*e1dfad11Sjparcel * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 2345916cd2Sjpk * Use is subject to license terms. 2445916cd2Sjpk */ 2545916cd2Sjpk 2645916cd2Sjpk #pragma ident "%Z%%M% %I% %E% SMI" 2745916cd2Sjpk 2845916cd2Sjpk 2945916cd2Sjpk /* 3045916cd2Sjpk * Name: getpathbylabel.c 3145916cd2Sjpk * 3245916cd2Sjpk * Description: Returns the global zone pathname corresponding 3345916cd2Sjpk * to the specified label. The pathname does 3445916cd2Sjpk * not need to match an existing file system object. 3545916cd2Sjpk * 3645916cd2Sjpk */ 3745916cd2Sjpk #include <stdio.h> 3845916cd2Sjpk #include <string.h> 3945916cd2Sjpk #include <unistd.h> 4045916cd2Sjpk #include <errno.h> 4145916cd2Sjpk #include <sys/types.h> 4245916cd2Sjpk #include <tsol/label.h> 4345916cd2Sjpk #include <stdlib.h> 4445916cd2Sjpk #include <zone.h> 4545916cd2Sjpk #include <sys/mntent.h> 4645916cd2Sjpk #include <sys/mnttab.h> 4745916cd2Sjpk #include <stdarg.h> 4845916cd2Sjpk 4945916cd2Sjpk /* 5045916cd2Sjpk * This structure is used to chain mntent structures into a list 5145916cd2Sjpk * and to cache stat information for each member of the list. 5245916cd2Sjpk */ 5345916cd2Sjpk struct mntlist { 5445916cd2Sjpk struct mnttab *mntl_mnt; 5545916cd2Sjpk struct mntlist *mntl_next; 5645916cd2Sjpk }; 5745916cd2Sjpk 5845916cd2Sjpk 5945916cd2Sjpk /* 6045916cd2Sjpk * Return a pointer to the trailing suffix of full that follows the prefix 6145916cd2Sjpk * given by pref. If pref isn't a prefix of full, return NULL. Apply 6245916cd2Sjpk * pathname semantics to the prefix test, so that pref must match at a 6345916cd2Sjpk * component boundary. 6445916cd2Sjpk */ 6545916cd2Sjpk static char * 6645916cd2Sjpk pathsuffix(char *full, char *pref) 6745916cd2Sjpk { 6845916cd2Sjpk int preflen; 6945916cd2Sjpk 7045916cd2Sjpk if (full == NULL || pref == NULL) 7145916cd2Sjpk return (NULL); 7245916cd2Sjpk 7345916cd2Sjpk preflen = strlen(pref); 7445916cd2Sjpk if (strncmp(pref, full, preflen) != 0) 7545916cd2Sjpk return (NULL); 7645916cd2Sjpk 7745916cd2Sjpk /* 7845916cd2Sjpk * pref is a substring of full. To be a subpath, it cannot cover a 7945916cd2Sjpk * partial component of full. The last clause of the test handles the 8045916cd2Sjpk * special case of the root. 8145916cd2Sjpk */ 8245916cd2Sjpk if (full[preflen] != '\0' && full[preflen] != '/' && preflen > 1) 8345916cd2Sjpk return (NULL); 8445916cd2Sjpk 8545916cd2Sjpk if (preflen == 1 && full[0] == '/') 8645916cd2Sjpk return (full); 8745916cd2Sjpk else 8845916cd2Sjpk return (full + preflen); 8945916cd2Sjpk } 9045916cd2Sjpk 9145916cd2Sjpk /* 9245916cd2Sjpk * Return zero iff the path named by sub is a leading subpath 9345916cd2Sjpk * of the path named by full. 9445916cd2Sjpk * 9545916cd2Sjpk * Treat null paths as matching nothing. 9645916cd2Sjpk */ 9745916cd2Sjpk static int 9845916cd2Sjpk subpath(char *full, char *sub) 9945916cd2Sjpk { 10045916cd2Sjpk return (pathsuffix(full, sub) == NULL); 10145916cd2Sjpk } 10245916cd2Sjpk 10345916cd2Sjpk static void 10445916cd2Sjpk tsol_mnt_free(struct mnttab *mnt) 10545916cd2Sjpk { 10645916cd2Sjpk if (mnt->mnt_special) 10745916cd2Sjpk free(mnt->mnt_special); 10845916cd2Sjpk if (mnt->mnt_mountp) 10945916cd2Sjpk free(mnt->mnt_mountp); 11045916cd2Sjpk if (mnt->mnt_fstype) 11145916cd2Sjpk free(mnt->mnt_fstype); 11245916cd2Sjpk if (mnt->mnt_mntopts) 11345916cd2Sjpk free(mnt->mnt_mntopts); 11445916cd2Sjpk free(mnt); 11545916cd2Sjpk } 11645916cd2Sjpk 11745916cd2Sjpk static void 11845916cd2Sjpk tsol_mlist_free(struct mntlist *mlist) 11945916cd2Sjpk { 12045916cd2Sjpk struct mntlist *mlp; 121*e1dfad11Sjparcel struct mntlist *oldmlp; 12245916cd2Sjpk 123*e1dfad11Sjparcel mlp = mlist; 124*e1dfad11Sjparcel while (mlp) { 12545916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 12645916cd2Sjpk 12745916cd2Sjpk if (mnt) 12845916cd2Sjpk tsol_mnt_free(mnt); 129*e1dfad11Sjparcel oldmlp = mlp; 130*e1dfad11Sjparcel mlp = mlp->mntl_next; 131*e1dfad11Sjparcel free(oldmlp); 13245916cd2Sjpk } 13345916cd2Sjpk } 13445916cd2Sjpk 13545916cd2Sjpk static struct mnttab * 13645916cd2Sjpk mntdup(struct mnttab *mnt) 13745916cd2Sjpk { 13845916cd2Sjpk struct mnttab *new; 13945916cd2Sjpk 14045916cd2Sjpk new = (struct mnttab *)malloc(sizeof (*new)); 14145916cd2Sjpk if (new == NULL) 14245916cd2Sjpk return (NULL); 14345916cd2Sjpk 14445916cd2Sjpk new->mnt_special = NULL; 14545916cd2Sjpk new->mnt_mountp = NULL; 14645916cd2Sjpk new->mnt_fstype = NULL; 14745916cd2Sjpk new->mnt_mntopts = NULL; 14845916cd2Sjpk 14945916cd2Sjpk new->mnt_special = strdup(mnt->mnt_special); 15045916cd2Sjpk if (new->mnt_special == NULL) { 15145916cd2Sjpk tsol_mnt_free(new); 15245916cd2Sjpk return (NULL); 15345916cd2Sjpk } 15445916cd2Sjpk new->mnt_mountp = strdup(mnt->mnt_mountp); 15545916cd2Sjpk if (new->mnt_mountp == NULL) { 15645916cd2Sjpk tsol_mnt_free(new); 15745916cd2Sjpk return (NULL); 15845916cd2Sjpk } 15945916cd2Sjpk new->mnt_fstype = strdup(mnt->mnt_fstype); 16045916cd2Sjpk if (new->mnt_fstype == NULL) { 16145916cd2Sjpk tsol_mnt_free(new); 16245916cd2Sjpk return (NULL); 16345916cd2Sjpk } 16445916cd2Sjpk new->mnt_mntopts = strdup(mnt->mnt_mntopts); 16545916cd2Sjpk if (new->mnt_mntopts == NULL) { 16645916cd2Sjpk tsol_mnt_free(new); 16745916cd2Sjpk return (NULL); 16845916cd2Sjpk } 16945916cd2Sjpk return (new); 17045916cd2Sjpk } 17145916cd2Sjpk 17245916cd2Sjpk static struct mntlist * 17345916cd2Sjpk tsol_mkmntlist(void) 17445916cd2Sjpk { 17545916cd2Sjpk FILE *mounted; 17645916cd2Sjpk struct mntlist *mntl; 17745916cd2Sjpk struct mntlist *mntst = NULL; 17845916cd2Sjpk struct mnttab mnt; 17945916cd2Sjpk 180004388ebScasper if ((mounted = fopen(MNTTAB, "rF")) == NULL) { 18145916cd2Sjpk perror(MNTTAB); 18245916cd2Sjpk return (NULL); 18345916cd2Sjpk } 18445916cd2Sjpk resetmnttab(mounted); 18545916cd2Sjpk while (getmntent(mounted, &mnt) == NULL) { 18645916cd2Sjpk mntl = (struct mntlist *)malloc(sizeof (*mntl)); 18745916cd2Sjpk if (mntl == NULL) { 18845916cd2Sjpk tsol_mlist_free(mntst); 18945916cd2Sjpk mntst = NULL; 19045916cd2Sjpk break; 19145916cd2Sjpk } 19245916cd2Sjpk mntl->mntl_mnt = mntdup((struct mnttab *)(&mnt)); 19345916cd2Sjpk if (mntl->mntl_mnt == NULL) { 19445916cd2Sjpk tsol_mlist_free(mntst); 19545916cd2Sjpk mntst = NULL; 19645916cd2Sjpk break; 19745916cd2Sjpk } 19845916cd2Sjpk mntl->mntl_next = mntst; 19945916cd2Sjpk mntst = mntl; 20045916cd2Sjpk } 20145916cd2Sjpk (void) fclose(mounted); 20245916cd2Sjpk return (mntst); 20345916cd2Sjpk } 20445916cd2Sjpk 20545916cd2Sjpk /* 20645916cd2Sjpk * This function attempts to convert local zone NFS mounted pathnames 20745916cd2Sjpk * into equivalent global zone NFS mounted pathnames. At present 20845916cd2Sjpk * it only works for automounted filesystems. It depends on the 20945916cd2Sjpk * assumption that both the local and global zone automounters 21045916cd2Sjpk * share the same nameservices. It also assumes that any automount 21145916cd2Sjpk * map used by a local zone is available to the global zone automounter. 21245916cd2Sjpk * 21345916cd2Sjpk * The algorithm used consists of three phases. 21445916cd2Sjpk * 21545916cd2Sjpk * 1. The local zone's mnttab is searched to find the automount map 21645916cd2Sjpk * with the closest matching mountpath. 21745916cd2Sjpk * 21845916cd2Sjpk * 2. The matching autmount map name is looked up in the global zone's 21945916cd2Sjpk * mnttab to determine the path where it should be mounted in the 22045916cd2Sjpk * global zone. 22145916cd2Sjpk * 22245916cd2Sjpk * 3. A pathname covered by an appropiate autofs trigger mount in 22345916cd2Sjpk * the global zone is generated as the resolved pathname 22445916cd2Sjpk * 22545916cd2Sjpk * Among the things that can go wrong is that global zone doesn't have 22645916cd2Sjpk * a matching automount map or the mount was not done via the automounter. 22745916cd2Sjpk * Either of these cases return a NULL path. 22845916cd2Sjpk */ 22945916cd2Sjpk #define ZONE_OPT "zone=" 23045916cd2Sjpk static int 23145916cd2Sjpk getnfspathbyautofs(struct mntlist *mlist, zoneid_t zoneid, 23245916cd2Sjpk struct mnttab *autofs_mnt, char *globalpath, char *zonepath, int global_len) 23345916cd2Sjpk { 23445916cd2Sjpk struct mntlist *mlp; 23545916cd2Sjpk char zonematch[ZONENAME_MAX + 20]; 23645916cd2Sjpk char zonename[ZONENAME_MAX]; 23745916cd2Sjpk int longestmatch; 23845916cd2Sjpk struct mnttab *mountmatch; 23945916cd2Sjpk 24045916cd2Sjpk if (autofs_mnt) { 24145916cd2Sjpk mountmatch = autofs_mnt; 24245916cd2Sjpk longestmatch = strlen(mountmatch->mnt_mountp); 24345916cd2Sjpk } else { 24445916cd2Sjpk /* 24545916cd2Sjpk * First we need to get the zonename to look for 24645916cd2Sjpk */ 24745916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_NAME, zonename, 24845916cd2Sjpk ZONENAME_MAX) == -1) { 24945916cd2Sjpk return (0); 25045916cd2Sjpk } 25145916cd2Sjpk 25245916cd2Sjpk (void) strncpy(zonematch, ZONE_OPT, sizeof (zonematch)); 25345916cd2Sjpk (void) strlcat(zonematch, zonename, sizeof (zonematch)); 25445916cd2Sjpk 25545916cd2Sjpk /* 25645916cd2Sjpk * Find the best match for an automount map that 25745916cd2Sjpk * corresponds to the local zone's pathname 25845916cd2Sjpk */ 25945916cd2Sjpk longestmatch = 0; 26045916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 26145916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 26245916cd2Sjpk int len; 26345916cd2Sjpk int matchfound; 26445916cd2Sjpk char *token; 26545916cd2Sjpk char *lasts; 26645916cd2Sjpk char mntopts[MAXPATHLEN]; 26745916cd2Sjpk 26845916cd2Sjpk if (subpath(globalpath, mnt->mnt_mountp) != 0) 26945916cd2Sjpk continue; 27045916cd2Sjpk if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) 27145916cd2Sjpk continue; 27245916cd2Sjpk 27345916cd2Sjpk matchfound = 0; 27445916cd2Sjpk (void) strncpy(mntopts, mnt->mnt_mntopts, MAXPATHLEN); 27545916cd2Sjpk if ((token = strtok_r(mntopts, ",", &lasts)) != NULL) { 27645916cd2Sjpk if (strcmp(token, zonematch) == 0) { 27745916cd2Sjpk matchfound = 1; 27845916cd2Sjpk } else while ((token = strtok_r(NULL, ",", 27945916cd2Sjpk &lasts)) != NULL) { 28045916cd2Sjpk if (strcmp(token, zonematch) == 0) { 28145916cd2Sjpk matchfound = 1; 28245916cd2Sjpk break; 28345916cd2Sjpk } 28445916cd2Sjpk } 28545916cd2Sjpk } 28645916cd2Sjpk if (matchfound) { 28745916cd2Sjpk len = strlen(mnt->mnt_mountp); 28845916cd2Sjpk if (len > longestmatch) { 28945916cd2Sjpk mountmatch = mnt; 29045916cd2Sjpk longestmatch = len; 29145916cd2Sjpk } 29245916cd2Sjpk } 29345916cd2Sjpk } 29445916cd2Sjpk } 29545916cd2Sjpk if (longestmatch == 0) { 29645916cd2Sjpk return (0); 29745916cd2Sjpk } else { 29845916cd2Sjpk /* 29945916cd2Sjpk * Now we may have found the corresponding autofs mount 30045916cd2Sjpk * Try to find the matching global zone autofs entry 30145916cd2Sjpk */ 30245916cd2Sjpk 30345916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 30445916cd2Sjpk char p[MAXPATHLEN]; 30545916cd2Sjpk size_t zp_len; 30645916cd2Sjpk size_t mp_len; 30745916cd2Sjpk 30845916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 30945916cd2Sjpk 31045916cd2Sjpk if (strcmp(mountmatch->mnt_special, 31145916cd2Sjpk mnt->mnt_special) != 0) 31245916cd2Sjpk continue; 31345916cd2Sjpk if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) 31445916cd2Sjpk continue; 31545916cd2Sjpk if (strstr(mnt->mnt_mntopts, ZONE_OPT) != NULL) 31645916cd2Sjpk continue; 31745916cd2Sjpk /* 31845916cd2Sjpk * OK, we have a matching global zone automap 31945916cd2Sjpk * so adjust the path for the global zone. 32045916cd2Sjpk */ 32145916cd2Sjpk zp_len = strlen(zonepath); 32245916cd2Sjpk mp_len = strlen(mnt->mnt_mountp); 32345916cd2Sjpk (void) strncpy(p, globalpath + zp_len, MAXPATHLEN); 32445916cd2Sjpk /* 32545916cd2Sjpk * If both global zone and zone-relative 32645916cd2Sjpk * mountpoint match, just use the same pathname 32745916cd2Sjpk */ 32845916cd2Sjpk if (strncmp(mnt->mnt_mountp, p, mp_len) == 0) { 32945916cd2Sjpk (void) strncpy(globalpath, p, global_len); 33045916cd2Sjpk return (1); 33145916cd2Sjpk } else { 33245916cd2Sjpk (void) strncpy(p, globalpath, MAXPATHLEN); 33345916cd2Sjpk (void) strncpy(globalpath, mnt->mnt_mountp, 33445916cd2Sjpk global_len); 33545916cd2Sjpk (void) strlcat(globalpath, 33645916cd2Sjpk p + strlen(mountmatch->mnt_mountp), 33745916cd2Sjpk global_len); 33845916cd2Sjpk return (1); 33945916cd2Sjpk } 34045916cd2Sjpk } 34145916cd2Sjpk return (0); 34245916cd2Sjpk } 34345916cd2Sjpk } 34445916cd2Sjpk 345*e1dfad11Sjparcel /* 346*e1dfad11Sjparcel * Find the pathname for the entry in mlist that corresponds to the 347*e1dfad11Sjparcel * file named by path (i.e., that names a mount table entry for the 348*e1dfad11Sjparcel * file system in which path lies). 349*e1dfad11Sjparcel * 350*e1dfad11Sjparcel * Return 0 is there an error. 351*e1dfad11Sjparcel */ 352*e1dfad11Sjparcel static int 353*e1dfad11Sjparcel getglobalpath(const char *path, zoneid_t zoneid, struct mntlist *mlist, 354*e1dfad11Sjparcel char *globalpath) 355*e1dfad11Sjparcel { 356*e1dfad11Sjparcel struct mntlist *mlp; 357*e1dfad11Sjparcel char lofspath[MAXPATHLEN]; 358*e1dfad11Sjparcel char zonepath[MAXPATHLEN]; 359*e1dfad11Sjparcel int longestmatch; 360*e1dfad11Sjparcel struct mnttab *mountmatch; 361*e1dfad11Sjparcel 362*e1dfad11Sjparcel if (zoneid != GLOBAL_ZONEID) { 363*e1dfad11Sjparcel char *prefix; 364*e1dfad11Sjparcel 365*e1dfad11Sjparcel if ((prefix = getzonerootbyid(zoneid)) == NULL) { 366*e1dfad11Sjparcel return (0); 36745916cd2Sjpk } 368*e1dfad11Sjparcel (void) strncpy(zonepath, prefix, MAXPATHLEN); 369*e1dfad11Sjparcel (void) strlcpy(globalpath, prefix, MAXPATHLEN); 370*e1dfad11Sjparcel (void) strlcat(globalpath, path, MAXPATHLEN); 371*e1dfad11Sjparcel free(prefix); 372*e1dfad11Sjparcel } else { 373*e1dfad11Sjparcel (void) strlcpy(globalpath, path, MAXPATHLEN); 374*e1dfad11Sjparcel } 37545916cd2Sjpk 376*e1dfad11Sjparcel for (;;) { 377*e1dfad11Sjparcel longestmatch = 0; 378*e1dfad11Sjparcel for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 379*e1dfad11Sjparcel struct mnttab *mnt = mlp->mntl_mnt; 380*e1dfad11Sjparcel int len; 38145916cd2Sjpk 38245916cd2Sjpk if (subpath(globalpath, mnt->mnt_mountp) != 0) 38345916cd2Sjpk continue; 38445916cd2Sjpk len = strlen(mnt->mnt_mountp); 38545916cd2Sjpk if (len > longestmatch) { 38645916cd2Sjpk mountmatch = mnt; 38745916cd2Sjpk longestmatch = len; 38845916cd2Sjpk } 38945916cd2Sjpk } 39045916cd2Sjpk /* 39145916cd2Sjpk * Handle interesting mounts. 39245916cd2Sjpk */ 39345916cd2Sjpk if ((strcmp(mountmatch->mnt_fstype, MNTTYPE_NFS) == 0) || 39445916cd2Sjpk (strcmp(mountmatch->mnt_fstype, MNTTYPE_AUTOFS) == 0)) { 39545916cd2Sjpk if (zoneid > GLOBAL_ZONEID) { 39645916cd2Sjpk struct mnttab *m = NULL; 39745916cd2Sjpk 39845916cd2Sjpk if (strcmp(mountmatch->mnt_fstype, 39945916cd2Sjpk MNTTYPE_AUTOFS) == 0) 40045916cd2Sjpk m = mountmatch; 40145916cd2Sjpk if (getnfspathbyautofs(mlist, zoneid, m, 40245916cd2Sjpk globalpath, zonepath, MAXPATHLEN) == 0) { 40345916cd2Sjpk return (0); 40445916cd2Sjpk } 40545916cd2Sjpk } 40645916cd2Sjpk break; 40745916cd2Sjpk } else if (strcmp(mountmatch->mnt_fstype, MNTTYPE_LOFS) == 0) { 40845916cd2Sjpk /* 40945916cd2Sjpk * count up what's left 41045916cd2Sjpk */ 41145916cd2Sjpk int remainder; 41245916cd2Sjpk 41345916cd2Sjpk remainder = strlen(globalpath) - longestmatch; 41445916cd2Sjpk if (remainder > 0) { 41545916cd2Sjpk path = pathsuffix(globalpath, 41645916cd2Sjpk mountmatch->mnt_mountp); 41745916cd2Sjpk (void) strlcpy(lofspath, path, MAXPATHLEN); 41845916cd2Sjpk } 41945916cd2Sjpk (void) strlcpy(globalpath, mountmatch->mnt_special, 42045916cd2Sjpk MAXPATHLEN); 42145916cd2Sjpk if (remainder > 0) { 42245916cd2Sjpk (void) strlcat(globalpath, lofspath, 42345916cd2Sjpk MAXPATHLEN); 42445916cd2Sjpk } 42545916cd2Sjpk } else { 42645916cd2Sjpk if ((zoneid > GLOBAL_ZONEID) && 42745916cd2Sjpk (strncmp(path, "/home/", strlen("/home/")) == 0)) { 42845916cd2Sjpk char zonename[ZONENAME_MAX]; 42945916cd2Sjpk 43045916cd2Sjpk /* 43145916cd2Sjpk * If this is a cross-zone reference to 43245916cd2Sjpk * a home directory, it must be corrected. 43345916cd2Sjpk * We should only get here if the zone's 43445916cd2Sjpk * automounter hasn't yet mounted its 43545916cd2Sjpk * autofs trigger on /home. 43645916cd2Sjpk * 43745916cd2Sjpk * Since it is likely to do so in the 43845916cd2Sjpk * future, we will assume that the global 43945916cd2Sjpk * zone already has an equivalent autofs 44045916cd2Sjpk * mount established. By convention, 44145916cd2Sjpk * this should be mounted at the 44245916cd2Sjpk * /zone/<zonename> 44345916cd2Sjpk */ 44445916cd2Sjpk 44545916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_NAME, 44645916cd2Sjpk zonename, ZONENAME_MAX) == -1) { 44745916cd2Sjpk return (0); 44845916cd2Sjpk } else { 44945916cd2Sjpk (void) snprintf(globalpath, MAXPATHLEN, 45045916cd2Sjpk "/zone/%s%s", zonename, path); 45145916cd2Sjpk } 45245916cd2Sjpk } 45345916cd2Sjpk break; 45445916cd2Sjpk } 45545916cd2Sjpk } 45645916cd2Sjpk return (1); 45745916cd2Sjpk } 45845916cd2Sjpk 45945916cd2Sjpk 46045916cd2Sjpk /* 46145916cd2Sjpk * This function is only useful for global zone callers 46245916cd2Sjpk * It uses the global zone mnttab to translate local zone pathnames 46345916cd2Sjpk * into global zone pathnames. 46445916cd2Sjpk */ 46545916cd2Sjpk char * 46645916cd2Sjpk getpathbylabel(const char *path_name, char *resolved_path, size_t bufsize, 467*e1dfad11Sjparcel const bslabel_t *sl) 468*e1dfad11Sjparcel { 46945916cd2Sjpk char ret_path[MAXPATHLEN]; /* pathname to return */ 47045916cd2Sjpk zoneid_t zoneid; 47145916cd2Sjpk struct mntlist *mlist; 47245916cd2Sjpk 47345916cd2Sjpk if (getzoneid() != GLOBAL_ZONEID) { 47445916cd2Sjpk errno = EINVAL; 47545916cd2Sjpk return (NULL); 47645916cd2Sjpk } 47745916cd2Sjpk 47845916cd2Sjpk if (path_name[0] != '/') { /* need absolute pathname */ 47945916cd2Sjpk errno = EINVAL; 48045916cd2Sjpk return (NULL); 48145916cd2Sjpk } 48245916cd2Sjpk 48345916cd2Sjpk if (resolved_path == NULL) { 48445916cd2Sjpk errno = EINVAL; 48545916cd2Sjpk return (NULL); 48645916cd2Sjpk } 48745916cd2Sjpk 48845916cd2Sjpk if ((zoneid = getzoneidbylabel(sl)) == -1) 48945916cd2Sjpk return (NULL); 49045916cd2Sjpk 49145916cd2Sjpk /* 49245916cd2Sjpk * Construct the list of mounted file systems. 49345916cd2Sjpk */ 49445916cd2Sjpk 49545916cd2Sjpk if ((mlist = tsol_mkmntlist()) == NULL) { 49645916cd2Sjpk return (NULL); 49745916cd2Sjpk } 49845916cd2Sjpk if (getglobalpath(path_name, zoneid, mlist, ret_path) == 0) { 49945916cd2Sjpk tsol_mlist_free(mlist); 50045916cd2Sjpk return (NULL); 50145916cd2Sjpk } 50245916cd2Sjpk tsol_mlist_free(mlist); 50345916cd2Sjpk if (strlen(ret_path) >= bufsize) { 50445916cd2Sjpk errno = EFAULT; 50545916cd2Sjpk return (NULL); 50645916cd2Sjpk } 50745916cd2Sjpk return (strcpy(resolved_path, ret_path)); 50845916cd2Sjpk } /* end getpathbylabel() */ 509