diff options
| author | Chuck Lever <chuck.lever@oracle.com> | 2013-03-16 15:55:10 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-03-29 15:43:33 -0400 |
| commit | a77c806fb9d097bb7733b64207cf52fc2c6438bb (patch) | |
| tree | 198d62d0436f22e7288142eb7341880a1b99ee3e | |
| parent | 83523d083a045a2069e5f3443d2e4f810a6e6d9a (diff) | |
SUNRPC: Refactor nfsd4_do_encode_secinfo()
Clean up. This matches a similar API for the client side, and
keeps ULP fingers out the of the GSS mech switch.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Acked-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | fs/nfsd/nfs4xdr.c | 24 | ||||
| -rw-r--r-- | include/linux/sunrpc/auth.h | 4 | ||||
| -rw-r--r-- | include/linux/sunrpc/gss_api.h | 3 | ||||
| -rw-r--r-- | net/sunrpc/auth.c | 35 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 1 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/gss_mech_switch.c | 35 |
6 files changed, 87 insertions, 15 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 01168865dd37..2a2745615b42 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -3138,10 +3138,9 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ | |||
| 3138 | 3138 | ||
| 3139 | static __be32 | 3139 | static __be32 |
| 3140 | nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, | 3140 | nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, |
| 3141 | __be32 nfserr,struct svc_export *exp) | 3141 | __be32 nfserr, struct svc_export *exp) |
| 3142 | { | 3142 | { |
| 3143 | int i = 0; | 3143 | u32 i, nflavs; |
| 3144 | u32 nflavs; | ||
| 3145 | struct exp_flavor_info *flavs; | 3144 | struct exp_flavor_info *flavs; |
| 3146 | struct exp_flavor_info def_flavs[2]; | 3145 | struct exp_flavor_info def_flavs[2]; |
| 3147 | __be32 *p; | 3146 | __be32 *p; |
| @@ -3172,30 +3171,29 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, | |||
| 3172 | WRITE32(nflavs); | 3171 | WRITE32(nflavs); |
| 3173 | ADJUST_ARGS(); | 3172 | ADJUST_ARGS(); |
| 3174 | for (i = 0; i < nflavs; i++) { | 3173 | for (i = 0; i < nflavs; i++) { |
| 3175 | u32 flav = flavs[i].pseudoflavor; | 3174 | struct rpcsec_gss_info info; |
| 3176 | struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav); | ||
| 3177 | 3175 | ||
| 3178 | if (gm) { | 3176 | if (rpcauth_get_gssinfo(flavs[i].pseudoflavor, &info) == 0) { |
| 3179 | RESERVE_SPACE(4); | 3177 | RESERVE_SPACE(4); |
| 3180 | WRITE32(RPC_AUTH_GSS); | 3178 | WRITE32(RPC_AUTH_GSS); |
| 3181 | ADJUST_ARGS(); | 3179 | ADJUST_ARGS(); |
| 3182 | RESERVE_SPACE(4 + gm->gm_oid.len); | 3180 | RESERVE_SPACE(4 + info.oid.len); |
| 3183 | WRITE32(gm->gm_oid.len); | 3181 | WRITE32(info.oid.len); |
| 3184 | WRITEMEM(gm->gm_oid.data, gm->gm_oid.len); | 3182 | WRITEMEM(info.oid.data, info.oid.len); |
| 3185 | ADJUST_ARGS(); | 3183 | ADJUST_ARGS(); |
| 3186 | RESERVE_SPACE(4); | 3184 | RESERVE_SPACE(4); |
| 3187 | WRITE32(0); /* qop */ | 3185 | WRITE32(info.qop); |
| 3188 | ADJUST_ARGS(); | 3186 | ADJUST_ARGS(); |
| 3189 | RESERVE_SPACE(4); | 3187 | RESERVE_SPACE(4); |
| 3190 | WRITE32(gss_pseudoflavor_to_service(gm, flav)); | 3188 | WRITE32(info.service); |
| 3191 | ADJUST_ARGS(); | 3189 | ADJUST_ARGS(); |
| 3192 | gss_mech_put(gm); | ||
| 3193 | } else { | 3190 | } else { |
| 3194 | RESERVE_SPACE(4); | 3191 | RESERVE_SPACE(4); |
| 3195 | WRITE32(flav); | 3192 | WRITE32(flavs[i].pseudoflavor); |
| 3196 | ADJUST_ARGS(); | 3193 | ADJUST_ARGS(); |
| 3197 | } | 3194 | } |
| 3198 | } | 3195 | } |
| 3196 | |||
| 3199 | out: | 3197 | out: |
| 3200 | if (exp) | 3198 | if (exp) |
| 3201 | exp_put(exp); | 3199 | exp_put(exp); |
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index 6851da4cb416..0dd00f4f6810 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h | |||
| @@ -106,6 +106,8 @@ struct rpc_authops { | |||
| 106 | void (*pipes_destroy)(struct rpc_auth *); | 106 | void (*pipes_destroy)(struct rpc_auth *); |
| 107 | int (*list_pseudoflavors)(rpc_authflavor_t *, int); | 107 | int (*list_pseudoflavors)(rpc_authflavor_t *, int); |
| 108 | rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *); | 108 | rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *); |
| 109 | int (*flavor2info)(rpc_authflavor_t, | ||
| 110 | struct rpcsec_gss_info *); | ||
| 109 | }; | 111 | }; |
| 110 | 112 | ||
| 111 | struct rpc_credops { | 113 | struct rpc_credops { |
| @@ -142,6 +144,8 @@ struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); | |||
| 142 | void rpcauth_release(struct rpc_auth *); | 144 | void rpcauth_release(struct rpc_auth *); |
| 143 | rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t, | 145 | rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t, |
| 144 | struct rpcsec_gss_info *); | 146 | struct rpcsec_gss_info *); |
| 147 | int rpcauth_get_gssinfo(rpc_authflavor_t, | ||
| 148 | struct rpcsec_gss_info *); | ||
| 145 | int rpcauth_list_flavors(rpc_authflavor_t *, int); | 149 | int rpcauth_list_flavors(rpc_authflavor_t *, int); |
| 146 | struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); | 150 | struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); |
| 147 | void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); | 151 | void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); |
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h index 96e5a81a54d7..fca23380e667 100644 --- a/include/linux/sunrpc/gss_api.h +++ b/include/linux/sunrpc/gss_api.h | |||
| @@ -133,6 +133,9 @@ void gss_mech_unregister(struct gss_api_mech *); | |||
| 133 | /* Given a GSS security tuple, look up a pseudoflavor */ | 133 | /* Given a GSS security tuple, look up a pseudoflavor */ |
| 134 | rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *); | 134 | rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *); |
| 135 | 135 | ||
| 136 | /* Given a pseudoflavor, look up a GSS security tuple */ | ||
| 137 | int gss_mech_flavor2info(rpc_authflavor_t, struct rpcsec_gss_info *); | ||
| 138 | |||
| 136 | /* Returns a reference to a mechanism, given a name like "krb5" etc. */ | 139 | /* Returns a reference to a mechanism, given a name like "krb5" etc. */ |
| 137 | struct gss_api_mech *gss_mech_get_by_name(const char *); | 140 | struct gss_api_mech *gss_mech_get_by_name(const char *); |
| 138 | 141 | ||
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 9b81be8d9946..2bc0cc2196e0 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -159,6 +159,41 @@ rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info) | |||
| 159 | EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor); | 159 | EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor); |
| 160 | 160 | ||
| 161 | /** | 161 | /** |
| 162 | * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor | ||
| 163 | * @pseudoflavor: GSS pseudoflavor to match | ||
| 164 | * @info: rpcsec_gss_info structure to fill in | ||
| 165 | * | ||
| 166 | * Returns zero and fills in "info" if pseudoflavor matches a | ||
| 167 | * supported mechanism. | ||
| 168 | */ | ||
| 169 | int | ||
| 170 | rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info) | ||
| 171 | { | ||
| 172 | rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor); | ||
| 173 | const struct rpc_authops *ops; | ||
| 174 | int result; | ||
| 175 | |||
| 176 | ops = auth_flavors[flavor]; | ||
| 177 | if (ops == NULL) | ||
| 178 | request_module("rpc-auth-%u", flavor); | ||
| 179 | spin_lock(&rpc_authflavor_lock); | ||
| 180 | ops = auth_flavors[flavor]; | ||
| 181 | if (ops == NULL || !try_module_get(ops->owner)) { | ||
| 182 | spin_unlock(&rpc_authflavor_lock); | ||
| 183 | return -ENOENT; | ||
| 184 | } | ||
| 185 | spin_unlock(&rpc_authflavor_lock); | ||
| 186 | |||
| 187 | result = -ENOENT; | ||
| 188 | if (ops->flavor2info != NULL) | ||
| 189 | result = ops->flavor2info(pseudoflavor, info); | ||
| 190 | |||
| 191 | module_put(ops->owner); | ||
| 192 | return result; | ||
| 193 | } | ||
| 194 | EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo); | ||
| 195 | |||
| 196 | /** | ||
| 162 | * rpcauth_list_flavors - discover registered flavors and pseudoflavors | 197 | * rpcauth_list_flavors - discover registered flavors and pseudoflavors |
| 163 | * @array: array to fill in | 198 | * @array: array to fill in |
| 164 | * @size: size of "array" | 199 | * @size: size of "array" |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index a7420076ef39..51415b07174e 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -1642,6 +1642,7 @@ static const struct rpc_authops authgss_ops = { | |||
| 1642 | .pipes_destroy = gss_pipes_dentries_destroy, | 1642 | .pipes_destroy = gss_pipes_dentries_destroy, |
| 1643 | .list_pseudoflavors = gss_mech_list_pseudoflavors, | 1643 | .list_pseudoflavors = gss_mech_list_pseudoflavors, |
| 1644 | .info2flavor = gss_mech_info2flavor, | 1644 | .info2flavor = gss_mech_info2flavor, |
| 1645 | .flavor2info = gss_mech_flavor2info, | ||
| 1645 | }; | 1646 | }; |
| 1646 | 1647 | ||
| 1647 | static const struct rpc_credops gss_credops = { | 1648 | static const struct rpc_credops gss_credops = { |
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index 81fb6f3e2424..deaa7ae81cdf 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c | |||
| @@ -240,8 +240,6 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | |||
| 240 | return gm; | 240 | return gm; |
| 241 | } | 241 | } |
| 242 | 242 | ||
| 243 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); | ||
| 244 | |||
| 245 | /** | 243 | /** |
| 246 | * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors | 244 | * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors |
| 247 | * @array: array to fill in | 245 | * @array: array to fill in |
| @@ -315,6 +313,39 @@ rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *info) | |||
| 315 | return pseudoflavor; | 313 | return pseudoflavor; |
| 316 | } | 314 | } |
| 317 | 315 | ||
| 316 | /** | ||
| 317 | * gss_mech_flavor2info - look up a GSS tuple for a given pseudoflavor | ||
| 318 | * @pseudoflavor: GSS pseudoflavor to match | ||
| 319 | * @info: rpcsec_gss_info structure to fill in | ||
| 320 | * | ||
| 321 | * Returns zero and fills in "info" if pseudoflavor matches a | ||
| 322 | * supported mechanism. Otherwise a negative errno is returned. | ||
| 323 | */ | ||
| 324 | int gss_mech_flavor2info(rpc_authflavor_t pseudoflavor, | ||
| 325 | struct rpcsec_gss_info *info) | ||
| 326 | { | ||
| 327 | struct gss_api_mech *gm; | ||
| 328 | int i; | ||
| 329 | |||
| 330 | gm = gss_mech_get_by_pseudoflavor(pseudoflavor); | ||
| 331 | if (gm == NULL) | ||
| 332 | return -ENOENT; | ||
| 333 | |||
| 334 | for (i = 0; i < gm->gm_pf_num; i++) { | ||
| 335 | if (gm->gm_pfs[i].pseudoflavor == pseudoflavor) { | ||
| 336 | memcpy(info->oid.data, gm->gm_oid.data, gm->gm_oid.len); | ||
| 337 | info->oid.len = gm->gm_oid.len; | ||
| 338 | info->qop = gm->gm_pfs[i].qop; | ||
| 339 | info->service = gm->gm_pfs[i].service; | ||
| 340 | gss_mech_put(gm); | ||
| 341 | return 0; | ||
| 342 | } | ||
| 343 | } | ||
| 344 | |||
| 345 | gss_mech_put(gm); | ||
| 346 | return -ENOENT; | ||
| 347 | } | ||
| 348 | |||
| 318 | u32 | 349 | u32 |
| 319 | gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) | 350 | gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor) |
| 320 | { | 351 | { |
