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 /* 2245916cd2Sjpk * Copyright 2006 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; 12145916cd2Sjpk 12245916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 12345916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 12445916cd2Sjpk 12545916cd2Sjpk if (mnt) 12645916cd2Sjpk tsol_mnt_free(mnt); 12745916cd2Sjpk free(mlp); 12845916cd2Sjpk } 12945916cd2Sjpk } 13045916cd2Sjpk 13145916cd2Sjpk static struct mnttab * 13245916cd2Sjpk mntdup(struct mnttab *mnt) 13345916cd2Sjpk { 13445916cd2Sjpk struct mnttab *new; 13545916cd2Sjpk 13645916cd2Sjpk new = (struct mnttab *)malloc(sizeof (*new)); 13745916cd2Sjpk if (new == NULL) 13845916cd2Sjpk return (NULL); 13945916cd2Sjpk 14045916cd2Sjpk new->mnt_special = NULL; 14145916cd2Sjpk new->mnt_mountp = NULL; 14245916cd2Sjpk new->mnt_fstype = NULL; 14345916cd2Sjpk new->mnt_mntopts = NULL; 14445916cd2Sjpk 14545916cd2Sjpk new->mnt_special = strdup(mnt->mnt_special); 14645916cd2Sjpk if (new->mnt_special == NULL) { 14745916cd2Sjpk tsol_mnt_free(new); 14845916cd2Sjpk return (NULL); 14945916cd2Sjpk } 15045916cd2Sjpk new->mnt_mountp = strdup(mnt->mnt_mountp); 15145916cd2Sjpk if (new->mnt_mountp == NULL) { 15245916cd2Sjpk tsol_mnt_free(new); 15345916cd2Sjpk return (NULL); 15445916cd2Sjpk } 15545916cd2Sjpk new->mnt_fstype = strdup(mnt->mnt_fstype); 15645916cd2Sjpk if (new->mnt_fstype == NULL) { 15745916cd2Sjpk tsol_mnt_free(new); 15845916cd2Sjpk return (NULL); 15945916cd2Sjpk } 16045916cd2Sjpk new->mnt_mntopts = strdup(mnt->mnt_mntopts); 16145916cd2Sjpk if (new->mnt_mntopts == NULL) { 16245916cd2Sjpk tsol_mnt_free(new); 16345916cd2Sjpk return (NULL); 16445916cd2Sjpk } 16545916cd2Sjpk return (new); 16645916cd2Sjpk } 16745916cd2Sjpk 16845916cd2Sjpk static struct mntlist * 16945916cd2Sjpk tsol_mkmntlist(void) 17045916cd2Sjpk { 17145916cd2Sjpk FILE *mounted; 17245916cd2Sjpk struct mntlist *mntl; 17345916cd2Sjpk struct mntlist *mntst = NULL; 17445916cd2Sjpk struct mnttab mnt; 17545916cd2Sjpk 176*004388ebScasper if ((mounted = fopen(MNTTAB, "rF")) == NULL) { 17745916cd2Sjpk perror(MNTTAB); 17845916cd2Sjpk return (NULL); 17945916cd2Sjpk } 18045916cd2Sjpk resetmnttab(mounted); 18145916cd2Sjpk while (getmntent(mounted, &mnt) == NULL) { 18245916cd2Sjpk mntl = (struct mntlist *)malloc(sizeof (*mntl)); 18345916cd2Sjpk if (mntl == NULL) { 18445916cd2Sjpk tsol_mlist_free(mntst); 18545916cd2Sjpk mntst = NULL; 18645916cd2Sjpk break; 18745916cd2Sjpk } 18845916cd2Sjpk mntl->mntl_mnt = mntdup((struct mnttab *)(&mnt)); 18945916cd2Sjpk if (mntl->mntl_mnt == NULL) { 19045916cd2Sjpk tsol_mlist_free(mntst); 19145916cd2Sjpk mntst = NULL; 19245916cd2Sjpk break; 19345916cd2Sjpk } 19445916cd2Sjpk mntl->mntl_next = mntst; 19545916cd2Sjpk mntst = mntl; 19645916cd2Sjpk } 19745916cd2Sjpk (void) fclose(mounted); 19845916cd2Sjpk return (mntst); 19945916cd2Sjpk } 20045916cd2Sjpk 20145916cd2Sjpk /* 20245916cd2Sjpk * This function attempts to convert local zone NFS mounted pathnames 20345916cd2Sjpk * into equivalent global zone NFS mounted pathnames. At present 20445916cd2Sjpk * it only works for automounted filesystems. It depends on the 20545916cd2Sjpk * assumption that both the local and global zone automounters 20645916cd2Sjpk * share the same nameservices. It also assumes that any automount 20745916cd2Sjpk * map used by a local zone is available to the global zone automounter. 20845916cd2Sjpk * 20945916cd2Sjpk * The algorithm used consists of three phases. 21045916cd2Sjpk * 21145916cd2Sjpk * 1. The local zone's mnttab is searched to find the automount map 21245916cd2Sjpk * with the closest matching mountpath. 21345916cd2Sjpk * 21445916cd2Sjpk * 2. The matching autmount map name is looked up in the global zone's 21545916cd2Sjpk * mnttab to determine the path where it should be mounted in the 21645916cd2Sjpk * global zone. 21745916cd2Sjpk * 21845916cd2Sjpk * 3. A pathname covered by an appropiate autofs trigger mount in 21945916cd2Sjpk * the global zone is generated as the resolved pathname 22045916cd2Sjpk * 22145916cd2Sjpk * Among the things that can go wrong is that global zone doesn't have 22245916cd2Sjpk * a matching automount map or the mount was not done via the automounter. 22345916cd2Sjpk * Either of these cases return a NULL path. 22445916cd2Sjpk */ 22545916cd2Sjpk #define ZONE_OPT "zone=" 22645916cd2Sjpk static int 22745916cd2Sjpk getnfspathbyautofs(struct mntlist *mlist, zoneid_t zoneid, 22845916cd2Sjpk struct mnttab *autofs_mnt, char *globalpath, char *zonepath, int global_len) 22945916cd2Sjpk { 23045916cd2Sjpk struct mntlist *mlp; 23145916cd2Sjpk char zonematch[ZONENAME_MAX + 20]; 23245916cd2Sjpk char zonename[ZONENAME_MAX]; 23345916cd2Sjpk int longestmatch; 23445916cd2Sjpk struct mnttab *mountmatch; 23545916cd2Sjpk 23645916cd2Sjpk if (autofs_mnt) { 23745916cd2Sjpk mountmatch = autofs_mnt; 23845916cd2Sjpk longestmatch = strlen(mountmatch->mnt_mountp); 23945916cd2Sjpk } else { 24045916cd2Sjpk /* 24145916cd2Sjpk * First we need to get the zonename to look for 24245916cd2Sjpk */ 24345916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_NAME, zonename, 24445916cd2Sjpk ZONENAME_MAX) == -1) { 24545916cd2Sjpk return (0); 24645916cd2Sjpk } 24745916cd2Sjpk 24845916cd2Sjpk (void) strncpy(zonematch, ZONE_OPT, sizeof (zonematch)); 24945916cd2Sjpk (void) strlcat(zonematch, zonename, sizeof (zonematch)); 25045916cd2Sjpk 25145916cd2Sjpk /* 25245916cd2Sjpk * Find the best match for an automount map that 25345916cd2Sjpk * corresponds to the local zone's pathname 25445916cd2Sjpk */ 25545916cd2Sjpk longestmatch = 0; 25645916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 25745916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 25845916cd2Sjpk int len; 25945916cd2Sjpk int matchfound; 26045916cd2Sjpk char *token; 26145916cd2Sjpk char *lasts; 26245916cd2Sjpk char mntopts[MAXPATHLEN]; 26345916cd2Sjpk 26445916cd2Sjpk if (subpath(globalpath, mnt->mnt_mountp) != 0) 26545916cd2Sjpk continue; 26645916cd2Sjpk if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) 26745916cd2Sjpk continue; 26845916cd2Sjpk 26945916cd2Sjpk matchfound = 0; 27045916cd2Sjpk (void) strncpy(mntopts, mnt->mnt_mntopts, MAXPATHLEN); 27145916cd2Sjpk if ((token = strtok_r(mntopts, ",", &lasts)) != NULL) { 27245916cd2Sjpk if (strcmp(token, zonematch) == 0) { 27345916cd2Sjpk matchfound = 1; 27445916cd2Sjpk } else while ((token = strtok_r(NULL, ",", 27545916cd2Sjpk &lasts)) != NULL) { 27645916cd2Sjpk if (strcmp(token, zonematch) == 0) { 27745916cd2Sjpk matchfound = 1; 27845916cd2Sjpk break; 27945916cd2Sjpk } 28045916cd2Sjpk } 28145916cd2Sjpk } 28245916cd2Sjpk if (matchfound) { 28345916cd2Sjpk len = strlen(mnt->mnt_mountp); 28445916cd2Sjpk if (len > longestmatch) { 28545916cd2Sjpk mountmatch = mnt; 28645916cd2Sjpk longestmatch = len; 28745916cd2Sjpk } 28845916cd2Sjpk } 28945916cd2Sjpk } 29045916cd2Sjpk } 29145916cd2Sjpk if (longestmatch == 0) { 29245916cd2Sjpk return (0); 29345916cd2Sjpk } else { 29445916cd2Sjpk /* 29545916cd2Sjpk * Now we may have found the corresponding autofs mount 29645916cd2Sjpk * Try to find the matching global zone autofs entry 29745916cd2Sjpk */ 29845916cd2Sjpk 29945916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 30045916cd2Sjpk char p[MAXPATHLEN]; 30145916cd2Sjpk size_t zp_len; 30245916cd2Sjpk size_t mp_len; 30345916cd2Sjpk 30445916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 30545916cd2Sjpk 30645916cd2Sjpk if (strcmp(mountmatch->mnt_special, 30745916cd2Sjpk mnt->mnt_special) != 0) 30845916cd2Sjpk continue; 30945916cd2Sjpk if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) 31045916cd2Sjpk continue; 31145916cd2Sjpk if (strstr(mnt->mnt_mntopts, ZONE_OPT) != NULL) 31245916cd2Sjpk continue; 31345916cd2Sjpk /* 31445916cd2Sjpk * OK, we have a matching global zone automap 31545916cd2Sjpk * so adjust the path for the global zone. 31645916cd2Sjpk */ 31745916cd2Sjpk zp_len = strlen(zonepath); 31845916cd2Sjpk mp_len = strlen(mnt->mnt_mountp); 31945916cd2Sjpk (void) strncpy(p, globalpath + zp_len, MAXPATHLEN); 32045916cd2Sjpk /* 32145916cd2Sjpk * If both global zone and zone-relative 32245916cd2Sjpk * mountpoint match, just use the same pathname 32345916cd2Sjpk */ 32445916cd2Sjpk if (strncmp(mnt->mnt_mountp, p, mp_len) == 0) { 32545916cd2Sjpk (void) strncpy(globalpath, p, global_len); 32645916cd2Sjpk return (1); 32745916cd2Sjpk } else { 32845916cd2Sjpk (void) strncpy(p, globalpath, MAXPATHLEN); 32945916cd2Sjpk (void) strncpy(globalpath, mnt->mnt_mountp, 33045916cd2Sjpk global_len); 33145916cd2Sjpk (void) strlcat(globalpath, 33245916cd2Sjpk p + strlen(mountmatch->mnt_mountp), 33345916cd2Sjpk global_len); 33445916cd2Sjpk return (1); 33545916cd2Sjpk } 33645916cd2Sjpk } 33745916cd2Sjpk return (0); 33845916cd2Sjpk } 33945916cd2Sjpk } 34045916cd2Sjpk 34145916cd2Sjpk /* 34245916cd2Sjpk * Find the pathname for the entry in mlist that corresponds to the 34345916cd2Sjpk * file named by path (i.e., that names a mount table entry for the 34445916cd2Sjpk * file system in which path lies). 34545916cd2Sjpk * 34645916cd2Sjpk * Return 0 is there an error. 34745916cd2Sjpk */ 34845916cd2Sjpk static int 34945916cd2Sjpk getglobalpath(const char *path, zoneid_t zoneid, struct mntlist *mlist, 35045916cd2Sjpk char *globalpath) 35145916cd2Sjpk { 35245916cd2Sjpk struct mntlist *mlp; 35345916cd2Sjpk char lofspath[MAXPATHLEN]; 35445916cd2Sjpk char zonepath[MAXPATHLEN]; 35545916cd2Sjpk int longestmatch; 35645916cd2Sjpk struct mnttab *mountmatch; 35745916cd2Sjpk 35845916cd2Sjpk if (zoneid != GLOBAL_ZONEID) { 35945916cd2Sjpk char *prefix; 36045916cd2Sjpk 36145916cd2Sjpk if ((prefix = getzonerootbyid(zoneid)) == NULL) { 36245916cd2Sjpk return (0); 36345916cd2Sjpk } 36445916cd2Sjpk (void) strncpy(zonepath, prefix, MAXPATHLEN); 36545916cd2Sjpk (void) strlcpy(globalpath, prefix, MAXPATHLEN); 36645916cd2Sjpk (void) strlcat(globalpath, path, MAXPATHLEN); 36745916cd2Sjpk free(prefix); 36845916cd2Sjpk } else { 36945916cd2Sjpk (void) strlcpy(globalpath, path, MAXPATHLEN); 37045916cd2Sjpk } 37145916cd2Sjpk 37245916cd2Sjpk for (;;) { 37345916cd2Sjpk longestmatch = 0; 37445916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 37545916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 37645916cd2Sjpk int len; 37745916cd2Sjpk 37845916cd2Sjpk if (subpath(globalpath, mnt->mnt_mountp) != 0) 37945916cd2Sjpk continue; 38045916cd2Sjpk len = strlen(mnt->mnt_mountp); 38145916cd2Sjpk if (len > longestmatch) { 38245916cd2Sjpk mountmatch = mnt; 38345916cd2Sjpk longestmatch = len; 38445916cd2Sjpk } 38545916cd2Sjpk } 38645916cd2Sjpk /* 38745916cd2Sjpk * Handle interesting mounts. 38845916cd2Sjpk */ 38945916cd2Sjpk if ((strcmp(mountmatch->mnt_fstype, MNTTYPE_NFS) == 0) || 39045916cd2Sjpk (strcmp(mountmatch->mnt_fstype, MNTTYPE_AUTOFS) == 0)) { 39145916cd2Sjpk if (zoneid > GLOBAL_ZONEID) { 39245916cd2Sjpk struct mnttab *m = NULL; 39345916cd2Sjpk 39445916cd2Sjpk if (strcmp(mountmatch->mnt_fstype, 39545916cd2Sjpk MNTTYPE_AUTOFS) == 0) 39645916cd2Sjpk m = mountmatch; 39745916cd2Sjpk if (getnfspathbyautofs(mlist, zoneid, m, 39845916cd2Sjpk globalpath, zonepath, MAXPATHLEN) == 0) { 39945916cd2Sjpk return (0); 40045916cd2Sjpk } 40145916cd2Sjpk } 40245916cd2Sjpk break; 40345916cd2Sjpk } else if (strcmp(mountmatch->mnt_fstype, MNTTYPE_LOFS) == 0) { 40445916cd2Sjpk /* 40545916cd2Sjpk * count up what's left 40645916cd2Sjpk */ 40745916cd2Sjpk int remainder; 40845916cd2Sjpk 40945916cd2Sjpk remainder = strlen(globalpath) - longestmatch; 41045916cd2Sjpk if (remainder > 0) { 41145916cd2Sjpk path = pathsuffix(globalpath, 41245916cd2Sjpk mountmatch->mnt_mountp); 41345916cd2Sjpk (void) strlcpy(lofspath, path, MAXPATHLEN); 41445916cd2Sjpk } 41545916cd2Sjpk (void) strlcpy(globalpath, mountmatch->mnt_special, 41645916cd2Sjpk MAXPATHLEN); 41745916cd2Sjpk if (remainder > 0) { 41845916cd2Sjpk (void) strlcat(globalpath, lofspath, 41945916cd2Sjpk MAXPATHLEN); 42045916cd2Sjpk } 42145916cd2Sjpk } else { 42245916cd2Sjpk if ((zoneid > GLOBAL_ZONEID) && 42345916cd2Sjpk (strncmp(path, "/home/", strlen("/home/")) == 0)) { 42445916cd2Sjpk char zonename[ZONENAME_MAX]; 42545916cd2Sjpk 42645916cd2Sjpk /* 42745916cd2Sjpk * If this is a cross-zone reference to 42845916cd2Sjpk * a home directory, it must be corrected. 42945916cd2Sjpk * We should only get here if the zone's 43045916cd2Sjpk * automounter hasn't yet mounted its 43145916cd2Sjpk * autofs trigger on /home. 43245916cd2Sjpk * 43345916cd2Sjpk * Since it is likely to do so in the 43445916cd2Sjpk * future, we will assume that the global 43545916cd2Sjpk * zone already has an equivalent autofs 43645916cd2Sjpk * mount established. By convention, 43745916cd2Sjpk * this should be mounted at the 43845916cd2Sjpk * /zone/<zonename> 43945916cd2Sjpk */ 44045916cd2Sjpk 44145916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_NAME, 44245916cd2Sjpk zonename, ZONENAME_MAX) == -1) { 44345916cd2Sjpk return (0); 44445916cd2Sjpk } else { 44545916cd2Sjpk (void) snprintf(globalpath, MAXPATHLEN, 44645916cd2Sjpk "/zone/%s%s", zonename, path); 44745916cd2Sjpk } 44845916cd2Sjpk } 44945916cd2Sjpk break; 45045916cd2Sjpk } 45145916cd2Sjpk } 45245916cd2Sjpk return (1); 45345916cd2Sjpk } 45445916cd2Sjpk 45545916cd2Sjpk 45645916cd2Sjpk /* 45745916cd2Sjpk * This function is only useful for global zone callers 45845916cd2Sjpk * It uses the global zone mnttab to translate local zone pathnames 45945916cd2Sjpk * into global zone pathnames. 46045916cd2Sjpk */ 46145916cd2Sjpk char * 46245916cd2Sjpk getpathbylabel(const char *path_name, char *resolved_path, size_t bufsize, 46345916cd2Sjpk const bslabel_t *sl) { 46445916cd2Sjpk char ret_path[MAXPATHLEN]; /* pathname to return */ 46545916cd2Sjpk zoneid_t zoneid; 46645916cd2Sjpk struct mntlist *mlist; 46745916cd2Sjpk 46845916cd2Sjpk if (getzoneid() != GLOBAL_ZONEID) { 46945916cd2Sjpk errno = EINVAL; 47045916cd2Sjpk return (NULL); 47145916cd2Sjpk } 47245916cd2Sjpk 47345916cd2Sjpk if (path_name[0] != '/') { /* need absolute pathname */ 47445916cd2Sjpk errno = EINVAL; 47545916cd2Sjpk return (NULL); 47645916cd2Sjpk } 47745916cd2Sjpk 47845916cd2Sjpk if (resolved_path == NULL) { 47945916cd2Sjpk errno = EINVAL; 48045916cd2Sjpk return (NULL); 48145916cd2Sjpk } 48245916cd2Sjpk 48345916cd2Sjpk if ((zoneid = getzoneidbylabel(sl)) == -1) 48445916cd2Sjpk return (NULL); 48545916cd2Sjpk 48645916cd2Sjpk /* 48745916cd2Sjpk * Construct the list of mounted file systems. 48845916cd2Sjpk */ 48945916cd2Sjpk 49045916cd2Sjpk if ((mlist = tsol_mkmntlist()) == NULL) { 49145916cd2Sjpk return (NULL); 49245916cd2Sjpk } 49345916cd2Sjpk if (getglobalpath(path_name, zoneid, mlist, ret_path) == 0) { 49445916cd2Sjpk tsol_mlist_free(mlist); 49545916cd2Sjpk return (NULL); 49645916cd2Sjpk } 49745916cd2Sjpk tsol_mlist_free(mlist); 49845916cd2Sjpk if (strlen(ret_path) >= bufsize) { 49945916cd2Sjpk errno = EFAULT; 50045916cd2Sjpk return (NULL); 50145916cd2Sjpk } 50245916cd2Sjpk return (strcpy(resolved_path, ret_path)); 50345916cd2Sjpk } /* end getpathbylabel() */ 504