Blame SOURCES/0014-Issue-50201-nsIndexIDListScanLimit-accepts-any-value.patch

5873fa
From f60364cd9472edc61e7d327d13dca67eadf0c5b2 Mon Sep 17 00:00:00 2001
5873fa
From: Simon Pichugin <simon.pichugin@gmail.com>
5873fa
Date: Tue, 28 Apr 2020 23:44:20 +0200
5873fa
Subject: [PATCH] Issue 50201 - nsIndexIDListScanLimit accepts any value
5873fa
5873fa
Bug Description: Setting of nsIndexIDListScanLimit like
5873fa
'limit=2 limit=3' are detected and logged in error logs.
5873fa
But the invalid value is successfully applied in the config entry
5873fa
and the operation itself is successful.
5873fa
The impact is limited because the index will be used following
5873fa
idlistscanlimit rather than invalid definition nsIndexIDListScanLimit.
5873fa
5873fa
Fix Description: Print the errors to the user when he tries to add
5873fa
or to modify index config entry with malformed values.
5873fa
Change tests accordingly.
5873fa
5873fa
https://pagure.io/389-ds-base/issue/50201
5873fa
5873fa
Reviewed by: mreynolds, tbordaz (Thanks!)
5873fa
---
5873fa
 .../suites/filter/filterscanlimit_test.py     | 87 ++++++++-----------
5873fa
 ldap/servers/slapd/back-ldbm/instance.c       |  4 +-
5873fa
 ldap/servers/slapd/back-ldbm/ldbm_attr.c      | 33 ++++++-
5873fa
 .../slapd/back-ldbm/ldbm_index_config.c       | 59 +++++++++----
5873fa
 ldap/servers/slapd/back-ldbm/ldif2ldbm.c      |  2 +-
5873fa
 .../servers/slapd/back-ldbm/proto-back-ldbm.h |  2 +-
5873fa
 6 files changed, 114 insertions(+), 73 deletions(-)
5873fa
5873fa
diff --git a/dirsrvtests/tests/suites/filter/filterscanlimit_test.py b/dirsrvtests/tests/suites/filter/filterscanlimit_test.py
5873fa
index dd9c6ee4e..0198f6533 100644
5873fa
--- a/dirsrvtests/tests/suites/filter/filterscanlimit_test.py
5873fa
+++ b/dirsrvtests/tests/suites/filter/filterscanlimit_test.py
5873fa
@@ -11,6 +11,7 @@ This script will test different type of Filers.
5873fa
 """
5873fa
 
5873fa
 import os
5873fa
+import ldap
5873fa
 import pytest
5873fa
 
5873fa
 from lib389._constants import DEFAULT_SUFFIX, PW_DM
5873fa
@@ -19,11 +20,10 @@ from lib389.idm.user import UserAccounts
5873fa
 from lib389.idm.organizationalunit import OrganizationalUnits
5873fa
 from lib389.index import Index
5873fa
 from lib389.idm.account import Accounts
5873fa
-from lib389.idm.group import UniqueGroups, Group
5873fa
+from lib389.idm.group import UniqueGroups
5873fa
 
5873fa
 pytestmark = pytest.mark.tier1
5873fa
 
5873fa
-
5873fa
 GIVEN_NAME = 'cn=givenname,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
5873fa
 CN_NAME = 'cn=sn,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
5873fa
 UNIQMEMBER = 'cn=uniquemember,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
5873fa
@@ -39,7 +39,6 @@ LIST_OF_USER_ACCOUNTING = [
5873fa
     "Judy Wallace",
5873fa
     "Marcus Ward",
5873fa
     "Judy McFarland",
5873fa
-    "Anuj Hall",
5873fa
     "Gern Triplett",
5873fa
     "Emanuel Johnson",
5873fa
     "Brad Walker",
5873fa
@@ -57,7 +56,6 @@ LIST_OF_USER_ACCOUNTING = [
5873fa
     "Randy Ulrich",
5873fa
     "Richard Francis",
5873fa
     "Morgan White",
5873fa
-    "Anuj Maddox",
5873fa
     "Jody Jensen",
5873fa
     "Mike Carter",
5873fa
     "Gern Tyler",
5873fa
@@ -77,8 +75,6 @@ LIST_OF_USER_HUMAN = [
5873fa
     "Robert Daugherty",
5873fa
     "Torrey Mason",
5873fa
     "Brad Talbot",
5873fa
-    "Anuj Jablonski",
5873fa
-    "Harry Miller",
5873fa
     "Jeffrey Campaigne",
5873fa
     "Stephen Triplett",
5873fa
     "John Falena",
5873fa
@@ -107,8 +103,7 @@ LIST_OF_USER_HUMAN = [
5873fa
     "Tobias Schmith",
5873fa
     "Jon Goldstein",
5873fa
     "Janet Lutz",
5873fa
-    "Karl Cope",
5873fa
-]
5873fa
+    "Karl Cope"]
5873fa
 
5873fa
 LIST_OF_USER_TESTING = [
5873fa
     "Andy Bergin",
5873fa
@@ -122,8 +117,7 @@ LIST_OF_USER_TESTING = [
5873fa
     "Alan White",
5873fa
     "Daniel Ward",
5873fa
     "Lee Stockton",
5873fa
-    "Matthew Vaughan"
5873fa
-]
5873fa
+    "Matthew Vaughan"]
5873fa
 
5873fa
 LIST_OF_USER_DEVELOPMENT = [
5873fa
     "Kelly Winters",
5873fa
@@ -143,7 +137,6 @@ LIST_OF_USER_DEVELOPMENT = [
5873fa
     "Timothy Kelly",
5873fa
     "Sue Mason",
5873fa
     "Chris Alexander",
5873fa
-    "Anuj Jensen",
5873fa
     "Martin Talbot",
5873fa
     "Scott Farmer",
5873fa
     "Allison Jensen",
5873fa
@@ -152,9 +145,7 @@ LIST_OF_USER_DEVELOPMENT = [
5873fa
     "Dan Langdon",
5873fa
     "Ashley Knutson",
5873fa
     "Jon Bourke",
5873fa
-    "Pete Hunt",
5873fa
-
5873fa
-]
5873fa
+    "Pete Hunt"]
5873fa
 
5873fa
 LIST_OF_USER_PAYROLL = [
5873fa
     "Ashley Chassin",
5873fa
@@ -164,12 +155,17 @@ LIST_OF_USER_PAYROLL = [
5873fa
     "Patricia Shelton",
5873fa
     "Dietrich Swain",
5873fa
     "Allison Hunter",
5873fa
-    "Anne-Louise Barnes"
5873fa
+    "Anne-Louise Barnes"]
5873fa
 
5873fa
-]
5873fa
+LIST_OF_USER_PEOPLE = [
5873fa
+    'Sam Carter',
5873fa
+    'Tom Morris',
5873fa
+    'Kevin Vaughan',
5873fa
+    'Rich Daugherty',
5873fa
+    'Harry Miller',
5873fa
+    'Sam Schmith']
5873fa
 
5873fa
 
5873fa
-@pytest.mark.skip(reason="https://pagure.io/389-ds-base/issue/50201")
5873fa
 def test_invalid_configuration(topo):
5873fa
     """"
5873fa
     Error handling for invalid configuration
5873fa
@@ -190,10 +186,7 @@ def test_invalid_configuration(topo):
5873fa
               'limit=0 flags=AND flags=AND',
5873fa
               'limit=0 type=eq values=foo values=foo',
5873fa
               'limit=0 type=eq values=foo,foo',
5873fa
-              'limit=0 type=sub',
5873fa
-              'limit=0 type=eq values=notvalid',
5873fa
               'limit',
5873fa
-              'limit=0 type=eq values=notavaliddn',
5873fa
               'limit=0 type=pres values=bogus',
5873fa
               'limit=0 type=eq,sub values=bogus',
5873fa
               'limit=',
5873fa
@@ -203,7 +196,8 @@ def test_invalid_configuration(topo):
5873fa
               'limit=-2',
5873fa
               'type=eq',
5873fa
               'limit=0 type=bogus']:
5873fa
-        Index(topo.standalone, GIVEN_NAME).replace('nsIndexIDListScanLimit', i)
5873fa
+        with pytest.raises(ldap.UNWILLING_TO_PERFORM):
5873fa
+            Index(topo.standalone, GIVEN_NAME).replace('nsIndexIDListScanLimit', i)
5873fa
 
5873fa
 
5873fa
 def test_idlistscanlimit(topo):
5873fa
@@ -247,28 +241,24 @@ def test_idlistscanlimit(topo):
5873fa
                  (LIST_OF_USER_HUMAN, users_human),
5873fa
                  (LIST_OF_USER_TESTING, users_testing),
5873fa
                  (LIST_OF_USER_DEVELOPMENT, users_development),
5873fa
-                 (LIST_OF_USER_PAYROLL, users_payroll)]:
5873fa
+                 (LIST_OF_USER_PAYROLL, users_payroll),
5873fa
+                 (LIST_OF_USER_PEOPLE, users_people)]:
5873fa
         for demo1 in data[0]:
5873fa
+            fn = demo1.split()[0]
5873fa
+            sn = demo1.split()[1]
5873fa
+            uid = ''.join([fn[:1], sn]).lower()
5873fa
             data[1].create(properties={
5873fa
-                'uid': demo1,
5873fa
+                'uid': uid,
5873fa
                 'cn': demo1,
5873fa
-                'sn': demo1.split()[1],
5873fa
+                'sn': sn,
5873fa
                 'uidNumber': str(1000),
5873fa
                 'gidNumber': '2000',
5873fa
-                'homeDirectory': '/home/' + demo1,
5873fa
-                'givenname': demo1.split()[0],
5873fa
-                'userpassword': PW_DM
5873fa
+                'homeDirectory': f'/home/{uid}',
5873fa
+                'givenname': fn,
5873fa
+                'userpassword': PW_DM,
5873fa
+                'mail': f'{uid}@test.com'
5873fa
             })
5873fa
 
5873fa
-    users_people.create(properties={
5873fa
-        'uid': 'scarter',
5873fa
-        'cn': 'Sam Carter',
5873fa
-        'sn': 'Carter',
5873fa
-        'uidNumber': str(1000),
5873fa
-        'gidNumber': '2000',
5873fa
-        'homeDirectory': '/home/' + 'scarter',
5873fa
-        'mail': 'scarter@anuj.com',
5873fa
-    })
5873fa
     try:
5873fa
         # Change log levels
5873fa
         errorlog_value = topo.standalone.config.get_attr_val_utf8('nsslapd-errorlog-level')
5873fa
@@ -297,16 +287,12 @@ def test_idlistscanlimit(topo):
5873fa
 
5873fa
         Index(topo.standalone, UNIQMEMBER).\
5873fa
         replace('nsIndexIDListScanLimit',
5873fa
-                'limit=0 type=eq values=uid=kvaughan,ou=People,'
5873fa
-                'dc=example,dc=com,uid=rdaugherty,ou=People,dc=example,dc=com')
5873fa
+                'limit=0 type=eq values=uid=kvaughan\2Cou=People\2Cdc=example\2Cdc=com,'
5873fa
+                'uid=rdaugherty\2Cou=People\2Cdc=example\2Cdc=com')
5873fa
 
5873fa
         Index(topo.standalone, OBJECTCLASS).\
5873fa
         replace('nsIndexIDListScanLimit', 'limit=0 type=eq flags=AND values=inetOrgPerson')
5873fa
 
5873fa
-        Index(topo.standalone, MAIL).\
5873fa
-        replace('nsIndexIDListScanLimit',
5873fa
-                'cn=mail,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config')
5873fa
-
5873fa
         # Search with filter
5873fa
         for i in ['(sn=Lutz)',
5873fa
                   '(sn=*ter)',
5873fa
@@ -321,22 +307,24 @@ def test_idlistscanlimit(topo):
5873fa
                   '(&(sn=*)(cn=*))',
5873fa
                   '(sn=Hunter)',
5873fa
                   '(&(givenname=Richard)(objectclass=organizationalPerson))',
5873fa
-                  '(givenname=Anuj)',
5873fa
+                  '(givenname=Morgan)',
5873fa
                   '(&(givenname=*)(cn=*))',
5873fa
                   '(givenname=*)']:
5873fa
             assert Accounts(topo.standalone, DEFAULT_SUFFIX).filter(f'{i}')
5873fa
 
5873fa
-        # Creating Group
5873fa
-        Group(topo.standalone, 'cn=Accounting Managers,ou=groups,dc=example,dc=com').\
5873fa
-        add('uniquemember',
5873fa
+        # Creating Groups and adding members
5873fa
+        groups = UniqueGroups(topo.standalone, DEFAULT_SUFFIX)
5873fa
+        accounting_managers = groups.ensure_state(properties={'cn': 'Accounting Managers'})
5873fa
+        hr_managers = groups.ensure_state(properties={'cn': 'HR Managers'})
5873fa
+
5873fa
+        accounting_managers.add('uniquemember',
5873fa
             ['uid=scarter, ou=People, dc=example,dc=com',
5873fa
              'uid=tmorris, ou=People, dc=example,dc=com',
5873fa
              'uid=kvaughan, ou=People, dc=example,dc=com',
5873fa
              'uid=rdaugherty, ou=People, dc=example,dc=com',
5873fa
              'uid=hmiller, ou=People, dc=example,dc=com'])
5873fa
 
5873fa
-        Group(topo.standalone, 'cn=HR Managers,ou=groups,dc=example,dc=com').\
5873fa
-        add('uniquemember',
5873fa
+        hr_managers.add('uniquemember',
5873fa
             ['uid=kvaughan, ou=People, dc=example,dc=com',
5873fa
              'uid=cschmith, ou=People, dc=example,dc=com'])
5873fa
 
5873fa
@@ -403,10 +391,9 @@ def test_idlistscanlimit(topo):
5873fa
                       '(&(sn=*)(cn=*))',
5873fa
                       '(sn=Hunter)',
5873fa
                       '(&(givenname=Richard)(objectclass=organizationalPerson))',
5873fa
-                      '(givenname=Anuj)',
5873fa
+                      '(givenname=Morgan)',
5873fa
                       '(&(givenname=*)(cn=*))',
5873fa
                       '(givenname=*)']:
5873fa
-
5873fa
             assert Accounts(topo.standalone, DEFAULT_SUFFIX).filter(value)
5873fa
 
5873fa
     finally:
5873fa
diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
5873fa
index 04c28ff39..07655a8ec 100644
5873fa
--- a/ldap/servers/slapd/back-ldbm/instance.c
5873fa
+++ b/ldap/servers/slapd/back-ldbm/instance.c
5873fa
@@ -231,7 +231,7 @@ ldbm_instance_create_default_indexes(backend *be)
5873fa
 
5873fa
     /* ldbm_instance_config_add_index_entry(inst, 2, argv); */
5873fa
     e = ldbm_instance_init_config_entry(LDBM_PSEUDO_ATTR_DEFAULT, "none", 0, 0, 0);
5873fa
-    attr_index_config(be, "ldbm index init", 0, e, 1, 0);
5873fa
+    attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL);
5873fa
     slapi_entry_free(e);
5873fa
 
5873fa
     if (!entryrdn_get_noancestorid()) {
5873fa
@@ -240,7 +240,7 @@ ldbm_instance_create_default_indexes(backend *be)
5873fa
          * but we still want to use the attr index file APIs.
5873fa
          */
5873fa
         e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR, "eq", 0, 0, 0);
5873fa
-        attr_index_config(be, "ldbm index init", 0, e, 1, 0);
5873fa
+        attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL);
5873fa
         slapi_entry_free(e);
5873fa
     }
5873fa
 
5873fa
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
5873fa
index b9e130d77..f0d418572 100644
5873fa
--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
5873fa
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
5873fa
@@ -633,6 +633,18 @@ attr_index_idlistsize_config(Slapi_Entry *e, struct attrinfo *ai, char *returnte
5873fa
     return rc;
5873fa
 }
5873fa
 
5873fa
+/*
5873fa
+ * Function that process index attributes and modifies attrinfo structure
5873fa
+ *
5873fa
+ * Called while adding default indexes, during db2index execution and
5873fa
+ * when we add/modify/delete index config entry
5873fa
+ *
5873fa
+ * If char *err_buf is not NULL, it will additionally print all error messages to STDERR
5873fa
+ * It is used when we add/modify/delete index config entry, so the user would have a better verbose
5873fa
+ *
5873fa
+ * returns -1, 1 on a failure
5873fa
+ *         0 on success
5873fa
+ */
5873fa
 int
5873fa
 attr_index_config(
5873fa
     backend *be,
5873fa
@@ -640,7 +652,8 @@ attr_index_config(
5873fa
     int lineno,
5873fa
     Slapi_Entry *e,
5873fa
     int init __attribute__((unused)),
5873fa
-    int indextype_none)
5873fa
+    int indextype_none,
5873fa
+    char *err_buf)
5873fa
 {
5873fa
     ldbm_instance *inst = (ldbm_instance *)be->be_instance_info;
5873fa
     int j = 0;
5873fa
@@ -662,6 +675,7 @@ attr_index_config(
5873fa
         slapi_attr_first_value(attr, &sval);
5873fa
         attrValue = slapi_value_get_berval(sval);
5873fa
     } else {
5873fa
+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: missing indexing arguments\n");
5873fa
         slapi_log_err(SLAPI_LOG_ERR, "attr_index_config", "Missing indexing arguments\n");
5873fa
         return -1;
5873fa
     }
5873fa
@@ -705,6 +719,10 @@ attr_index_config(
5873fa
                 }
5873fa
                 a->ai_indexmask = INDEX_OFFLINE; /* note that the index isn't available */
5873fa
             } else {
5873fa
+                slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                                      "Error: %s: line %d: unknown index type \"%s\" (ignored) in entry (%s), "
5873fa
+                                      "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n",
5873fa
+                                      fname, lineno, attrValue->bv_val, slapi_entry_get_dn(e));
5873fa
                 slapi_log_err(SLAPI_LOG_ERR, "attr_index_config",
5873fa
                               "%s: line %d: unknown index type \"%s\" (ignored) in entry (%s), "
5873fa
                               "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n",
5873fa
@@ -715,6 +733,7 @@ attr_index_config(
5873fa
         }
5873fa
         if (hasIndexType == 0) {
5873fa
             /* indexType missing, error out */
5873fa
+            slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: missing index type\n");
5873fa
             slapi_log_err(SLAPI_LOG_ERR, "attr_index_config", "Missing index type\n");
5873fa
             attrinfo_delete(&a);
5873fa
             return -1;
5873fa
@@ -873,16 +892,26 @@ attr_index_config(
5873fa
             slapi_ch_free((void **)&official_rules);
5873fa
         }
5873fa
     }
5873fa
-
5873fa
     if ((return_value = attr_index_idlistsize_config(e, a, myreturntext))) {
5873fa
+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: %s: Failed to parse idscanlimit info: %d:%s\n",
5873fa
+                              fname, return_value, myreturntext);
5873fa
         slapi_log_err(SLAPI_LOG_ERR, "attr_index_config", "%s: Failed to parse idscanlimit info: %d:%s\n",
5873fa
                       fname, return_value, myreturntext);
5873fa
+        if (err_buf != NULL) {
5873fa
+            /* we are inside of a callback, we shouldn't allow malformed attributes in index entries */
5873fa
+            attrinfo_delete(&a);
5873fa
+            return return_value;
5873fa
+        }
5873fa
     }
5873fa
 
5873fa
     /* initialize the IDL code's private data */
5873fa
     return_value = idl_init_private(be, a);
5873fa
     if (0 != return_value) {
5873fa
         /* fatal error, exit */
5873fa
+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: %s: line %d:Fatal Error: Failed to initialize attribute structure\n",
5873fa
+                              fname, lineno);
5873fa
         slapi_log_err(SLAPI_LOG_CRIT, "attr_index_config",
5873fa
                       "%s: line %d:Fatal Error: Failed to initialize attribute structure\n",
5873fa
                       fname, lineno);
5873fa
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
5873fa
index 45f0034f0..720f93036 100644
5873fa
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
5873fa
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
5873fa
@@ -25,26 +25,34 @@ int ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry *en
5873fa
 #define INDEXTYPE_NONE 1
5873fa
 
5873fa
 static int
5873fa
-ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name)
5873fa
+ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name, char *err_buf)
5873fa
 {
5873fa
     Slapi_Attr *attr;
5873fa
     const struct berval *attrValue;
5873fa
     Slapi_Value *sval;
5873fa
+    char *edn = slapi_entry_get_dn(e);
5873fa
 
5873fa
     /* Get the name of the attribute to index which will be the value
5873fa
      * of the cn attribute. */
5873fa
     if (slapi_entry_attr_find(e, "cn", &attr) != 0) {
5873fa
-        slapi_log_err(SLAPI_LOG_ERR, "ldbm_index_parse_entry", "Malformed index entry %s\n",
5873fa
-                      slapi_entry_get_dn(e));
5873fa
+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: malformed index entry %s\n",
5873fa
+                              edn);
5873fa
+        slapi_log_err(SLAPI_LOG_ERR,
5873fa
+                      "ldbm_index_parse_entry", "Malformed index entry %s\n",
5873fa
+                      edn);
5873fa
         return LDAP_OPERATIONS_ERROR;
5873fa
     }
5873fa
 
5873fa
     slapi_attr_first_value(attr, &sval);
5873fa
     attrValue = slapi_value_get_berval(sval);
5873fa
     if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
5873fa
+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: malformed index entry %s -- empty index name\n",
5873fa
+                              edn);
5873fa
         slapi_log_err(SLAPI_LOG_ERR,
5873fa
                       "ldbm_index_parse_entry", "Malformed index entry %s -- empty index name\n",
5873fa
-                      slapi_entry_get_dn(e));
5873fa
+                      edn);
5873fa
         return LDAP_OPERATIONS_ERROR;
5873fa
     }
5873fa
 
5873fa
@@ -59,16 +67,19 @@ ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_st
5873fa
         attrValue = slapi_value_get_berval(sval);
5873fa
         if (NULL == attrValue->bv_val || attrValue->bv_len == 0) {
5873fa
             /* missing the index type, error out */
5873fa
-            slapi_log_err(SLAPI_LOG_ERR,
5873fa
-                          "ldbm_index_parse_entry", "Malformed index entry %s -- empty nsIndexType\n",
5873fa
-                          slapi_entry_get_dn(e));
5873fa
+            slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                                  "Error: malformed index entry %s -- empty nsIndexType\n",
5873fa
+                                  edn);
5873fa
+            slapi_log_err(SLAPI_LOG_ERR, "ldbm_index_parse_entry",
5873fa
+                          "Malformed index entry %s -- empty nsIndexType\n",
5873fa
+                          edn);
5873fa
             slapi_ch_free_string(index_name);
5873fa
             return LDAP_OPERATIONS_ERROR;
5873fa
         }
5873fa
     }
5873fa
 
5873fa
     /* ok the entry is good to process, pass it to attr_index_config */
5873fa
-    if (attr_index_config(inst->inst_be, (char *)trace_string, 0, e, 0, 0)) {
5873fa
+    if (attr_index_config(inst->inst_be, (char *)trace_string, 0, e, 0, 0, err_buf)) {
5873fa
         slapi_ch_free_string(index_name);
5873fa
         return LDAP_OPERATIONS_ERROR;
5873fa
     }
5873fa
@@ -92,7 +103,7 @@ ldbm_index_init_entry_callback(Slapi_PBlock *pb __attribute__((unused)),
5873fa
     ldbm_instance *inst = (ldbm_instance *)arg;
5873fa
 
5873fa
     returntext[0] = '\0';
5873fa
-    *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL);
5873fa
+    *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL, NULL);
5873fa
     if (*returncode == LDAP_SUCCESS) {
5873fa
         return SLAPI_DSE_CALLBACK_OK;
5873fa
     } else {
5873fa
@@ -117,7 +128,7 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb __attribute__((unused))
5873fa
     char *index_name = NULL;
5873fa
 
5873fa
     returntext[0] = '\0';
5873fa
-    *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name);
5873fa
+    *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, returntext);
5873fa
     if (*returncode == LDAP_SUCCESS) {
5873fa
         struct attrinfo *ai = NULL;
5873fa
         /* if the index is a "system" index, we assume it's being added by
5873fa
@@ -179,7 +190,7 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb,
5873fa
     slapi_attr_first_value(attr, &sval);
5873fa
     attrValue = slapi_value_get_berval(sval);
5873fa
 
5873fa
-    attr_index_config(inst->inst_be, "From DSE delete", 0, e, 0, INDEXTYPE_NONE);
5873fa
+    attr_index_config(inst->inst_be, "From DSE delete", 0, e, 0, INDEXTYPE_NONE, returntext);
5873fa
 
5873fa
     ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
5873fa
     if (NULL == ainfo) {
5873fa
@@ -213,14 +224,19 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb __attribute__((unuse
5873fa
     Slapi_Value *sval;
5873fa
     const struct berval *attrValue;
5873fa
     struct attrinfo *ainfo = NULL;
5873fa
+    char *edn = slapi_entry_get_dn(e);
5873fa
+    char *edn_after = slapi_entry_get_dn(entryAfter);
5873fa
 
5873fa
     returntext[0] = '\0';
5873fa
     *returncode = LDAP_SUCCESS;
5873fa
 
5873fa
     if (slapi_entry_attr_find(entryAfter, "cn", &attr) != 0) {
5873fa
+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: malformed index entry %s - missing cn attribute\n",
5873fa
+                              edn_after);
5873fa
         slapi_log_err(SLAPI_LOG_ERR,
5873fa
                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s - missing cn attribute\n",
5873fa
-                      slapi_entry_get_dn(entryAfter));
5873fa
+                      edn_after);
5873fa
         *returncode = LDAP_OBJECT_CLASS_VIOLATION;
5873fa
         return SLAPI_DSE_CALLBACK_ERROR;
5873fa
     }
5873fa
@@ -228,31 +244,40 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb __attribute__((unuse
5873fa
     attrValue = slapi_value_get_berval(sval);
5873fa
 
5873fa
     if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
5873fa
+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: malformed index entry %s - missing index name\n",
5873fa
+                              edn);
5873fa
         slapi_log_err(SLAPI_LOG_ERR,
5873fa
                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s, missing index name\n",
5873fa
-                      slapi_entry_get_dn(e));
5873fa
+                      edn);
5873fa
         *returncode = LDAP_UNWILLING_TO_PERFORM;
5873fa
         return SLAPI_DSE_CALLBACK_ERROR;
5873fa
     }
5873fa
 
5873fa
     ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
5873fa
     if (NULL == ainfo) {
5873fa
+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: malformed index entry %s - missing cn attribute info\n",
5873fa
+                              edn);
5873fa
         slapi_log_err(SLAPI_LOG_ERR,
5873fa
                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s - missing cn attribute info\n",
5873fa
-                      slapi_entry_get_dn(e));
5873fa
+                      edn);
5873fa
         *returncode = LDAP_UNWILLING_TO_PERFORM;
5873fa
         return SLAPI_DSE_CALLBACK_ERROR;
5873fa
     }
5873fa
 
5873fa
     if (slapi_entry_attr_find(entryAfter, "nsIndexType", &attr) != 0) {
5873fa
+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
5873fa
+                              "Error: malformed index entry %s - missing nsIndexType attribute\n",
5873fa
+                              edn_after);
5873fa
         slapi_log_err(SLAPI_LOG_ERR,
5873fa
                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s - missing nsIndexType attribute\n",
5873fa
-                      slapi_entry_get_dn(entryAfter));
5873fa
+                      edn_after);
5873fa
         *returncode = LDAP_OBJECT_CLASS_VIOLATION;
5873fa
         return SLAPI_DSE_CALLBACK_ERROR;
5873fa
     }
5873fa
 
5873fa
-    if (attr_index_config(inst->inst_be, "from DSE modify", 0, entryAfter, 0, 0)) {
5873fa
+    if (attr_index_config(inst->inst_be, "from DSE modify", 0, entryAfter, 0, 0, returntext)) {
5873fa
         *returncode = LDAP_UNWILLING_TO_PERFORM;
5873fa
         return SLAPI_DSE_CALLBACK_ERROR;
5873fa
     }
5873fa
@@ -364,7 +389,7 @@ ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry *e)
5873fa
         ainfo_get(inst->inst_be, index_name, &ai);
5873fa
     }
5873fa
     if (!ai) {
5873fa
-        rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name);
5873fa
+        rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, NULL);
5873fa
     }
5873fa
     if (rc == LDAP_SUCCESS) {
5873fa
         /* Assume the caller knows if it is OK to go online immediately */
5873fa
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
5873fa
index 9d82c8228..f2ef5ecd4 100644
5873fa
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
5873fa
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
5873fa
@@ -291,7 +291,7 @@ db2index_add_indexed_attr(backend *be, char *attrString)
5873fa
         }
5873fa
     }
5873fa
 
5873fa
-    attr_index_config(be, "from db2index()", 0, e, 0, 0);
5873fa
+    attr_index_config(be, "from db2index()", 0, e, 0, 0, NULL);
5873fa
     slapi_entry_free(e);
5873fa
 
5873fa
     return (0);
5873fa
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
5873fa
index 9a86c752b..a07acee5e 100644
5873fa
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
5873fa
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
5873fa
@@ -24,7 +24,7 @@ void attrinfo_delete(struct attrinfo **pp);
5873fa
 void ainfo_get(backend *be, char *type, struct attrinfo **at);
5873fa
 void attr_masks(backend *be, char *type, int *indexmask, int *syntaxmask);
5873fa
 void attr_masks_ex(backend *be, char *type, int *indexmask, int *syntaxmask, struct attrinfo **at);
5873fa
-int attr_index_config(backend *be, char *fname, int lineno, Slapi_Entry *e, int init, int none);
5873fa
+int attr_index_config(backend *be, char *fname, int lineno, Slapi_Entry *e, int init, int none, char *err_buf);
5873fa
 int db2index_add_indexed_attr(backend *be, char *attrString);
5873fa
 int ldbm_compute_init(void);
5873fa
 void attrinfo_deletetree(ldbm_instance *inst);
5873fa
-- 
5873fa
2.26.2
5873fa