|
@@ -36,6 +36,7 @@
|
|
|
#include <linux/types.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <linux/module.h>
|
|
|
+#include <linux/oid_registry.h>
|
|
|
#include <linux/sunrpc/msg_prot.h>
|
|
|
#include <linux/sunrpc/gss_asn1.h>
|
|
|
#include <linux/sunrpc/auth_gss.h>
|
|
@@ -102,8 +103,13 @@ out:
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-int
|
|
|
-gss_mech_register(struct gss_api_mech *gm)
|
|
|
+/**
|
|
|
+ * gss_mech_register - register a GSS mechanism
|
|
|
+ * @gm: GSS mechanism handle
|
|
|
+ *
|
|
|
+ * Returns zero if successful, or a negative errno.
|
|
|
+ */
|
|
|
+int gss_mech_register(struct gss_api_mech *gm)
|
|
|
{
|
|
|
int status;
|
|
|
|
|
@@ -116,11 +122,14 @@ gss_mech_register(struct gss_api_mech *gm)
|
|
|
dprintk("RPC: registered gss mechanism %s\n", gm->gm_name);
|
|
|
return 0;
|
|
|
}
|
|
|
-
|
|
|
EXPORT_SYMBOL_GPL(gss_mech_register);
|
|
|
|
|
|
-void
|
|
|
-gss_mech_unregister(struct gss_api_mech *gm)
|
|
|
+/**
|
|
|
+ * gss_mech_unregister - release a GSS mechanism
|
|
|
+ * @gm: GSS mechanism handle
|
|
|
+ *
|
|
|
+ */
|
|
|
+void gss_mech_unregister(struct gss_api_mech *gm)
|
|
|
{
|
|
|
spin_lock(®istered_mechs_lock);
|
|
|
list_del(&gm->gm_list);
|
|
@@ -128,18 +137,14 @@ gss_mech_unregister(struct gss_api_mech *gm)
|
|
|
dprintk("RPC: unregistered gss mechanism %s\n", gm->gm_name);
|
|
|
gss_mech_free(gm);
|
|
|
}
|
|
|
-
|
|
|
EXPORT_SYMBOL_GPL(gss_mech_unregister);
|
|
|
|
|
|
-struct gss_api_mech *
|
|
|
-gss_mech_get(struct gss_api_mech *gm)
|
|
|
+static struct gss_api_mech *gss_mech_get(struct gss_api_mech *gm)
|
|
|
{
|
|
|
__module_get(gm->gm_owner);
|
|
|
return gm;
|
|
|
}
|
|
|
|
|
|
-EXPORT_SYMBOL_GPL(gss_mech_get);
|
|
|
-
|
|
|
static struct gss_api_mech *
|
|
|
_gss_mech_get_by_name(const char *name)
|
|
|
{
|
|
@@ -169,12 +174,16 @@ struct gss_api_mech * gss_mech_get_by_name(const char *name)
|
|
|
}
|
|
|
return gm;
|
|
|
}
|
|
|
-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;
|
|
|
+ char buf[32];
|
|
|
+
|
|
|
+ if (sprint_oid(obj->data, obj->len, buf, sizeof(buf)) < 0)
|
|
|
+ return NULL;
|
|
|
+ dprintk("RPC: %s(%s)\n", __func__, buf);
|
|
|
+ request_module("rpc-auth-gss-%s", buf);
|
|
|
|
|
|
spin_lock(®istered_mechs_lock);
|
|
|
list_for_each_entry(pos, ®istered_mechs, gm_list) {
|
|
@@ -188,11 +197,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)
|
|
|
{
|
|
@@ -237,8 +243,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
|
|
@@ -268,19 +272,82 @@ int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size)
|
|
|
return i;
|
|
|
}
|
|
|
|
|
|
-u32
|
|
|
-gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 service)
|
|
|
+/**
|
|
|
+ * gss_svc_to_pseudoflavor - map a GSS service number to a pseudoflavor
|
|
|
+ * @gm: GSS mechanism handle
|
|
|
+ * @qop: GSS quality-of-protection value
|
|
|
+ * @service: GSS service value
|
|
|
+ *
|
|
|
+ * Returns a matching security flavor, or RPC_AUTH_MAXFLAVOR if none is found.
|
|
|
+ */
|
|
|
+rpc_authflavor_t gss_svc_to_pseudoflavor(struct gss_api_mech *gm, u32 qop,
|
|
|
+ u32 service)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
for (i = 0; i < gm->gm_pf_num; i++) {
|
|
|
- if (gm->gm_pfs[i].service == service) {
|
|
|
+ if (gm->gm_pfs[i].qop == qop &&
|
|
|
+ gm->gm_pfs[i].service == service) {
|
|
|
return gm->gm_pfs[i].pseudoflavor;
|
|
|
}
|
|
|
}
|
|
|
- return RPC_AUTH_MAXFLAVOR; /* illegal value */
|
|
|
+ return RPC_AUTH_MAXFLAVOR;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 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->qop, info->service);
|
|
|
+
|
|
|
+ gss_mech_put(gm);
|
|
|
+ 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;
|
|
|
}
|
|
|
-EXPORT_SYMBOL_GPL(gss_svc_to_pseudoflavor);
|
|
|
|
|
|
u32
|
|
|
gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
|
|
@@ -294,8 +361,6 @@ gss_pseudoflavor_to_service(struct gss_api_mech *gm, u32 pseudoflavor)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-EXPORT_SYMBOL_GPL(gss_pseudoflavor_to_service);
|
|
|
-
|
|
|
char *
|
|
|
gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
|
|
|
{
|
|
@@ -308,8 +373,6 @@ gss_service_to_auth_domain_name(struct gss_api_mech *gm, u32 service)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-EXPORT_SYMBOL_GPL(gss_service_to_auth_domain_name);
|
|
|
-
|
|
|
void
|
|
|
gss_mech_put(struct gss_api_mech * gm)
|
|
|
{
|
|
@@ -317,8 +380,6 @@ gss_mech_put(struct gss_api_mech * gm)
|
|
|
module_put(gm->gm_owner);
|
|
|
}
|
|
|
|
|
|
-EXPORT_SYMBOL_GPL(gss_mech_put);
|
|
|
-
|
|
|
/* The mech could probably be determined from the token instead, but it's just
|
|
|
* as easy for now to pass it in. */
|
|
|
int
|