|
|
d2edb4 |
commit 4a1ad4aa3028d26d830d9a9003ff9e3337b0e0d5
|
|
|
d2edb4 |
Author: Scott Mayhew <smayhew@redhat.com>
|
|
|
d2edb4 |
Date: Thu Apr 2 11:15:15 2015 -0400
|
|
|
d2edb4 |
|
|
|
d2edb4 |
mountd: Enable all auth flavors on pseudofs exports
|
|
|
d2edb4 |
|
|
|
d2edb4 |
With the current mountd code it's possible to craft exports in such a
|
|
|
d2edb4 |
manner that clients will be unable to mount exports that they *should*
|
|
|
d2edb4 |
be able to mount.
|
|
|
d2edb4 |
|
|
|
d2edb4 |
Consider the following example:
|
|
|
d2edb4 |
|
|
|
d2edb4 |
/foo *(rw,insecure,no_root_squash,sec=krb5p)
|
|
|
d2edb4 |
/bar client.example.com(rw,insecure,no_root_squash)
|
|
|
d2edb4 |
|
|
|
d2edb4 |
Initially, client.example.com will be able to mount the /foo export
|
|
|
d2edb4 |
using sec=krb5p, but attempts to mount /bar using sec=sys will return
|
|
|
d2edb4 |
EPERM. Once the nfsd.export cache entry expires, client.example.com
|
|
|
d2edb4 |
will then be able to mount /bar using sec=sys but attempts to mount /foo
|
|
|
d2edb4 |
using sec=krb5p will return EPERM.
|
|
|
d2edb4 |
|
|
|
d2edb4 |
The reason this happens is because the initial nfsd.export cache entry
|
|
|
d2edb4 |
is actually pre-populated by nfsd_fh(), which is the handler for the
|
|
|
d2edb4 |
nfsd.fh cache, while later cache requests (once the initial entry
|
|
|
d2edb4 |
expires) are handled by nfsd_export(). These functions have slightly
|
|
|
d2edb4 |
different logic in how they select a v4root export from the cache --
|
|
|
d2edb4 |
nfsd_fh() takes last matching v4root export it finds, while
|
|
|
d2edb4 |
nfsd_export() (actually lookup_export()) takes the first. Either way
|
|
|
d2edb4 |
it's wrong because the client should be able to mount both exports.
|
|
|
d2edb4 |
|
|
|
d2edb4 |
Both rfc3503bis and rfc5661 say:
|
|
|
d2edb4 |
|
|
|
d2edb4 |
A common and convenient practice, unless strong security requirements
|
|
|
d2edb4 |
dictate otherwise, is to make the entire pseudo file system
|
|
|
d2edb4 |
accessible by all of the valid security mechanisms.
|
|
|
d2edb4 |
|
|
|
d2edb4 |
...so lets do that.
|
|
|
d2edb4 |
|
|
|
d2edb4 |
Acked-by: J. Bruce Fields <bfields@fieldses.org>
|
|
|
d2edb4 |
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
|
|
|
d2edb4 |
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
|
d2edb4 |
|
|
|
d2edb4 |
diff --git a/utils/mountd/v4root.c b/utils/mountd/v4root.c
|
|
|
d2edb4 |
index 34d098a..429ebb8 100644
|
|
|
d2edb4 |
--- a/utils/mountd/v4root.c
|
|
|
d2edb4 |
+++ b/utils/mountd/v4root.c
|
|
|
d2edb4 |
@@ -26,6 +26,7 @@
|
|
|
d2edb4 |
#include "nfslib.h"
|
|
|
d2edb4 |
#include "misc.h"
|
|
|
d2edb4 |
#include "v4root.h"
|
|
|
d2edb4 |
+#include "pseudoflavors.h"
|
|
|
d2edb4 |
|
|
|
d2edb4 |
int v4root_needed;
|
|
|
d2edb4 |
|
|
|
d2edb4 |
@@ -56,22 +57,22 @@ static nfs_export pseudo_root = {
|
|
|
d2edb4 |
};
|
|
|
d2edb4 |
|
|
|
d2edb4 |
static void
|
|
|
d2edb4 |
-set_pseudofs_security(struct exportent *pseudo, struct exportent *source)
|
|
|
d2edb4 |
+set_pseudofs_security(struct exportent *pseudo, int flags)
|
|
|
d2edb4 |
{
|
|
|
d2edb4 |
- struct sec_entry *se;
|
|
|
d2edb4 |
+ struct flav_info *flav;
|
|
|
d2edb4 |
int i;
|
|
|
d2edb4 |
|
|
|
d2edb4 |
- if (source->e_flags & NFSEXP_INSECURE_PORT)
|
|
|
d2edb4 |
+ if (flags & NFSEXP_INSECURE_PORT)
|
|
|
d2edb4 |
pseudo->e_flags |= NFSEXP_INSECURE_PORT;
|
|
|
d2edb4 |
- if ((source->e_flags & NFSEXP_ROOTSQUASH) == 0)
|
|
|
d2edb4 |
+ if ((flags & NFSEXP_ROOTSQUASH) == 0)
|
|
|
d2edb4 |
pseudo->e_flags &= ~NFSEXP_ROOTSQUASH;
|
|
|
d2edb4 |
- for (se = source->e_secinfo; se->flav; se++) {
|
|
|
d2edb4 |
+ for (flav = flav_map; flav < flav_map + flav_map_size; flav++) {
|
|
|
d2edb4 |
struct sec_entry *new;
|
|
|
d2edb4 |
|
|
|
d2edb4 |
- i = secinfo_addflavor(se->flav, pseudo);
|
|
|
d2edb4 |
+ i = secinfo_addflavor(flav, pseudo);
|
|
|
d2edb4 |
new = &pseudo->e_secinfo[i];
|
|
|
d2edb4 |
|
|
|
d2edb4 |
- if (se->flags & NFSEXP_INSECURE_PORT)
|
|
|
d2edb4 |
+ if (flags & NFSEXP_INSECURE_PORT)
|
|
|
d2edb4 |
new->flags |= NFSEXP_INSECURE_PORT;
|
|
|
d2edb4 |
}
|
|
|
d2edb4 |
}
|
|
|
d2edb4 |
@@ -91,7 +92,7 @@ v4root_create(char *path, nfs_export *export)
|
|
|
d2edb4 |
strncpy(eep.e_path, path, sizeof(eep.e_path));
|
|
|
d2edb4 |
if (strcmp(path, "/") != 0)
|
|
|
d2edb4 |
eep.e_flags &= ~NFSEXP_FSID;
|
|
|
d2edb4 |
- set_pseudofs_security(&eep, curexp);
|
|
|
d2edb4 |
+ set_pseudofs_security(&eep, curexp->e_flags);
|
|
|
d2edb4 |
exp = export_create(&eep, 0);
|
|
|
d2edb4 |
if (exp == NULL)
|
|
|
d2edb4 |
return NULL;
|
|
|
d2edb4 |
@@ -139,7 +140,7 @@ pseudofs_update(char *hostname, char *path, nfs_export *source)
|
|
|
d2edb4 |
return 0;
|
|
|
d2edb4 |
}
|
|
|
d2edb4 |
/* Update an existing V4ROOT export: */
|
|
|
d2edb4 |
- set_pseudofs_security(&exp->m_export, &source->m_export);
|
|
|
d2edb4 |
+ set_pseudofs_security(&exp->m_export, source->m_export.e_flags);
|
|
|
d2edb4 |
return 0;
|
|
|
d2edb4 |
}
|
|
|
d2edb4 |
|