aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2015-10-15 15:33:23 -0400
committerJ. Bruce Fields <bfields@redhat.com>2015-10-23 15:57:30 -0400
commit2b63482185e6054cc11ca6d6c073f90160c161fd (patch)
tree82c4dda36d1c0cdb6b64c5c7d90793727a9c3c9f /fs/nfsd/nfs4state.c
parent778620364ef525e83597a6edee4d0a69db67fd3d (diff)
nfsd: fix clid_inuse on mount with security change
In bakeathon testing Solaris client was getting CLID_INUSE error when doing a krb5 mount soon after an auth_sys mount, or vice versa. That's not really necessary since in this case the old client doesn't have any state any more: http://tools.ietf.org/html/rfc7530#page-103 "when the server gets a SETCLIENTID for a client ID that currently has no state, or it has state but the lease has expired, rather than returning NFS4ERR_CLID_INUSE, the server MUST allow the SETCLIENTID and confirm the new client ID if followed by the appropriate SETCLIENTID_CONFIRM." This doesn't fix the problem completely since our client_has_state() check counts openowners left around to handle close replays, which we should probably just remove in this case. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 1b39edf10b67..bac6207191d5 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -2262,7 +2262,8 @@ static bool client_has_state(struct nfs4_client *clp)
2262 * Note clp->cl_openowners check isn't quite right: there's no 2262 * Note clp->cl_openowners check isn't quite right: there's no
2263 * need to count owners without stateid's. 2263 * need to count owners without stateid's.
2264 * 2264 *
2265 * Also note we should probably be using this in 4.0 case too. 2265 * Also note in 4.0 case should also be checking for openowners
2266 * kept around just for close handling.
2266 */ 2267 */
2267 return !list_empty(&clp->cl_openowners) 2268 return !list_empty(&clp->cl_openowners)
2268#ifdef CONFIG_NFSD_PNFS 2269#ifdef CONFIG_NFSD_PNFS
@@ -3049,7 +3050,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
3049 /* Cases below refer to rfc 3530 section 14.2.33: */ 3050 /* Cases below refer to rfc 3530 section 14.2.33: */
3050 spin_lock(&nn->client_lock); 3051 spin_lock(&nn->client_lock);
3051 conf = find_confirmed_client_by_name(&clname, nn); 3052 conf = find_confirmed_client_by_name(&clname, nn);
3052 if (conf) { 3053 if (conf && client_has_state(conf)) {
3053 /* case 0: */ 3054 /* case 0: */
3054 status = nfserr_clid_inuse; 3055 status = nfserr_clid_inuse;
3055 if (clp_used_exchangeid(conf)) 3056 if (clp_used_exchangeid(conf))
@@ -3136,6 +3137,11 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp,
3136 } else { /* case 3: normal case; new or rebooted client */ 3137 } else { /* case 3: normal case; new or rebooted client */
3137 old = find_confirmed_client_by_name(&unconf->cl_name, nn); 3138 old = find_confirmed_client_by_name(&unconf->cl_name, nn);
3138 if (old) { 3139 if (old) {
3140 status = nfserr_clid_inuse;
3141 if (client_has_state(old)
3142 && !same_creds(&unconf->cl_cred,
3143 &old->cl_cred))
3144 goto out;
3139 status = mark_client_expired_locked(old); 3145 status = mark_client_expired_locked(old);
3140 if (status) { 3146 if (status) {
3141 old = NULL; 3147 old = NULL;