diff options
author | J. Bruce Fields <bfields@redhat.com> | 2012-05-19 10:05:58 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2012-05-31 20:30:04 -0400 |
commit | 8695b90ac3c37278010c76ab3680f35ab358caf9 (patch) | |
tree | 6376644c7d8f6c0c36874c0388400dc5f1e41fac /fs/nfsd/nfs4state.c | |
parent | 788c1eba50133777df5ca2972cda3c9a8f78f52f (diff) |
nfsd4: fix error return in non-matching-creds case
Note CLID_INUSE is for the case where two clients are trying to use the
same client-provided long-form client identifiers. But what we're
looking at here is the server-returned shorthand client id--if those
clash there's a bug somewhere.
Fix the error return, pull the check out into common code, and do the
check unconditionally in all cases.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 62 |
1 files changed, 26 insertions, 36 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0f108f68da77..8a1dfb20a3de 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2229,59 +2229,49 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | |||
2229 | 2229 | ||
2230 | if (STALE_CLIENTID(clid)) | 2230 | if (STALE_CLIENTID(clid)) |
2231 | return nfserr_stale_clientid; | 2231 | return nfserr_stale_clientid; |
2232 | /* | ||
2233 | * XXX The Duplicate Request Cache (DRC) has been checked (??) | ||
2234 | * We get here on a DRC miss. | ||
2235 | */ | ||
2236 | |||
2237 | nfs4_lock_state(); | 2232 | nfs4_lock_state(); |
2238 | 2233 | ||
2239 | conf = find_confirmed_client(clid); | 2234 | conf = find_confirmed_client(clid); |
2240 | unconf = find_unconfirmed_client(clid); | 2235 | unconf = find_unconfirmed_client(clid); |
2241 | 2236 | /* | |
2237 | * We try hard to give out unique clientid's, so if we get an | ||
2238 | * attempt to confirm the same clientid with a different cred, | ||
2239 | * there's a bug somewhere. Let's charitably assume it's our | ||
2240 | * bug. | ||
2241 | */ | ||
2242 | status = nfserr_serverfault; | ||
2243 | if (unconf && !same_creds(&unconf->cl_cred, &rqstp->rq_cred)) | ||
2244 | goto out; | ||
2245 | if (conf && !same_creds(&conf->cl_cred, &rqstp->rq_cred)) | ||
2246 | goto out; | ||
2242 | /* cases below refer to rfc 3530 section 14.2.34: */ | 2247 | /* cases below refer to rfc 3530 section 14.2.34: */ |
2243 | status = nfserr_clid_inuse; | ||
2244 | if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) { | 2248 | if (conf && unconf && same_verf(&confirm, &unconf->cl_confirm)) { |
2245 | /* case 1: callback update */ | 2249 | /* case 1: callback update */ |
2246 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) | 2250 | nfsd4_change_callback(conf, &unconf->cl_cb_conn); |
2247 | status = nfserr_clid_inuse; | 2251 | nfsd4_probe_callback(conf); |
2248 | else { | 2252 | expire_client(unconf); |
2249 | nfsd4_change_callback(conf, &unconf->cl_cb_conn); | 2253 | status = nfs_ok; |
2250 | nfsd4_probe_callback(conf); | ||
2251 | expire_client(unconf); | ||
2252 | status = nfs_ok; | ||
2253 | } | ||
2254 | } else if (conf && !unconf) { | 2254 | } else if (conf && !unconf) { |
2255 | /* case 2: probable retransmit: */ | 2255 | status = nfs_ok; |
2256 | if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) | ||
2257 | status = nfserr_clid_inuse; | ||
2258 | else | ||
2259 | status = nfs_ok; | ||
2260 | } else if (!conf && unconf | 2256 | } else if (!conf && unconf |
2261 | && same_verf(&unconf->cl_confirm, &confirm)) { | 2257 | && same_verf(&unconf->cl_confirm, &confirm)) { |
2262 | /* case 3: normal case; new or rebooted client */ | 2258 | /* case 3: normal case; new or rebooted client */ |
2263 | if (!same_creds(&unconf->cl_cred, &rqstp->rq_cred)) { | 2259 | unsigned int hash = clientstr_hashval(unconf->cl_recdir); |
2264 | status = nfserr_clid_inuse; | 2260 | conf = find_confirmed_client_by_str(unconf->cl_recdir, hash); |
2265 | } else { | 2261 | if (conf) { |
2266 | unsigned int hash = | 2262 | nfsd4_client_record_remove(conf); |
2267 | clientstr_hashval(unconf->cl_recdir); | 2263 | expire_client(conf); |
2268 | conf = find_confirmed_client_by_str(unconf->cl_recdir, | ||
2269 | hash); | ||
2270 | if (conf) { | ||
2271 | nfsd4_client_record_remove(conf); | ||
2272 | expire_client(conf); | ||
2273 | } | ||
2274 | move_to_confirmed(unconf); | ||
2275 | conf = unconf; | ||
2276 | nfsd4_probe_callback(conf); | ||
2277 | status = nfs_ok; | ||
2278 | } | 2264 | } |
2265 | move_to_confirmed(unconf); | ||
2266 | conf = unconf; | ||
2267 | nfsd4_probe_callback(conf); | ||
2268 | status = nfs_ok; | ||
2279 | } else if ((!conf || !same_verf(&conf->cl_confirm, &confirm)) | 2269 | } else if ((!conf || !same_verf(&conf->cl_confirm, &confirm)) |
2280 | && (!unconf || !same_verf(&unconf->cl_confirm, &confirm))) { | 2270 | && (!unconf || !same_verf(&unconf->cl_confirm, &confirm))) { |
2281 | /* case 4: client hasn't noticed we rebooted yet? */ | 2271 | /* case 4: client hasn't noticed we rebooted yet? */ |
2282 | status = nfserr_stale_clientid; | 2272 | status = nfserr_stale_clientid; |
2283 | } | 2273 | } |
2284 | 2274 | out: | |
2285 | nfs4_unlock_state(); | 2275 | nfs4_unlock_state(); |
2286 | return status; | 2276 | return status; |
2287 | } | 2277 | } |