Commit a77c806fb9d097bb7733b64207cf52fc2c6438bb

Authored by Chuck Lever
Committed by Trond Myklebust
1 parent 83523d083a

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>

Showing 6 changed files with 87 additions and 15 deletions Side-by-side Diff

... ... @@ -3138,10 +3138,9 @@
3138 3138  
3139 3139 static __be32
3140 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;
3144   - u32 nflavs;
  3143 + u32 i, nflavs;
3145 3144 struct exp_flavor_info *flavs;
3146 3145 struct exp_flavor_info def_flavs[2];
3147 3146 __be32 *p;
3148 3147  
3149 3148  
3150 3149  
3151 3150  
3152 3151  
3153 3152  
3154 3153  
... ... @@ -3172,30 +3171,29 @@
3172 3171 WRITE32(nflavs);
3173 3172 ADJUST_ARGS();
3174 3173 for (i = 0; i < nflavs; i++) {
3175   - u32 flav = flavs[i].pseudoflavor;
3176   - struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
  3174 + struct rpcsec_gss_info info;
3177 3175  
3178   - if (gm) {
  3176 + if (rpcauth_get_gssinfo(flavs[i].pseudoflavor, &info) == 0) {
3179 3177 RESERVE_SPACE(4);
3180 3178 WRITE32(RPC_AUTH_GSS);
3181 3179 ADJUST_ARGS();
3182   - RESERVE_SPACE(4 + gm->gm_oid.len);
3183   - WRITE32(gm->gm_oid.len);
3184   - WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
  3180 + RESERVE_SPACE(4 + info.oid.len);
  3181 + WRITE32(info.oid.len);
  3182 + WRITEMEM(info.oid.data, info.oid.len);
3185 3183 ADJUST_ARGS();
3186 3184 RESERVE_SPACE(4);
3187   - WRITE32(0); /* qop */
  3185 + WRITE32(info.qop);
3188 3186 ADJUST_ARGS();
3189 3187 RESERVE_SPACE(4);
3190   - WRITE32(gss_pseudoflavor_to_service(gm, flav));
  3188 + WRITE32(info.service);
3191 3189 ADJUST_ARGS();
3192   - gss_mech_put(gm);
3193 3190 } else {
3194 3191 RESERVE_SPACE(4);
3195   - WRITE32(flav);
  3192 + WRITE32(flavs[i].pseudoflavor);
3196 3193 ADJUST_ARGS();
3197 3194 }
3198 3195 }
  3196 +
3199 3197 out:
3200 3198 if (exp)
3201 3199 exp_put(exp);
include/linux/sunrpc/auth.h
... ... @@ -106,6 +106,8 @@
106 106 void (*pipes_destroy)(struct rpc_auth *);
107 107 int (*list_pseudoflavors)(rpc_authflavor_t *, int);
108 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 113 struct rpc_credops {
... ... @@ -141,6 +143,8 @@
141 143 struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
142 144 void rpcauth_release(struct rpc_auth *);
143 145 rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t,
  146 + struct rpcsec_gss_info *);
  147 +int rpcauth_get_gssinfo(rpc_authflavor_t,
144 148 struct rpcsec_gss_info *);
145 149 int rpcauth_list_flavors(rpc_authflavor_t *, int);
146 150 struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
include/linux/sunrpc/gss_api.h
... ... @@ -133,6 +133,9 @@
133 133 /* Given a GSS security tuple, look up a pseudoflavor */
134 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 139 /* Returns a reference to a mechanism, given a name like "krb5" etc. */
137 140 struct gss_api_mech *gss_mech_get_by_name(const char *);
138 141  
... ... @@ -159,6 +159,41 @@
159 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 197 * rpcauth_list_flavors - discover registered flavors and pseudoflavors
163 198 * @array: array to fill in
164 199 * @size: size of "array"
net/sunrpc/auth_gss/auth_gss.c
... ... @@ -1642,6 +1642,7 @@
1642 1642 .pipes_destroy = gss_pipes_dentries_destroy,
1643 1643 .list_pseudoflavors = gss_mech_list_pseudoflavors,
1644 1644 .info2flavor = gss_mech_info2flavor,
  1645 + .flavor2info = gss_mech_flavor2info,
1645 1646 };
1646 1647  
1647 1648 static const struct rpc_credops gss_credops = {
net/sunrpc/auth_gss/gss_mech_switch.c
... ... @@ -240,8 +240,6 @@
240 240 return gm;
241 241 }
242 242  
243   -EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor);
244   -
245 243 /**
246 244 * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors
247 245 * @array: array to fill in
... ... @@ -313,6 +311,39 @@
313 311  
314 312 gss_mech_put(gm);
315 313 return pseudoflavor;
  314 +}
  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;
316 347 }
317 348  
318 349 u32