diff options
author | J. Bruce Fields <bfields@redhat.com> | 2015-11-20 10:48:02 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2015-11-24 13:36:31 -0500 |
commit | 414ca017a54d26c3a58ed1504884e51448d22ae1 (patch) | |
tree | e76eb79e0573b50eed71b8fe5a20696f702fde82 /fs/nfsd | |
parent | 920dd9bb7d7cf9ae339e15240326a28a22f08a74 (diff) |
nfsd4: fix gss-proxy 4.1 mounts for some AD principals
The principal name on a gss cred is used to setup the NFSv4.0 callback,
which has to have a client principal name to authenticate to.
That code wants the name to be in the form servicetype@hostname.
rpc.svcgssd passes down such names (and passes down no principal name at
all in the case the principal isn't a service principal).
gss-proxy always passes down the principal name, and passes it down in
the form servicetype/hostname@REALM. So we've been munging the name
gss-proxy passes down into the format the NFSv4.0 callback code expects,
or throwing away the name if we can't.
Since the introduction of the MACH_CRED enforcement in NFSv4.1, we've
also been using the principal name to verify that certain operations are
done as the same principal as was used on the original EXCHANGE_ID call.
For that application, the original name passed down by gss-proxy is also
useful.
Lack of that name in some cases was causing some kerberized NFSv4.1
mount failures in an Active Directory environment.
This fix only works in the gss-proxy case. The fix for legacy
rpc.svcgssd would be more involved, and rpc.svcgssd already has other
problems in the AD case.
Reported-and-tested-by: James Ralston <ralston@pobox.com>
Acked-by: Simo Sorce <simo@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4state.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ed58ced6fa8b..113ecbfac25c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1875,6 +1875,10 @@ static int copy_cred(struct svc_cred *target, struct svc_cred *source) | |||
1875 | ret = strdup_if_nonnull(&target->cr_principal, source->cr_principal); | 1875 | ret = strdup_if_nonnull(&target->cr_principal, source->cr_principal); |
1876 | if (ret) | 1876 | if (ret) |
1877 | return ret; | 1877 | return ret; |
1878 | ret = strdup_if_nonnull(&target->cr_raw_principal, | ||
1879 | source->cr_raw_principal); | ||
1880 | if (ret) | ||
1881 | return ret; | ||
1878 | target->cr_flavor = source->cr_flavor; | 1882 | target->cr_flavor = source->cr_flavor; |
1879 | target->cr_uid = source->cr_uid; | 1883 | target->cr_uid = source->cr_uid; |
1880 | target->cr_gid = source->cr_gid; | 1884 | target->cr_gid = source->cr_gid; |
@@ -1978,6 +1982,9 @@ static bool mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp) | |||
1978 | return false; | 1982 | return false; |
1979 | if (!svc_rqst_integrity_protected(rqstp)) | 1983 | if (!svc_rqst_integrity_protected(rqstp)) |
1980 | return false; | 1984 | return false; |
1985 | if (cl->cl_cred.cr_raw_principal) | ||
1986 | return 0 == strcmp(cl->cl_cred.cr_raw_principal, | ||
1987 | cr->cr_raw_principal); | ||
1981 | if (!cr->cr_principal) | 1988 | if (!cr->cr_principal) |
1982 | return false; | 1989 | return false; |
1983 | return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal); | 1990 | return 0 == strcmp(cl->cl_cred.cr_principal, cr->cr_principal); |
@@ -2390,7 +2397,8 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, | |||
2390 | * Which is a bug, really. Anyway, we can't enforce | 2397 | * Which is a bug, really. Anyway, we can't enforce |
2391 | * MACH_CRED in that case, better to give up now: | 2398 | * MACH_CRED in that case, better to give up now: |
2392 | */ | 2399 | */ |
2393 | if (!new->cl_cred.cr_principal) { | 2400 | if (!new->cl_cred.cr_principal && |
2401 | !new->cl_cred.cr_raw_principal) { | ||
2394 | status = nfserr_serverfault; | 2402 | status = nfserr_serverfault; |
2395 | goto out_nolock; | 2403 | goto out_nolock; |
2396 | } | 2404 | } |