diff options
Diffstat (limited to 'net/sunrpc/auth.c')
| -rw-r--r-- | net/sunrpc/auth.c | 54 | 
1 files changed, 54 insertions, 0 deletions
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 727e506cacd..b5c067bccc4 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -13,6 +13,7 @@  #include <linux/errno.h>  #include <linux/hash.h>  #include <linux/sunrpc/clnt.h> +#include <linux/sunrpc/gss_api.h>  #include <linux/spinlock.h>  #ifdef RPC_DEBUG @@ -122,6 +123,59 @@ rpcauth_unregister(const struct rpc_authops *ops)  }  EXPORT_SYMBOL_GPL(rpcauth_unregister); +/** + * rpcauth_list_flavors - discover registered flavors and pseudoflavors + * @array: array to fill in + * @size: size of "array" + * + * Returns the number of array items filled in, or a negative errno. + * + * The returned array is not sorted by any policy.  Callers should not + * rely on the order of the items in the returned array. + */ +int +rpcauth_list_flavors(rpc_authflavor_t *array, int size) +{ +	rpc_authflavor_t flavor; +	int result = 0; + +	spin_lock(&rpc_authflavor_lock); +	for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) { +		const struct rpc_authops *ops = auth_flavors[flavor]; +		rpc_authflavor_t pseudos[4]; +		int i, len; + +		if (result >= size) { +			result = -ENOMEM; +			break; +		} + +		if (ops == NULL) +			continue; +		if (ops->list_pseudoflavors == NULL) { +			array[result++] = ops->au_flavor; +			continue; +		} +		len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos)); +		if (len < 0) { +			result = len; +			break; +		} +		for (i = 0; i < len; i++) { +			if (result >= size) { +				result = -ENOMEM; +				break; +			} +			array[result++] = pseudos[i]; +		} +	} +	spin_unlock(&rpc_authflavor_lock); + +	dprintk("RPC:       %s returns %d\n", __func__, result); +	return result; +} +EXPORT_SYMBOL_GPL(rpcauth_list_flavors); +  struct rpc_auth *  rpcauth_create(rpc_authflavor_t pseudoflavor, struct rpc_clnt *clnt)  {  |