Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 May 2009 21:39:08 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r192121 - in head/sys/fs: nfs nfsclient nfsserver
Message-ID:  <200905142139.n4ELd8Zw003155@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Thu May 14 21:39:08 2009
New Revision: 192121
URL: http://svn.freebsd.org/changeset/base/192121

Log:
  Apply changes to the experimental nfs server so that it uses the security
  flavors as exported in FreeBSD-CURRENT. This allows it to use a
  slightly modified mountd.c instead of a different utility.
  
  Approved by:	kib (mentor)

Modified:
  head/sys/fs/nfs/nfs.h
  head/sys/fs/nfs/nfs_var.h
  head/sys/fs/nfs/nfsdport.h
  head/sys/fs/nfs/nfsport.h
  head/sys/fs/nfsclient/nfs_clkrpc.c
  head/sys/fs/nfsserver/nfs_nfsdkrpc.c
  head/sys/fs/nfsserver/nfs_nfsdport.c
  head/sys/fs/nfsserver/nfs_nfsdserv.c
  head/sys/fs/nfsserver/nfs_nfsdsocket.c
  head/sys/fs/nfsserver/nfs_nfsdsubs.c

Modified: head/sys/fs/nfs/nfs.h
==============================================================================
--- head/sys/fs/nfs/nfs.h	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfs/nfs.h	Thu May 14 21:39:08 2009	(r192121)
@@ -580,7 +580,6 @@ struct nfsrv_descript {
 	u_int64_t		nd_compref;	/* Compound RPC ref# */
 	time_t			nd_tcpconntime;	/* Time TCP connection est. */
 	nfsquad_t		nd_clientid;	/* Implied clientid */
-	int			nd_credflavor;	/* credential flavor */
 	int			nd_gssnamelen;	/* principal name length */
 	char			*nd_gssname;	/* principal name */
 };
@@ -608,8 +607,11 @@ struct nfsrv_descript {
 #define	ND_V4WCCATTR		0x00010000
 #define	ND_NFSCB		0x00020000
 #define	ND_AUTHNONE		0x00040000
-#define	ND_EXGSSONLY		0x00080000
-#define	ND_INCRSEQID		0x00100000
+#define	ND_EXAUTHSYS		0x00080000
+#define	ND_EXGSS		0x00100000
+#define	ND_EXGSSINTEGRITY	0x00200000
+#define	ND_EXGSSPRIVACY		0x00400000
+#define	ND_INCRSEQID		0x00800000
 
 /*
  * ND_GSS should be the "or" of all GSS type authentications.
@@ -631,11 +633,6 @@ struct nfsv4_opflag {
 #define	NFSRVSEQID_OPEN		0x04
 
 /*
- * MNT_EXGSSONLY is the Or of all the EXGSS bits.
- */
-#define	MNT_EXGSSONLY		MNT_EXGSSKRB5
-
-/*
  * assign a doubly linked list to a new head
  * and prepend one list into another.
  */

Modified: head/sys/fs/nfs/nfs_var.h
==============================================================================
--- head/sys/fs/nfs/nfs_var.h	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfs/nfs_var.h	Thu May 14 21:39:08 2009	(r192121)
@@ -306,6 +306,7 @@ int nfsrv_putreferralattr(struct nfsrv_d
 int nfsrv_parsename(struct nfsrv_descript *, char *, u_long *,
     NFSPATHLEN_T *);
 void nfsd_init(void);
+int nfsd_checkrootexp(struct nfsrv_descript *);
 
 /* nfs_clvfsops.c */
 
@@ -575,6 +576,7 @@ int nfsvno_advlock(vnode_t, int, u_int64
 void nfsvno_unlockvfs(mount_t);
 int nfsvno_lockvfs(mount_t);
 int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *);
+int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *);
 
 /* nfs_commonkrpc.c */
 int newnfs_nmcancelreqs(struct nfsmount *);

Modified: head/sys/fs/nfs/nfsdport.h
==============================================================================
--- head/sys/fs/nfs/nfsdport.h	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfs/nfsdport.h	Thu May 14 21:39:08 2009	(r192121)
@@ -52,8 +52,10 @@
  * needs to be returned by nfsd_fhtovp().
  */
 struct nfsexstuff {
-	int	nes_vfslocked;	/* required for all ports */
-	int	nes_exflag;
+	int	nes_vfslocked;			/* required for all ports */
+	int	nes_exflag;			/* export flags */
+	int	nes_numsecflavor;		/* # of security flavors */
+	int	nes_secflavors[MAXSECFLAVORS];	/* and the flavors */
 };
 
 #define	NFSVNO_EXINIT(e)		((e)->nes_exflag = 0)
@@ -61,11 +63,9 @@ struct nfsexstuff {
 #define	NFSVNO_EXRDONLY(e)		((e)->nes_exflag & MNT_EXRDONLY)
 #define	NFSVNO_EXPORTANON(e)		((e)->nes_exflag & MNT_EXPORTANON)
 #define	NFSVNO_EXSTRICTACCESS(e)	((e)->nes_exflag & MNT_EXSTRICTACCESS)
-#define	NFSVNO_EXGSSONLY(e)		((e)->nes_exflag & MNT_EXGSSONLY)
 #define	NFSVNO_EXV4ONLY(e)		((e)->nes_exflag & MNT_EXV4ONLY)
 
 #define	NFSVNO_SETEXRDONLY(e)	((e)->nes_exflag = (MNT_EXPORTED|MNT_EXRDONLY))
-#define	NFSVNO_SETEXGSSONLY(e)		((e)->nes_exflag |= MNT_EXGSSONLY)
 
 #define	NFSVNO_CMPFH(f1, f2)						\
     ((f1)->fh_fsid.val[0] == (f2)->fh_fsid.val[0] &&			\

Modified: head/sys/fs/nfs/nfsport.h
==============================================================================
--- head/sys/fs/nfs/nfsport.h	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfs/nfsport.h	Thu May 14 21:39:08 2009	(r192121)
@@ -645,11 +645,6 @@ struct nfsex_args {
 };
 
 /*
- * Define these here, so they don't have to be in mount.h, for now.
- */
-#define	MNT_EXGSSKRB5	MNT_EXKERB
-
-/*
  * These export flags should be defined, but there are no bits left.
  * Maybe a separate mnt_exflag field could be added or the mnt_flag
  * field increased to 64 bits?

Modified: head/sys/fs/nfsclient/nfs_clkrpc.c
==============================================================================
--- head/sys/fs/nfsclient/nfs_clkrpc.c	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfsclient/nfs_clkrpc.c	Thu May 14 21:39:08 2009	(r192121)
@@ -66,7 +66,7 @@ static void
 nfscb_program(struct svc_req *rqst, SVCXPRT *xprt)
 {
 	struct nfsrv_descript nd;
-	int cacherep;
+	int cacherep, credflavor;
 
 	memset(&nd, 0, sizeof(nd));
 	if (rqst->rq_proc != NFSPROC_NULL &&
@@ -94,12 +94,14 @@ nfscb_program(struct svc_req *rqst, SVCX
 	nd.nd_cred = NULL;
 
 	if (nd.nd_procnum != NFSPROC_NULL) {
-		if (!svc_getcred(rqst, &nd.nd_cred, &nd.nd_credflavor)) {
+		if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) {
 			svcerr_weakauth(rqst);
 			svc_freereq(rqst);
 			m_freem(nd.nd_mrep);
 			return;
 		}
+
+		/* For now, I don't care what credential flavor was used. */
 #ifdef notyet
 #ifdef MAC
 		mac_cred_associate_nfsd(nd.nd_cred);

Modified: head/sys/fs/nfsserver/nfs_nfsdkrpc.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdkrpc.c	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfsserver/nfs_nfsdkrpc.c	Thu May 14 21:39:08 2009	(r192121)
@@ -97,7 +97,7 @@ nfssvc_program(struct svc_req *rqst, SVC
 {
 	struct nfsrv_descript nd;
 	struct nfsrvcache *rp = NULL;
-	int cacherep;
+	int cacherep, credflavor;
 
 	memset(&nd, 0, sizeof(nd));
 	if (rqst->rq_vers == NFS_VER2) {
@@ -186,12 +186,27 @@ nfssvc_program(struct svc_req *rqst, SVC
 	}
 
 	if (nd.nd_procnum != NFSPROC_NULL) {
-		if (!svc_getcred(rqst, &nd.nd_cred, &nd.nd_credflavor)) {
+		if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) {
 			svcerr_weakauth(rqst);
 			svc_freereq(rqst);
 			m_freem(nd.nd_mrep);
 			return;
 		}
+
+		/* Set the flag based on credflavor */
+		if (credflavor == RPCSEC_GSS_KRB5) {
+			nd.nd_flag |= ND_GSS;
+		} else if (credflavor == RPCSEC_GSS_KRB5I) {
+			nd.nd_flag |= (ND_GSS | ND_GSSINTEGRITY);
+		} else if (credflavor == RPCSEC_GSS_KRB5P) {
+			nd.nd_flag |= (ND_GSS | ND_GSSPRIVACY);
+		} else if (credflavor != AUTH_SYS) {
+			svcerr_weakauth(rqst);
+			svc_freereq(rqst);
+			m_freem(nd.nd_mrep);
+			return;
+		}
+
 #ifdef MAC
 		mac_cred_associate_nfsd(nd.nd_cred);
 #endif

Modified: head/sys/fs/nfsserver/nfs_nfsdport.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdport.c	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfsserver/nfs_nfsdport.c	Thu May 14 21:39:08 2009	(r192121)
@@ -2352,14 +2352,16 @@ nfsd_excred(struct nfsrv_descript *nd, s
 	 * Check/setup credentials.
 	 */
 	if (nd->nd_flag & ND_GSS)
-		exp->nes_exflag &= ~(MNT_EXGSSONLY | MNT_EXPORTANON);
+		exp->nes_exflag &= ~MNT_EXPORTANON;
 
 	/*
-	 * For AUTH_SYS, check to see if it is allowed.
+	 * Check to see if the operation is allowed for this security flavor.
 	 * RFC2623 suggests that the NFSv3 Fsinfo RPC be allowed to
 	 * AUTH_NONE or AUTH_SYS for file systems requiring RPCSEC_GSS.
+	 * Also, allow Secinfo, so that it can acquire the correct flavor(s).
 	 */
-	if (NFSVNO_EXGSSONLY(exp) &&
+	if (nfsvno_testexp(nd, exp) &&
+	    nd->nd_procnum != NFSV4OP_SECINFO &&
 	    nd->nd_procnum != NFSPROC_FSINFO) {
 		if (nd->nd_flag & ND_NFSV4)
 			error = NFSERR_WRONGSEC;
@@ -2400,14 +2402,20 @@ int
 nfsvno_checkexp(struct mount *mp, struct sockaddr *nam, struct nfsexstuff *exp,
     struct ucred **credp)
 {
-	int error;
-	int numsecflavor, *secflavors;
+	int i, error, *secflavors;
 
 	error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
-	    &numsecflavor, &secflavors);
-	if (error && nfs_rootfhset) {
-		exp->nes_exflag = 0;
-		error = 0;
+	    &exp->nes_numsecflavor, &secflavors);
+	if (error) {
+		if (nfs_rootfhset) {
+			exp->nes_exflag = 0;
+			exp->nes_numsecflavor = 0;
+			error = 0;
+		}
+	} else {
+		/* Copy the security flavors. */
+		for (i = 0; i < exp->nes_numsecflavor; i++)
+			exp->nes_secflavors[i] = secflavors[i];
 	}
 	return (error);
 }
@@ -2419,21 +2427,26 @@ int
 nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam,
     struct vnode **vpp, struct nfsexstuff *exp, struct ucred **credp)
 {
-	int error;
-	int numsecflavor, *secflavors;
+	int i, error, *secflavors;
 
 	*credp = NULL;
+	exp->nes_numsecflavor = 0;
 	error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp);
 	if (nam && !error) {
 		error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp,
-		    &numsecflavor, &secflavors);
+		    &exp->nes_numsecflavor, &secflavors);
 		if (error) {
 			if (nfs_rootfhset) {
 				exp->nes_exflag = 0;
+				exp->nes_numsecflavor = 0;
 				error = 0;
 			} else {
 				vput(*vpp);
 			}
+		} else {
+			/* Copy the security flavors. */
+			for (i = 0; i < exp->nes_numsecflavor; i++)
+				exp->nes_secflavors[i] = secflavors[i];
 		}
 	}
 	return (error);
@@ -2539,18 +2552,19 @@ nfsd_fhtovp(struct nfsrv_descript *nd, s
 	 */
 #ifdef NFS_REQRSVPORT
 	if (!nd->nd_repstat) {
-	  struct sockaddr_in *saddr;
-	  struct sockaddr_in6 *saddr6;
-	  saddr = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *);
-	  saddr6 = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in6 *);
-	  if (!(nd->nd_flag & ND_NFSV4) &&
-	      ((saddr->sin_family == AF_INET &&
-	        ntohs(saddr->sin_port) >= IPPORT_RESERVED) ||
-	       (saddr6->sin6_family == AF_INET6 &&
-	        ntohs(saddr6->sin6_port) >= IPPORT_RESERVED))) {
-		vput(*vpp);
-		nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK);
-	  }
+		struct sockaddr_in *saddr;
+		struct sockaddr_in6 *saddr6;
+
+		saddr = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *);
+		saddr6 = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in6 *);
+		if (!(nd->nd_flag & ND_NFSV4) &&
+		    ((saddr->sin_family == AF_INET &&
+		      ntohs(saddr->sin_port) >= IPPORT_RESERVED) ||
+		     (saddr6->sin6_family == AF_INET6 &&
+		      ntohs(saddr6->sin6_port) >= IPPORT_RESERVED))) {
+			vput(*vpp);
+			nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK);
+		}
 	}
 #endif	/* NFS_REQRSVPORT */
 
@@ -2598,7 +2612,7 @@ fp_getfvp(struct thread *p, int fd, stru
 }
 
 /*
- * Called from newnfssvc() to update the exports list. Just call
+ * Called from nfssvc() to update the exports list. Just call
  * vfs_export(). This has to be done, since the v4 root fake fs isn't
  * in the mount list.
  */
@@ -2610,11 +2624,6 @@ nfsrv_v4rootexport(void *argp, struct uc
 	struct nameidata nd;
 	fhandle_t fh;
 
-	/*
-	 * Until newmountd is using the secflavor fields, just make
-	 * sure it's 0.
-	 */
-	nfsexargp->export.ex_numsecflavors = 0;
 	error = vfs_export(&nfsv4root_mnt, &nfsexargp->export);
 	if ((nfsexargp->export.ex_flags & MNT_DELEXPORT)) {
 		nfs_rootfhset = 0;
@@ -2843,16 +2852,24 @@ int
 nfsvno_v4rootexport(struct nfsrv_descript *nd)
 {
 	struct ucred *credanon;
-	int exflags, error;
+	int exflags, error, numsecflavor, *secflavors, i;
 
 	error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags,
-	    &credanon, NULL, NULL);
+	    &credanon, &numsecflavor, &secflavors);
 	if (error)
 		return (NFSERR_PROGUNAVAIL);
-	if ((exflags & MNT_EXGSSONLY))
-		nd->nd_flag |= ND_EXGSSONLY;
 	if (credanon != NULL)
 		crfree(credanon);
+	for (i = 0; i < numsecflavor; i++) {
+		if (secflavors[i] == AUTH_SYS)
+			nd->nd_flag |= ND_EXAUTHSYS;
+		else if (secflavors[i] == RPCSEC_GSS_KRB5)
+			nd->nd_flag |= ND_EXGSS;
+		else if (secflavors[i] == RPCSEC_GSS_KRB5I)
+			nd->nd_flag |= ND_EXGSSINTEGRITY;
+		else if (secflavors[i] == RPCSEC_GSS_KRB5P)
+			nd->nd_flag |= ND_EXGSSPRIVACY;
+	}
 	return (0);
 }
 
@@ -2985,6 +3002,45 @@ nfssvc_srvcall(struct thread *p, struct 
 	return (error);
 }
 
+/*
+ * Check exports.
+ * Returns 0 if ok, 1 otherwise.
+ */
+int
+nfsvno_testexp(struct nfsrv_descript *nd, struct nfsexstuff *exp)
+{
+	int i;
+
+	/*
+	 * This seems odd, but allow the case where the security flavor
+	 * list is empty. This happens when NFSv4 is traversing non-exported
+	 * file systems. Exported file systems should always have a non-empty
+	 * security flavor list.
+	 */
+	if (exp->nes_numsecflavor == 0)
+		return (0);
+
+	for (i = 0; i < exp->nes_numsecflavor; i++) {
+		/*
+		 * The tests for privacy and integrity must be first,
+		 * since ND_GSS is set for everything but AUTH_SYS.
+		 */
+		if (exp->nes_secflavors[i] == RPCSEC_GSS_KRB5P &&
+		    (nd->nd_flag & ND_GSSPRIVACY))
+			return (0);
+		if (exp->nes_secflavors[i] == RPCSEC_GSS_KRB5I &&
+		    (nd->nd_flag & ND_GSSINTEGRITY))
+			return (0);
+		if (exp->nes_secflavors[i] == RPCSEC_GSS_KRB5 &&
+		    (nd->nd_flag & ND_GSS))
+			return (0);
+		if (exp->nes_secflavors[i] == AUTH_SYS &&
+		    (nd->nd_flag & ND_GSS) == 0)
+			return (0);
+	}
+	return (1);
+}
+
 extern int (*nfsd_call_nfsd)(struct thread *, struct nfssvc_args *);
 
 /*

Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c	Thu May 14 21:39:08 2009	(r192121)
@@ -3090,7 +3090,6 @@ nfsrvd_secinfo(struct nfsrv_descript *nd
 	retnes.nes_vfslocked = exp->nes_vfslocked;
 	vput(vp);
 	savflag = nd->nd_flag;
-	nd->nd_flag |= ND_GSS;	/* so nfsd_fhtovp() won't reply Wrongsec */
 	if (!nd->nd_repstat) {
 		nfsd_fhtovp(nd, &fh, &vp, &retnes, &mp, 0, p);
 		if (vp)
@@ -3106,20 +3105,39 @@ nfsrvd_secinfo(struct nfsrv_descript *nd
 	 */
 	len = 0;
 	NFSM_BUILD(sizp, u_int32_t *, NFSX_UNSIGNED);
-	if (!NFSVNO_EXGSSONLY(&retnes)) {
-		NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
-		*tl = txdr_unsigned(RPCAUTH_UNIX);
-		len++;
-	}
-	for (i = RPCAUTHGSS_SVCNONE; i <= RPCAUTHGSS_SVCPRIVACY; i++) {
-		NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
-		*tl++ = txdr_unsigned(RPCAUTH_GSS);
-		(void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str,
-		    nfsgss_mechlist[KERBV_MECH].len);
-		NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
-		*tl++ = txdr_unsigned(GSS_KERBV_QOP);
-		*tl = txdr_unsigned(i);
-		len++;
+	for (i = 0; i < retnes.nes_numsecflavor; i++) {
+		if (retnes.nes_secflavors[i] == AUTH_SYS) {
+			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+			*tl = txdr_unsigned(RPCAUTH_UNIX);
+			len++;
+		} else if (retnes.nes_secflavors[i] == RPCSEC_GSS_KRB5) {
+			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+			*tl++ = txdr_unsigned(RPCAUTH_GSS);
+			(void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str,
+			    nfsgss_mechlist[KERBV_MECH].len);
+			NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+			*tl++ = txdr_unsigned(GSS_KERBV_QOP);
+			*tl = txdr_unsigned(RPCAUTHGSS_SVCNONE);
+			len++;
+		} else if (retnes.nes_secflavors[i] == RPCSEC_GSS_KRB5I) {
+			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+			*tl++ = txdr_unsigned(RPCAUTH_GSS);
+			(void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str,
+			    nfsgss_mechlist[KERBV_MECH].len);
+			NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+			*tl++ = txdr_unsigned(GSS_KERBV_QOP);
+			*tl = txdr_unsigned(RPCAUTHGSS_SVCINTEGRITY);
+			len++;
+		} else if (retnes.nes_secflavors[i] == RPCSEC_GSS_KRB5P) {
+			NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
+			*tl++ = txdr_unsigned(RPCAUTH_GSS);
+			(void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str,
+			    nfsgss_mechlist[KERBV_MECH].len);
+			NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
+			*tl++ = txdr_unsigned(GSS_KERBV_QOP);
+			*tl = txdr_unsigned(RPCAUTHGSS_SVCPRIVACY);
+			len++;
+		}
 	}
 	*sizp = txdr_unsigned(len);
 	return (0);
@@ -3141,7 +3159,7 @@ nfsrvd_setclientid(struct nfsrv_descript
 	nfsquad_t clientid, confirm;
 
 	if ((!nfs_rootfhset && !nfsv4root_set) ||
-	    (nd->nd_flag & (ND_GSS | ND_EXGSSONLY)) == ND_EXGSSONLY) {
+	    nfsd_checkrootexp(nd)) {
 		nd->nd_repstat = NFSERR_WRONGSEC;
 		return (0);
 	}
@@ -3250,7 +3268,7 @@ nfsrvd_setclientidcfrm(struct nfsrv_desc
 	nfsquad_t clientid, confirm;
 
 	if ((!nfs_rootfhset && !nfsv4root_set) ||
-	    (nd->nd_flag & (ND_GSS | ND_EXGSSONLY)) == ND_EXGSSONLY) {
+	    nfsd_checkrootexp(nd)) {
 		nd->nd_repstat = NFSERR_WRONGSEC;
 		return (0);
 	}

Modified: head/sys/fs/nfsserver/nfs_nfsdsocket.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdsocket.c	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfsserver/nfs_nfsdsocket.c	Thu May 14 21:39:08 2009	(r192121)
@@ -819,8 +819,7 @@ nfsrvd_compound(struct nfsrv_descript *n
 			    op != NFSV4OP_GETFH &&
 			    op != NFSV4OP_SECINFO)
 				nd->nd_repstat = NFSERR_NOFILEHANDLE;
-			else if (NFSVNO_EXGSSONLY(&vpnes) &&
-			    !(nd->nd_flag & ND_GSS) &&
+			else if (nfsvno_testexp(nd, &vpnes) &&
 			    op != NFSV4OP_LOOKUP &&
 			    op != NFSV4OP_GETFH &&
 			    op != NFSV4OP_GETATTR &&

Modified: head/sys/fs/nfsserver/nfs_nfsdsubs.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdsubs.c	Thu May 14 21:27:03 2009	(r192120)
+++ head/sys/fs/nfsserver/nfs_nfsdsubs.c	Thu May 14 21:39:08 2009	(r192121)
@@ -2019,3 +2019,25 @@ nfsd_init(void)
 	NFSBZERO(nfs_v2pubfh, NFSX_V2FH);
 }
 
+/*
+ * Check the v4 root exports.
+ * Return 0 if ok, 1 otherwise.
+ */
+int
+nfsd_checkrootexp(struct nfsrv_descript *nd)
+{
+
+	if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS)
+		return (0);
+	if ((nd->nd_flag & (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) ==
+	    (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY))
+		return (0);
+	if ((nd->nd_flag & (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) ==
+	    (ND_GSSPRIVACY | ND_EXGSSPRIVACY))
+		return (0);
+	if ((nd->nd_flag & (ND_GSS | ND_GSSINTEGRITY | ND_GSSPRIVACY |
+	     ND_EXGSS)) == (ND_GSS | ND_EXGSS))
+		return (0);
+	return (1);
+}
+



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905142139.n4ELd8Zw003155>