2008-08-07 18:11:50

by J. Bruce Fields

[permalink] [raw]
Subject: [PATCH] nfsd: permit unauthenticated stat of export root

From: J. Bruce Fields <[email protected]>

RFC 2623 section 2.3.2 permits the server to bypass gss authentication
checks for certain operations that a client may perform when mounting.
In the case of a client that doesn't have some form of credentials
available to it on boot, this allows it to perform the mount unattended.
(Presumably real file access won't be needed until a user with
credentials logs in.)

Being slightly more lenient allows lots of old clients to access
krb5-only exports, with the only loss being a small amount of
information leaked about the root directory of the export.

This affects on v2 and v3; v4 still requires authentication for all
access.

Signed-off-by: J. Bruce Fields <[email protected]>
---
fs/nfsd/nfs3proc.c | 5 +++--
fs/nfsd/nfsfh.c | 30 ++++++++++++++++++++----------
fs/nfsd/nfsproc.c | 6 ++++--
fs/nfsd/vfs.c | 4 ++--
include/linux/nfsd/nfsd.h | 3 ++-
5 files changed, 31 insertions(+), 17 deletions(-)

I intend to submit this for 2.6.28

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 4d617ea..1419142 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -530,7 +530,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
dprintk("nfsd: FSSTAT(3) %s\n",
SVCFH_fmt(&argp->fh));

- nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+ nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
fh_put(&argp->fh);
RETURN_STATUS(nfserr);
}
@@ -558,7 +558,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
resp->f_maxfilesize = ~(u32) 0;
resp->f_properties = NFS3_FSF_DEFAULT;

- nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
+ nfserr = fh_verify(rqstp, &argp->fh, 0,
+ NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);

/* Check special features of the file system. May request
* different read/write sizes for file systems known to have
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index f45451e..7c6847e 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -302,17 +302,27 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
if (error)
goto out;

- if (!(access & NFSD_MAY_LOCK)) {
- /*
- * pseudoflavor restrictions are not enforced on NLM,
- * which clients virtually always use auth_sys for,
- * even while using RPCSEC_GSS for NFS.
- */
- error = check_nfsd_access(exp, rqstp);
- if (error)
- goto out;
- }
+ /*
+ * pseudoflavor restrictions are not enforced on NLM,
+ * which clients virtually always use auth_sys for,
+ * even while using RPCSEC_GSS for NFS.
+ */
+ if (access & NFSD_MAY_LOCK)
+ goto skip_pseudoflavor_check;
+ /*
+ * Clients may expect to be able to use auth_sys during mount,
+ * even if they use gss for everything else; see section 2.3.2
+ * of rfc 2623.
+ */
+ if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT
+ && exp->ex_path.dentry == dentry)
+ goto skip_pseudoflavor_check;
+
+ error = check_nfsd_access(exp, rqstp);
+ if (error)
+ goto out;

+skip_pseudoflavor_check:
/* Finally, check access permissions. */
error = nfsd_permission(rqstp, exp, dentry, access);

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 0766f95..5cffeca 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -65,7 +65,8 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));

fh_copy(&resp->fh, &argp->fh);
- nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP);
+ nfserr = fh_verify(rqstp, &resp->fh, 0,
+ NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
return nfsd_return_attrs(nfserr, resp);
}

@@ -521,7 +522,8 @@ nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,

dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));

- nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+ nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats,
+ NFSD_MAY_BYPASS_GSS_ON_ROOT);
fh_put(&argp->fh);
return nfserr;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0f4481e..f51bdf6 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1872,9 +1872,9 @@ out:
* N.B. After this call fhp needs an fh_put
*/
__be32
-nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
+nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access)
{
- __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
+ __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access);
if (!err && vfs_statfs(fhp->fh_dentry,stat))
err = nfserr_io;
return err;
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index a2861d9..47bea82 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -39,6 +39,7 @@
#define NFSD_MAY_LOCK 32
#define NFSD_MAY_OWNER_OVERRIDE 64
#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
+#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256

#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
@@ -126,7 +127,7 @@ int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
loff_t *, struct readdir_cd *, filldir_t);
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
- struct kstatfs *);
+ struct kstatfs *, int access);

int nfsd_notify_change(struct inode *, struct iattr *);
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
--
1.5.5.rc1



2008-08-07 18:23:43

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

J. Bruce Fields wrote:
> From: J. Bruce Fields <[email protected]>
>
> RFC 2623 section 2.3.2 permits the server to bypass gss authentication
> checks for certain operations that a client may perform when mounting.
> In the case of a client that doesn't have some form of credentials
> available to it on boot, this allows it to perform the mount unattended.
> (Presumably real file access won't be needed until a user with
> credentials logs in.)
>
> Being slightly more lenient allows lots of old clients to access
> krb5-only exports, with the only loss being a small amount of
> information leaked about the root directory of the export.
>
> This affects on v2 and v3; v4 still requires authentication for all
> access.
>
> Signed-off-by: J. Bruce Fields <[email protected]>
> ---
> fs/nfsd/nfs3proc.c | 5 +++--
> fs/nfsd/nfsfh.c | 30 ++++++++++++++++++++----------
> fs/nfsd/nfsproc.c | 6 ++++--
> fs/nfsd/vfs.c | 4 ++--
> include/linux/nfsd/nfsd.h | 3 ++-
> 5 files changed, 31 insertions(+), 17 deletions(-)
>
> I intend to submit this for 2.6.28
>
> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
> index 4d617ea..1419142 100644
> --- a/fs/nfsd/nfs3proc.c
> +++ b/fs/nfsd/nfs3proc.c
> @@ -530,7 +530,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
> dprintk("nfsd: FSSTAT(3) %s\n",
> SVCFH_fmt(&argp->fh));
>
> - nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
> + nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
> fh_put(&argp->fh);
> RETURN_STATUS(nfserr);
> }
> @@ -558,7 +558,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
> resp->f_maxfilesize = ~(u32) 0;
> resp->f_properties = NFS3_FSF_DEFAULT;
>
> - nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
> + nfserr = fh_verify(rqstp, &argp->fh, 0,
> + NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
>
> /* Check special features of the file system. May request
> * different read/write sizes for file systems known to have
>

I would think that you might want to have nfsd3_proc_getattr()
in this list too. Some clients may need to generate a GETATTR
if they need the attributes for the root node.

ps

> diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
> index f45451e..7c6847e 100644
> --- a/fs/nfsd/nfsfh.c
> +++ b/fs/nfsd/nfsfh.c
> @@ -302,17 +302,27 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
> if (error)
> goto out;
>
> - if (!(access & NFSD_MAY_LOCK)) {
> - /*
> - * pseudoflavor restrictions are not enforced on NLM,
> - * which clients virtually always use auth_sys for,
> - * even while using RPCSEC_GSS for NFS.
> - */
> - error = check_nfsd_access(exp, rqstp);
> - if (error)
> - goto out;
> - }
> + /*
> + * pseudoflavor restrictions are not enforced on NLM,
> + * which clients virtually always use auth_sys for,
> + * even while using RPCSEC_GSS for NFS.
> + */
> + if (access & NFSD_MAY_LOCK)
> + goto skip_pseudoflavor_check;
> + /*
> + * Clients may expect to be able to use auth_sys during mount,
> + * even if they use gss for everything else; see section 2.3.2
> + * of rfc 2623.
> + */
> + if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT
> + && exp->ex_path.dentry == dentry)
> + goto skip_pseudoflavor_check;
> +
> + error = check_nfsd_access(exp, rqstp);
> + if (error)
> + goto out;
>
> +skip_pseudoflavor_check:
> /* Finally, check access permissions. */
> error = nfsd_permission(rqstp, exp, dentry, access);
>
> diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
> index 0766f95..5cffeca 100644
> --- a/fs/nfsd/nfsproc.c
> +++ b/fs/nfsd/nfsproc.c
> @@ -65,7 +65,8 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
> dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
>
> fh_copy(&resp->fh, &argp->fh);
> - nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP);
> + nfserr = fh_verify(rqstp, &resp->fh, 0,
> + NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
> return nfsd_return_attrs(nfserr, resp);
> }
>
> @@ -521,7 +522,8 @@ nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>
> dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));
>
> - nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
> + nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats,
> + NFSD_MAY_BYPASS_GSS_ON_ROOT);
> fh_put(&argp->fh);
> return nfserr;
> }
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index 0f4481e..f51bdf6 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -1872,9 +1872,9 @@ out:
> * N.B. After this call fhp needs an fh_put
> */
> __be32
> -nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
> +nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access)
> {
> - __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
> + __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access);
> if (!err && vfs_statfs(fhp->fh_dentry,stat))
> err = nfserr_io;
> return err;
> diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
> index a2861d9..47bea82 100644
> --- a/include/linux/nfsd/nfsd.h
> +++ b/include/linux/nfsd/nfsd.h
> @@ -39,6 +39,7 @@
> #define NFSD_MAY_LOCK 32
> #define NFSD_MAY_OWNER_OVERRIDE 64
> #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
> +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256
>
> #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
> #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
> @@ -126,7 +127,7 @@ int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
> __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
> loff_t *, struct readdir_cd *, filldir_t);
> __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
> - struct kstatfs *);
> + struct kstatfs *, int access);
>
> int nfsd_notify_change(struct inode *, struct iattr *);
> __be32 nfsd_permission(struct svc_rqst *, struct svc_export *,
>


2008-08-07 19:16:58

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
> J. Bruce Fields wrote:
>> From: J. Bruce Fields <[email protected]>
>>
>> RFC 2623 section 2.3.2 permits the server to bypass gss authentication
>> checks for certain operations that a client may perform when mounting.
>> In the case of a client that doesn't have some form of credentials
>> available to it on boot, this allows it to perform the mount unattended.
>> (Presumably real file access won't be needed until a user with
>> credentials logs in.)
>>
>> Being slightly more lenient allows lots of old clients to access
>> krb5-only exports, with the only loss being a small amount of
>> information leaked about the root directory of the export.
>>
>> This affects on v2 and v3; v4 still requires authentication for all
>> access.
>>
>> Signed-off-by: J. Bruce Fields <[email protected]>
>> ---
>> fs/nfsd/nfs3proc.c | 5 +++--
>> fs/nfsd/nfsfh.c | 30 ++++++++++++++++++++----------
>> fs/nfsd/nfsproc.c | 6 ++++--
>> fs/nfsd/vfs.c | 4 ++--
>> include/linux/nfsd/nfsd.h | 3 ++-
>> 5 files changed, 31 insertions(+), 17 deletions(-)
>>
>> I intend to submit this for 2.6.28
>>
>> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
>> index 4d617ea..1419142 100644
>> --- a/fs/nfsd/nfs3proc.c
>> +++ b/fs/nfsd/nfs3proc.c
>> @@ -530,7 +530,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>> dprintk("nfsd: FSSTAT(3) %s\n",
>> SVCFH_fmt(&argp->fh));
>> - nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
>> + nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
>> fh_put(&argp->fh);
>> RETURN_STATUS(nfserr);
>> }
>> @@ -558,7 +558,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>> resp->f_maxfilesize = ~(u32) 0;
>> resp->f_properties = NFS3_FSF_DEFAULT;
>> - nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
>> + nfserr = fh_verify(rqstp, &argp->fh, 0,
>> + NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
>> /* Check special features of the file system. May request
>> * different read/write sizes for file systems known to have
>>
>
> I would think that you might want to have nfsd3_proc_getattr()
> in this list too. Some clients may need to generate a GETATTR
> if they need the attributes for the root node.

Do you know of any? rfc 2623 makes it sound like those clients are out
of luck. And testing confirms that this patch is sufficient for the
linux client, at least.

--b.

2008-08-07 19:39:48

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

J. Bruce Fields wrote:
> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
>
>> J. Bruce Fields wrote:
>>
>>> From: J. Bruce Fields <[email protected]>
>>>
>>> RFC 2623 section 2.3.2 permits the server to bypass gss authentication
>>> checks for certain operations that a client may perform when mounting.
>>> In the case of a client that doesn't have some form of credentials
>>> available to it on boot, this allows it to perform the mount unattended.
>>> (Presumably real file access won't be needed until a user with
>>> credentials logs in.)
>>>
>>> Being slightly more lenient allows lots of old clients to access
>>> krb5-only exports, with the only loss being a small amount of
>>> information leaked about the root directory of the export.
>>>
>>> This affects on v2 and v3; v4 still requires authentication for all
>>> access.
>>>
>>> Signed-off-by: J. Bruce Fields <[email protected]>
>>> ---
>>> fs/nfsd/nfs3proc.c | 5 +++--
>>> fs/nfsd/nfsfh.c | 30 ++++++++++++++++++++----------
>>> fs/nfsd/nfsproc.c | 6 ++++--
>>> fs/nfsd/vfs.c | 4 ++--
>>> include/linux/nfsd/nfsd.h | 3 ++-
>>> 5 files changed, 31 insertions(+), 17 deletions(-)
>>>
>>> I intend to submit this for 2.6.28
>>>
>>> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
>>> index 4d617ea..1419142 100644
>>> --- a/fs/nfsd/nfs3proc.c
>>> +++ b/fs/nfsd/nfs3proc.c
>>> @@ -530,7 +530,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>>> dprintk("nfsd: FSSTAT(3) %s\n",
>>> SVCFH_fmt(&argp->fh));
>>> - nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
>>> + nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
>>> fh_put(&argp->fh);
>>> RETURN_STATUS(nfserr);
>>> }
>>> @@ -558,7 +558,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>>> resp->f_maxfilesize = ~(u32) 0;
>>> resp->f_properties = NFS3_FSF_DEFAULT;
>>> - nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
>>> + nfserr = fh_verify(rqstp, &argp->fh, 0,
>>> + NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
>>> /* Check special features of the file system. May request
>>> * different read/write sizes for file systems known to have
>>>
>>>
>> I would think that you might want to have nfsd3_proc_getattr()
>> in this list too. Some clients may need to generate a GETATTR
>> if they need the attributes for the root node.
>>
>
> Do you know of any? rfc 2623 makes it sound like those clients are out
> of luck. And testing confirms that this patch is sufficient for the
> linux client, at least.

I believe that the Solaris client may. I think that it may
use the attributes returned from the FSINFO call, if there
are any, to prevent the additional GETATTR, but this should
be tested. It might also be interesting to test out a
readonly failover mount on the Solaris client to see what
behavior that that exhibits.

ps

2008-08-07 20:41:56

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Thu, Aug 07, 2008 at 03:39:45PM -0400, Peter Staubach wrote:
> J. Bruce Fields wrote:
>> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
>>
>>> J. Bruce Fields wrote:
>>>
>>>> From: J. Bruce Fields <[email protected]>
>>>>
>>>> RFC 2623 section 2.3.2 permits the server to bypass gss authentication
>>>> checks for certain operations that a client may perform when mounting.
>>>> In the case of a client that doesn't have some form of credentials
>>>> available to it on boot, this allows it to perform the mount unattended.
>>>> (Presumably real file access won't be needed until a user with
>>>> credentials logs in.)
>>>>
>>>> Being slightly more lenient allows lots of old clients to access
>>>> krb5-only exports, with the only loss being a small amount of
>>>> information leaked about the root directory of the export.
>>>>
>>>> This affects on v2 and v3; v4 still requires authentication for all
>>>> access.
>>>>
>>>> Signed-off-by: J. Bruce Fields <[email protected]>
>>>> ---
>>>> fs/nfsd/nfs3proc.c | 5 +++--
>>>> fs/nfsd/nfsfh.c | 30 ++++++++++++++++++++----------
>>>> fs/nfsd/nfsproc.c | 6 ++++--
>>>> fs/nfsd/vfs.c | 4 ++--
>>>> include/linux/nfsd/nfsd.h | 3 ++-
>>>> 5 files changed, 31 insertions(+), 17 deletions(-)
>>>>
>>>> I intend to submit this for 2.6.28
>>>>
>>>> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
>>>> index 4d617ea..1419142 100644
>>>> --- a/fs/nfsd/nfs3proc.c
>>>> +++ b/fs/nfsd/nfs3proc.c
>>>> @@ -530,7 +530,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>>>> dprintk("nfsd: FSSTAT(3) %s\n",
>>>> SVCFH_fmt(&argp->fh));
>>>> - nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
>>>> + nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
>>>> fh_put(&argp->fh);
>>>> RETURN_STATUS(nfserr);
>>>> }
>>>> @@ -558,7 +558,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>>>> resp->f_maxfilesize = ~(u32) 0;
>>>> resp->f_properties = NFS3_FSF_DEFAULT;
>>>> - nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
>>>> + nfserr = fh_verify(rqstp, &argp->fh, 0,
>>>> + NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
>>>> /* Check special features of the file system. May request
>>>> * different read/write sizes for file systems known to have
>>>>
>>> I would think that you might want to have nfsd3_proc_getattr()
>>> in this list too. Some clients may need to generate a GETATTR
>>> if they need the attributes for the root node.
>>>
>>
>> Do you know of any? rfc 2623 makes it sound like those clients are out
>> of luck. And testing confirms that this patch is sufficient for the
>> linux client, at least.
>
> I believe that the Solaris client may. I think that it may
> use the attributes returned from the FSINFO call, if there
> are any, to prevent the additional GETATTR, but this should
> be tested. It might also be interesting to test out a
> readonly failover mount on the Solaris client to see what
> behavior that that exhibits.

OK, could be. Volunteers to test that welcomed--for now I think I'll
stick to the list in the RFC.

--b.

2008-08-08 20:21:07

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Thu, Aug 07, 2008 at 04:41:54PM -0400, J. Bruce Fields wrote:
> On Thu, Aug 07, 2008 at 03:39:45PM -0400, Peter Staubach wrote:
> > J. Bruce Fields wrote:
> >> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
> >>> I would think that you might want to have nfsd3_proc_getattr()
> >>> in this list too. Some clients may need to generate a GETATTR
> >>> if they need the attributes for the root node.
> >>>
> >>
> >> Do you know of any? rfc 2623 makes it sound like those clients are out
> >> of luck. And testing confirms that this patch is sufficient for the
> >> linux client, at least.
> >
> > I believe that the Solaris client may. I think that it may
> > use the attributes returned from the FSINFO call, if there
> > are any, to prevent the additional GETATTR, but this should
> > be tested. It might also be interesting to test out a
> > readonly failover mount on the Solaris client to see what
> > behavior that that exhibits.
>
> OK, could be. Volunteers to test that welcomed--for now I think I'll
> stick to the list in the RFC.

By the way, I don't mean to brush off the idea, it's just that this
satisfies my immediate problem, and it would be extremely easy for
someone else to test:

- Apply this patch to a linux nfs server, export a filesystem with
/export *(sec=krb5)
- mount -osec=krb5 server:/export from a solaris client.
- report whether it works, and get a packet capture if not.

... If someone gets a chance to figure out the Solaris client behavior,
that'd be great.

--b.

2008-08-08 20:32:35

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

J. Bruce Fields wrote:
> On Thu, Aug 07, 2008 at 04:41:54PM -0400, J. Bruce Fields wrote:
>
>> On Thu, Aug 07, 2008 at 03:39:45PM -0400, Peter Staubach wrote:
>>
>>> J. Bruce Fields wrote:
>>>
>>>> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
>>>>
>>>>> I would think that you might want to have nfsd3_proc_getattr()
>>>>> in this list too. Some clients may need to generate a GETATTR
>>>>> if they need the attributes for the root node.
>>>>>
>>>>>
>>>> Do you know of any? rfc 2623 makes it sound like those clients are out
>>>> of luck. And testing confirms that this patch is sufficient for the
>>>> linux client, at least.
>>>>
>>> I believe that the Solaris client may. I think that it may
>>> use the attributes returned from the FSINFO call, if there
>>> are any, to prevent the additional GETATTR, but this should
>>> be tested. It might also be interesting to test out a
>>> readonly failover mount on the Solaris client to see what
>>> behavior that that exhibits.
>>>
>> OK, could be. Volunteers to test that welcomed--for now I think I'll
>> stick to the list in the RFC.
>>
>
> By the way, I don't mean to brush off the idea, it's just that this
> satisfies my immediate problem, and it would be extremely easy for
> someone else to test:
>
> - Apply this patch to a linux nfs server, export a filesystem with
> /export *(sec=krb5)
> - mount -osec=krb5 server:/export from a solaris client.
> - report whether it works, and get a packet capture if not.
>
> ... If someone gets a chance to figure out the Solaris client behavior,
> that'd be great.

I will try it when I can, but I was thinking of just watching
the traffic generated during the mount. It shouldn't matter
whether the mount is done with krb5 or not, the sequence of
NFS operations should be the same.

Thanx...

ps

2008-08-08 20:39:58

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Fri, Aug 08, 2008 at 04:32:17PM -0400, Peter Staubach wrote:
> J. Bruce Fields wrote:
>> On Thu, Aug 07, 2008 at 04:41:54PM -0400, J. Bruce Fields wrote:
>>
>>> On Thu, Aug 07, 2008 at 03:39:45PM -0400, Peter Staubach wrote:
>>>
>>>> J. Bruce Fields wrote:
>>>>
>>>>> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
>>>>>
>>>>>> I would think that you might want to have nfsd3_proc_getattr()
>>>>>> in this list too. Some clients may need to generate a GETATTR
>>>>>> if they need the attributes for the root node.
>>>>>>
>>>>> Do you know of any? rfc 2623 makes it sound like those clients are out
>>>>> of luck. And testing confirms that this patch is sufficient for the
>>>>> linux client, at least.
>>>>>
>>>> I believe that the Solaris client may. I think that it may
>>>> use the attributes returned from the FSINFO call, if there
>>>> are any, to prevent the additional GETATTR, but this should
>>>> be tested. It might also be interesting to test out a
>>>> readonly failover mount on the Solaris client to see what
>>>> behavior that that exhibits.
>>>>
>>> OK, could be. Volunteers to test that welcomed--for now I think I'll
>>> stick to the list in the RFC.
>>>
>>
>> By the way, I don't mean to brush off the idea, it's just that this
>> satisfies my immediate problem, and it would be extremely easy for
>> someone else to test:
>>
>> - Apply this patch to a linux nfs server, export a filesystem with
>> /export *(sec=krb5)
>> - mount -osec=krb5 server:/export from a solaris client.
>> - report whether it works, and get a packet capture if not.
>>
>> ... If someone gets a chance to figure out the Solaris client behavior,
>> that'd be great.
>
> I will try it when I can, but I was thinking of just watching
> the traffic generated during the mount. It shouldn't matter
> whether the mount is done with krb5 or not, the sequence of
> NFS operations should be the same.

Sure, yep. Oh, and of course I forgot to mention that test should be
with v3....

--b.

2008-08-11 20:51:33

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

J. Bruce Fields wrote:
> On Thu, Aug 07, 2008 at 04:41:54PM -0400, J. Bruce Fields wrote:
>
>> On Thu, Aug 07, 2008 at 03:39:45PM -0400, Peter Staubach wrote:
>>
>>> J. Bruce Fields wrote:
>>>
>>>> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
>>>>
>>>>> I would think that you might want to have nfsd3_proc_getattr()
>>>>> in this list too. Some clients may need to generate a GETATTR
>>>>> if they need the attributes for the root node.
>>>>>
>>>>>
>>>> Do you know of any? rfc 2623 makes it sound like those clients are out
>>>> of luck. And testing confirms that this patch is sufficient for the
>>>> linux client, at least.
>>>>
>>> I believe that the Solaris client may. I think that it may
>>> use the attributes returned from the FSINFO call, if there
>>> are any, to prevent the additional GETATTR, but this should
>>> be tested. It might also be interesting to test out a
>>> readonly failover mount on the Solaris client to see what
>>> behavior that that exhibits.
>>>
>> OK, could be. Volunteers to test that welcomed--for now I think I'll
>> stick to the list in the RFC.
>>
>
> By the way, I don't mean to brush off the idea, it's just that this
> satisfies my immediate problem, and it would be extremely easy for
> someone else to test:
>
> - Apply this patch to a linux nfs server, export a filesystem with
> /export *(sec=krb5)
> - mount -osec=krb5 server:/export from a solaris client.
> - report whether it works, and get a packet capture if not.
>
> ... If someone gets a chance to figure out the Solaris client behavior,
> that'd be great.

The Solaris client behaves plus or minus like the Linux client.
It generates a GETATTR unless it receives the attributes via
one of the previous calls. In the Solaris case, it is an FSINFO
call.

The current Linux NFS server does not return attributes for the
PATHCONF, FSINFO, or FSSTAT calls.

Unless these calls are modified, then the NFSv3 GETATTR will need
to be allowed for the same reason that the NFSv2 GETATTR is
allowed. The NFS client needs, at the very least, the file type
of the node that it is mounting.

I am confused as to how the testing could have been successful.

Thanx...

ps

2008-08-11 21:26:41

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Mon, Aug 11, 2008 at 04:51:26PM -0400, Peter Staubach wrote:
> The Solaris client behaves plus or minus like the Linux client.
> It generates a GETATTR unless it receives the attributes via
> one of the previous calls. In the Solaris case, it is an FSINFO
> call.
>
> The current Linux NFS server does not return attributes for the
> PATHCONF, FSINFO, or FSSTAT calls.

Hm. I don't know why that is.

> Unless these calls are modified, then the NFSv3 GETATTR will need
> to be allowed for the same reason that the NFSv2 GETATTR is
> allowed. The NFS client needs, at the very least, the file type
> of the node that it is mounting.
>
> I am confused as to how the testing could have been successful.

Well, you can try exporting a filesystem with sec=krb5:krb5i:krb5p (no
sys) and try mounting v2 or v3, and you'll see that if fails without the
patch, and succeeds with it.

But testing again (linux client and server), and taking a network trace
this time: I mount with -overs=3,sec=krb5, and the client behavior is
odd:

FSINFO call with auth_sys
GETATTR call with krb5
FSINFO call with krb5

Note that this client actually *does* have access to kerberos
credentials--it's just not using them on the initial FSINFO call.

That could make some sense if it was trying to ensure the mount will
succeed in the absence of kerberos credentials, and doesn't want to
bother first trying to get a credentials and then falling back on
auth_sys if it doesn't find them.

But currently it fails if the server requests auth_sys on the initial
FSINFO *or* if it fails to get kerberos credentials for those second two
rpc calls. Something similar seems to be true for v2. Huh.

Anyway, so in the Solaris v3 case I take it that what you're seeing is
FSINFO, GETATTR, both done with auth_sys, and a failure of the mount
command if both aren't permitted?

OK, so I agree the server should either permit v3 GETATTR (trivial, if
arguably contrary to rfc 2623) or add attributes to FSINFO (which I
assume is also easy, but I don't know why it was left out before).
Seems the client needs some looking at too.

--b.

2008-08-11 21:27:58

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

J. Bruce Fields wrote:
> On Thu, Aug 07, 2008 at 03:39:45PM -0400, Peter Staubach wrote:
>
>> J. Bruce Fields wrote:
>>
>>> On Thu, Aug 07, 2008 at 02:23:40PM -0400, Peter Staubach wrote:
>>>
>>>
>>>> J. Bruce Fields wrote:
>>>>
>>>>
>>>>> From: J. Bruce Fields <[email protected]>
>>>>>
>>>>> RFC 2623 section 2.3.2 permits the server to bypass gss authentication
>>>>> checks for certain operations that a client may perform when mounting.
>>>>> In the case of a client that doesn't have some form of credentials
>>>>> available to it on boot, this allows it to perform the mount unattended.
>>>>> (Presumably real file access won't be needed until a user with
>>>>> credentials logs in.)
>>>>>
>>>>> Being slightly more lenient allows lots of old clients to access
>>>>> krb5-only exports, with the only loss being a small amount of
>>>>> information leaked about the root directory of the export.
>>>>>
>>>>> This affects on v2 and v3; v4 still requires authentication for all
>>>>> access.
>>>>>
>>>>> Signed-off-by: J. Bruce Fields <[email protected]>
>>>>> ---
>>>>> fs/nfsd/nfs3proc.c | 5 +++--
>>>>> fs/nfsd/nfsfh.c | 30 ++++++++++++++++++++----------
>>>>> fs/nfsd/nfsproc.c | 6 ++++--
>>>>> fs/nfsd/vfs.c | 4 ++--
>>>>> include/linux/nfsd/nfsd.h | 3 ++-
>>>>> 5 files changed, 31 insertions(+), 17 deletions(-)
>>>>>
>>>>> I intend to submit this for 2.6.28
>>>>>
>>>>> diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
>>>>> index 4d617ea..1419142 100644
>>>>> --- a/fs/nfsd/nfs3proc.c
>>>>> +++ b/fs/nfsd/nfs3proc.c
>>>>> @@ -530,7 +530,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>>>>> dprintk("nfsd: FSSTAT(3) %s\n",
>>>>> SVCFH_fmt(&argp->fh));
>>>>> - nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
>>>>> + nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
>>>>> fh_put(&argp->fh);
>>>>> RETURN_STATUS(nfserr);
>>>>> }
>>>>> @@ -558,7 +558,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
>>>>> resp->f_maxfilesize = ~(u32) 0;
>>>>> resp->f_properties = NFS3_FSF_DEFAULT;
>>>>> - nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
>>>>> + nfserr = fh_verify(rqstp, &argp->fh, 0,
>>>>> + NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
>>>>> /* Check special features of the file system. May request
>>>>> * different read/write sizes for file systems known to have
>>>>>
>>>>>
>>>> I would think that you might want to have nfsd3_proc_getattr()
>>>> in this list too. Some clients may need to generate a GETATTR
>>>> if they need the attributes for the root node.
>>>>
>>>>
>>> Do you know of any? rfc 2623 makes it sound like those clients are out
>>> of luck. And testing confirms that this patch is sufficient for the
>>> linux client, at least.
>>>
>> I believe that the Solaris client may. I think that it may
>> use the attributes returned from the FSINFO call, if there
>> are any, to prevent the additional GETATTR, but this should
>> be tested. It might also be interesting to test out a
>> readonly failover mount on the Solaris client to see what
>> behavior that that exhibits.
>>
>
> OK, could be. Volunteers to test that welcomed--for now I think I'll
> stick to the list in the RFC.

I think that RFC2623 doesn't quite completely describe the entire
situation. I believe that Mike Eisler probably looked to see what
traffic that a client, like Solaris, generated, using some network
analysis tool such as snoop or wireshark, when mounting a file
system from a NetApp filer or a Solaris server.

These servers return post_op_attributes with the FSINFO response.
Thus, the client does not need to generate a GETATTR call in order
to retrieve the initial attributes, or more precisely, to retrieve
the file type.

The Linux NFS server does not return post_op_attributes with the
FSINFO response. Thus, the client is forced to generate a
subsequent GETATTR call to retrieve the attributes.

A better description of the set of operations which should be
allowed and which ones are not should include a discussion on
the contents of the response to the FSINFO request. If the
server returns attributes in the FSINFO response, then it does
not need to allow unauthenticated GETATTR requests. If it does
not return attributes in the FSINFO response, then it must allow
unauthenticated GETATTR requests because this is required in
order to allow clients to successfully mount file systems using
strong authentication.

ps

2008-08-11 21:38:40

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Mon, 2008-08-11 at 17:27 -0400, Peter Staubach wrote:
> A better description of the set of operations which should be
> allowed and which ones are not should include a discussion on
> the contents of the response to the FSINFO request. If the
> server returns attributes in the FSINFO response, then it does
> not need to allow unauthenticated GETATTR requests. If it does
> not return attributes in the FSINFO response, then it must allow
> unauthenticated GETATTR requests because this is required in
> order to allow clients to successfully mount file systems using
> strong authentication.

Well... That's true for NFSv3, but if your server also supports
NFSv2-with-RPCSEC_GSS, then it also has to support the NFSv2 FSSTAT
+GETATTR under AUTH_SYS.

In any case, this is an issue of efficiency rather than security.
Whether you allow FSINFO w/ post-op attributes but no GETATTR, or you
allow FSINFO w/o post-op attributes and allow GETATTR on the mountpoint
is entirely equivalent from the security viewpoint: the amount of
information available using weak security is the same.

Cheers,
Trond


2008-08-11 21:40:38

by Peter Staubach

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

J. Bruce Fields wrote:
> On Mon, Aug 11, 2008 at 04:51:26PM -0400, Peter Staubach wrote:
>
>> The Solaris client behaves plus or minus like the Linux client.
>> It generates a GETATTR unless it receives the attributes via
>> one of the previous calls. In the Solaris case, it is an FSINFO
>> call.
>>
>> The current Linux NFS server does not return attributes for the
>> PATHCONF, FSINFO, or FSSTAT calls.
>>
>
> Hm. I don't know why that is.
>
>
>> Unless these calls are modified, then the NFSv3 GETATTR will need
>> to be allowed for the same reason that the NFSv2 GETATTR is
>> allowed. The NFS client needs, at the very least, the file type
>> of the node that it is mounting.
>>
>> I am confused as to how the testing could have been successful.
>>
>
> Well, you can try exporting a filesystem with sec=krb5:krb5i:krb5p (no
> sys) and try mounting v2 or v3, and you'll see that if fails without the
> patch, and succeeds with it.
>
> But testing again (linux client and server), and taking a network trace
> this time: I mount with -overs=3,sec=krb5, and the client behavior is
> odd:
>
> FSINFO call with auth_sys
> GETATTR call with krb5
> FSINFO call with krb5
>
> Note that this client actually *does* have access to kerberos
> credentials--it's just not using them on the initial FSINFO call.
>
>

What happens if you perform this mount using autofs?

Thanx...

ps

> That could make some sense if it was trying to ensure the mount will
> succeed in the absence of kerberos credentials, and doesn't want to
> bother first trying to get a credentials and then falling back on
> auth_sys if it doesn't find them.
>
> But currently it fails if the server requests auth_sys on the initial
> FSINFO *or* if it fails to get kerberos credentials for those second two
> rpc calls. Something similar seems to be true for v2. Huh.
>
> Anyway, so in the Solaris v3 case I take it that what you're seeing is
> FSINFO, GETATTR, both done with auth_sys, and a failure of the mount
> command if both aren't permitted?
>
> OK, so I agree the server should either permit v3 GETATTR (trivial, if
> arguably contrary to rfc 2623) or add attributes to FSINFO (which I
> assume is also easy, but I don't know why it was left out before).
> Seems the client needs some looking at too.
>
> --b.
>


2008-08-11 22:11:50

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Mon, Aug 11, 2008 at 05:29:41PM -0400, Peter Staubach wrote:
> J. Bruce Fields wrote:
>> On Mon, Aug 11, 2008 at 04:51:26PM -0400, Peter Staubach wrote:
>>
>>> The Solaris client behaves plus or minus like the Linux client.
>>> It generates a GETATTR unless it receives the attributes via
>>> one of the previous calls. In the Solaris case, it is an FSINFO
>>> call.
>>>
>>> The current Linux NFS server does not return attributes for the
>>> PATHCONF, FSINFO, or FSSTAT calls.
>>>
>>
>> Hm. I don't know why that is.
>>
>>
>>> Unless these calls are modified, then the NFSv3 GETATTR will need
>>> to be allowed for the same reason that the NFSv2 GETATTR is
>>> allowed. The NFS client needs, at the very least, the file type
>>> of the node that it is mounting.
>>>
>>> I am confused as to how the testing could have been successful.
>>>
>>
>> Well, you can try exporting a filesystem with sec=krb5:krb5i:krb5p (no
>> sys) and try mounting v2 or v3, and you'll see that if fails without the
>> patch, and succeeds with it.
>>
>> But testing again (linux client and server), and taking a network trace
>> this time: I mount with -overs=3,sec=krb5, and the client behavior is
>> odd:
>>
>> FSINFO call with auth_sys
>> GETATTR call with krb5
>> FSINFO call with krb5
>>
>> Note that this client actually *does* have access to kerberos
>> credentials--it's just not using them on the initial FSINFO call.
>>
>>
>
> What happens if you perform this mount using autofs?

I haven't tried yet.

--b.

2008-08-12 15:43:21

by J. Bruce Fields

[permalink] [raw]
Subject: Re: [PATCH] nfsd: permit unauthenticated stat of export root

On Mon, Aug 11, 2008 at 05:38:31PM -0400, Trond Myklebust wrote:
> On Mon, 2008-08-11 at 17:27 -0400, Peter Staubach wrote:
> > A better description of the set of operations which should be
> > allowed and which ones are not should include a discussion on
> > the contents of the response to the FSINFO request. If the
> > server returns attributes in the FSINFO response, then it does
> > not need to allow unauthenticated GETATTR requests. If it does
> > not return attributes in the FSINFO response, then it must allow
> > unauthenticated GETATTR requests because this is required in
> > order to allow clients to successfully mount file systems using
> > strong authentication.
>
> Well... That's true for NFSv3, but if your server also supports
> NFSv2-with-RPCSEC_GSS, then it also has to support the NFSv2 FSSTAT
> +GETATTR under AUTH_SYS.
>
> In any case, this is an issue of efficiency rather than security.
> Whether you allow FSINFO w/ post-op attributes but no GETATTR, or you
> allow FSINFO w/o post-op attributes and allow GETATTR on the mountpoint
> is entirely equivalent from the security viewpoint: the amount of
> information available using weak security is the same.

That makes sense, thanks. (And thanks to Peter for the testing!)

So for now I'd like to just do the easy thing and add the v3 getattr to
the list of operations that don't require gss on the export root.

Still todo:

- Test behavior with automount
- Consider adding attributes to the return from fsinfo,
pathconf, and fsstat.
- Look at client code to figure out why it's still requiring a
krb5 cred on mount.

But I don't know when I'll get to these, so if someone else is
interested, please go ahead and let us know what you find out....

--b.

commit ca80290ebda9009aedc4bd93ede5d397cb1853dc
Author: J. Bruce Fields <[email protected]>
Date: Thu Aug 7 13:00:20 2008 -0400

nfsd: permit unauthenticated stat of export root

RFC 2623 section 2.3.2 permits the server to bypass gss authentication
checks for certain operations that a client may perform when mounting.
In the case of a client that doesn't have some form of credentials
available to it on boot, this allows it to perform the mount unattended.
(Presumably real file access won't be needed until a user with
credentials logs in.)

Being slightly more lenient allows lots of old clients to access
krb5-only exports, with the only loss being a small amount of
information leaked about the root directory of the export.

This affects only v2 and v3; v4 still requires authentication for all
access.

Thanks to Peter Staubach testing against a Solaris client, which
suggesting addition of v3 getattr, to the list, and to Trond for noting
that doing so exposes no additional information.

Signed-off-by: J. Bruce Fields <[email protected]>
Cc: Peter Staubach <[email protected]>
Cc: Trond Myklebust <[email protected]>

diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 4d617ea..9dbd2eb 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -63,7 +63,8 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
SVCFH_fmt(&argp->fh));

fh_copy(&resp->fh, &argp->fh);
- nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP);
+ nfserr = fh_verify(rqstp, &resp->fh, 0,
+ NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
if (nfserr)
RETURN_STATUS(nfserr);

@@ -530,7 +531,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
dprintk("nfsd: FSSTAT(3) %s\n",
SVCFH_fmt(&argp->fh));

- nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+ nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
fh_put(&argp->fh);
RETURN_STATUS(nfserr);
}
@@ -558,7 +559,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
resp->f_maxfilesize = ~(u32) 0;
resp->f_properties = NFS3_FSF_DEFAULT;

- nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
+ nfserr = fh_verify(rqstp, &argp->fh, 0,
+ NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);

/* Check special features of the file system. May request
* different read/write sizes for file systems known to have
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index f45451e..7c6847e 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -302,17 +302,27 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
if (error)
goto out;

- if (!(access & NFSD_MAY_LOCK)) {
- /*
- * pseudoflavor restrictions are not enforced on NLM,
- * which clients virtually always use auth_sys for,
- * even while using RPCSEC_GSS for NFS.
- */
- error = check_nfsd_access(exp, rqstp);
- if (error)
- goto out;
- }
+ /*
+ * pseudoflavor restrictions are not enforced on NLM,
+ * which clients virtually always use auth_sys for,
+ * even while using RPCSEC_GSS for NFS.
+ */
+ if (access & NFSD_MAY_LOCK)
+ goto skip_pseudoflavor_check;
+ /*
+ * Clients may expect to be able to use auth_sys during mount,
+ * even if they use gss for everything else; see section 2.3.2
+ * of rfc 2623.
+ */
+ if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT
+ && exp->ex_path.dentry == dentry)
+ goto skip_pseudoflavor_check;
+
+ error = check_nfsd_access(exp, rqstp);
+ if (error)
+ goto out;

+skip_pseudoflavor_check:
/* Finally, check access permissions. */
error = nfsd_permission(rqstp, exp, dentry, access);

diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 0766f95..5cffeca 100644
--- a/fs/nfsd/nfsproc.c
+++ b/fs/nfsd/nfsproc.c
@@ -65,7 +65,8 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp,
dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));

fh_copy(&resp->fh, &argp->fh);
- nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP);
+ nfserr = fh_verify(rqstp, &resp->fh, 0,
+ NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
return nfsd_return_attrs(nfserr, resp);
}

@@ -521,7 +522,8 @@ nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,

dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));

- nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+ nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats,
+ NFSD_MAY_BYPASS_GSS_ON_ROOT);
fh_put(&argp->fh);
return nfserr;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0f4481e..f51bdf6 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1872,9 +1872,9 @@ out:
* N.B. After this call fhp needs an fh_put
*/
__be32
-nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat)
+nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access)
{
- __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
+ __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access);
if (!err && vfs_statfs(fhp->fh_dentry,stat))
err = nfserr_io;
return err;
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
index a2861d9..47bea82 100644
--- a/include/linux/nfsd/nfsd.h
+++ b/include/linux/nfsd/nfsd.h
@@ -39,6 +39,7 @@
#define NFSD_MAY_LOCK 32
#define NFSD_MAY_OWNER_OVERRIDE 64
#define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/
+#define NFSD_MAY_BYPASS_GSS_ON_ROOT 256

#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
#define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
@@ -126,7 +127,7 @@ int nfsd_truncate(struct svc_rqst *, struct svc_fh *,
__be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
loff_t *, struct readdir_cd *, filldir_t);
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
- struct kstatfs *);
+ struct kstatfs *, int access);

int nfsd_notify_change(struct inode *, struct iattr *);
__be32 nfsd_permission(struct svc_rqst *, struct svc_export *,