Skip to content

Commit

Permalink
SUNRPC: Refactor nfsd4_do_encode_secinfo()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
chucklever authored and Trond Myklebust committed Mar 29, 2013
1 parent 83523d0 commit a77c806
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 15 deletions.
24 changes: 11 additions & 13 deletions fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -3138,10 +3138,9 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_

static __be32
nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
__be32 nfserr,struct svc_export *exp)
__be32 nfserr, struct svc_export *exp)
{
int i = 0;
u32 nflavs;
u32 i, nflavs;
struct exp_flavor_info *flavs;
struct exp_flavor_info def_flavs[2];
__be32 *p;
Expand Down Expand Up @@ -3172,30 +3171,29 @@ nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
WRITE32(nflavs);
ADJUST_ARGS();
for (i = 0; i < nflavs; i++) {
u32 flav = flavs[i].pseudoflavor;
struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
struct rpcsec_gss_info info;

if (gm) {
if (rpcauth_get_gssinfo(flavs[i].pseudoflavor, &info) == 0) {
RESERVE_SPACE(4);
WRITE32(RPC_AUTH_GSS);
ADJUST_ARGS();
RESERVE_SPACE(4 + gm->gm_oid.len);
WRITE32(gm->gm_oid.len);
WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
RESERVE_SPACE(4 + info.oid.len);
WRITE32(info.oid.len);
WRITEMEM(info.oid.data, info.oid.len);
ADJUST_ARGS();
RESERVE_SPACE(4);
WRITE32(0); /* qop */
WRITE32(info.qop);
ADJUST_ARGS();
RESERVE_SPACE(4);
WRITE32(gss_pseudoflavor_to_service(gm, flav));
WRITE32(info.service);
ADJUST_ARGS();
gss_mech_put(gm);
} else {
RESERVE_SPACE(4);
WRITE32(flav);
WRITE32(flavs[i].pseudoflavor);
ADJUST_ARGS();
}
}

out:
if (exp)
exp_put(exp);
Expand Down
4 changes: 4 additions & 0 deletions include/linux/sunrpc/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ struct rpc_authops {
void (*pipes_destroy)(struct rpc_auth *);
int (*list_pseudoflavors)(rpc_authflavor_t *, int);
rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *);
int (*flavor2info)(rpc_authflavor_t,
struct rpcsec_gss_info *);
};

struct rpc_credops {
Expand Down Expand Up @@ -142,6 +144,8 @@ struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
void rpcauth_release(struct rpc_auth *);
rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t,
struct rpcsec_gss_info *);
int rpcauth_get_gssinfo(rpc_authflavor_t,
struct rpcsec_gss_info *);
int rpcauth_list_flavors(rpc_authflavor_t *, int);
struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
Expand Down
3 changes: 3 additions & 0 deletions include/linux/sunrpc/gss_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ void gss_mech_unregister(struct gss_api_mech *);
/* Given a GSS security tuple, look up a pseudoflavor */
rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *);

/* Given a pseudoflavor, look up a GSS security tuple */
int gss_mech_flavor2info(rpc_authflavor_t, struct rpcsec_gss_info *);

/* Returns a reference to a mechanism, given a name like "krb5" etc. */
struct gss_api_mech *gss_mech_get_by_name(const char *);

Expand Down
35 changes: 35 additions & 0 deletions net/sunrpc/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,41 @@ rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info)
}
EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor);

/**
* rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
* @pseudoflavor: GSS pseudoflavor to match
* @info: rpcsec_gss_info structure to fill in
*
* Returns zero and fills in "info" if pseudoflavor matches a
* supported mechanism.
*/
int
rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info)
{
rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor);
const struct rpc_authops *ops;
int result;

ops = auth_flavors[flavor];
if (ops == NULL)
request_module("rpc-auth-%u", flavor);
spin_lock(&rpc_authflavor_lock);
ops = auth_flavors[flavor];
if (ops == NULL || !try_module_get(ops->owner)) {
spin_unlock(&rpc_authflavor_lock);
return -ENOENT;
}
spin_unlock(&rpc_authflavor_lock);

result = -ENOENT;
if (ops->flavor2info != NULL)
result = ops->flavor2info(pseudoflavor, info);

module_put(ops->owner);
return result;
}
EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo);

/**
* rpcauth_list_flavors - discover registered flavors and pseudoflavors
* @array: array to fill in
Expand Down
1 change: 1 addition & 0 deletions net/sunrpc/auth_gss/auth_gss.c
Original file line number Diff line number Diff line change
Expand Up @@ -1642,6 +1642,7 @@ static const struct rpc_authops authgss_ops = {
.pipes_destroy = gss_pipes_dentries_destroy,
.list_pseudoflavors = gss_mech_list_pseudoflavors,
.info2flavor = gss_mech_info2flavor,
.flavor2info = gss_mech_flavor2info,
};

static const struct rpc_credops gss_credops = {
Expand Down
35 changes: 33 additions & 2 deletions net/sunrpc/auth_gss/gss_mech_switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,6 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor)
return gm;
}

EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor);

/**
* gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors
* @array: array to fill in
Expand Down Expand Up @@ -315,6 +313,39 @@ rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *info)
return pseudoflavor;
}

/**
* gss_mech_flavor2info - look up a GSS tuple for a given pseudoflavor
* @pseudoflavor: GSS pseudoflavor to match
* @info: rpcsec_gss_info structure to fill in
*
* Returns zero and fills in "info" if pseudoflavor matches a
* supported mechanism. Otherwise a negative errno is returned.
*/
int gss_mech_flavor2info(rpc_authflavor_t pseudoflavor,
struct rpcsec_gss_info *info)
{
struct gss_api_mech *gm;
int i;

gm = gss_mech_get_by_pseudoflavor(pseudoflavor);
if (gm == NULL)
return -ENOENT;

for (i = 0; i < gm->gm_pf_num; i++) {
if (gm->gm_pfs[i].pseudoflavor == pseudoflavor) {
memcpy(info->oid.data, gm->gm_oid.data, gm->gm_oid.len);
info->oid.len = gm->gm_oid.len;
info->qop = gm->gm_pfs[i].qop;
info->service = gm->gm_pfs[i].service;
gss_mech_put(gm);
return 0;
}
}

gss_mech_put(gm);
return -ENOENT;
}

u32
gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
{
Expand Down

0 comments on commit a77c806

Please sign in to comment.