aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2008-08-07 13:00:20 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-09-29 17:56:56 -0400
commit04716e6621ff4abb422d64ba7b48718f52716a3e (patch)
tree742e2e7b6d4c7cf3a39f504000a49e57fe0b538b /fs/nfsd
parent5dd248f6f1ffe1f691fd66749e2a3dc8f8eb7b5e (diff)
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 <bfields@citi.umich.edu> Cc: Peter Staubach <staubach@redhat.com> Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs3proc.c8
-rw-r--r--fs/nfsd/nfsfh.c30
-rw-r--r--fs/nfsd/nfsproc.c6
-rw-r--r--fs/nfsd/vfs.c4
4 files changed, 31 insertions, 17 deletions
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 4d617ea28cfc..9dbd2eb91281 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,
63 SVCFH_fmt(&argp->fh)); 63 SVCFH_fmt(&argp->fh));
64 64
65 fh_copy(&resp->fh, &argp->fh); 65 fh_copy(&resp->fh, &argp->fh);
66 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); 66 nfserr = fh_verify(rqstp, &resp->fh, 0,
67 NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
67 if (nfserr) 68 if (nfserr)
68 RETURN_STATUS(nfserr); 69 RETURN_STATUS(nfserr);
69 70
@@ -530,7 +531,7 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
530 dprintk("nfsd: FSSTAT(3) %s\n", 531 dprintk("nfsd: FSSTAT(3) %s\n",
531 SVCFH_fmt(&argp->fh)); 532 SVCFH_fmt(&argp->fh));
532 533
533 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats); 534 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
534 fh_put(&argp->fh); 535 fh_put(&argp->fh);
535 RETURN_STATUS(nfserr); 536 RETURN_STATUS(nfserr);
536} 537}
@@ -558,7 +559,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
558 resp->f_maxfilesize = ~(u32) 0; 559 resp->f_maxfilesize = ~(u32) 0;
559 resp->f_properties = NFS3_FSF_DEFAULT; 560 resp->f_properties = NFS3_FSF_DEFAULT;
560 561
561 nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP); 562 nfserr = fh_verify(rqstp, &argp->fh, 0,
563 NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
562 564
563 /* Check special features of the file system. May request 565 /* Check special features of the file system. May request
564 * different read/write sizes for file systems known to have 566 * different read/write sizes for file systems known to have
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index ea37c96f0445..cd25d91895a1 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)
302 if (error) 302 if (error)
303 goto out; 303 goto out;
304 304
305 if (!(access & NFSD_MAY_LOCK)) { 305 /*
306 /* 306 * pseudoflavor restrictions are not enforced on NLM,
307 * pseudoflavor restrictions are not enforced on NLM, 307 * which clients virtually always use auth_sys for,
308 * which clients virtually always use auth_sys for, 308 * even while using RPCSEC_GSS for NFS.
309 * even while using RPCSEC_GSS for NFS. 309 */
310 */ 310 if (access & NFSD_MAY_LOCK)
311 error = check_nfsd_access(exp, rqstp); 311 goto skip_pseudoflavor_check;
312 if (error) 312 /*
313 goto out; 313 * Clients may expect to be able to use auth_sys during mount,
314 } 314 * even if they use gss for everything else; see section 2.3.2
315 * of rfc 2623.
316 */
317 if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT
318 && exp->ex_path.dentry == dentry)
319 goto skip_pseudoflavor_check;
320
321 error = check_nfsd_access(exp, rqstp);
322 if (error)
323 goto out;
315 324
325skip_pseudoflavor_check:
316 /* Finally, check access permissions. */ 326 /* Finally, check access permissions. */
317 error = nfsd_permission(rqstp, exp, dentry, access); 327 error = nfsd_permission(rqstp, exp, dentry, access);
318 328
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
index 0766f95d236a..5cffeca7acef 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,
65 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); 65 dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh));
66 66
67 fh_copy(&resp->fh, &argp->fh); 67 fh_copy(&resp->fh, &argp->fh);
68 nfserr = fh_verify(rqstp, &resp->fh, 0, NFSD_MAY_NOP); 68 nfserr = fh_verify(rqstp, &resp->fh, 0,
69 NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
69 return nfsd_return_attrs(nfserr, resp); 70 return nfsd_return_attrs(nfserr, resp);
70} 71}
71 72
@@ -521,7 +522,8 @@ nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp,
521 522
522 dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh)); 523 dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh));
523 524
524 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats); 525 nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats,
526 NFSD_MAY_BYPASS_GSS_ON_ROOT);
525 fh_put(&argp->fh); 527 fh_put(&argp->fh);
526 return nfserr; 528 return nfserr;
527} 529}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 18060bed5267..1319e8027d55 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1866,9 +1866,9 @@ out:
1866 * N.B. After this call fhp needs an fh_put 1866 * N.B. After this call fhp needs an fh_put
1867 */ 1867 */
1868__be32 1868__be32
1869nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat) 1869nfsd_statfs(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kstatfs *stat, int access)
1870{ 1870{
1871 __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP); 1871 __be32 err = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP | access);
1872 if (!err && vfs_statfs(fhp->fh_dentry,stat)) 1872 if (!err && vfs_statfs(fhp->fh_dentry,stat))
1873 err = nfserr_io; 1873 err = nfserr_io;
1874 return err; 1874 return err;