aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-08-21 12:48:30 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-10-01 17:39:14 -0400
commit68eb35081e297b37db49d854cda144c6a3397699 (patch)
treeb71fff7512d2ed12fec10bb15cc2aed2a6637f99 /fs
parent6e67b5d1840b5788875ad561f2e76a1bf5facc86 (diff)
nfsd4: don't pin clientids to pseudoflavors
I added cr_flavor to the data compared in same_creds without any justification, in d5497fc693a446ce9100fcf4117c3f795ddfd0d2 "nfsd4: move rq_flavor into svc_cred". Recent client changes then started making mount -osec=krb5 server:/export /mnt/ echo "hello" >/mnt/TMP umount /mnt/ mount -osec=krb5i server:/export /mnt/ echo "hello" >/mnt/TMP to fail due to a clid_inuse on the second open. Mounting sequentially like this with different flavors probably isn't that common outside artificial tests. Also, the real bug here may be that the server isn't just destroying the former clientid in this case (because it isn't good enough at recognizing when the old state is gone). But it prompted some discussion and a look back at the spec, and I think the check was probably wrong. Fix and document. Cc: stable@kernel.org Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs4state.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 5122e1704cd4..0f8d7e7922eb 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1223,10 +1223,26 @@ static bool groups_equal(struct group_info *g1, struct group_info *g2)
1223 return true; 1223 return true;
1224} 1224}
1225 1225
1226/*
1227 * RFC 3530 language requires clid_inuse be returned when the
1228 * "principal" associated with a requests differs from that previously
1229 * used. We use uid, gid's, and gss principal string as our best
1230 * approximation. We also don't want to allow non-gss use of a client
1231 * established using gss: in theory cr_principal should catch that
1232 * change, but in practice cr_principal can be null even in the gss case
1233 * since gssd doesn't always pass down a principal string.
1234 */
1235static bool is_gss_cred(struct svc_cred *cr)
1236{
1237 /* Is cr_flavor one of the gss "pseudoflavors"?: */
1238 return (cr->cr_flavor > RPC_AUTH_MAXFLAVOR);
1239}
1240
1241
1226static bool 1242static bool
1227same_creds(struct svc_cred *cr1, struct svc_cred *cr2) 1243same_creds(struct svc_cred *cr1, struct svc_cred *cr2)
1228{ 1244{
1229 if ((cr1->cr_flavor != cr2->cr_flavor) 1245 if ((is_gss_cred(cr1) != is_gss_cred(cr2))
1230 || (cr1->cr_uid != cr2->cr_uid) 1246 || (cr1->cr_uid != cr2->cr_uid)
1231 || (cr1->cr_gid != cr2->cr_gid) 1247 || (cr1->cr_gid != cr2->cr_gid)
1232 || !groups_equal(cr1->cr_group_info, cr2->cr_group_info)) 1248 || !groups_equal(cr1->cr_group_info, cr2->cr_group_info))