aboutsummaryrefslogtreecommitdiffstats
path: root/net/sunrpc/auth_gss
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2013-03-16 15:55:01 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-03-29 15:43:24 -0400
commit83523d083a045a2069e5f3443d2e4f810a6e6d9a (patch)
treee09dba12aaa71997d1ebe1913ddf6a3f9d5f55cb /net/sunrpc/auth_gss
parentf783288f0cf47f1988f5284c89e325bd22c74f91 (diff)
SUNRPC: Consider qop when looking up pseudoflavors
The NFSv4 SECINFO operation returns a list of security flavors that the server supports for a particular share. An NFSv4 client is supposed to pick a pseudoflavor it supports that corresponds to one of the flavors returned by the server. GSS flavors in this list have a GSS tuple that identify a specific GSS pseudoflavor. Currently our client ignores the GSS tuple's "qop" value. A matching pseudoflavor is chosen based only on the OID and service value. So far this omission has not had much effect on Linux. The NFSv4 protocol currently supports only one qop value: GSS_C_QOP_DEFAULT, also known as zero. However, if an NFSv4 server happens to return something other than zero in the qop field, our client won't notice. This could cause the client to behave in incorrect ways that could have security implications. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'net/sunrpc/auth_gss')
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c3
-rw-r--r--net/sunrpc/auth_gss/gss_mech_switch.c20
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c4
3 files changed, 20 insertions, 7 deletions
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index b822ec5cdc58..33255ff889c0 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -729,16 +729,19 @@ static const struct gss_api_ops gss_kerberos_ops = {
729static struct pf_desc gss_kerberos_pfs[] = { 729static struct pf_desc gss_kerberos_pfs[] = {
730 [0] = { 730 [0] = {
731 .pseudoflavor = RPC_AUTH_GSS_KRB5, 731 .pseudoflavor = RPC_AUTH_GSS_KRB5,
732 .qop = GSS_C_QOP_DEFAULT,
732 .service = RPC_GSS_SVC_NONE, 733 .service = RPC_GSS_SVC_NONE,
733 .name = "krb5", 734 .name = "krb5",
734 }, 735 },
735 [1] = { 736 [1] = {
736 .pseudoflavor = RPC_AUTH_GSS_KRB5I, 737 .pseudoflavor = RPC_AUTH_GSS_KRB5I,
738 .qop = GSS_C_QOP_DEFAULT,
737 .service = RPC_GSS_SVC_INTEGRITY, 739 .service = RPC_GSS_SVC_INTEGRITY,
738 .name = "krb5i", 740 .name = "krb5i",
739 }, 741 },
740 [2] = { 742 [2] = {
741 .pseudoflavor = RPC_AUTH_GSS_KRB5P, 743 .pseudoflavor = RPC_AUTH_GSS_KRB5P,
744 .qop = GSS_C_QOP_DEFAULT,
742 .service = RPC_GSS_SVC_PRIVACY, 745 .service = RPC_GSS_SVC_PRIVACY,
743 .name = "krb5p", 746 .name = "krb5p",
744 }, 747 },
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
index 92a72404e6d5..81fb6f3e2424 100644
--- a/net/sunrpc/auth_gss/gss_mech_switch.c
+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
@@ -271,19 +271,27 @@ int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size)
271 return i; 271 return i;
272} 272}
273 273
274u32 274/**
275gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service) 275 * gss_svc_to_pseudoflavor - map a GSS service number to a pseudoflavor
276 * @gm: GSS mechanism handle
277 * @qop: GSS quality-of-protection value
278 * @service: GSS service value
279 *
280 * Returns a matching security flavor, or RPC_AUTH_MAXFLAVOR if none is found.
281 */
282rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 qop,
283 u32 service)
276{ 284{
277 int i; 285 int i;
278 286
279 for (i = 0; i < gm->gm_pf_num; i++) { 287 for (i = 0; i < gm->gm_pf_num; i++) {
280 if (gm->gm_pfs[i].service == service) { 288 if (gm->gm_pfs[i].qop == qop &&
289 gm->gm_pfs[i].service == service) {
281 return gm->gm_pfs[i].pseudoflavor; 290 return gm->gm_pfs[i].pseudoflavor;
282 } 291 }
283 } 292 }
284 return RPC_AUTH_MAXFLAVOR; /* illegal value */ 293 return RPC_AUTH_MAXFLAVOR;
285} 294}
286EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor);
287 295
288/** 296/**
289 * gss_mech_info2flavor - look up a pseudoflavor given a GSS tuple 297 * gss_mech_info2flavor - look up a pseudoflavor given a GSS tuple
@@ -301,7 +309,7 @@ rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *info)
301 if (gm == NULL) 309 if (gm == NULL)
302 return RPC_AUTH_MAXFLAVOR; 310 return RPC_AUTH_MAXFLAVOR;
303 311
304 pseudoflavor = gss_svc_to_pseudoflavor(gm, info->service); 312 pseudoflavor = gss_svc_to_pseudoflavor(gm, info->qop, info->service);
305 313
306 gss_mech_put(gm); 314 gss_mech_put(gm);
307 return pseudoflavor; 315 return pseudoflavor;
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index f7d34e7b6f81..74f6d30f5ded 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -1216,7 +1216,9 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1216 svcdata->rsci = rsci; 1216 svcdata->rsci = rsci;
1217 cache_get(&rsci->h); 1217 cache_get(&rsci->h);
1218 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor( 1218 rqstp->rq_cred.cr_flavor = gss_svc_to_pseudoflavor(
1219 rsci->mechctx->mech_type, gc->gc_svc); 1219 rsci->mechctx->mech_type,
1220 GSS_C_QOP_DEFAULT,
1221 gc->gc_svc);
1220 ret = SVC_OK; 1222 ret = SVC_OK;
1221 goto out; 1223 goto out;
1222 } 1224 }