Blob Blame History Raw
commit 4a1ad4aa3028d26d830d9a9003ff9e3337b0e0d5
Author: Scott Mayhew <smayhew@redhat.com>
Date:   Thu Apr 2 11:15:15 2015 -0400

    mountd: Enable all auth flavors on pseudofs exports
    
    With the current mountd code it's possible to craft exports in such a
    manner that clients will be unable to mount exports that they *should*
    be able to mount.
    
    Consider the following example:
    
    /foo	*(rw,insecure,no_root_squash,sec=krb5p)
    /bar	client.example.com(rw,insecure,no_root_squash)
    
    Initially, client.example.com will be able to mount the /foo export
    using sec=krb5p, but attempts to mount /bar using sec=sys will return
    EPERM.  Once the nfsd.export cache entry expires, client.example.com
    will then be able to mount /bar using sec=sys but attempts to mount /foo
    using sec=krb5p will return EPERM.
    
    The reason this happens is because the initial nfsd.export cache entry
    is actually pre-populated by nfsd_fh(), which is the handler for the
    nfsd.fh cache, while later cache requests (once the initial entry
    expires) are handled by nfsd_export().  These functions have slightly
    different logic in how they select a v4root export from the cache --
    nfsd_fh() takes last matching v4root export it finds, while
    nfsd_export() (actually lookup_export()) takes the first.  Either way
    it's wrong because the client should be able to mount both exports.
    
    Both rfc3503bis and rfc5661 say:
    
       A common and convenient practice, unless strong security requirements
       dictate otherwise, is to make the entire pseudo file system
       accessible by all of the valid security mechanisms.
    
    ...so lets do that.
    
    Acked-by: J. Bruce Fields <bfields@fieldses.org>
    Signed-off-by: Scott Mayhew <smayhew@redhat.com>
    Signed-off-by: Steve Dickson <steved@redhat.com>

diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c
index 34d098a..429ebb8 100644
--- a/utils/mountd/v4root.c
+++ b/utils/mountd/v4root.c
@@ -26,6 +26,7 @@
 #include "nfslib.h"
 #include "misc.h"
 #include "v4root.h"
+#include "pseudoflavors.h"
 
 int v4root_needed;
 
@@ -56,22 +57,22 @@ static nfs_export pseudo_root = {
 };
 
 static void
-set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
+set_pseudofs_security(struct exportent *pseudo, int flags)
 {
-	struct sec_entry *se;
+	struct flav_info *flav;
 	int i;
 
-	if (source->e_flags & NFSEXP_INSECURE_PORT)
+	if (flags & NFSEXP_INSECURE_PORT)
 		pseudo->e_flags |= NFSEXP_INSECURE_PORT;
-	if ((source->e_flags & NFSEXP_ROOTSQUASH) == 0)
+	if ((flags & NFSEXP_ROOTSQUASH) == 0)
 		pseudo->e_flags &= ~NFSEXP_ROOTSQUASH;
-	for (se = source->e_secinfo; se->flav; se++) {
+	for (flav = flav_map; flav < flav_map + flav_map_size; flav++) {
 		struct sec_entry *new;
 
-		i = secinfo_addflavor(se->flav, pseudo);
+		i = secinfo_addflavor(flav, pseudo);
 		new = &pseudo->e_secinfo[i];
 
-		if (se->flags & NFSEXP_INSECURE_PORT)
+		if (flags & NFSEXP_INSECURE_PORT)
 			new->flags |= NFSEXP_INSECURE_PORT;
 	}
 }
@@ -91,7 +92,7 @@ v4root_create(char *path, nfs_export *export)
 	strncpy(eep.e_path, path, sizeof(eep.e_path));
 	if (strcmp(path, "/") != 0)
 		eep.e_flags &= ~NFSEXP_FSID;
-	set_pseudofs_security(&eep, curexp);
+	set_pseudofs_security(&eep, curexp->e_flags);
 	exp = export_create(&eep, 0);
 	if (exp == NULL)
 		return NULL;
@@ -139,7 +140,7 @@ pseudofs_update(char *hostname, char *path, nfs_export *source)
 		return 0;
 	}
 	/* Update an existing V4ROOT export: */
-	set_pseudofs_security(&exp->m_export, &source->m_export);
+	set_pseudofs_security(&exp->m_export, source->m_export.e_flags);
 	return 0;
 }