nfsd: refine and rename NFSD_MAY_LOCK

NFSD_MAY_LOCK means a few different things.
- it means that GSS is not required.
- it means that with NFSEXP_NOAUTHNLM, authentication is not required
- it means that OWNER_OVERRIDE is allowed.

None of these are specific to locking, they are specific to the NLM
protocol.
So:
 - rename to NFSD_MAY_NLM
 - set NFSD_MAY_OWNER_OVERRIDE and NFSD_MAY_BYPASS_GSS in nlm_fopen()
   so that NFSD_MAY_NLM doesn't need to imply these.
 - move the test on NFSEXP_NOAUTHNLM out of nfsd_permission() and
   into fh_verify where other special-case tests on the MAY flags
   happen.  nfsd_permission() can be called from other places than
   fh_verify(), but none of these will have NFSD_MAY_NLM.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
NeilBrown 2024-10-18 08:42:31 +11:00 committed by Chuck Lever
parent 6640556b0c
commit 4cc9b9f2bf
5 changed files with 18 additions and 23 deletions

View file

@ -38,11 +38,20 @@ nlm_fopen(struct svc_rqst *rqstp, struct nfs_fh *f, struct file **filp,
memcpy(&fh.fh_handle.fh_raw, f->data, f->size); memcpy(&fh.fh_handle.fh_raw, f->data, f->size);
fh.fh_export = NULL; fh.fh_export = NULL;
/*
* Allow BYPASS_GSS as some client implementations use AUTH_SYS
* for NLM even when GSS is used for NFS.
* Allow OWNER_OVERRIDE as permission might have been changed
* after the file was opened.
* Pass MAY_NLM so that authentication can be completely bypassed
* if NFSEXP_NOAUTHNLM is set. Some older clients use AUTH_NULL
* for NLM requests.
*/
access = (mode == O_WRONLY) ? NFSD_MAY_WRITE : NFSD_MAY_READ; access = (mode == O_WRONLY) ? NFSD_MAY_WRITE : NFSD_MAY_READ;
access |= NFSD_MAY_LOCK; access |= NFSD_MAY_NLM | NFSD_MAY_OWNER_OVERRIDE | NFSD_MAY_BYPASS_GSS;
nfserr = nfsd_open(rqstp, &fh, S_IFREG, access, filp); nfserr = nfsd_open(rqstp, &fh, S_IFREG, access, filp);
fh_put(&fh); fh_put(&fh);
/* We return nlm error codes as nlm doesn't know /* We return nlm error codes as nlm doesn't know
* about nfsd, but nfsd does know about nlm.. * about nfsd, but nfsd does know about nlm..
*/ */
switch (nfserr) { switch (nfserr) {

View file

@ -363,13 +363,10 @@ __fh_verify(struct svc_rqst *rqstp,
if (error) if (error)
goto out; goto out;
/* if ((access & NFSD_MAY_NLM) && (exp->ex_flags & NFSEXP_NOAUTHNLM))
* pseudoflavor restrictions are not enforced on NLM, /* NLM is allowed to fully bypass authentication */
* which clients virtually always use auth_sys for, goto out;
* even while using RPCSEC_GSS for NFS.
*/
if (access & NFSD_MAY_LOCK)
goto skip_pseudoflavor_check;
if (access & NFSD_MAY_BYPASS_GSS) if (access & NFSD_MAY_BYPASS_GSS)
may_bypass_gss = true; may_bypass_gss = true;
/* /*
@ -385,7 +382,6 @@ __fh_verify(struct svc_rqst *rqstp,
if (error) if (error)
goto out; goto out;
skip_pseudoflavor_check:
/* Finally, check access permissions. */ /* Finally, check access permissions. */
error = nfsd_permission(cred, exp, dentry, access); error = nfsd_permission(cred, exp, dentry, access);
out: out:

View file

@ -79,7 +79,7 @@ DEFINE_NFSD_XDR_ERR_EVENT(cant_encode);
{ NFSD_MAY_READ, "READ" }, \ { NFSD_MAY_READ, "READ" }, \
{ NFSD_MAY_SATTR, "SATTR" }, \ { NFSD_MAY_SATTR, "SATTR" }, \
{ NFSD_MAY_TRUNC, "TRUNC" }, \ { NFSD_MAY_TRUNC, "TRUNC" }, \
{ NFSD_MAY_LOCK, "LOCK" }, \ { NFSD_MAY_NLM, "NLM" }, \
{ NFSD_MAY_OWNER_OVERRIDE, "OWNER_OVERRIDE" }, \ { NFSD_MAY_OWNER_OVERRIDE, "OWNER_OVERRIDE" }, \
{ NFSD_MAY_LOCAL_ACCESS, "LOCAL_ACCESS" }, \ { NFSD_MAY_LOCAL_ACCESS, "LOCAL_ACCESS" }, \
{ NFSD_MAY_BYPASS_GSS_ON_ROOT, "BYPASS_GSS_ON_ROOT" }, \ { NFSD_MAY_BYPASS_GSS_ON_ROOT, "BYPASS_GSS_ON_ROOT" }, \

View file

@ -2506,7 +2506,7 @@ nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
(acc & NFSD_MAY_EXEC)? " exec" : "", (acc & NFSD_MAY_EXEC)? " exec" : "",
(acc & NFSD_MAY_SATTR)? " sattr" : "", (acc & NFSD_MAY_SATTR)? " sattr" : "",
(acc & NFSD_MAY_TRUNC)? " trunc" : "", (acc & NFSD_MAY_TRUNC)? " trunc" : "",
(acc & NFSD_MAY_LOCK)? " lock" : "", (acc & NFSD_MAY_NLM)? " nlm" : "",
(acc & NFSD_MAY_OWNER_OVERRIDE)? " owneroverride" : "", (acc & NFSD_MAY_OWNER_OVERRIDE)? " owneroverride" : "",
inode->i_mode, inode->i_mode,
IS_IMMUTABLE(inode)? " immut" : "", IS_IMMUTABLE(inode)? " immut" : "",
@ -2531,16 +2531,6 @@ nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
if ((acc & NFSD_MAY_TRUNC) && IS_APPEND(inode)) if ((acc & NFSD_MAY_TRUNC) && IS_APPEND(inode))
return nfserr_perm; return nfserr_perm;
if (acc & NFSD_MAY_LOCK) {
/* If we cannot rely on authentication in NLM requests,
* just allow locks, otherwise require read permission, or
* ownership
*/
if (exp->ex_flags & NFSEXP_NOAUTHNLM)
return 0;
else
acc = NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE;
}
/* /*
* The file owner always gets access permission for accesses that * The file owner always gets access permission for accesses that
* would normally be checked at open time. This is to make * would normally be checked at open time. This is to make

View file

@ -20,7 +20,7 @@
#define NFSD_MAY_READ 0x004 /* == MAY_READ */ #define NFSD_MAY_READ 0x004 /* == MAY_READ */
#define NFSD_MAY_SATTR 0x008 #define NFSD_MAY_SATTR 0x008
#define NFSD_MAY_TRUNC 0x010 #define NFSD_MAY_TRUNC 0x010
#define NFSD_MAY_LOCK 0x020 #define NFSD_MAY_NLM 0x020 /* request is from lockd */
#define NFSD_MAY_MASK 0x03f #define NFSD_MAY_MASK 0x03f
/* extra hints to permission and open routines: */ /* extra hints to permission and open routines: */