|
|
816ad1 |
From 41a037c8310d204d21e9c3161d2015dd5177cff6 Mon Sep 17 00:00:00 2001
|
|
|
816ad1 |
From: Thierry Bordaz <tbordaz@redhat.com>
|
|
|
816ad1 |
Date: Tue, 19 Dec 2017 11:53:13 +0100
|
|
|
816ad1 |
Subject: [PATCH] Ticket 49509 - Indexing of internationalized matching rules
|
|
|
816ad1 |
is failing
|
|
|
816ad1 |
|
|
|
816ad1 |
Bug Description:
|
|
|
816ad1 |
Indexing of the internationalized matching rules tests if a
|
|
|
816ad1 |
matching rule indexer handle or not a given OID.
|
|
|
816ad1 |
A side effect of https://pagure.io/389-ds-base/issue/49097 is that
|
|
|
816ad1 |
the returned indexing callbacks are lost.
|
|
|
816ad1 |
Indeed, the indexing callbacks (and potentially others fields) were
|
|
|
816ad1 |
stored in the temporary pblock that was memcpy to the provided
|
|
|
816ad1 |
pblock in case of success
|
|
|
816ad1 |
|
|
|
816ad1 |
Fix Description:
|
|
|
816ad1 |
The fix basically restores the previous behavior but do not
|
|
|
816ad1 |
memcpy pblock. It read/store the pblock fields that are
|
|
|
816ad1 |
inputs/outputs of slapi_mr_indexer_create.
|
|
|
816ad1 |
|
|
|
816ad1 |
https://pagure.io/389-ds-base/issue/49509
|
|
|
816ad1 |
|
|
|
816ad1 |
Reviewed by: Ludwig Krispenz
|
|
|
816ad1 |
|
|
|
816ad1 |
Platforms tested: F23
|
|
|
816ad1 |
|
|
|
816ad1 |
Flag Day: no
|
|
|
816ad1 |
|
|
|
816ad1 |
Doc impact: no
|
|
|
816ad1 |
---
|
|
|
816ad1 |
ldap/servers/slapd/plugin_mr.c | 202 ++++++++++++++++++++++++++++++-----------
|
|
|
816ad1 |
1 file changed, 148 insertions(+), 54 deletions(-)
|
|
|
816ad1 |
|
|
|
816ad1 |
diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c
|
|
|
816ad1 |
index d216d12b9..b3cd4adf0 100644
|
|
|
816ad1 |
--- a/ldap/servers/slapd/plugin_mr.c
|
|
|
816ad1 |
+++ b/ldap/servers/slapd/plugin_mr.c
|
|
|
816ad1 |
@@ -145,6 +145,82 @@ plugin_mr_bind (char* oid, struct slapdplugin* plugin)
|
|
|
816ad1 |
slapi_log_err(SLAPI_LOG_FILTER, "plugin_mr_bind", "<=\n");
|
|
|
816ad1 |
}
|
|
|
816ad1 |
|
|
|
816ad1 |
+void
|
|
|
816ad1 |
+mr_indexer_init_pb(Slapi_PBlock* src_pb, Slapi_PBlock* dst_pb)
|
|
|
816ad1 |
+{
|
|
|
816ad1 |
+ char* oid;
|
|
|
816ad1 |
+ char *type;
|
|
|
816ad1 |
+ uint32_t usage;
|
|
|
816ad1 |
+ void *object;
|
|
|
816ad1 |
+ IFP destroyFn;
|
|
|
816ad1 |
+ IFP indexFn, indexSvFn;
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ /* matching rule plugin arguments */
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_OID, &oid;;
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_TYPE, &type);
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_OID, oid);
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_TYPE, type);
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_USAGE, &usage);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ /* matching rule plugin functions */
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn);
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ /* common */
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_OBJECT, &object);
|
|
|
816ad1 |
+ slapi_pblock_get(src_pb, SLAPI_PLUGIN_DESTROY_FN, &destroyFn);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_OBJECT, object);
|
|
|
816ad1 |
+ slapi_pblock_set(dst_pb, SLAPI_PLUGIN_DESTROY_FN, destroyFn);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+}
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+/*
|
|
|
816ad1 |
+ * Retrieves the matching rule plugin able to index/sort the provided OID/type
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * The Matching rules able to index/sort a given OID are stored in a global list: global_mr_oids
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * The retrieval is done in 3 phases:
|
|
|
816ad1 |
+ * - It first searches (in global_mr_oids) for the already bound OID->MR
|
|
|
816ad1 |
+ * - Else, look first in old style MR plugin
|
|
|
816ad1 |
+ * for each registered 'syntax' and 'matchingrule' plugins having a
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, it binds (plugin_mr_bind) the first
|
|
|
816ad1 |
+ * plugin that support the OID
|
|
|
816ad1 |
+ * - Else, look in new style MR plugin
|
|
|
816ad1 |
+ * for each registered 'syntax' and 'matchingrule' plugins, it binds (plugin_mr_bind) the first
|
|
|
816ad1 |
+ * plugin that contains OID in its plg_mr_names
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * Inputs:
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_OID
|
|
|
816ad1 |
+ * should contain the OID of the matching rule that you want used for indexing or sorting.
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_TYPE
|
|
|
816ad1 |
+ * should contain the attribute type that you want used for indexing or sorting.
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_USAGE
|
|
|
816ad1 |
+ * should specify if the indexer will be used for indexing (SLAPI_PLUGIN_MR_USAGE_INDEX)
|
|
|
816ad1 |
+ * or for sorting (SLAPI_PLUGIN_MR_USAGE_SORT)
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * Output:
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_OID
|
|
|
816ad1 |
+ * contain the OFFICIAL OID of the matching rule that you want used for indexing or sorting.
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_INDEX_FN
|
|
|
816ad1 |
+ * specifies the indexer function responsible for indexing or sorting of struct berval **
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_MR_INDEX_SV_FN
|
|
|
816ad1 |
+ * specifies the indexer function responsible for indexing or sorting of Slapi_Value **
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_OBJECT
|
|
|
816ad1 |
+ * contain any information that you want passed to the indexer function.
|
|
|
816ad1 |
+ * SLAPI_PLUGIN_DESTROY_FN
|
|
|
816ad1 |
+ * specifies the function responsible for freeing any memory allocated by this indexer factory function.
|
|
|
816ad1 |
+ * For example, memory allocated for a structure that you pass to the indexer function using SLAPI_PLUGIN_OBJECT.
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ */
|
|
|
816ad1 |
int /* an LDAP error code, hopefully LDAP_SUCCESS */
|
|
|
816ad1 |
slapi_mr_indexer_create (Slapi_PBlock* opb)
|
|
|
816ad1 |
{
|
|
|
816ad1 |
@@ -152,60 +228,73 @@ slapi_mr_indexer_create (Slapi_PBlock* opb)
|
|
|
816ad1 |
char* oid;
|
|
|
816ad1 |
if (!(rc = slapi_pblock_get (opb, SLAPI_PLUGIN_MR_OID, &oid)))
|
|
|
816ad1 |
{
|
|
|
816ad1 |
- IFP createFn = NULL;
|
|
|
816ad1 |
- struct slapdplugin* mrp = plugin_mr_find_registered (oid);
|
|
|
816ad1 |
- if (mrp != NULL)
|
|
|
816ad1 |
- {
|
|
|
816ad1 |
- if (!(rc = slapi_pblock_set (opb, SLAPI_PLUGIN, mrp)) &&
|
|
|
816ad1 |
- !(rc = slapi_pblock_get (opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) &&
|
|
|
816ad1 |
- createFn != NULL)
|
|
|
816ad1 |
- {
|
|
|
816ad1 |
- rc = createFn (opb);
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- else
|
|
|
816ad1 |
- {
|
|
|
816ad1 |
- /* call each plugin, until one is able to handle this request. */
|
|
|
816ad1 |
- rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
|
|
|
816ad1 |
- for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next)
|
|
|
816ad1 |
- {
|
|
|
816ad1 |
- IFP indexFn = NULL;
|
|
|
816ad1 |
- IFP indexSvFn = NULL;
|
|
|
816ad1 |
- Slapi_PBlock pb;
|
|
|
816ad1 |
- memcpy (&pb, opb, sizeof(Slapi_PBlock));
|
|
|
816ad1 |
- slapi_pblock_set(&pb, SLAPI_PLUGIN, mrp);
|
|
|
816ad1 |
- if (slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) {
|
|
|
816ad1 |
- /* plugin not a matchingrule type */
|
|
|
816ad1 |
- continue;
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- if (createFn && !createFn(&pb)) {
|
|
|
816ad1 |
- slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
|
|
|
816ad1 |
- slapi_pblock_get(&pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
|
|
|
816ad1 |
- if (indexFn || indexSvFn) {
|
|
|
816ad1 |
- /* Success: this plugin can handle it. */
|
|
|
816ad1 |
- memcpy(opb, &pb, sizeof (Slapi_PBlock));
|
|
|
816ad1 |
- plugin_mr_bind(oid, mrp); /* for future reference */
|
|
|
816ad1 |
- rc = 0; /* success */
|
|
|
816ad1 |
- break;
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
-
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- if (rc != 0) {
|
|
|
816ad1 |
- /* look for a new syntax-style mr plugin */
|
|
|
816ad1 |
- struct slapdplugin *pi = plugin_mr_find(oid);
|
|
|
816ad1 |
- if (pi) {
|
|
|
816ad1 |
- Slapi_PBlock pb;
|
|
|
816ad1 |
- memcpy (&pb, opb, sizeof(Slapi_PBlock));
|
|
|
816ad1 |
- slapi_pblock_set(&pb, SLAPI_PLUGIN, pi);
|
|
|
816ad1 |
- rc = default_mr_indexer_create(&pb;;
|
|
|
816ad1 |
- if (!rc) {
|
|
|
816ad1 |
- memcpy (opb, &pb, sizeof(Slapi_PBlock));
|
|
|
816ad1 |
- plugin_mr_bind (oid, pi); /* for future reference */
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
- }
|
|
|
816ad1 |
+ IFP createFn = NULL;
|
|
|
816ad1 |
+ struct slapdplugin* mrp = plugin_mr_find_registered(oid);
|
|
|
816ad1 |
+ if (mrp != NULL) {
|
|
|
816ad1 |
+ /* Great the matching OID -> MR plugin was already found, just reuse it */
|
|
|
816ad1 |
+ if (!(rc = slapi_pblock_set(opb, SLAPI_PLUGIN, mrp)) &&
|
|
|
816ad1 |
+ !(rc = slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) &&
|
|
|
816ad1 |
+ createFn != NULL) {
|
|
|
816ad1 |
+ rc = createFn(opb);
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ } else {
|
|
|
816ad1 |
+ /* We need to find in the MR plugins list, the MR plugin that will be able to handle OID
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * It can be "old style" MR plugin (i.e. collation) that define indexer
|
|
|
816ad1 |
+ *
|
|
|
816ad1 |
+ * It can be "now style" MR plugin that contain OID string in 'plg_mr_names'
|
|
|
816ad1 |
+ * (ie. ces, cis, bin...) where plg_mr_names is defined in 'mr_plugin_table' in each file
|
|
|
816ad1 |
+ * ces.c, cis.c...
|
|
|
816ad1 |
+ * New style MR plugin have NULL indexer create function but rather use a default indexer
|
|
|
816ad1 |
+ */
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ /* Look for a old syntax-style mr plugin
|
|
|
816ad1 |
+ * call each plugin, until one is able to handle this request.
|
|
|
816ad1 |
+ */
|
|
|
816ad1 |
+ rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next) {
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ Slapi_PBlock *pb = slapi_pblock_new();
|
|
|
816ad1 |
+ mr_indexer_init_pb(opb, pb);
|
|
|
816ad1 |
+ slapi_pblock_set(pb, SLAPI_PLUGIN, mrp);
|
|
|
816ad1 |
+ /* This is associated with the pb_plugin struct, so it comes with mrp */
|
|
|
816ad1 |
+ if (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) {
|
|
|
816ad1 |
+ /* plugin not a matchingrule type */
|
|
|
816ad1 |
+ slapi_pblock_destroy(pb);
|
|
|
816ad1 |
+ continue;
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ if (createFn && !createFn(pb)) {
|
|
|
816ad1 |
+ IFP indexFn = NULL;
|
|
|
816ad1 |
+ IFP indexSvFn = NULL;
|
|
|
816ad1 |
+ /* These however, are in the pblock direct, so we need to copy them. */
|
|
|
816ad1 |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
|
|
|
816ad1 |
+ slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
|
|
|
816ad1 |
+ if (indexFn || indexSvFn) {
|
|
|
816ad1 |
+ /* Success: this plugin can handle it. */
|
|
|
816ad1 |
+ mr_indexer_init_pb(pb, opb);
|
|
|
816ad1 |
+ plugin_mr_bind(oid, mrp); /* for future reference */
|
|
|
816ad1 |
+ rc = 0; /* success */
|
|
|
816ad1 |
+ slapi_pblock_destroy(pb);
|
|
|
816ad1 |
+ break;
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ slapi_pblock_destroy(pb);
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ if (rc != 0) {
|
|
|
816ad1 |
+ /* look for a new syntax-style mr plugin */
|
|
|
816ad1 |
+ struct slapdplugin *pi = plugin_mr_find(oid);
|
|
|
816ad1 |
+ if (pi) {
|
|
|
816ad1 |
+ slapi_pblock_set(opb, SLAPI_PLUGIN, pi);
|
|
|
816ad1 |
+ rc = default_mr_indexer_create(opb);
|
|
|
816ad1 |
+ if (!rc) {
|
|
|
816ad1 |
+ plugin_mr_bind(oid, pi); /* for future reference */
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ slapi_pblock_set(opb, SLAPI_PLUGIN, NULL);
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
+ }
|
|
|
816ad1 |
}
|
|
|
816ad1 |
return rc;
|
|
|
816ad1 |
}
|
|
|
816ad1 |
@@ -683,6 +772,11 @@ default_mr_indexer_create(Slapi_PBlock* pb)
|
|
|
816ad1 |
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn);
|
|
|
816ad1 |
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, mr_wrap_mr_index_sv_fn);
|
|
|
816ad1 |
slapi_pblock_set(pb, SLAPI_PLUGIN_DESTROY_FN, default_mr_indexer_destroy);
|
|
|
816ad1 |
+
|
|
|
816ad1 |
+ /* Note the two following setting are in the slapdplugin struct SLAPI_PLUGIN
|
|
|
816ad1 |
+ * so they are not really output of the function but will just
|
|
|
816ad1 |
+ * be stored in the bound (OID <--> plugin) list (plugin_mr_find_registered/plugin_mr_bind)
|
|
|
816ad1 |
+ */
|
|
|
816ad1 |
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, default_mr_indexer_create);
|
|
|
816ad1 |
slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create);
|
|
|
816ad1 |
rc = 0;
|
|
|
816ad1 |
--
|
|
|
816ad1 |
2.13.6
|
|
|
816ad1 |
|