mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 03:27:44 -04:00
SUNRPC: Introduce rpcauth_get_pseudoflavor()
A SECINFO reply may contain flavors whose kernel module is not yet loaded by the client's kernel. A new RPC client API, called rpcauth_get_pseudoflavor(), is introduced to do proper checking for support of a security flavor. When this API is invoked, the RPC client now tries to load the module for each flavor first before performing the "is this supported?" check. This means if a module is available on the client, but has not been loaded yet, it will be loaded and registered automatically when the SECINFO reply is processed. The new API can take a full GSS tuple (OID, QoP, and service). Previously only the OID and service were considered. nfs_find_best_sec() is updated to verify all flavors requested in a SECINFO reply, including AUTH_NULL and AUTH_UNIX. Previously these two flavors were simply assumed to be supported without consulting the RPC client. Note that the replaced version of nfs_find_best_sec() can return RPC_AUTH_MAXFLAVOR if the server returns a recognized OID but an unsupported "service" value. nfs_find_best_sec() now returns RPC_AUTH_UNIX in this case. Signed-off-by: Chuck Lever <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
This commit is contained in:
parent
fb15b26f8b
commit
9568c5e9a6
6 changed files with 89 additions and 26 deletions
|
|
@ -123,6 +123,41 @@ rpcauth_unregister(const struct rpc_authops *ops)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_unregister);
|
||||
|
||||
/**
|
||||
* rpcauth_get_pseudoflavor - check if security flavor is supported
|
||||
* @flavor: a security flavor
|
||||
* @info: a GSS mech OID, quality of protection, and service value
|
||||
*
|
||||
* Verifies that an appropriate kernel module is available or already loaded.
|
||||
* Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
|
||||
* not supported locally.
|
||||
*/
|
||||
rpc_authflavor_t
|
||||
rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info)
|
||||
{
|
||||
const struct rpc_authops *ops;
|
||||
rpc_authflavor_t pseudoflavor;
|
||||
|
||||
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 RPC_AUTH_MAXFLAVOR;
|
||||
}
|
||||
spin_unlock(&rpc_authflavor_lock);
|
||||
|
||||
pseudoflavor = flavor;
|
||||
if (ops->info2flavor != NULL)
|
||||
pseudoflavor = ops->info2flavor(info);
|
||||
|
||||
module_put(ops->owner);
|
||||
return pseudoflavor;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor);
|
||||
|
||||
/**
|
||||
* rpcauth_list_flavors - discover registered flavors and pseudoflavors
|
||||
* @array: array to fill in
|
||||
|
|
|
|||
|
|
@ -1641,6 +1641,7 @@ static const struct rpc_authops authgss_ops = {
|
|||
.pipes_create = gss_pipes_dentries_create,
|
||||
.pipes_destroy = gss_pipes_dentries_destroy,
|
||||
.list_pseudoflavors = gss_mech_list_pseudoflavors,
|
||||
.info2flavor = gss_mech_info2flavor,
|
||||
};
|
||||
|
||||
static const struct rpc_credops gss_credops = {
|
||||
|
|
|
|||
|
|
@ -171,8 +171,7 @@ struct gss_api_mech * gss_mech_get_by_name(const char *name)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(gss_mech_get_by_name);
|
||||
|
||||
struct gss_api_mech *
|
||||
gss_mech_get_by_OID(struct xdr_netobj *obj)
|
||||
static struct gss_api_mech *gss_mech_get_by_OID(struct rpcsec_gss_oid *obj)
|
||||
{
|
||||
struct gss_api_mech *pos, *gm = NULL;
|
||||
|
||||
|
|
@ -188,11 +187,8 @@ gss_mech_get_by_OID(struct xdr_netobj *obj)
|
|||
}
|
||||
spin_unlock(®istered_mechs_lock);
|
||||
return gm;
|
||||
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(gss_mech_get_by_OID);
|
||||
|
||||
static inline int
|
||||
mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor)
|
||||
{
|
||||
|
|
@ -282,6 +278,28 @@ gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor);
|
||||
|
||||
/**
|
||||
* gss_mech_info2flavor - look up a pseudoflavor given a GSS tuple
|
||||
* @info: a GSS mech OID, quality of protection, and service value
|
||||
*
|
||||
* Returns a matching pseudoflavor, or RPC_AUTH_MAXFLAVOR if the tuple is
|
||||
* not supported.
|
||||
*/
|
||||
rpc_authflavor_t gss_mech_info2flavor(struct rpcsec_gss_info *info)
|
||||
{
|
||||
rpc_authflavor_t pseudoflavor;
|
||||
struct gss_api_mech *gm;
|
||||
|
||||
gm = gss_mech_get_by_OID(&info->oid);
|
||||
if (gm == NULL)
|
||||
return RPC_AUTH_MAXFLAVOR;
|
||||
|
||||
pseudoflavor = gss_svc_to_pseudoflavor(gm, info->service);
|
||||
|
||||
gss_mech_put(gm);
|
||||
return pseudoflavor;
|
||||
}
|
||||
|
||||
u32
|
||||
gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue