Introduce an external function call that can report whether sunrpc.ko
can support an authentication flavor or not.
A new optional rpc_authops hook is added. If the hook is not
present,
then the flavor is assumed to be supported. If the hook is present,
it is passed the pseudoflavor to check, and returns an indication of
whether the pseudoflavor is supported or not.
Signed-off-by: Chuck Lever <chuck.lever@xxxxxxxxxx>
---
include/linux/sunrpc/auth.h | 2 ++
net/sunrpc/auth.c | 33 ++++++++++++++++++++++++++++++
+++
net/sunrpc/auth_gss/auth_gss.c | 18 +++++++++++++++++-
3 files changed, 52 insertions(+), 1 deletions(-)
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/
auth.h
index 3f63218..ad9bc97 100644
--- a/include/linux/sunrpc/auth.h
+++ b/include/linux/sunrpc/auth.h
@@ -103,6 +103,7 @@ struct rpc_authops {
struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct
auth_cred *, int);
struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred
*, int);
+ int (*is_supported)(const rpc_authflavor_t);
};
struct rpc_credops {
@@ -134,6 +135,7 @@ struct rpc_cred * rpc_lookup_cred(void);
struct rpc_cred * rpc_lookup_machine_cred(void);
int rpcauth_register(const struct rpc_authops *);
int rpcauth_unregister(const struct rpc_authops *);
+int rpcauth_is_supported(rpc_authflavor_t pseudoflavor);
struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt
*);
void rpcauth_release(struct rpc_auth *);
struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *,
struct auth_cred *, int);
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c
index 0c431c2..ef31ff6 100644
--- a/net/sunrpc/auth.c
+++ b/net/sunrpc/auth.c
@@ -72,6 +72,39 @@ rpcauth_unregister(const struct rpc_authops *ops)
}
EXPORT_SYMBOL_GPL(rpcauth_unregister);
+/**
+ * rpcauth_is_supported - report whether a particular flavor is
supported
+ * @pseudoflavor: RPC authentication flavor to check
+ *
+ * Returns 1 if there is built-in support, or a loaded module,
which can
+ * handle @pseudoflavor. Otherwise, zero is returned.
+ */
+int
+rpcauth_is_supported(rpc_authflavor_t pseudoflavor)
+{
+ const rpc_authflavor_t flavor =
pseudoflavor_to_flavor(pseudoflavor);
+ const struct rpc_authops *ops;
+ int ret = 0;
+
+ spin_lock(&rpc_authflavor_lock);
+ ops = auth_flavors[flavor];
+ if (ops == NULL || !try_module_get(ops->owner)) {
+ spin_unlock(&rpc_authflavor_lock);
+ goto out;
+ }
+ spin_unlock(&rpc_authflavor_lock);
+
+ ret = 1;
+ if (ops->is_supported)
+ ret = ops->is_supported(pseudoflavor);
+
+ module_put(ops->owner);
+
+out:
+ return ret;
+}
+EXPORT_SYMBOL_GPL(rpcauth_is_supported);
+