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

081b2d
From 8d79d7c81157e77f4da595a723a6ed10a8e9789b Mon Sep 17 00:00:00 2001
816ad1
From: Thierry Bordaz <tbordaz@redhat.com>
081b2d
Date: Thu, 11 Jan 2018 18:52:43 +0100
816ad1
Subject: [PATCH] Ticket 49509 - Indexing of internationalized matching rules
816ad1
 is failing
816ad1
816ad1
Bug Description:
081b2d
    Indexing of the internationalized matching rules tests if a
081b2d
    matching rule indexer handle or not a given OID.
081b2d
    A side effect of https://pagure.io/389-ds-base/issue/49097 is that
081b2d
    the returned indexing callbacks are lost.
081b2d
    Indeed, the indexing callbacks (and potentially others fields) were
081b2d
    stored in the temporary pblock that was memcpy to the provided
081b2d
    pblock in case of success
816ad1
816ad1
Fix Description:
081b2d
    The fix basically restores the previous behavior but do not
081b2d
    memcpy pblock. It read/store the pblock fields that are
081b2d
    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
---
081b2d
 ldap/servers/slapd/plugin_mr.c | 148 ++++++++++++++++++++++++++++-------------
081b2d
 1 file changed, 103 insertions(+), 45 deletions(-)
816ad1
816ad1
diff --git a/ldap/servers/slapd/plugin_mr.c b/ldap/servers/slapd/plugin_mr.c
081b2d
index bd2baff6c..ca4fe00e1 100644
816ad1
--- a/ldap/servers/slapd/plugin_mr.c
816ad1
+++ b/ldap/servers/slapd/plugin_mr.c
081b2d
@@ -143,6 +143,82 @@ plugin_mr_bind(char *oid, struct slapdplugin *plugin)
081b2d
     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;
081b2d
+
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);
081b2d
+
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);
081b2d
+
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);
081b2d
+
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
081b2d
+ *
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 */
081b2d
     slapi_mr_indexer_create(Slapi_PBlock *opb)
816ad1
 {
081b2d
@@ -152,28 +228,33 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */
081b2d
         IFP createFn = NULL;
081b2d
         struct slapdplugin *mrp = plugin_mr_find_registered(oid);
081b2d
         if (mrp != NULL) {
816ad1
+            /* Great the matching OID -> MR plugin was already found, just reuse it */
081b2d
             if (!(rc = slapi_pblock_set(opb, SLAPI_PLUGIN, mrp)) &&
081b2d
                 !(rc = slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) &&
081b2d
                 createFn != NULL) {
081b2d
                 rc = createFn(opb);
081b2d
             }
081b2d
         } else {
081b2d
-            /* call each plugin, until one is able to handle this request. */
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
+             */
081b2d
             rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
081b2d
-            // We need to get the type and usage from the caller.
081b2d
-            char *type;
081b2d
-            uint32_t usage;
081b2d
-            slapi_pblock_get(opb, SLAPI_PLUGIN_MR_TYPE, &type);
081b2d
-            slapi_pblock_get(opb, SLAPI_PLUGIN_MR_USAGE, &usage);
816ad1
+
081b2d
             for (mrp = get_plugin_list(PLUGIN_LIST_MATCHINGRULE); mrp != NULL; mrp = mrp->plg_next) {
081b2d
 
081b2d
                 Slapi_PBlock *pb = slapi_pblock_new();
816ad1
+                mr_indexer_init_pb(opb, pb);
081b2d
                 slapi_pblock_set(pb, SLAPI_PLUGIN, mrp);
081b2d
-                /* From filtercmp.c and matchrule.c, these are the values we need to set. into pb */
081b2d
-                slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, oid);
081b2d
-                slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, type);
081b2d
-                slapi_pblock_set(pb, SLAPI_PLUGIN_MR_USAGE, &usage);
081b2d
-
081b2d
                 /* This is associated with the pb_plugin struct, so it comes with mrp */
081b2d
                 if (slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, &createFn)) {
081b2d
                     /* plugin not a matchingrule type */
081b2d
@@ -185,14 +266,11 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */
081b2d
                     IFP indexFn = NULL;
081b2d
                     IFP indexSvFn = NULL;
081b2d
                     /* These however, are in the pblock direct, so we need to copy them. */
081b2d
-                    slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
081b2d
-                    slapi_pblock_get(opb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
081b2d
-                    slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, indexFn);
081b2d
-                    slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, indexSvFn);
816ad1
+                    slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &indexFn);
816ad1
+                    slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &indexSvFn);
081b2d
                     if (indexFn || indexSvFn) {
081b2d
                         /* Success: this plugin can handle it. */
081b2d
-                        /* call create on the opb? */
081b2d
-                        createFn(opb);
816ad1
+                        mr_indexer_init_pb(pb, opb);
081b2d
                         plugin_mr_bind(oid, mrp); /* for future reference */
081b2d
                         rc = 0;                   /* success */
081b2d
                         slapi_pblock_destroy(pb);
081b2d
@@ -205,37 +283,12 @@ int /* an LDAP error code, hopefully LDAP_SUCCESS */
081b2d
                 /* look for a new syntax-style mr plugin */
081b2d
                 struct slapdplugin *pi = plugin_mr_find(oid);
081b2d
                 if (pi) {
081b2d
-                    Slapi_PBlock *pb = slapi_pblock_new();
081b2d
-                    slapi_pblock_set(pb, SLAPI_PLUGIN_MR_OID, oid);
081b2d
-                    slapi_pblock_set(pb, SLAPI_PLUGIN_MR_TYPE, type);
081b2d
-                    slapi_pblock_set(pb, SLAPI_PLUGIN_MR_USAGE, &usage);
081b2d
-                    slapi_pblock_set(pb, SLAPI_PLUGIN, pi);
081b2d
-                    rc = default_mr_indexer_create(pb);
816ad1
+                    slapi_pblock_set(opb, SLAPI_PLUGIN, pi);
816ad1
+                    rc = default_mr_indexer_create(opb);
081b2d
                     if (!rc) {
081b2d
-                        /* On success, copy the needed values in. These are added by default_mr_indexer_create */
081b2d
-                        void *pb_object = NULL;
081b2d
-                        IFP destroy_fn = NULL;
081b2d
-                        IFP index_fn = NULL;
081b2d
-                        IFP index_sv_fn = NULL;
081b2d
-
081b2d
-                        slapi_pblock_get(pb, SLAPI_PLUGIN_OBJECT, &pb_object);
081b2d
-                        slapi_pblock_get(pb, SLAPI_PLUGIN_DESTROY_FN, &destroy_fn);
081b2d
-                        slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_FN, &index_fn);
081b2d
-                        slapi_pblock_get(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, &index_sv_fn);
081b2d
-
081b2d
-                        /* SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, and SLAPI_PLUGIN_MR_FILTER_CREATE_FN, are part of pb_plugin */
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN, pi);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_MR_OID, oid);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_MR_TYPE, type);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_MR_USAGE, &usage);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_OBJECT, pb_object);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_DESTROY_FN, destroy_fn);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_MR_INDEX_FN, index_fn);
081b2d
-                        slapi_pblock_set(opb, SLAPI_PLUGIN_MR_INDEX_SV_FN, index_sv_fn);
081b2d
-
081b2d
                         plugin_mr_bind(oid, pi); /* for future reference */
081b2d
                     }
081b2d
-                    slapi_pblock_destroy(pb);
816ad1
+                    slapi_pblock_set(opb, SLAPI_PLUGIN, NULL);
081b2d
                 }
081b2d
             }
081b2d
         }
081b2d
@@ -706,6 +759,11 @@ default_mr_indexer_create(Slapi_PBlock *pb)
081b2d
     slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_FN, mr_wrap_mr_index_fn);
081b2d
     slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEX_SV_FN, mr_wrap_mr_index_sv_fn);
081b2d
     slapi_pblock_set(pb, SLAPI_PLUGIN_DESTROY_FN, default_mr_indexer_destroy);
816ad1
+
081b2d
+    /* Note the two following setting are in the slapdplugin struct SLAPI_PLUGIN
081b2d
+     * so they are not really output of the function but will just
081b2d
+     * be stored in the bound (OID <--> plugin) list (plugin_mr_find_registered/plugin_mr_bind)
081b2d
+     */
081b2d
     slapi_pblock_set(pb, SLAPI_PLUGIN_MR_INDEXER_CREATE_FN, default_mr_indexer_create);
081b2d
     slapi_pblock_set(pb, SLAPI_PLUGIN_MR_FILTER_CREATE_FN, default_mr_filter_create);
081b2d
     rc = 0;
816ad1
-- 
816ad1
2.13.6
816ad1