diff options
-rw-r--r-- | fs/nfsd/nfs4state.c | 18 |
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 | */ | ||
1235 | static 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 | |||
1226 | static bool | 1242 | static bool |
1227 | same_creds(struct svc_cred *cr1, struct svc_cred *cr2) | 1243 | same_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)) |