svn commit: r364496 - in projects/nfs-over-tls: sys/fs/nfs sys/fs/nfsserver sys/sys usr.sbin/mountd
Rick Macklem
rmacklem at FreeBSD.org
Sat Aug 22 22:56:51 UTC 2020
Author: rmacklem
Date: Sat Aug 22 22:56:50 2020
New Revision: 364496
URL: https://svnweb.freebsd.org/changeset/base/364496
Log:
Update mount.h to use high order bits of the 64bit mnt_flags and merge
recent changes to mountd.c.
Modified:
projects/nfs-over-tls/sys/fs/nfs/nfsdport.h
projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c
projects/nfs-over-tls/sys/sys/mount.h
projects/nfs-over-tls/usr.sbin/mountd/mountd.c
Modified: projects/nfs-over-tls/sys/fs/nfs/nfsdport.h
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfs/nfsdport.h Sat Aug 22 21:32:11 2020 (r364495)
+++ projects/nfs-over-tls/sys/fs/nfs/nfsdport.h Sat Aug 22 22:56:50 2020 (r364496)
@@ -81,9 +81,9 @@ struct nfsexstuff {
#define NFSVNO_EXPORTANON(e) ((e)->nes_exflag & MNT_EXPORTANON)
#define NFSVNO_EXSTRICTACCESS(e) ((e)->nes_exflag & MNT_EXSTRICTACCESS)
#define NFSVNO_EXV4ONLY(e) ((e)->nes_exflag & MNT_EXV4ONLY)
-#define NFSVNO_EXTLS(e) ((e)->nes_exflag & MNTEX_TLS)
-#define NFSVNO_EXTLSCERT(e) ((e)->nes_exflag & MNTEX_TLSCERT)
-#define NFSVNO_EXTLSCERTUSER(e) ((e)->nes_exflag & MNTEX_TLSCERTUSER)
+#define NFSVNO_EXTLS(e) ((e)->nes_exflag & MNT_EXTLS)
+#define NFSVNO_EXTLSCERT(e) ((e)->nes_exflag & MNT_EXTLSCERT)
+#define NFSVNO_EXTLSCERTUSER(e) ((e)->nes_exflag & MNT_EXTLSCERTUSER)
#define NFSVNO_SETEXRDONLY(e) ((e)->nes_exflag = (MNT_EXPORTED|MNT_EXRDONLY))
Modified: projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c Sat Aug 22 21:32:11 2020 (r364495)
+++ projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c Sat Aug 22 22:56:50 2020 (r364496)
@@ -3561,11 +3561,11 @@ nfsvno_v4rootexport(struct nfsrv_descript *nd)
}
/* And set ND_EXxx flags for TLS. */
- if ((exflags & MNTEX_TLS) != 0) {
+ if ((exflags & MNT_EXTLS) != 0) {
nd->nd_flag |= ND_EXTLS;
- if ((exflags & MNTEX_TLSCERT) != 0)
+ if ((exflags & MNT_EXTLSCERT) != 0)
nd->nd_flag |= ND_EXTLSCERT;
- if ((exflags & MNTEX_TLSCERTUSER) != 0)
+ if ((exflags & MNT_EXTLSCERTUSER) != 0)
nd->nd_flag |= ND_EXTLSCERTUSER;
}
Modified: projects/nfs-over-tls/sys/sys/mount.h
==============================================================================
--- projects/nfs-over-tls/sys/sys/mount.h Sat Aug 22 21:32:11 2020 (r364495)
+++ projects/nfs-over-tls/sys/sys/mount.h Sat Aug 22 22:56:50 2020 (r364496)
@@ -294,6 +294,45 @@ void __mnt_vnode_markerfree_lazy(struct vnode
#endif /* _KERNEL */
+#if defined(_WANT_MNTOPTNAMES) || defined(_KERNEL)
+struct mntoptnames {
+ uint64_t o_opt;
+ const char *o_name;
+};
+#define MNTOPT_NAMES \
+ { MNT_ASYNC, "asynchronous" }, \
+ { MNT_EXPORTED, "NFS exported" }, \
+ { MNT_LOCAL, "local" }, \
+ { MNT_NOATIME, "noatime" }, \
+ { MNT_NOEXEC, "noexec" }, \
+ { MNT_NOSUID, "nosuid" }, \
+ { MNT_NOSYMFOLLOW, "nosymfollow" }, \
+ { MNT_QUOTA, "with quotas" }, \
+ { MNT_RDONLY, "read-only" }, \
+ { MNT_SYNCHRONOUS, "synchronous" }, \
+ { MNT_UNION, "union" }, \
+ { MNT_NOCLUSTERR, "noclusterr" }, \
+ { MNT_NOCLUSTERW, "noclusterw" }, \
+ { MNT_SUIDDIR, "suiddir" }, \
+ { MNT_SOFTDEP, "soft-updates" }, \
+ { MNT_SUJ, "journaled soft-updates" }, \
+ { MNT_MULTILABEL, "multilabel" }, \
+ { MNT_ACLS, "acls" }, \
+ { MNT_NFS4ACLS, "nfsv4acls" }, \
+ { MNT_GJOURNAL, "gjournal" }, \
+ { MNT_AUTOMOUNTED, "automounted" }, \
+ { MNT_VERIFIED, "verified" }, \
+ { MNT_UNTRUSTED, "untrusted" }, \
+ { MNT_NOCOVER, "nocover" }, \
+ { MNT_EMPTYDIR, "emptydir" }, \
+ { MNT_UPDATE, "update" }, \
+ { MNT_DELEXPORT, "delexport" }, \
+ { MNT_RELOAD, "reload" }, \
+ { MNT_FORCE, "force" }, \
+ { MNT_SNAPSHOT, "snapshot" }, \
+ { 0, NULL }
+#endif
+
/*
* User specifiable flags, stored in mnt_flag.
*/
@@ -326,6 +365,9 @@ void __mnt_vnode_markerfree_lazy(struct vnode
#define MNT_EXPORTANON 0x0000000000000400ULL /* anon uid mapping for all */
#define MNT_EXKERB 0x0000000000000800ULL /* exported with Kerberos */
#define MNT_EXPUBLIC 0x0000000020000000ULL /* public export (WebNFS) */
+#define MNT_EXTLS 0x0000004000000000ULL /* require TLS */
+#define MNT_EXTLSCERT 0x0000008000000000ULL /* require TLS with client cert */
+#define MNT_EXTLSCERTUSER 0x0000010000000000ULL /* require TLS with user cert */
/*
* Flags set by internal operations,
@@ -364,23 +406,6 @@ void __mnt_vnode_markerfree_lazy(struct vnode
MNT_NOCLUSTERR | MNT_NOCLUSTERW | MNT_SUIDDIR | \
MNT_ACLS | MNT_USER | MNT_NFS4ACLS | \
MNT_AUTOMOUNTED | MNT_UNTRUSTED)
-
-/*
- * Export flags that are only set/used in the ex_flags field and
- * not in mnt_flag. Since some are defined as MNT_EXxxx above,
- * these ones are just redefined here.
- * MNT_EXPORTED must remain and be set/cleared in mnt_flag.
- * The others defined as MNT_xxx should probably remain for
- * compatibility with old versions of mountd, etc.
- */
-#define MNTEX_TLS 0x0000000000000001ULL /* TLS RPC required */
-#define MNTEX_TLSCERT 0x0000000000000002ULL /* verified cert req */
-#define MNTEX_TLSCERTUSER 0x0000000000000004ULL /* user cert req */
-#define MNTEX_EXPORTED MNT_EXPORTED /* filesystem exported */
-#define MNTEX_RDONLY MNT_EXRDONLY /* exported read only */
-#define MNTEX_EXPORTANON MNT_EXPORTANON /* anon uid mapping for all */
-#define MNTEX_KERB MNT_EXKERB /* exported with Kerberos */
-#define MNTEX_PUBLIC MNT_EXPUBLIC /* public export (WebNFS) */
/*
* External filesystem command modifier flags.
Modified: projects/nfs-over-tls/usr.sbin/mountd/mountd.c
==============================================================================
--- projects/nfs-over-tls/usr.sbin/mountd/mountd.c Sat Aug 22 21:32:11 2020 (r364495)
+++ projects/nfs-over-tls/usr.sbin/mountd/mountd.c Sat Aug 22 22:56:50 2020 (r364496)
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/fnv_hash.h>
#include <sys/linker.h>
@@ -112,6 +113,15 @@ struct dirlist {
#define DP_DEFSET 0x1
#define DP_HOSTSET 0x2
+/*
+ * maproot/mapall credentials.
+ */
+struct expcred {
+ uid_t cr_uid;
+ int cr_ngroups;
+ gid_t cr_groups[NGROUPS_MAX + 1];
+};
+
struct exportlist {
struct dirlist *ex_dirl;
struct dirlist *ex_defdir;
@@ -120,8 +130,8 @@ struct exportlist {
fsid_t ex_fs;
char *ex_fsdir;
char *ex_indexfile;
- struct xucred ex_defanon;
- int ex_defexflags;
+ struct expcred ex_defanon;
+ uint64_t ex_defexflags;
int ex_numsecflavors;
int ex_secflavors[MAXSECFLAVORS];
int ex_defnumsecflavors;
@@ -152,8 +162,8 @@ struct grouplist {
int gr_type;
union grouptypes gr_ptr;
struct grouplist *gr_next;
- struct xucred gr_anon;
- int gr_exflags;
+ struct expcred gr_anon;
+ uint64_t gr_exflags;
int gr_flag;
int gr_numsecflavors;
int gr_secflavors[MAXSECFLAVORS];
@@ -184,11 +194,17 @@ struct fhreturn {
#define GETPORT_MAXTRY 20 /* Max tries to get a port # */
+/*
+ * How long to delay a reload of exports when there are RPC request(s)
+ * to process, in usec. Must be less than 1second.
+ */
+#define RELOADDELAY 250000
+
/* Global defs */
static char *add_expdir(struct dirlist **, char *, int);
static void add_dlist(struct dirlist **, struct dirlist *,
struct grouplist *, int, struct exportlist *,
- struct xucred *, int);
+ struct expcred *, uint64_t);
static void add_mlist(char *, char *);
static int check_dirpath(char *);
static int check_options(struct dirlist *);
@@ -202,10 +218,10 @@ static void clearout_service(void);
static void del_mlist(char *hostp, char *dirp);
static struct dirlist *dirp_search(struct dirlist *, char *);
static int do_export_mount(struct exportlist *, struct statfs *);
-static int do_mount(struct exportlist *, struct grouplist *, int,
- struct xucred *, char *, int, struct statfs *, int, int *);
+static int do_mount(struct exportlist *, struct grouplist *, uint64_t,
+ struct expcred *, char *, int, struct statfs *, int, int *);
static int do_opt(char **, char **, struct exportlist *,
- struct grouplist *, int *, int *, struct xucred *);
+ struct grouplist *, int *, uint64_t *, struct expcred *);
static struct exportlist *ex_search(fsid_t *, struct exportlisthead *);
static struct exportlist *get_exp(void);
static void free_dir(struct dirlist *);
@@ -220,7 +236,7 @@ static void free_exports(struct exportlisthead *);
static void read_exportfile(int);
static int compare_nmount_exportlist(struct iovec *, int, char *);
static int compare_export(struct exportlist *, struct exportlist *);
-static int compare_cred(struct xucred *, struct xucred *);
+static int compare_cred(struct expcred *, struct expcred *);
static int compare_secflavor(int *, int *, int);
static void delete_export(struct iovec *, int, struct statfs *, char *);
static int get_host(char *, struct grouplist *, struct grouplist *);
@@ -231,13 +247,13 @@ static int get_net(char *, struct netmsk *, int);
static void getexp_err(struct exportlist *, struct grouplist *, const char *);
static struct grouplist *get_grp(void);
static void hang_dirp(struct dirlist *, struct grouplist *,
- struct exportlist *, int, struct xucred *, int);
+ struct exportlist *, int, struct expcred *, uint64_t);
static void huphandler(int sig);
static int makemask(struct sockaddr_storage *ssp, int bitlen);
static void mntsrv(struct svc_req *, SVCXPRT *);
static void nextfield(char **, char **);
static void out_of_mem(void);
-static void parsecred(char *, struct xucred *);
+static void parsecred(char *, struct expcred *);
static int parsesec(char *, struct exportlist *);
static int put_exlist(struct dirlist *, XDR *, struct dirlist *,
int *, int);
@@ -253,6 +269,7 @@ static int xdr_explist_common(XDR *, caddr_t, int);
static int xdr_fhs(XDR *, caddr_t);
static int xdr_mlist(XDR *, caddr_t);
static void terminate(int);
+static void cp_cred(struct expcred *, struct expcred *);
#define EXPHASH(f) (fnv_32_buf((f), sizeof(fsid_t), 0) % exphashsize)
static struct exportlisthead *exphead = NULL;
@@ -262,13 +279,6 @@ static SLIST_HEAD(, mountlist) mlhead = SLIST_HEAD_INI
static char *exnames_default[2] = { _PATH_EXPORTS, NULL };
static char **exnames;
static char **hosts = NULL;
-static struct xucred def_anon = {
- XUCRED_VERSION,
- (uid_t)65534,
- 1,
- { (gid_t)65533 },
- { NULL }
-};
static int force_v2 = 0;
static int resvport_only = 1;
static int nhosts = 0;
@@ -410,6 +420,10 @@ main(int argc, char **argv)
int maxrec = RPC_MAXDATASIZE;
int attempt_cnt, port_len, port_pos, ret;
char **port_list;
+ uint64_t curtime, nexttime;
+ struct timeval tv;
+ struct timespec tp;
+ sigset_t sighup_mask;
/* Check that another mountd isn't already running. */
pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &otherpid);
@@ -665,19 +679,49 @@ main(int argc, char **argv)
}
/* Expand svc_run() here so that we can call get_exportlist(). */
+ curtime = nexttime = 0;
+ sigemptyset(&sighup_mask);
+ sigaddset(&sighup_mask, SIGHUP);
for (;;) {
- if (got_sighup) {
- get_exportlist(1);
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ curtime = tp.tv_sec;
+ curtime = curtime * 1000000 + tp.tv_nsec / 1000;
+ sigprocmask(SIG_BLOCK, &sighup_mask, NULL);
+ if (got_sighup && curtime >= nexttime) {
got_sighup = 0;
- }
+ sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
+ get_exportlist(1);
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ nexttime = tp.tv_sec;
+ nexttime = nexttime * 1000000 + tp.tv_nsec / 1000 +
+ RELOADDELAY;
+ } else
+ sigprocmask(SIG_UNBLOCK, &sighup_mask, NULL);
+
+ /*
+ * If a reload is pending, poll for received request(s),
+ * otherwise set a RELOADDELAY timeout, since a SIGHUP
+ * could be processed between the got_sighup test and
+ * the select() system call.
+ */
+ tv.tv_sec = 0;
+ if (got_sighup)
+ tv.tv_usec = 0;
+ else
+ tv.tv_usec = RELOADDELAY;
readfds = svc_fdset;
- switch (select(svc_maxfd + 1, &readfds, NULL, NULL, NULL)) {
+ switch (select(svc_maxfd + 1, &readfds, NULL, NULL, &tv)) {
case -1:
- if (errno == EINTR)
- continue;
+ if (errno == EINTR) {
+ /* Allow a reload now. */
+ nexttime = 0;
+ continue;
+ }
syslog(LOG_ERR, "mountd died: select: %m");
exit(1);
case 0:
+ /* Allow a reload now. */
+ nexttime = 0;
continue;
default:
svc_getreqset(&readfds);
@@ -1047,7 +1091,8 @@ mntsrv(struct svc_req *rqstp, SVCXPRT *transp)
struct sockaddr *saddr;
u_short sport;
char rpcpath[MNTPATHLEN + 1], dirpath[MAXPATHLEN];
- int bad = 0, defset, hostset;
+ int defset, hostset;
+ long bad = 0;
sigset_t sighup_mask;
int numsecflavors, *secflavorsp;
@@ -1463,9 +1508,10 @@ get_exportlist_one(int passno)
struct grouplist *grp, *tgrp, *savgrp;
struct dirlist *dirhead;
struct statfs fsb;
- struct xucred anon;
+ struct expcred anon;
char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
- int len, has_host, exflags, got_nondir, dirplen, netgrp;
+ int len, has_host, got_nondir, dirplen, netgrp;
+ uint64_t exflags;
v4root_phase = 0;
dirhead = (struct dirlist *)NULL;
@@ -1481,8 +1527,10 @@ get_exportlist_one(int passno)
* Set defaults.
*/
has_host = FALSE;
- anon = def_anon;
- exflags = MNTEX_EXPORTED;
+ anon.cr_uid = UID_NOBODY;
+ anon.cr_ngroups = 1;
+ anon.cr_groups[0] = GID_NOGROUP;
+ exflags = MNT_EXPORTED;
got_nondir = 0;
opt_flags = 0;
ep = (struct exportlist *)NULL;
@@ -1568,10 +1616,8 @@ get_exportlist_one(int passno)
ep = get_exp();
} else {
if (ep) {
- if (ep->ex_fs.val[0] !=
- fsb.f_fsid.val[0] ||
- ep->ex_fs.val[1] !=
- fsb.f_fsid.val[1]) {
+ if (fsidcmp(&ep->ex_fs, &fsb.f_fsid)
+ != 0) {
getexp_err(ep, tgrp,
"fsid mismatch");
goto nextline;
@@ -1700,7 +1746,7 @@ get_exportlist_one(int passno)
grp = tgrp;
do {
grp->gr_exflags = exflags;
- grp->gr_anon = anon;
+ cp_cred(&grp->gr_anon, &anon);
if (v4root_phase == 2 && passno == 0)
LOGDEBUG("do_mount v4root");
if (passno == 0 && do_mount(ep, grp, exflags, &anon,
@@ -1840,7 +1886,7 @@ get_exportlist(int passno)
*/
bzero(&eargs, sizeof (eargs));
eargs.export.ex_flags = MNT_DELEXPORT;
- if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&eargs) < 0 &&
+ if (nfssvc(NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT, (caddr_t)&eargs) < 0 &&
errno != ENOENT)
syslog(LOG_ERR, "Can't delete exports for V4:");
@@ -1868,7 +1914,7 @@ get_exportlist(int passno)
LOGDEBUG("doing passno=0");
/*
* Clear flag that notes if a public fh has been exported.
- * It is set by do_mount() if MNTEX_PUBLIC is set for the entry.
+ * It is set by do_mount() if MNT_EXPUBLIC is set for the entry.
*/
has_publicfh = 0;
@@ -2088,8 +2134,7 @@ compare_nmount_exportlist(struct iovec *iov, int iovle
if ((oep->ex_flag & EX_DONE) == 0) {
LOGDEBUG("not done delete=%s", oep->ex_fsdir);
if (statfs(oep->ex_fsdir, &ofs) >= 0 &&
- oep->ex_fs.val[0] == ofs.f_fsid.val[0] &&
- oep->ex_fs.val[1] == ofs.f_fsid.val[1]) {
+ fsidcmp(&oep->ex_fs, &ofs.f_fsid) == 0) {
LOGDEBUG("do delete");
/*
* Clear has_publicfh if if was set
@@ -2220,10 +2265,10 @@ compare_export(struct exportlist *ep, struct exportlis
} while (0)
/*
- * Compare to struct xucred's. Return 0 if the same and 1 otherwise.
+ * Compare two struct expcred's. Return 0 if the same and 1 otherwise.
*/
static int
-compare_cred(struct xucred *cr0, struct xucred *cr1)
+compare_cred(struct expcred *cr0, struct expcred *cr1)
{
if (cr0->cr_uid != cr1->cr_uid || cr0->cr_ngroups != cr1->cr_ngroups)
@@ -2353,8 +2398,7 @@ ex_search(fsid_t *fsid, struct exportlisthead *exhp)
i = EXPHASH(fsid);
SLIST_FOREACH(ep, &exhp[i], entries) {
- if (ep->ex_fs.val[0] == fsid->val[0] &&
- ep->ex_fs.val[1] == fsid->val[1])
+ if (fsidcmp(&ep->ex_fs, fsid) == 0)
return (ep);
}
@@ -2389,7 +2433,7 @@ add_expdir(struct dirlist **dpp, char *cp, int len)
*/
static void
hang_dirp(struct dirlist *dp, struct grouplist *grp, struct exportlist *ep,
- int flags, struct xucred *anoncrp, int exflags)
+ int flags, struct expcred *anoncrp, uint64_t exflags)
{
struct hostlist *hp;
struct dirlist *dp2;
@@ -2407,7 +2451,7 @@ hang_dirp(struct dirlist *dp, struct grouplist *grp, s
if (ep->ex_numsecflavors > 0)
memcpy(ep->ex_defsecflavors, ep->ex_secflavors,
sizeof(ep->ex_secflavors));
- ep->ex_defanon = *anoncrp;
+ cp_cred(&ep->ex_defanon, anoncrp);
ep->ex_defexflags = exflags;
} else while (grp) {
hp = get_ht();
@@ -2441,7 +2485,8 @@ hang_dirp(struct dirlist *dp, struct grouplist *grp, s
*/
static void
add_dlist(struct dirlist **dpp, struct dirlist *newdp, struct grouplist *grp,
- int flags, struct exportlist *ep, struct xucred *anoncrp, int exflags)
+ int flags, struct exportlist *ep, struct expcred *anoncrp,
+ uint64_t exflags)
{
struct dirlist *dp;
struct hostlist *hp;
@@ -2490,7 +2535,7 @@ add_dlist(struct dirlist **dpp, struct dirlist *newdp,
if (ep->ex_numsecflavors > 0)
memcpy(ep->ex_defsecflavors, ep->ex_secflavors,
sizeof(ep->ex_secflavors));
- ep->ex_defanon = *anoncrp;
+ cp_cred(&ep->ex_defanon, anoncrp);
ep->ex_defexflags = exflags;
}
}
@@ -2662,7 +2707,7 @@ parsesec(char *seclist, struct exportlist *ep)
*/
static int
do_opt(char **cpp, char **endcpp, struct exportlist *ep, struct grouplist *grp,
- int *has_hostp, int *exflagsp, struct xucred *cr)
+ int *has_hostp, uint64_t *exflagsp, struct expcred *cr)
{
char *cpoptarg, *cpoptend;
char *cp, *endcp, *cpopt, savedc, savedc2;
@@ -2697,14 +2742,14 @@ do_opt(char **cpp, char **endcpp, struct exportlist *e
}
}
if (!strcmp(cpopt, "ro") || !strcmp(cpopt, "o")) {
- *exflagsp |= MNTEX_RDONLY;
+ *exflagsp |= MNT_EXRDONLY;
} else if (cpoptarg && (!strcmp(cpopt, "maproot") ||
!(allflag = strcmp(cpopt, "mapall")) ||
!strcmp(cpopt, "root") || !strcmp(cpopt, "r"))) {
usedarg++;
parsecred(cpoptarg, cr);
if (allflag == 0) {
- *exflagsp |= MNTEX_EXPORTANON;
+ *exflagsp |= MNT_EXPORTANON;
opt_flags |= OP_MAPALL;
} else
opt_flags |= OP_MAPROOT;
@@ -2737,9 +2782,9 @@ do_opt(char **cpp, char **endcpp, struct exportlist *e
} else if (!strcmp(cpopt, "alldirs")) {
opt_flags |= OP_ALLDIRS;
} else if (!strcmp(cpopt, "public")) {
- *exflagsp |= MNTEX_PUBLIC;
+ *exflagsp |= MNT_EXPUBLIC;
} else if (!strcmp(cpopt, "webnfs")) {
- *exflagsp |= (MNTEX_PUBLIC|MNTEX_RDONLY|MNTEX_EXPORTANON);
+ *exflagsp |= (MNT_EXPUBLIC|MNT_EXRDONLY|MNT_EXPORTANON);
opt_flags |= OP_MAPALL;
} else if (cpoptarg && !strcmp(cpopt, "index")) {
ep->ex_indexfile = strdup(cpoptarg);
@@ -2751,11 +2796,12 @@ do_opt(char **cpp, char **endcpp, struct exportlist *e
opt_flags |= OP_SEC;
usedarg++;
} else if (!strcmp(cpopt, "tls")) {
- *exflagsp |= MNTEX_TLS;
+ *exflagsp |= MNT_EXTLS;
} else if (!strcmp(cpopt, "tlscert")) {
- *exflagsp |= (MNTEX_TLS | MNTEX_TLSCERT);
+ *exflagsp |= (MNT_EXTLS | MNT_EXTLSCERT);
} else if (!strcmp(cpopt, "tlscertuser")) {
- *exflagsp |= (MNTEX_TLS | MNTEX_TLSCERT | MNTEX_TLSCERTUSER);
+ *exflagsp |= (MNT_EXTLS | MNT_EXTLSCERT |
+ MNT_EXTLSCERTUSER);
} else {
syslog(LOG_ERR, "bad opt %s", cpopt);
return (1);
@@ -2930,7 +2976,7 @@ do_export_mount(struct exportlist *ep, struct statfs *
defgrp.gr_type = GT_DEFAULT;
defgrp.gr_next = NULL;
/* We have an entry for all other hosts/nets. */
- LOGDEBUG("ex_defexflags=0x%x", ep->ex_defexflags);
+ LOGDEBUG("ex_defexflags=0x%jx", (uintmax_t)ep->ex_defexflags);
ret = do_mount(ep, &defgrp, ep->ex_defexflags, &ep->ex_defanon,
ep->ex_fsdir, dirlen, fsp, ep->ex_defnumsecflavors,
ep->ex_defsecflavors);
@@ -2941,8 +2987,8 @@ do_export_mount(struct exportlist *ep, struct statfs *
/* Do a mount for each group. */
grp = ep->ex_grphead;
while (grp != NULL) {
- LOGDEBUG("do mount gr_type=0x%x gr_exflags=0x%x",
- grp->gr_type, grp->gr_exflags);
+ LOGDEBUG("do mount gr_type=0x%x gr_exflags=0x%jx",
+ grp->gr_type, (uintmax_t)grp->gr_exflags);
ret = do_mount(ep, grp, grp->gr_exflags, &grp->gr_anon,
ep->ex_fsdir, dirlen, fsp, grp->gr_numsecflavors,
grp->gr_secflavors);
@@ -2958,8 +3004,8 @@ do_export_mount(struct exportlist *ep, struct statfs *
* the kernel.
*/
static int
-do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
- struct xucred *anoncrp, char *dirp, int dirplen, struct statfs *fsb,
+do_mount(struct exportlist *ep, struct grouplist *grp, uint64_t exflags,
+ struct expcred *anoncrp, char *dirp, int dirplen, struct statfs *fsb,
int numsecflavors, int *secflavors)
{
struct statfs fsb1;
@@ -2985,8 +3031,14 @@ do_mount(struct exportlist *ep, struct grouplist *grp,
bzero(eap, sizeof (struct export_args));
bzero(errmsg, sizeof(errmsg));
eap->ex_flags = exflags;
- eap->ex_anon = *anoncrp;
- LOGDEBUG("do_mount exflags=0x%x", exflags);
+ eap->ex_uid = anoncrp->cr_uid;
+ eap->ex_ngroups = anoncrp->cr_ngroups;
+ if (eap->ex_ngroups > 0) {
+ eap->ex_groups = malloc(eap->ex_ngroups * sizeof(gid_t));
+ memcpy(eap->ex_groups, anoncrp->cr_groups, eap->ex_ngroups *
+ sizeof(gid_t));
+ }
+ LOGDEBUG("do_mount exflags=0x%jx", (uintmax_t)exflags);
eap->ex_indexfile = ep->ex_indexfile;
if (grp->gr_type == GT_HOST)
ai = grp->gr_ptr.gt_addrinfo;
@@ -3056,9 +3108,11 @@ do_mount(struct exportlist *ep, struct grouplist *grp,
*/
if (v4root_phase == 2) {
nfsea.fspec = v4root_dirpath;
- if (nfssvc(NFSSVC_V4ROOTEXPORT, (caddr_t)&nfsea) < 0) {
+ if (nfssvc(NFSSVC_V4ROOTEXPORT | NFSSVC_NEWSTRUCT,
+ (caddr_t)&nfsea) < 0) {
syslog(LOG_ERR, "Exporting V4: failed");
- return (2);
+ ret = 2;
+ goto error_exit;
}
} else {
/*
@@ -3109,9 +3163,9 @@ do_mount(struct exportlist *ep, struct grouplist *grp,
goto error_exit;
}
/* back up over the last component */
- while (*cp == '/' && cp > dirp)
+ while (cp > dirp && *cp == '/')
cp--;
- while (*(cp - 1) != '/' && cp > dirp)
+ while (cp > dirp && *(cp - 1) != '/')
cp--;
if (cp == dirp) {
if (debug)
@@ -3128,8 +3182,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp,
* filesystem.
*/
if (statfs(dirp, &fsb1) != 0 ||
- bcmp(&fsb1.f_fsid, &fsb->f_fsid,
- sizeof (fsb1.f_fsid)) != 0) {
+ fsidcmp(&fsb1.f_fsid, &fsb->f_fsid) != 0) {
*cp = savedc;
syslog(LOG_ERR,
"can't export %s %s", dirp,
@@ -3145,7 +3198,7 @@ do_mount(struct exportlist *ep, struct grouplist *grp,
* If this is the public directory, get the file handle
* and load it into the kernel via the nfssvc() syscall.
*/
- if ((exflags & MNTEX_PUBLIC) != 0) {
+ if ((exflags & MNT_EXPUBLIC) != 0) {
fhandle_t fh;
char *public_name;
@@ -3174,6 +3227,7 @@ skip:
if (cp)
*cp = savedc;
error_exit:
+ free(eap->ex_groups);
/* free strings allocated by strdup() in getmntopts.c */
if (iov != NULL) {
free(iov[0].iov_base); /* fstype */
@@ -3400,22 +3454,19 @@ get_line(void)
* Parse a description of a credential.
*/
static void
-parsecred(char *namelist, struct xucred *cr)
+parsecred(char *namelist, struct expcred *cr)
{
char *name;
int cnt;
char *names;
struct passwd *pw;
struct group *gr;
- gid_t groups[XU_NGROUPS + 1];
- int ngroups;
- cr->cr_version = XUCRED_VERSION;
/*
* Set up the unprivileged user.
*/
- cr->cr_uid = 65534;
- cr->cr_groups[0] = 65533;
+ cr->cr_uid = UID_NOBODY;
+ cr->cr_groups[0] = GID_NOGROUP;
cr->cr_ngroups = 1;
/*
* Get the user's password table entry.
@@ -3436,19 +3487,24 @@ parsecred(char *namelist, struct xucred *cr)
return;
}
cr->cr_uid = pw->pw_uid;
- ngroups = XU_NGROUPS + 1;
- if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups)) {
+ cr->cr_ngroups = NGROUPS_MAX + 1;
+ if (getgrouplist(pw->pw_name, pw->pw_gid, cr->cr_groups,
+ &cr->cr_ngroups)) {
syslog(LOG_ERR, "too many groups");
- ngroups = XU_NGROUPS + 1;
+ cr->cr_ngroups = NGROUPS_MAX + 1;
}
/*
* Compress out duplicate.
*/
- cr->cr_ngroups = ngroups - 1;
- cr->cr_groups[0] = groups[0];
- for (cnt = 2; cnt < ngroups; cnt++)
- cr->cr_groups[cnt - 1] = groups[cnt];
+ if (cr->cr_ngroups > 1 && cr->cr_groups[0] ==
+ cr->cr_groups[1]) {
+ for (cnt = 2; cnt < cr->cr_ngroups; cnt++)
+ cr->cr_groups[cnt - 1] = cr->cr_groups[cnt];
+ cr->cr_ngroups--;
+ }
+ if (cr->cr_ngroups > NGROUPS_MAX)
+ cr->cr_ngroups = NGROUPS_MAX;
return;
}
/*
@@ -3464,7 +3520,7 @@ parsecred(char *namelist, struct xucred *cr)
return;
}
cr->cr_ngroups = 0;
- while (names != NULL && *names != '\0' && cr->cr_ngroups < XU_NGROUPS) {
+ while (names != NULL && *names != '\0' && cr->cr_ngroups < NGROUPS_MAX) {
name = strsep_quote(&names, ":");
if (isdigit(*name) || *name == '-') {
cr->cr_groups[cr->cr_ngroups++] = atoi(name);
@@ -3476,7 +3532,7 @@ parsecred(char *namelist, struct xucred *cr)
cr->cr_groups[cr->cr_ngroups++] = gr->gr_gid;
}
}
- if (names != NULL && *names != '\0' && cr->cr_ngroups == XU_NGROUPS)
+ if (names != NULL && *names != '\0' && cr->cr_ngroups == NGROUPS_MAX)
syslog(LOG_ERR, "too many groups");
}
@@ -3796,4 +3852,14 @@ terminate(int sig __unused)
rpcb_unset(MOUNTPROG, MOUNTVERS, NULL);
rpcb_unset(MOUNTPROG, MOUNTVERS3, NULL);
exit (0);
+}
+
+static void
+cp_cred(struct expcred *outcr, struct expcred *incr)
+{
+
+ outcr->cr_uid = incr->cr_uid;
+ outcr->cr_ngroups = incr->cr_ngroups;
+ memcpy(outcr->cr_groups, incr->cr_groups, incr->cr_ngroups *
+ sizeof(gid_t));
}
More information about the svn-src-projects
mailing list