diff options
Diffstat (limited to 'net/sunrpc/auth.c')
| -rw-r--r-- | net/sunrpc/auth.c | 75 | 
1 files changed, 74 insertions, 1 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index f5294047df7..ed2fdd210c0 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -82,7 +82,7 @@ MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");  static u32  pseudoflavor_to_flavor(u32 flavor) { -	if (flavor >= RPC_AUTH_MAXFLAVOR) +	if (flavor > RPC_AUTH_MAXFLAVOR)  		return RPC_AUTH_GSS;  	return flavor;  } @@ -124,6 +124,79 @@ 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_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; + +	if (flavor >= RPC_AUTH_MAXFLAVOR) +		return -EINVAL; + +	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   * @size: size of "array"  |