Blame SOURCES/0087-Ticket-49509-Indexing-of-internationalized-matching-.patch

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