aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorAndrew Elble <aweits@rit.edu>2016-06-15 12:52:09 -0400
committerJ. Bruce Fields <bfields@redhat.com>2016-07-13 15:32:47 -0400
commited94164398c935a42be7b129a478eb19c598b68a (patch)
tree54e540b879c62b023ff3d0f93ad537209bdf3ff4 /fs/nfsd/nfs4state.c
parentdedeb13f9efb4439a37cf56317c8f25860dd667b (diff)
nfsd: implement machine credential support for some operations
This addresses the conundrum referenced in RFC5661 18.35.3, and will allow clients to return state to the server using the machine credentials. The biggest part of the problem is that we need to allow the client to send a compound op with integrity/privacy on mounts that don't have it enabled. Add server support for properly decoding and using spo_must_enforce and spo_must_allow bits. Add support for machine credentials to be used for CLOSE, OPEN_DOWNGRADE, LOCKU, DELEGRETURN, and TEST/FREE STATEID. Implement a check so as to not throw WRONGSEC errors when these operations are used if integrity/privacy isn't turned on. Without this, Linux clients with credentials that expired while holding delegations were getting stuck in an endless loop. Signed-off-by: Andrew Elble <aweits@rit.edu> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index ef583507d276..ebfcebd5eab1 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2388,6 +2388,22 @@ nfsd4_exchange_id(struct svc_rqst *rqstp,
2388 2388
2389 switch (exid->spa_how) { 2389 switch (exid->spa_how) {
2390 case SP4_MACH_CRED: 2390 case SP4_MACH_CRED:
2391 exid->spo_must_enforce[0] = 0;
2392 exid->spo_must_enforce[1] = (
2393 1 << (OP_BIND_CONN_TO_SESSION - 32) |
2394 1 << (OP_EXCHANGE_ID - 32) |
2395 1 << (OP_CREATE_SESSION - 32) |
2396 1 << (OP_DESTROY_SESSION - 32) |
2397 1 << (OP_DESTROY_CLIENTID - 32));
2398
2399 exid->spo_must_allow[0] &= (1 << (OP_CLOSE) |
2400 1 << (OP_OPEN_DOWNGRADE) |
2401 1 << (OP_LOCKU) |
2402 1 << (OP_DELEGRETURN));
2403
2404 exid->spo_must_allow[1] &= (
2405 1 << (OP_TEST_STATEID - 32) |
2406 1 << (OP_FREE_STATEID - 32));
2391 if (!svc_rqst_integrity_protected(rqstp)) { 2407 if (!svc_rqst_integrity_protected(rqstp)) {
2392 status = nfserr_inval; 2408 status = nfserr_inval;
2393 goto out_nolock; 2409 goto out_nolock;
@@ -2473,6 +2489,8 @@ out_new:
2473 goto out; 2489 goto out;
2474 } 2490 }
2475 new->cl_minorversion = cstate->minorversion; 2491 new->cl_minorversion = cstate->minorversion;
2492 new->cl_spo_must_allow.u.words[0] = exid->spo_must_allow[0];
2493 new->cl_spo_must_allow.u.words[1] = exid->spo_must_allow[1];
2476 2494
2477 gen_clid(new, nn); 2495 gen_clid(new, nn);
2478 add_to_unconfirmed(new); 2496 add_to_unconfirmed(new);