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 #pragma ident "%Z%%M% %I% %E% SMI" 27*45916cd2Sjpk 28*45916cd2Sjpk 29*45916cd2Sjpk /* 30*45916cd2Sjpk * Name: getpathbylabel.c 31*45916cd2Sjpk * 32*45916cd2Sjpk * Description: Returns the global zone pathname corresponding 33*45916cd2Sjpk * to the specified label. The pathname does 34*45916cd2Sjpk * not need to match an existing file system object. 35*45916cd2Sjpk * 36*45916cd2Sjpk */ 37*45916cd2Sjpk #include <stdio.h> 38*45916cd2Sjpk #include <string.h> 39*45916cd2Sjpk #include <unistd.h> 40*45916cd2Sjpk #include <errno.h> 41*45916cd2Sjpk #include <sys/types.h> 42*45916cd2Sjpk #include <tsol/label.h> 43*45916cd2Sjpk #include <stdlib.h> 44*45916cd2Sjpk #include <zone.h> 45*45916cd2Sjpk #include <sys/mntent.h> 46*45916cd2Sjpk #include <sys/mnttab.h> 47*45916cd2Sjpk #include <stdarg.h> 48*45916cd2Sjpk 49*45916cd2Sjpk /* 50*45916cd2Sjpk * This structure is used to chain mntent structures into a list 51*45916cd2Sjpk * and to cache stat information for each member of the list. 52*45916cd2Sjpk */ 53*45916cd2Sjpk struct mntlist { 54*45916cd2Sjpk struct mnttab *mntl_mnt; 55*45916cd2Sjpk struct mntlist *mntl_next; 56*45916cd2Sjpk }; 57*45916cd2Sjpk 58*45916cd2Sjpk 59*45916cd2Sjpk /* 60*45916cd2Sjpk * Return a pointer to the trailing suffix of full that follows the prefix 61*45916cd2Sjpk * given by pref. If pref isn't a prefix of full, return NULL. Apply 62*45916cd2Sjpk * pathname semantics to the prefix test, so that pref must match at a 63*45916cd2Sjpk * component boundary. 64*45916cd2Sjpk */ 65*45916cd2Sjpk static char * 66*45916cd2Sjpk pathsuffix(char *full, char *pref) 67*45916cd2Sjpk { 68*45916cd2Sjpk int preflen; 69*45916cd2Sjpk 70*45916cd2Sjpk if (full == NULL || pref == NULL) 71*45916cd2Sjpk return (NULL); 72*45916cd2Sjpk 73*45916cd2Sjpk preflen = strlen(pref); 74*45916cd2Sjpk if (strncmp(pref, full, preflen) != 0) 75*45916cd2Sjpk return (NULL); 76*45916cd2Sjpk 77*45916cd2Sjpk /* 78*45916cd2Sjpk * pref is a substring of full. To be a subpath, it cannot cover a 79*45916cd2Sjpk * partial component of full. The last clause of the test handles the 80*45916cd2Sjpk * special case of the root. 81*45916cd2Sjpk */ 82*45916cd2Sjpk if (full[preflen] != '\0' && full[preflen] != '/' && preflen > 1) 83*45916cd2Sjpk return (NULL); 84*45916cd2Sjpk 85*45916cd2Sjpk if (preflen == 1 && full[0] == '/') 86*45916cd2Sjpk return (full); 87*45916cd2Sjpk else 88*45916cd2Sjpk return (full + preflen); 89*45916cd2Sjpk } 90*45916cd2Sjpk 91*45916cd2Sjpk /* 92*45916cd2Sjpk * Return zero iff the path named by sub is a leading subpath 93*45916cd2Sjpk * of the path named by full. 94*45916cd2Sjpk * 95*45916cd2Sjpk * Treat null paths as matching nothing. 96*45916cd2Sjpk */ 97*45916cd2Sjpk static int 98*45916cd2Sjpk subpath(char *full, char *sub) 99*45916cd2Sjpk { 100*45916cd2Sjpk return (pathsuffix(full, sub) == NULL); 101*45916cd2Sjpk } 102*45916cd2Sjpk 103*45916cd2Sjpk static void 104*45916cd2Sjpk tsol_mnt_free(struct mnttab *mnt) 105*45916cd2Sjpk { 106*45916cd2Sjpk if (mnt->mnt_special) 107*45916cd2Sjpk free(mnt->mnt_special); 108*45916cd2Sjpk if (mnt->mnt_mountp) 109*45916cd2Sjpk free(mnt->mnt_mountp); 110*45916cd2Sjpk if (mnt->mnt_fstype) 111*45916cd2Sjpk free(mnt->mnt_fstype); 112*45916cd2Sjpk if (mnt->mnt_mntopts) 113*45916cd2Sjpk free(mnt->mnt_mntopts); 114*45916cd2Sjpk free(mnt); 115*45916cd2Sjpk } 116*45916cd2Sjpk 117*45916cd2Sjpk static void 118*45916cd2Sjpk tsol_mlist_free(struct mntlist *mlist) 119*45916cd2Sjpk { 120*45916cd2Sjpk struct mntlist *mlp; 121*45916cd2Sjpk 122*45916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 123*45916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 124*45916cd2Sjpk 125*45916cd2Sjpk if (mnt) 126*45916cd2Sjpk tsol_mnt_free(mnt); 127*45916cd2Sjpk free(mlp); 128*45916cd2Sjpk } 129*45916cd2Sjpk } 130*45916cd2Sjpk 131*45916cd2Sjpk static struct mnttab * 132*45916cd2Sjpk mntdup(struct mnttab *mnt) 133*45916cd2Sjpk { 134*45916cd2Sjpk struct mnttab *new; 135*45916cd2Sjpk 136*45916cd2Sjpk new = (struct mnttab *)malloc(sizeof (*new)); 137*45916cd2Sjpk if (new == NULL) 138*45916cd2Sjpk return (NULL); 139*45916cd2Sjpk 140*45916cd2Sjpk new->mnt_special = NULL; 141*45916cd2Sjpk new->mnt_mountp = NULL; 142*45916cd2Sjpk new->mnt_fstype = NULL; 143*45916cd2Sjpk new->mnt_mntopts = NULL; 144*45916cd2Sjpk 145*45916cd2Sjpk new->mnt_special = strdup(mnt->mnt_special); 146*45916cd2Sjpk if (new->mnt_special == NULL) { 147*45916cd2Sjpk tsol_mnt_free(new); 148*45916cd2Sjpk return (NULL); 149*45916cd2Sjpk } 150*45916cd2Sjpk new->mnt_mountp = strdup(mnt->mnt_mountp); 151*45916cd2Sjpk if (new->mnt_mountp == NULL) { 152*45916cd2Sjpk tsol_mnt_free(new); 153*45916cd2Sjpk return (NULL); 154*45916cd2Sjpk } 155*45916cd2Sjpk new->mnt_fstype = strdup(mnt->mnt_fstype); 156*45916cd2Sjpk if (new->mnt_fstype == NULL) { 157*45916cd2Sjpk tsol_mnt_free(new); 158*45916cd2Sjpk return (NULL); 159*45916cd2Sjpk } 160*45916cd2Sjpk new->mnt_mntopts = strdup(mnt->mnt_mntopts); 161*45916cd2Sjpk if (new->mnt_mntopts == NULL) { 162*45916cd2Sjpk tsol_mnt_free(new); 163*45916cd2Sjpk return (NULL); 164*45916cd2Sjpk } 165*45916cd2Sjpk return (new); 166*45916cd2Sjpk } 167*45916cd2Sjpk 168*45916cd2Sjpk static struct mntlist * 169*45916cd2Sjpk tsol_mkmntlist(void) 170*45916cd2Sjpk { 171*45916cd2Sjpk FILE *mounted; 172*45916cd2Sjpk struct mntlist *mntl; 173*45916cd2Sjpk struct mntlist *mntst = NULL; 174*45916cd2Sjpk struct mnttab mnt; 175*45916cd2Sjpk 176*45916cd2Sjpk if ((mounted = fopen(MNTTAB, "r")) == NULL) { 177*45916cd2Sjpk perror(MNTTAB); 178*45916cd2Sjpk return (NULL); 179*45916cd2Sjpk } 180*45916cd2Sjpk resetmnttab(mounted); 181*45916cd2Sjpk while (getmntent(mounted, &mnt) == NULL) { 182*45916cd2Sjpk mntl = (struct mntlist *)malloc(sizeof (*mntl)); 183*45916cd2Sjpk if (mntl == NULL) { 184*45916cd2Sjpk tsol_mlist_free(mntst); 185*45916cd2Sjpk mntst = NULL; 186*45916cd2Sjpk break; 187*45916cd2Sjpk } 188*45916cd2Sjpk mntl->mntl_mnt = mntdup((struct mnttab *)(&mnt)); 189*45916cd2Sjpk if (mntl->mntl_mnt == NULL) { 190*45916cd2Sjpk tsol_mlist_free(mntst); 191*45916cd2Sjpk mntst = NULL; 192*45916cd2Sjpk break; 193*45916cd2Sjpk } 194*45916cd2Sjpk mntl->mntl_next = mntst; 195*45916cd2Sjpk mntst = mntl; 196*45916cd2Sjpk } 197*45916cd2Sjpk (void) fclose(mounted); 198*45916cd2Sjpk return (mntst); 199*45916cd2Sjpk } 200*45916cd2Sjpk 201*45916cd2Sjpk /* 202*45916cd2Sjpk * This function attempts to convert local zone NFS mounted pathnames 203*45916cd2Sjpk * into equivalent global zone NFS mounted pathnames. At present 204*45916cd2Sjpk * it only works for automounted filesystems. It depends on the 205*45916cd2Sjpk * assumption that both the local and global zone automounters 206*45916cd2Sjpk * share the same nameservices. It also assumes that any automount 207*45916cd2Sjpk * map used by a local zone is available to the global zone automounter. 208*45916cd2Sjpk * 209*45916cd2Sjpk * The algorithm used consists of three phases. 210*45916cd2Sjpk * 211*45916cd2Sjpk * 1. The local zone's mnttab is searched to find the automount map 212*45916cd2Sjpk * with the closest matching mountpath. 213*45916cd2Sjpk * 214*45916cd2Sjpk * 2. The matching autmount map name is looked up in the global zone's 215*45916cd2Sjpk * mnttab to determine the path where it should be mounted in the 216*45916cd2Sjpk * global zone. 217*45916cd2Sjpk * 218*45916cd2Sjpk * 3. A pathname covered by an appropiate autofs trigger mount in 219*45916cd2Sjpk * the global zone is generated as the resolved pathname 220*45916cd2Sjpk * 221*45916cd2Sjpk * Among the things that can go wrong is that global zone doesn't have 222*45916cd2Sjpk * a matching automount map or the mount was not done via the automounter. 223*45916cd2Sjpk * Either of these cases return a NULL path. 224*45916cd2Sjpk */ 225*45916cd2Sjpk #define ZONE_OPT "zone=" 226*45916cd2Sjpk static int 227*45916cd2Sjpk getnfspathbyautofs(struct mntlist *mlist, zoneid_t zoneid, 228*45916cd2Sjpk struct mnttab *autofs_mnt, char *globalpath, char *zonepath, int global_len) 229*45916cd2Sjpk { 230*45916cd2Sjpk struct mntlist *mlp; 231*45916cd2Sjpk char zonematch[ZONENAME_MAX + 20]; 232*45916cd2Sjpk char zonename[ZONENAME_MAX]; 233*45916cd2Sjpk int longestmatch; 234*45916cd2Sjpk struct mnttab *mountmatch; 235*45916cd2Sjpk 236*45916cd2Sjpk if (autofs_mnt) { 237*45916cd2Sjpk mountmatch = autofs_mnt; 238*45916cd2Sjpk longestmatch = strlen(mountmatch->mnt_mountp); 239*45916cd2Sjpk } else { 240*45916cd2Sjpk /* 241*45916cd2Sjpk * First we need to get the zonename to look for 242*45916cd2Sjpk */ 243*45916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_NAME, zonename, 244*45916cd2Sjpk ZONENAME_MAX) == -1) { 245*45916cd2Sjpk return (0); 246*45916cd2Sjpk } 247*45916cd2Sjpk 248*45916cd2Sjpk (void) strncpy(zonematch, ZONE_OPT, sizeof (zonematch)); 249*45916cd2Sjpk (void) strlcat(zonematch, zonename, sizeof (zonematch)); 250*45916cd2Sjpk 251*45916cd2Sjpk /* 252*45916cd2Sjpk * Find the best match for an automount map that 253*45916cd2Sjpk * corresponds to the local zone's pathname 254*45916cd2Sjpk */ 255*45916cd2Sjpk longestmatch = 0; 256*45916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 257*45916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 258*45916cd2Sjpk int len; 259*45916cd2Sjpk int matchfound; 260*45916cd2Sjpk char *token; 261*45916cd2Sjpk char *lasts; 262*45916cd2Sjpk char mntopts[MAXPATHLEN]; 263*45916cd2Sjpk 264*45916cd2Sjpk if (subpath(globalpath, mnt->mnt_mountp) != 0) 265*45916cd2Sjpk continue; 266*45916cd2Sjpk if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) 267*45916cd2Sjpk continue; 268*45916cd2Sjpk 269*45916cd2Sjpk matchfound = 0; 270*45916cd2Sjpk (void) strncpy(mntopts, mnt->mnt_mntopts, MAXPATHLEN); 271*45916cd2Sjpk if ((token = strtok_r(mntopts, ",", &lasts)) != NULL) { 272*45916cd2Sjpk if (strcmp(token, zonematch) == 0) { 273*45916cd2Sjpk matchfound = 1; 274*45916cd2Sjpk } else while ((token = strtok_r(NULL, ",", 275*45916cd2Sjpk &lasts)) != NULL) { 276*45916cd2Sjpk if (strcmp(token, zonematch) == 0) { 277*45916cd2Sjpk matchfound = 1; 278*45916cd2Sjpk break; 279*45916cd2Sjpk } 280*45916cd2Sjpk } 281*45916cd2Sjpk } 282*45916cd2Sjpk if (matchfound) { 283*45916cd2Sjpk len = strlen(mnt->mnt_mountp); 284*45916cd2Sjpk if (len > longestmatch) { 285*45916cd2Sjpk mountmatch = mnt; 286*45916cd2Sjpk longestmatch = len; 287*45916cd2Sjpk } 288*45916cd2Sjpk } 289*45916cd2Sjpk } 290*45916cd2Sjpk } 291*45916cd2Sjpk if (longestmatch == 0) { 292*45916cd2Sjpk return (0); 293*45916cd2Sjpk } else { 294*45916cd2Sjpk /* 295*45916cd2Sjpk * Now we may have found the corresponding autofs mount 296*45916cd2Sjpk * Try to find the matching global zone autofs entry 297*45916cd2Sjpk */ 298*45916cd2Sjpk 299*45916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 300*45916cd2Sjpk char p[MAXPATHLEN]; 301*45916cd2Sjpk size_t zp_len; 302*45916cd2Sjpk size_t mp_len; 303*45916cd2Sjpk 304*45916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 305*45916cd2Sjpk 306*45916cd2Sjpk if (strcmp(mountmatch->mnt_special, 307*45916cd2Sjpk mnt->mnt_special) != 0) 308*45916cd2Sjpk continue; 309*45916cd2Sjpk if (strcmp(mnt->mnt_fstype, MNTTYPE_AUTOFS)) 310*45916cd2Sjpk continue; 311*45916cd2Sjpk if (strstr(mnt->mnt_mntopts, ZONE_OPT) != NULL) 312*45916cd2Sjpk continue; 313*45916cd2Sjpk /* 314*45916cd2Sjpk * OK, we have a matching global zone automap 315*45916cd2Sjpk * so adjust the path for the global zone. 316*45916cd2Sjpk */ 317*45916cd2Sjpk zp_len = strlen(zonepath); 318*45916cd2Sjpk mp_len = strlen(mnt->mnt_mountp); 319*45916cd2Sjpk (void) strncpy(p, globalpath + zp_len, MAXPATHLEN); 320*45916cd2Sjpk /* 321*45916cd2Sjpk * If both global zone and zone-relative 322*45916cd2Sjpk * mountpoint match, just use the same pathname 323*45916cd2Sjpk */ 324*45916cd2Sjpk if (strncmp(mnt->mnt_mountp, p, mp_len) == 0) { 325*45916cd2Sjpk (void) strncpy(globalpath, p, global_len); 326*45916cd2Sjpk return (1); 327*45916cd2Sjpk } else { 328*45916cd2Sjpk (void) strncpy(p, globalpath, MAXPATHLEN); 329*45916cd2Sjpk (void) strncpy(globalpath, mnt->mnt_mountp, 330*45916cd2Sjpk global_len); 331*45916cd2Sjpk (void) strlcat(globalpath, 332*45916cd2Sjpk p + strlen(mountmatch->mnt_mountp), 333*45916cd2Sjpk global_len); 334*45916cd2Sjpk return (1); 335*45916cd2Sjpk } 336*45916cd2Sjpk } 337*45916cd2Sjpk return (0); 338*45916cd2Sjpk } 339*45916cd2Sjpk } 340*45916cd2Sjpk 341*45916cd2Sjpk /* 342*45916cd2Sjpk * Find the pathname for the entry in mlist that corresponds to the 343*45916cd2Sjpk * file named by path (i.e., that names a mount table entry for the 344*45916cd2Sjpk * file system in which path lies). 345*45916cd2Sjpk * 346*45916cd2Sjpk * Return 0 is there an error. 347*45916cd2Sjpk */ 348*45916cd2Sjpk static int 349*45916cd2Sjpk getglobalpath(const char *path, zoneid_t zoneid, struct mntlist *mlist, 350*45916cd2Sjpk char *globalpath) 351*45916cd2Sjpk { 352*45916cd2Sjpk struct mntlist *mlp; 353*45916cd2Sjpk char lofspath[MAXPATHLEN]; 354*45916cd2Sjpk char zonepath[MAXPATHLEN]; 355*45916cd2Sjpk int longestmatch; 356*45916cd2Sjpk struct mnttab *mountmatch; 357*45916cd2Sjpk 358*45916cd2Sjpk if (zoneid != GLOBAL_ZONEID) { 359*45916cd2Sjpk char *prefix; 360*45916cd2Sjpk 361*45916cd2Sjpk if ((prefix = getzonerootbyid(zoneid)) == NULL) { 362*45916cd2Sjpk return (0); 363*45916cd2Sjpk } 364*45916cd2Sjpk (void) strncpy(zonepath, prefix, MAXPATHLEN); 365*45916cd2Sjpk (void) strlcpy(globalpath, prefix, MAXPATHLEN); 366*45916cd2Sjpk (void) strlcat(globalpath, path, MAXPATHLEN); 367*45916cd2Sjpk free(prefix); 368*45916cd2Sjpk } else { 369*45916cd2Sjpk (void) strlcpy(globalpath, path, MAXPATHLEN); 370*45916cd2Sjpk } 371*45916cd2Sjpk 372*45916cd2Sjpk for (;;) { 373*45916cd2Sjpk longestmatch = 0; 374*45916cd2Sjpk for (mlp = mlist; mlp; mlp = mlp->mntl_next) { 375*45916cd2Sjpk struct mnttab *mnt = mlp->mntl_mnt; 376*45916cd2Sjpk int len; 377*45916cd2Sjpk 378*45916cd2Sjpk if (subpath(globalpath, mnt->mnt_mountp) != 0) 379*45916cd2Sjpk continue; 380*45916cd2Sjpk len = strlen(mnt->mnt_mountp); 381*45916cd2Sjpk if (len > longestmatch) { 382*45916cd2Sjpk mountmatch = mnt; 383*45916cd2Sjpk longestmatch = len; 384*45916cd2Sjpk } 385*45916cd2Sjpk } 386*45916cd2Sjpk /* 387*45916cd2Sjpk * Handle interesting mounts. 388*45916cd2Sjpk */ 389*45916cd2Sjpk if ((strcmp(mountmatch->mnt_fstype, MNTTYPE_NFS) == 0) || 390*45916cd2Sjpk (strcmp(mountmatch->mnt_fstype, MNTTYPE_AUTOFS) == 0)) { 391*45916cd2Sjpk if (zoneid > GLOBAL_ZONEID) { 392*45916cd2Sjpk struct mnttab *m = NULL; 393*45916cd2Sjpk 394*45916cd2Sjpk if (strcmp(mountmatch->mnt_fstype, 395*45916cd2Sjpk MNTTYPE_AUTOFS) == 0) 396*45916cd2Sjpk m = mountmatch; 397*45916cd2Sjpk if (getnfspathbyautofs(mlist, zoneid, m, 398*45916cd2Sjpk globalpath, zonepath, MAXPATHLEN) == 0) { 399*45916cd2Sjpk return (0); 400*45916cd2Sjpk } 401*45916cd2Sjpk } 402*45916cd2Sjpk break; 403*45916cd2Sjpk } else if (strcmp(mountmatch->mnt_fstype, MNTTYPE_LOFS) == 0) { 404*45916cd2Sjpk /* 405*45916cd2Sjpk * count up what's left 406*45916cd2Sjpk */ 407*45916cd2Sjpk int remainder; 408*45916cd2Sjpk 409*45916cd2Sjpk remainder = strlen(globalpath) - longestmatch; 410*45916cd2Sjpk if (remainder > 0) { 411*45916cd2Sjpk path = pathsuffix(globalpath, 412*45916cd2Sjpk mountmatch->mnt_mountp); 413*45916cd2Sjpk (void) strlcpy(lofspath, path, MAXPATHLEN); 414*45916cd2Sjpk } 415*45916cd2Sjpk (void) strlcpy(globalpath, mountmatch->mnt_special, 416*45916cd2Sjpk MAXPATHLEN); 417*45916cd2Sjpk if (remainder > 0) { 418*45916cd2Sjpk (void) strlcat(globalpath, lofspath, 419*45916cd2Sjpk MAXPATHLEN); 420*45916cd2Sjpk } 421*45916cd2Sjpk } else { 422*45916cd2Sjpk if ((zoneid > GLOBAL_ZONEID) && 423*45916cd2Sjpk (strncmp(path, "/home/", strlen("/home/")) == 0)) { 424*45916cd2Sjpk char zonename[ZONENAME_MAX]; 425*45916cd2Sjpk 426*45916cd2Sjpk /* 427*45916cd2Sjpk * If this is a cross-zone reference to 428*45916cd2Sjpk * a home directory, it must be corrected. 429*45916cd2Sjpk * We should only get here if the zone's 430*45916cd2Sjpk * automounter hasn't yet mounted its 431*45916cd2Sjpk * autofs trigger on /home. 432*45916cd2Sjpk * 433*45916cd2Sjpk * Since it is likely to do so in the 434*45916cd2Sjpk * future, we will assume that the global 435*45916cd2Sjpk * zone already has an equivalent autofs 436*45916cd2Sjpk * mount established. By convention, 437*45916cd2Sjpk * this should be mounted at the 438*45916cd2Sjpk * /zone/<zonename> 439*45916cd2Sjpk */ 440*45916cd2Sjpk 441*45916cd2Sjpk if (zone_getattr(zoneid, ZONE_ATTR_NAME, 442*45916cd2Sjpk zonename, ZONENAME_MAX) == -1) { 443*45916cd2Sjpk return (0); 444*45916cd2Sjpk } else { 445*45916cd2Sjpk (void) snprintf(globalpath, MAXPATHLEN, 446*45916cd2Sjpk "/zone/%s%s", zonename, path); 447*45916cd2Sjpk } 448*45916cd2Sjpk } 449*45916cd2Sjpk break; 450*45916cd2Sjpk } 451*45916cd2Sjpk } 452*45916cd2Sjpk return (1); 453*45916cd2Sjpk } 454*45916cd2Sjpk 455*45916cd2Sjpk 456*45916cd2Sjpk /* 457*45916cd2Sjpk * This function is only useful for global zone callers 458*45916cd2Sjpk * It uses the global zone mnttab to translate local zone pathnames 459*45916cd2Sjpk * into global zone pathnames. 460*45916cd2Sjpk */ 461*45916cd2Sjpk char * 462*45916cd2Sjpk getpathbylabel(const char *path_name, char *resolved_path, size_t bufsize, 463*45916cd2Sjpk const bslabel_t *sl) { 464*45916cd2Sjpk char ret_path[MAXPATHLEN]; /* pathname to return */ 465*45916cd2Sjpk zoneid_t zoneid; 466*45916cd2Sjpk struct mntlist *mlist; 467*45916cd2Sjpk 468*45916cd2Sjpk if (getzoneid() != GLOBAL_ZONEID) { 469*45916cd2Sjpk errno = EINVAL; 470*45916cd2Sjpk return (NULL); 471*45916cd2Sjpk } 472*45916cd2Sjpk 473*45916cd2Sjpk if (path_name[0] != '/') { /* need absolute pathname */ 474*45916cd2Sjpk errno = EINVAL; 475*45916cd2Sjpk return (NULL); 476*45916cd2Sjpk } 477*45916cd2Sjpk 478*45916cd2Sjpk if (resolved_path == NULL) { 479*45916cd2Sjpk errno = EINVAL; 480*45916cd2Sjpk return (NULL); 481*45916cd2Sjpk } 482*45916cd2Sjpk 483*45916cd2Sjpk if ((zoneid = getzoneidbylabel(sl)) == -1) 484*45916cd2Sjpk return (NULL); 485*45916cd2Sjpk 486*45916cd2Sjpk /* 487*45916cd2Sjpk * Construct the list of mounted file systems. 488*45916cd2Sjpk */ 489*45916cd2Sjpk 490*45916cd2Sjpk if ((mlist = tsol_mkmntlist()) == NULL) { 491*45916cd2Sjpk return (NULL); 492*45916cd2Sjpk } 493*45916cd2Sjpk if (getglobalpath(path_name, zoneid, mlist, ret_path) == 0) { 494*45916cd2Sjpk tsol_mlist_free(mlist); 495*45916cd2Sjpk return (NULL); 496*45916cd2Sjpk } 497*45916cd2Sjpk tsol_mlist_free(mlist); 498*45916cd2Sjpk if (strlen(ret_path) >= bufsize) { 499*45916cd2Sjpk errno = EFAULT; 500*45916cd2Sjpk return (NULL); 501*45916cd2Sjpk } 502*45916cd2Sjpk return (strcpy(resolved_path, ret_path)); 503*45916cd2Sjpk } /* end getpathbylabel() */ 504