aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 5122e1704cd..0f8d7e7922e 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))