Return to BSD News archive
Path: sserve!newshost.anu.edu.au!munnari.oz.au!news.Hawaii.Edu!ames!elroy.jpl.nasa.gov!swrinde!cs.utexas.edu!utnut!torn!nermal.cs.uoguelph.ca!herman!rmacklem From: rmacklem@uoguelph.ca (Richard A Macklem) Newsgroups: comp.os.386bsd.bugs Subject: NFS Exports bug/fix Date: 8 Sep 1993 14:40:54 GMT Organization: University of Guelph Lines: 317 Message-ID: <26kqtm$k69@nermal.cs.uoguelph.ca> NNTP-Posting-Host: herman.cs.uoguelph.ca Summary: pcnfsdv2 requires export of all directories Keywords: NFS export pcnfsd mountd X-Newsreader: TIN [version 1.2 PL1] The export file format for Net/2 did not export all directories within the server file system, exporting the specified directory path(s) only. At the time, this was considered a desirable feature, since it allowed the system manager to have tighter control over the exported file systems. It turns out that there are a couple of situations where exporting all directories within the server file system is needed. - pcnfsdv2 sometimes creates directories to be used as mount points on the fly - some sites need to export many mount points (user's home dirs) and doing so explicitly can be tedious As such, the following changes to mountd.c add an "alldirs" flag to the export file format for the above purpose. Note that the diff -c is against the vanilla Net/2 mountd.c and line numbers are probably different for most systems, due to other patches. (Rumour has it that "patch -F 20" will do the trick.) Just in case you need it, rick *** mountd.c.bak Tue Sep 7 10:59:27 1993 --- mountd.c Tue Sep 7 13:48:22 1993 *************** *** 76,95 **** --- 76,96 ---- char ml_host[RPCMNT_NAMELEN+1]; char ml_dirp[RPCMNT_PATHLEN+1]; }; struct exportlist { struct exportlist *ex_next; struct exportlist *ex_prev; struct grouplist *ex_groups; int ex_rootuid; int ex_exflags; + int ex_alldirflg; dev_t ex_dev; char ex_dirp[RPCMNT_PATHLEN+1]; }; struct grouplist { struct grouplist *gr_next; struct hostent *gr_hp; }; /* Global defs */ *************** *** 225,245 **** S_IFDIR) { if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) syslog(LOG_ERR, "Can't send reply"); return; } /* Check in the exports list */ omask = sigblock(sigmask(SIGHUP)); ep = exphead.ex_next; while (ep != NULL) { ! if (!strcmp(ep->ex_dirp, dirpath)) { grp = ep->ex_groups; if (grp == NULL) break; /* Check for a host match */ addrp = (u_long **)grp->gr_hp->h_addr_list; for (;;) { if (**addrp == saddr) break; if (*++addrp == NULL) --- 226,247 ---- S_IFDIR) { if (!svc_sendreply(transp, xdr_long, (caddr_t)&bad)) syslog(LOG_ERR, "Can't send reply"); return; } /* Check in the exports list */ omask = sigblock(sigmask(SIGHUP)); ep = exphead.ex_next; while (ep != NULL) { ! if (!strcmp(ep->ex_dirp, dirpath) || ! (stb.st_dev == ep->ex_dev && ep->ex_alldirflg)) { grp = ep->ex_groups; if (grp == NULL) break; /* Check for a host match */ addrp = (u_long **)grp->gr_hp->h_addr_list; for (;;) { if (**addrp == saddr) break; if (*++addrp == NULL) *************** *** 430,450 **** register int i; register struct grouplist *grp; register struct exportlist *ep, *ep2; struct statfs stfsbuf; struct ufs_args args; struct stat sb; FILE *inf; char *cp, *endcp; char savedc; int len, dirplen; ! int rootuid, exflags; u_long saddr; struct exportlist *fep; /* * First, get rid of the old list */ ep = exphead.ex_next; while (ep != NULL) { ep2 = ep; ep = ep->ex_next; --- 432,452 ---- register int i; register struct grouplist *grp; register struct exportlist *ep, *ep2; struct statfs stfsbuf; struct ufs_args args; struct stat sb; FILE *inf; char *cp, *endcp; char savedc; int len, dirplen; ! int rootuid, exflags, alldirflg; u_long saddr; struct exportlist *fep; /* * First, get rid of the old list */ ep = exphead.ex_next; while (ep != NULL) { ep2 = ep; ep = ep->ex_next; *************** *** 456,475 **** --- 458,478 ---- * exportfs() as we go along */ exphead.ex_next = exphead.ex_prev = (struct exportlist *)0; if ((inf = fopen(exname, "r")) == NULL) { syslog(LOG_ERR, "Can't open %s", exname); exit(2); } while (fgets(line, LINESIZ, inf)) { exflags = MNT_EXPORTED; rootuid = def_rootuid; + alldirflg = 0; cp = line; nextfield(&cp, &endcp); /* * Get file system devno and see if an entry for this * file system already exists. */ savedc = *endcp; *endcp = '\0'; if (stat(cp, &sb) < 0 || (sb.st_mode & S_IFMT) != S_IFDIR) { *************** *** 508,528 **** } cp = endcp; nextfield(&cp, &endcp); len = endcp-cp; while (len > 0) { savedc = *endcp; *endcp = '\0'; if (len > RPCMNT_NAMELEN) goto more; if (*cp == '-') { ! do_opt(cp + 1, fep, ep, &exflags, &rootuid); goto more; } if (isdigit(*cp)) { saddr = inet_addr(cp); if (saddr == -1 || (hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET)) == NULL) { syslog(LOG_ERR, "Bad Exports File, %s: %s", cp, "Gethostbyaddr failed, ignored"); --- 511,532 ---- } cp = endcp; nextfield(&cp, &endcp); len = endcp-cp; while (len > 0) { savedc = *endcp; *endcp = '\0'; if (len > RPCMNT_NAMELEN) goto more; if (*cp == '-') { ! do_opt(cp + 1, fep, ep, &exflags, &rootuid, ! &alldirflg); goto more; } if (isdigit(*cp)) { saddr = inet_addr(cp); if (saddr == -1 || (hp = gethostbyaddr((caddr_t)&saddr, sizeof(saddr), AF_INET)) == NULL) { syslog(LOG_ERR, "Bad Exports File, %s: %s", cp, "Gethostbyaddr failed, ignored"); *************** *** 599,621 **** --- 603,633 ---- free_exp(ep); goto nextline; } savedc = *cp; *cp = '\0'; } if (cp) *cp = savedc; ep->ex_rootuid = rootuid; ep->ex_exflags = exflags; + ep->ex_alldirflg = alldirflg; } else { + if (alldirflg || fep->ex_alldirflg) { + syslog(LOG_WARNING, + "Can't export alldirs plus other exports"); + free_exp(ep); + goto nextline; + } ep->ex_rootuid = fep->ex_rootuid; ep->ex_exflags = fep->ex_exflags; + ep->ex_alldirflg = 0; } ep->ex_dev = sb.st_dev; ep->ex_next = exphead.ex_next; ep->ex_prev = &exphead; if (ep->ex_next != NULL) ep->ex_next->ex_prev = ep; exphead.ex_next = ep; nextline: ; } *************** *** 644,667 **** } *cp = p++; while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') p++; *endcp = p; } /* * Parse the option string */ ! do_opt(cpopt, fep, ep, exflagsp, rootuidp) register char *cpopt; struct exportlist *fep, *ep; ! int *exflagsp, *rootuidp; { register char *cpoptarg, *cpoptend; while (cpopt && *cpopt) { if (cpoptend = index(cpopt, ',')) *cpoptend++ = '\0'; if (cpoptarg = index(cpopt, '=')) *cpoptarg++ = '\0'; if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) { if (fep && (fep->ex_exflags & MNT_EXRDONLY) == 0) --- 656,679 ---- } *cp = p++; while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') p++; *endcp = p; } /* * Parse the option string */ ! do_opt(cpopt, fep, ep, exflagsp, rootuidp, alldirflgp) register char *cpopt; struct exportlist *fep, *ep; ! int *exflagsp, *rootuidp, *alldirflgp; { register char *cpoptarg, *cpoptend; while (cpopt && *cpopt) { if (cpoptend = index(cpopt, ',')) *cpoptend++ = '\0'; if (cpoptarg = index(cpopt, '=')) *cpoptarg++ = '\0'; if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) { if (fep && (fep->ex_exflags & MNT_EXRDONLY) == 0) *************** *** 673,692 **** --- 685,706 ---- if (cpoptarg && isdigit(*cpoptarg)) { *rootuidp = atoi(cpoptarg); if (fep && fep->ex_rootuid != *rootuidp) syslog(LOG_WARNING, "uid failed for %s", ep->ex_dirp); } else syslog(LOG_WARNING, "uid failed for %s", ep->ex_dirp); + } else if (!strcmp(cpopt, "alldirs") || !strcmp(cpopt, "a")) { + *alldirflgp = 1; } else syslog(LOG_WARNING, "opt %s ignored for %s", cpopt, ep->ex_dirp); cpopt = cpoptend; } } #define STRSIZ (RPCMNT_NAMELEN+RPCMNT_PATHLEN+50) /* * Routines that maintain the remote mounttab