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

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