From a57b849d9d52b133333374b82f28609365ef97f4 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mareynol@redhat.com>
Date: Wed, 1 Feb 2012 14:39:16 -0500
Subject: [PATCH] Ticket #55 - Limit of 1024 characters for nsMatchingRule

Bug Description:  If the total length of all the nsMatchingRule attribute values in an index, exceeds
                  1024 characters, the remaining values will get truncated.

Fix Description:  Previously there was static buffer of 1024 chars. The reason for creating the buffer
                  was to comply with some older code.  Where we needed to take slapi attrs, and
                  convert them into comma separated lists. I changed the code to just use the slapi attrs
                  instead of comma separated lists.  Thus removing all the static buffers in this area of
                  the code.

                  I also, removed some unneccessary loops that were checking for muliple cn values.  This
                  was not neccessary.  However removing the loop caused a lot of indentation changes,
                  which makes the diff quite long.

	https://fedorahosted.org/389/ticket/55

Thanks for the review Rich!
---
 ldap/servers/slapd/back-ldbm/instance.c          |  131 +++--
 ldap/servers/slapd/back-ldbm/ldbm_attr.c         |  324 ++++++-----
 ldap/servers/slapd/back-ldbm/ldbm_config.h       |    3 +-
 ldap/servers/slapd/back-ldbm/ldbm_index_config.c |  681 ++++------------------
 ldap/servers/slapd/back-ldbm/ldif2ldbm.c         |   39 +-
 ldap/servers/slapd/back-ldbm/proto-back-ldbm.h   |    2 +-
 6 files changed, 396 insertions(+), 784 deletions(-)

diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
index 0217e96..dd8c673 100644
--- a/ldap/servers/slapd/back-ldbm/instance.c
+++ b/ldap/servers/slapd/back-ldbm/instance.c
@@ -44,7 +44,7 @@
 
 /* Forward declarations */
 static void ldbm_instance_destructor(void **arg);
-
+Slapi_Entry *ldbm_instance_init_config_entry(char *cn_val, char *v1, char *v2, char *v3, char *v4);
 
 
 /* Creates and initializes a new ldbm_instance structure.
@@ -148,13 +148,54 @@ done:
     return rc;
 }
 
+/*
+ * Take a bunch of strings, and create a index config entry
+ */
+Slapi_Entry *
+ldbm_instance_init_config_entry(char *cn_val, char *val1, char *val2, char *val3, char *val4){
+    Slapi_Entry *e = slapi_entry_alloc();
+    struct berval *vals[2];
+    struct berval val;
+
+    vals[0] = &val;
+    vals[1] = NULL;
+
+    slapi_entry_set_dn(e,slapi_ch_strdup("cn=indexContainer"));
+
+    val.bv_val = cn_val;
+    val.bv_len = strlen(cn_val);
+    slapi_entry_add_values(e,"cn",vals);
+
+    val.bv_val = val1;
+    val.bv_len = strlen(val1);
+    slapi_entry_add_values(e,"nsIndexType",vals);
+
+    if(val2){
+        val.bv_val = val2;
+        val.bv_len = strlen(val2);
+        slapi_entry_add_values(e,"nsIndexType",vals);
+    }
+    if(val3){
+        val.bv_val = val3;
+        val.bv_len = strlen(val3);
+        slapi_entry_add_values(e,"nsIndexType",vals);
+    }
+    if(val4){
+        val.bv_val = val4;
+        val.bv_len = strlen(val4);
+        slapi_entry_add_values(e,"nsIndexType",vals);
+    }
+
+    return e;
+}
+
 /* create the default indexes separately
  * (because when we're creating a new backend while the server is running,
  * the DSE needs to be pre-seeded first.)
  */
 int ldbm_instance_create_default_indexes(backend *be)
 {
-    char *argv[ 9 ];
+    Slapi_Entry *e;
     ldbm_instance *inst = (ldbm_instance *)be->be_instance_info;
     /* write the dse file only on the final index */
     int flags = LDBM_INSTANCE_CONFIG_DONT_WRITE;
@@ -166,76 +207,64 @@ int ldbm_instance_create_default_indexes(backend *be)
      * ACL routines.
      */
     if (entryrdn_get_switch()) { /* subtree-rename: on */
-        argv[ 0 ] = LDBM_ENTRYRDN_STR;
-        argv[ 1 ] = "subtree";
-        argv[ 2 ] = NULL;
-        ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+        e = ldbm_instance_init_config_entry(LDBM_ENTRYDN_STR,"subtree", 0, 0, 0);
+        ldbm_instance_config_add_index_entry(inst, e, flags);
+        slapi_entry_free(e);
     } else {
-        argv[ 0 ] = LDBM_ENTRYDN_STR;
-        argv[ 1 ] = "eq";
-        argv[ 2 ] = NULL;
-        ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+        e = ldbm_instance_init_config_entry(LDBM_ENTRYDN_STR,"eq", 0, 0, 0);
+        ldbm_instance_config_add_index_entry(inst, e, flags);
+        slapi_entry_free(e);
     }
 
-    argv[ 0 ] = LDBM_PARENTID_STR;
-    argv[ 1 ] = "eq";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry(LDBM_PARENTID_STR,"eq", 0, 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 
-    argv[ 0 ] = "objectclass";
-    argv[ 1 ] = "eq";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry("objectclass","eq", 0, 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 
-    argv[ 0 ] = "aci";
-    argv[ 1 ] = "pres";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry("aci","pres", 0, 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 
 #if 0    /* don't need copiedfrom */
-    argv[ 0 ] = "copiedfrom";
-    argv[ 1 ] = "pres";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry("copiedfrom","pres",0 ,0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 #endif
 
-    argv[ 0 ] = LDBM_NUMSUBORDINATES_STR;
-    argv[ 1 ] = "pres";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry(LDBM_NUMSUBORDINATES_STR,"pres", 0, 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 
-    argv[ 0 ] = SLAPI_ATTR_UNIQUEID;
-    argv[ 1 ] = "eq";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry(SLAPI_ATTR_UNIQUEID,"eq", 0, 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 
     /* For MMR, we need this attribute (to replace use of dncomp in delete). */
-    argv[ 0 ] = ATTR_NSDS5_REPLCONFLICT;
-    argv[ 1 ] = "eq,pres";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
+    e = ldbm_instance_init_config_entry(ATTR_NSDS5_REPLCONFLICT,"eq", "pres", 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
 
     /* write the dse file only on the final index */
-    argv[ 0 ] = SLAPI_ATTR_NSCP_ENTRYDN;
-    argv[ 1 ] = "eq";
-    argv[ 2 ] = NULL;
-    ldbm_instance_config_add_index_entry(inst, 2, argv, 0);
-
-    argv[ 0 ] = LDBM_PSEUDO_ATTR_DEFAULT;
-    argv[ 1 ] = "none";
-    argv[ 2 ] = NULL;
+    e = ldbm_instance_init_config_entry(SLAPI_ATTR_NSCP_ENTRYDN,"eq", 0, 0, 0);
+    ldbm_instance_config_add_index_entry(inst, e, flags);
+    slapi_entry_free(e);
+
     /* ldbm_instance_config_add_index_entry(inst, 2, argv); */
-    attr_index_config( be, "ldbm index init", 0, 2, argv, 1 );
+    e = ldbm_instance_init_config_entry(LDBM_PSEUDO_ATTR_DEFAULT,"none", 0, 0, 0);
+    attr_index_config( be, "ldbm index init", 0, e, 1, 0 );
+    slapi_entry_free(e);
 
     if (!entryrdn_get_noancestorid()) {
         /* 
          * ancestorid is special, there is actually no such attr type
          * but we still want to use the attr index file APIs.
          */
-        argv[ 0 ] = LDBM_ANCESTORID_STR;
-        argv[ 1 ] = "eq";
-        argv[ 2 ] = NULL;
-        attr_index_config( be, "ldbm index init", 0, 2, argv, 1 );
+        e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR,"eq", 0, 0, 0);
+        attr_index_config( be, "ldbm index init", 0, e, 1, 0 );
+        slapi_entry_free(e);
     }
 
     return 0;
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
index d09413f..63be423 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
@@ -171,64 +171,65 @@ attr_index_config(
     backend *be,
     char		*fname,
     int			lineno,
-    int			argc,
-    char		**argv,
-    int			init
+    Slapi_Entry *e,
+    int			init,
+    int 		indextype_none
 )
 {
 	ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
-	int	i, j;
-	char	**attrs = NULL;
-	char	**indexes = NULL;
-	char	**index_rules = NULL;
+	int	j = 0;
 	struct attrinfo	*a;
 	int return_value = -1;
 	int *substrlens = NULL;
-
-	if ((argc == 0) || (argv == NULL)) {
+	int need_compare_fn = 0;
+	int hasIndexType = 0;
+	const char *attrsyntax_oid = NULL;
+	const struct berval *attrValue;
+	Slapi_Value *sval;
+	Slapi_Attr *attr;
+	int mr_count = 0;
+
+	/* Get the cn */
+	if (0 == slapi_entry_attr_find(e, "cn", &attr)) {
+		 slapi_attr_first_value(attr, &sval);
+		 attrValue = slapi_value_get_berval(sval);
+	} else {
 		LDAPDebug(LDAP_DEBUG_ANY, "attr_index_config: Missing indexing arguments\n", 0, 0, 0);
-		goto done;
-	}
-
-	attrs = slapi_str2charray( argv[0], "," );
-	if ( argc > 1 ) {
-		indexes = slapi_str2charray( argv[1], "," );
-		if ( argc > 2 ) {
-			index_rules = slapi_str2charray( argv[2], "," );
-		}
-	}
-
-	if (!indexes) {
-		LDAPDebug(LDAP_DEBUG_ANY, "attr_index_config: Missing index\n", 0, 0, 0);
-		goto done;
+		return;
 	}
 
-	for ( i = 0; attrs[i] != NULL; i++ ) {
-		int need_compare_fn = 0;
-		const char *attrsyntax_oid = NULL;
-		a = attrinfo_new();
-		slapi_attr_init(&a->ai_sattr, attrs[i]);
-		/* we can't just set a->ai_type to the type from a->ai_sattr
-		   if the type has attroptions or subtypes, ai_sattr.a_type will
-		   contain them - but for the purposes of indexing, we don't want
-		   them */
-		a->ai_type = slapi_attr_basetype( attrs[i], NULL, 0 );
-		attrsyntax_oid = attr_get_syntax_oid(&a->ai_sattr);
-		a->ai_indexmask = 0;
-		for ( j = 0; indexes[j] != NULL; j++ ) {
-			if ( strncasecmp( indexes[j], "pres", 4 ) == 0 ) {
+	a = attrinfo_new();
+	slapi_attr_init(&a->ai_sattr, attrValue->bv_val);
+	/*
+	 *  we can't just set a->ai_type to the type from a->ai_sattr
+	 *  if the type has attroptions or subtypes, ai_sattr.a_type will
+	 *  contain them - but for the purposes of indexing, we don't want them
+	 */
+	a->ai_type = slapi_attr_basetype( attrValue->bv_val, NULL, 0 );
+	attrsyntax_oid = attr_get_syntax_oid(&a->ai_sattr);
+	a->ai_indexmask = 0;
+
+	if(indextype_none){
+		/* This is the same has having none for indexType, but applies to the whole entry */
+		a->ai_indexmask = INDEX_OFFLINE;
+	} else {
+		slapi_entry_attr_find(e, "nsIndexType", &attr);
+		for (j = slapi_attr_first_value(attr, &sval); j != -1;j = slapi_attr_next_value(attr, j, &sval)) {
+			hasIndexType = 1;
+			attrValue = slapi_value_get_berval(sval);
+			if ( strncasecmp( attrValue->bv_val, "pres", 4 ) == 0 ) {
 				a->ai_indexmask |= INDEX_PRESENCE;
-			} else if ( strncasecmp( indexes[j], "eq", 2 ) == 0 ) {
+			} else if ( strncasecmp( attrValue->bv_val, "eq", 2 ) == 0 ) {
 				a->ai_indexmask |= INDEX_EQUALITY;
-			} else if ( strncasecmp( indexes[j], "approx", 6 ) == 0 ) {
+			} else if ( strncasecmp( attrValue->bv_val, "approx", 6 ) == 0 ) {
 				a->ai_indexmask |= INDEX_APPROX;
-			} else if ( strncasecmp( indexes[j], "subtree", 7 ) == 0 ) {
+			} else if ( strncasecmp( attrValue->bv_val, "subtree", 7 ) == 0 ) {
 				/* subtree should be located before "sub" */
 				a->ai_indexmask |= INDEX_SUBTREE;
 				a->ai_dup_cmp_fn = entryrdn_compare_dups;
-			} else if ( strncasecmp( indexes[j], "sub", 3 ) == 0 ) {
+			} else if ( strncasecmp( attrValue->bv_val, "sub", 3 ) == 0 ) {
 				a->ai_indexmask |= INDEX_SUB;
-			} else if ( strncasecmp( indexes[j], "none", 4 ) == 0 ) {
+			} else if ( strncasecmp( attrValue->bv_val, "none", 4 ) == 0 ) {
 				if ( a->ai_indexmask != 0 ) {
 					LDAPDebug(LDAP_DEBUG_ANY,
 						"%s: line %d: index type \"none\" cannot be combined with other types\n",
@@ -238,77 +239,86 @@ attr_index_config(
 			} else {
 				LDAPDebug(LDAP_DEBUG_ANY,
 					"%s: line %d: unknown index type \"%s\" (ignored)\n",
-					fname, lineno, indexes[j]);
+					fname, lineno, attrValue->bv_val);
 				LDAPDebug(LDAP_DEBUG_ANY,
 					"valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n",
 					0, 0, 0);
 			}
 		}
+		if(hasIndexType == 0){
+			/* indexType missing, error out */
+			LDAPDebug(LDAP_DEBUG_ANY, "attr_index_config: Missing index type\n", 0, 0, 0);
+			return;
+		}
+	}
 
-		/* compute a->ai_index_rules: */
-		/* for index rules there are two uses:
-		 * 1) a simple way to define an ordered index to support <= and >= searches
-		 * for those attributes which do not have an ORDERING matching rule defined
-		 * for them in their schema definition.  The index generated is not a :RULE:
-		 * index, it is a normal = EQUALITY index, with the keys ordered using the
-		 * comparison function provided by the syntax plugin for the attribute.  For
-		 * example - the uidNumber attribute has INTEGER syntax, but the standard
-		 * definition of the attribute does not specify an ORDERING matching rule.
-		 * By default, this means that you cannot perform searches like
-		 * (uidNumber>=501) - but many users expect to be able to perform this type of
-		 * search.  By specifying that you want an ordered index, using an integer
-		 * matching rule, you can support indexed seaches of this type.
-		 * 2) a RULE index - the index key prefix is :NAMEOROID: - this is used
-		 * to support extensible match searches like (cn:fr-CA.3:=gilles), which would
-		 * find the index key :fr-CA.3:gilles in the cn index.
-		 * We check first to see if this is a simple ordered index - user specified an
-		 * ordering matching rule compatible with the attribute syntax, and there is
-		 * a compare function.  If not, we assume it is a RULE index definition.
-		 */
-		j = 0;
-		if (index_rules != NULL) for (; index_rules[j] != NULL; ++j);
-		if (j > 0) { /* there are some candidates */
-			char** official_rules =
-					(char**)slapi_ch_malloc ((j + 1) * sizeof (char*));
-			size_t k = 0;
-			for (j = 0; index_rules[j] != NULL; ++j) {
-				/* Check that index_rules[j] is an official OID */
-				char* officialOID = NULL;
-				IFP mrINDEX = NULL;
-				Slapi_PBlock* pb = NULL;
-				int do_continue = 0; /* can we skip the RULE parsing stuff? */
-
-				if (strstr(index_rules[j], INDEX_ATTR_SUBSTRBEGIN)) {
-					_set_attr_substrlen(INDEX_SUBSTRBEGIN, index_rules[j],
-										&substrlens);
-					do_continue = 1; /* done with j - next j */
-				} else if (strstr(index_rules[j], INDEX_ATTR_SUBSTRMIDDLE)) {
-					_set_attr_substrlen(INDEX_SUBSTRMIDDLE, index_rules[j],
-										&substrlens);
-					do_continue = 1; /* done with j - next j */
-				} else if (strstr(index_rules[j], INDEX_ATTR_SUBSTREND)) {
-					_set_attr_substrlen(INDEX_SUBSTREND, index_rules[j],
-										&substrlens);
-					do_continue = 1; /* done with j - next j */
-				/* check if this is a simple ordering specification
-				   for an attribute that has no ordering matching rule */
-				} else if (slapi_matchingrule_is_ordering(index_rules[j], attrsyntax_oid) &&
-						   slapi_matchingrule_can_use_compare_fn(index_rules[j]) &&
-						   !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
-					need_compare_fn = 1; /* get compare func for this attr */
-					do_continue = 1; /* done with j - next j */
-				}
+	/* compute a->ai_index_rules: */
+	/* for index rules there are two uses:
+	 * 1) a simple way to define an ordered index to support <= and >= searches
+	 * for those attributes which do not have an ORDERING matching rule defined
+	 * for them in their schema definition.  The index generated is not a :RULE:
+	 * index, it is a normal = EQUALITY index, with the keys ordered using the
+	 * comparison function provided by the syntax plugin for the attribute.  For
+	 * example - the uidNumber attribute has INTEGER syntax, but the standard
+	 * definition of the attribute does not specify an ORDERING matching rule.
+	 * By default, this means that you cannot perform searches like
+	 * (uidNumber>=501) - but many users expect to be able to perform this type of
+	 * search.  By specifying that you want an ordered index, using an integer
+	 * matching rule, you can support indexed seaches of this type.
+	 * 2) a RULE index - the index key prefix is :NAMEOROID: - this is used
+	 * to support extensible match searches like (cn:fr-CA.3:=gilles), which would
+	 * find the index key :fr-CA.3:gilles in the cn index.
+	 * We check first to see if this is a simple ordered index - user specified an
+	 * ordering matching rule compatible with the attribute syntax, and there is
+	 * a compare function.  If not, we assume it is a RULE index definition.
+	 */
 
-				if (do_continue) {
-					continue; /* done with index_rules[j] */
-				}
+	if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)){
+		char** official_rules;
+		size_t k = 0;
+
+		/* Get a count and allocate an array for the official matching rules */
+		slapi_attr_get_numvalues(attr, &mr_count);
+		official_rules = (char**)slapi_ch_malloc ((mr_count + 1) * sizeof (char*));
+
+		for (j = slapi_attr_first_value(attr, &sval); j != -1;j = slapi_attr_next_value(attr, j, &sval)) {
+			/* Check that index_rules[j] is an official OID */
+			char* officialOID = NULL;
+			IFP mrINDEX = NULL;
+			Slapi_PBlock* pb = NULL;
+			int do_continue = 0; /* can we skip the RULE parsing stuff? */
+			attrValue = slapi_value_get_berval(sval);
+
+			if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
+				_set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
+				do_continue = 1; /* done with j - next j */
+			} else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
+				_set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val,	&substrlens);
+				do_continue = 1; /* done with j - next j */
+			} else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
+				_set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
+				do_continue = 1; /* done with j - next j */
+			/* check if this is a simple ordering specification
+			   for an attribute that has no ordering matching rule */
+			} else if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
+					   slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
+					   !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
+				need_compare_fn = 1; /* get compare func for this attr */
+				do_continue = 1; /* done with j - next j */
+			}
+
+			if (do_continue) {
+				continue; /* done with index_rules[j] */
+			}
 
-				/* must be a RULE specification */
-				pb = slapi_pblock_new();
-				/* next check if this is a RULE type index
-				   try to actually create an indexer and see if the indexer
-				   actually has a regular INDEX_FN or an INDEX_SV_FN */
-				if (!slapi_pblock_set (pb, SLAPI_PLUGIN_MR_OID, index_rules[j]) &&
+			/* must be a RULE specification */
+			pb = slapi_pblock_new();
+			/*
+			 *  next check if this is a RULE type index
+			 *  try to actually create an indexer and see if the indexer
+			 *  actually has a regular INDEX_FN or an INDEX_SV_FN
+			 */
+			if (!slapi_pblock_set (pb, SLAPI_PLUGIN_MR_OID, attrValue->bv_val) &&
 					!slapi_pblock_set (pb, SLAPI_PLUGIN_MR_TYPE, a->ai_type) &&
 					!slapi_mr_indexer_create (pb) &&
 					((!slapi_pblock_get (pb, SLAPI_PLUGIN_MR_INDEX_FN, &mrINDEX) &&
@@ -317,76 +327,70 @@ attr_index_config(
 					  mrINDEX != NULL)) &&
 					!slapi_pblock_get (pb, SLAPI_PLUGIN_MR_OID, &officialOID) &&
 					officialOID != NULL) {
-					if (!strcasecmp (index_rules[j], officialOID)) {
-						official_rules[k++] = slapi_ch_strdup (officialOID);
-					} else {
-						char* preamble = slapi_ch_smprintf("%s: line %d", fname, lineno);
-						LDAPDebug (LDAP_DEBUG_ANY, "%s: use \"%s\" instead of \"%s\" (ignored)\n",
-								   preamble, officialOID, index_rules[j] );
-						slapi_ch_free((void**)&preamble);
-					}
-				} else { /* we don't know what this is */
-					LDAPDebug (LDAP_DEBUG_ANY, "%s: line %d: "
-						   "unknown or invalid matching rule \"%s\" in index configuration (ignored)\n",
-						   fname, lineno, index_rules[j] );
-				}
-				{/* It would improve speed to save the indexer, for future use.
-					But, for simplicity, we destroy it now: */
-					IFP mrDESTROY = NULL;
-					if (!slapi_pblock_get (pb, SLAPI_PLUGIN_DESTROY_FN, &mrDESTROY) &&
-						mrDESTROY != NULL) {
-						mrDESTROY (pb);
-					}
+				if (!strcasecmp (attrValue->bv_val, officialOID)) {
+					official_rules[k++] = slapi_ch_strdup (officialOID);
+				} else {
+					char* preamble = slapi_ch_smprintf("%s: line %d", fname, lineno);
+					LDAPDebug (LDAP_DEBUG_ANY, "%s: use \"%s\" instead of \"%s\" (ignored)\n",
+								  preamble, officialOID, attrValue->bv_val);
+					slapi_ch_free((void**)&preamble);
 				}
-				slapi_pblock_destroy (pb);
+			} else { /* we don't know what this is */
+				LDAPDebug (LDAP_DEBUG_ANY, "%s: line %d: "
+						   "unknown or invalid matching rule \"%s\" in index configuration (ignored)\n",
+						   fname, lineno, attrValue->bv_val);
 			}
-			official_rules[k] = NULL;
-			a->ai_substr_lens = substrlens;
-			if (k > 0) {
-				a->ai_index_rules = official_rules;
-				a->ai_indexmask |= INDEX_RULES;
-			} else {
-				slapi_ch_free((void**)&official_rules);
+
+			{  /*
+			    *  It would improve speed to save the indexer, for future use.
+			    * But, for simplicity, we destroy it now:
+			    */
+				IFP mrDESTROY = NULL;
+				if (!slapi_pblock_get (pb, SLAPI_PLUGIN_DESTROY_FN, &mrDESTROY) &&
+					mrDESTROY != NULL) {
+					mrDESTROY (pb);
+				}
 			}
+			slapi_pblock_destroy (pb);
 		}
+		official_rules[k] = NULL;
+		a->ai_substr_lens = substrlens;
+		if (k > 0) {
+			a->ai_index_rules = official_rules;
+			a->ai_indexmask |= INDEX_RULES;
+		} else {
+			slapi_ch_free((void**)&official_rules);
+		}
+	}
 
-		/* initialize the IDL code's private data */
-		return_value = idl_init_private(be, a);
-		if (0 != return_value) {
-			/* fatal error, exit */
-			LDAPDebug(LDAP_DEBUG_ANY,"%s: line %d:Fatal Error: Failed to initialize attribute structure\n",
+	/* initialize the IDL code's private data */
+	return_value = idl_init_private(be, a);
+	if (0 != return_value) {
+		/* fatal error, exit */
+		LDAPDebug(LDAP_DEBUG_ANY,"%s: line %d:Fatal Error: Failed to initialize attribute structure\n",
 				fname, lineno, 0);
-			exit( 1 );
-		}
+		exit( 1 );
+	}
 
-		/* if user didn't specify an ordering rule in the index config,
-		   see if the schema def for the attr defines one */
-		if (!need_compare_fn && a->ai_sattr.a_mr_ord_plugin) {
-			need_compare_fn = 1;
-		}
+	/* if user didn't specify an ordering rule in the index config,
+	   see if the schema def for the attr defines one */
+	if (!need_compare_fn && a->ai_sattr.a_mr_ord_plugin) {
+		need_compare_fn = 1;
+	}
 
-		if (need_compare_fn) {
-			int rc = attr_get_value_cmp_fn( &a->ai_sattr, &a->ai_key_cmp_fn );
-			if (rc != LDAP_SUCCESS) {
-				LDAPDebug(LDAP_DEBUG_ANY,
+	if (need_compare_fn) {
+		int rc = attr_get_value_cmp_fn( &a->ai_sattr, &a->ai_key_cmp_fn );
+		if (rc != LDAP_SUCCESS) {
+			LDAPDebug(LDAP_DEBUG_ANY,
 						  "The attribute [%s] does not have a valid ORDERING matching rule - error %d:s\n",
 						  a->ai_type, rc, ldap_err2string(rc));
-				a->ai_key_cmp_fn = NULL;
-			}
-		}
-
-		if ( avl_insert( &inst->inst_attrs, a, ainfo_cmp, ainfo_dup ) != 0 ) {
-			/* duplicate - existing version updated */
-			attrinfo_delete(&a);
+			a->ai_key_cmp_fn = NULL;
 		}
 	}
-done:
-	charray_free( attrs );
-	if ( indexes != NULL ) {
-		charray_free( indexes );
-	}
-	if ( index_rules != NULL ) {
-		charray_free( index_rules );
+
+	if ( avl_insert( &inst->inst_attrs, a, ainfo_cmp, ainfo_dup ) != 0 ) {
+		/* duplicate - existing version updated */
+		attrinfo_delete(&a);
 	}
 }
 
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_config.h b/ldap/servers/slapd/back-ldbm/ldbm_config.h
index e41b623..36b8f60 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_config.h
+++ b/ldap/servers/slapd/back-ldbm/ldbm_config.h
@@ -170,8 +170,7 @@ int ldbm_config_ignored_attr(char *attr_name);
 
 /* Functions in ldbm_instance_config.c used in ldbm_config.c */
 int ldbm_instance_config_load_dse_info(ldbm_instance *inst);
-int ldbm_instance_config_add_index_entry(ldbm_instance *inst, int argc,
-                                         char **argv, int flags);
+int ldbm_instance_config_add_index_entry(ldbm_instance *inst, Slapi_Entry *e, int flags);
 int
 ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry* e);
 int ldbm_instance_create_default_user_indexes(ldbm_instance *inst);
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
index aa47584..2775785 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
@@ -51,103 +51,14 @@
 int ldbm_instance_index_config_add_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg); 
 int ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* entryBefore, Slapi_Entry* e, int *returncode, char *returntext, void *arg); 
 
+#define INDEXTYPE_NONE 1
 
-
-
-
-/* attrinfo2ConfIndexes: converts attrinfo into "pres,eq,sub,approx" 
- *   as seen in index entries within dse.ldif
- */
-static char *attrinfo2ConfIndexes (struct attrinfo *pai)
-{ 
-    char buffer[128];
-
-    buffer[0] = '\0';
-    if (!(IS_INDEXED( pai->ai_indexmask ))) { /* skip if no index */
-	strcat (buffer, "none"); 
-    }
-
-    if (pai->ai_indexmask & INDEX_PRESENCE) { 
-	if (strlen (buffer)) {
-            strcat (buffer, ",");
-	}
-	strcat (buffer, "pres");
-    } 
-    if (pai->ai_indexmask & INDEX_EQUALITY) { 
-	if (strlen (buffer)) { 
-            strcat (buffer, ","); 
-	}
-	strcat (buffer, "eq"); 
-    } 
-    if (pai->ai_indexmask & INDEX_APPROX) { 
-	if (strlen(buffer)) { 
-            strcat (buffer, ","); 
-	} 
-	strcat (buffer, "approx"); 
-    } 
-    if (pai->ai_indexmask & INDEX_SUB) { 
-	if (strlen (buffer)) { 
-            strcat (buffer, ",");
-	} 
-	strcat (buffer, "sub"); 
-    }
-    if (entryrdn_get_switch()) { /* subtree-rename: on */
-        if (pai->ai_indexmask & INDEX_SUBTREE) { 
-            if (strlen (buffer)) { 
-                strcat (buffer, ",");
-            } 
-            strcat (buffer, "subtree"); 
-        }
-    }
-
-    return (slapi_ch_strdup (buffer) );
-}
-
-
-/* attrinfo2ConfMatchingRules: converts attrinfo into matching rule oids, as
- * seen in index entries within dse.ldif
- */
-static char *attrinfo2ConfMatchingRules (struct attrinfo *pai)
-{ 
-    int i;
-    char buffer[1024];
-
-    buffer[0] = '\0';
-
-    if (pai->ai_index_rules) {
-	strcat (buffer, "\t");
-	for (i = 0; pai->ai_index_rules[i]; i++) {
-            PL_strcatn (buffer, sizeof(buffer), pai->ai_index_rules[i]);
-            if (pai->ai_index_rules[i+1]) {
-		PL_strcatn (buffer, sizeof(buffer), ",");
-            }
-	}
-    }
-    return (slapi_ch_strdup (buffer) );
-}
-
-
-/* used by the two callbacks below, to parse an index entry into something
- * awkward that we can pass to attr_index_config().
- */
-#define MAX_TMPBUF      1024
-#define ZCAT_SAFE(_buf, _x1, _x2) do { \
-    if (strlen(_buf) + strlen(_x1) + strlen(_x2) + 2 < MAX_TMPBUF) { \
-        strcat(_buf, _x1); \
-        strcat(_buf, _x2); \
-    } \
-} while (0)
 static int ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e,
-                                  const char *trace_string,
-                                  char **index_name)
+                                  const char *trace_string, char **index_name)
 {
-    char *arglist[] = { NULL, NULL, NULL, NULL };
-    int argc = 0, i;
-    int isFirst;
     Slapi_Attr *attr;
     const struct berval *attrValue;
     Slapi_Value *sval;
-    char tmpBuf[MAX_TMPBUF];
 
     /* Get the name of the attribute to index which will be the value
      * of the cn attribute. */
@@ -159,127 +70,34 @@ static int ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e,
 
     slapi_attr_first_value(attr, &sval);
     attrValue = slapi_value_get_berval(sval);
-    if (NULL == attrValue->bv_val || 0 == strlen(attrValue->bv_val)) {
+    if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
         LDAPDebug(LDAP_DEBUG_ANY,
                   "Warning: malformed index entry %s -- empty index name\n",
-                      slapi_entry_get_dn(e), 0, 0);
+                   slapi_entry_get_dn(e), 0, 0);
         return LDAP_OPERATIONS_ERROR;
     }
-    arglist[argc++] = slapi_ch_strdup(attrValue->bv_val);
-    if (index_name != NULL) {
-        *index_name = slapi_ch_strdup(attrValue->bv_val);
+
+    if(index_name != NULL){
+    	*index_name = slapi_ch_strdup(attrValue->bv_val);
     }
 
-    /* Get the list of index types from the entry. */
+    /* check and see if we have the required indexType */
     if (0 == slapi_entry_attr_find(e, "nsIndexType", &attr)) {
-        tmpBuf[0] = 0;
-        isFirst = 1;
-        for (i = slapi_attr_first_value(attr, &sval); i != -1;
-             i = slapi_attr_next_value(attr, i, &sval)) {
-            attrValue = slapi_value_get_berval(sval);
-            if (NULL != attrValue->bv_val && strlen(attrValue->bv_val) > 0) {
-                if (isFirst) {
-                    ZCAT_SAFE(tmpBuf, "", attrValue->bv_val);
-                    isFirst = 0;
-                } else {
-                    ZCAT_SAFE(tmpBuf, ",", attrValue->bv_val);
-                }
-            }
-        }
-        if (0 == tmpBuf[0]) {
+    	slapi_attr_first_value(attr, &sval);
+    	attrValue = slapi_value_get_berval(sval);
+    	if (NULL == attrValue->bv_val || attrValue->bv_len == 0) {
+    		/* missing the index type, error out */
             LDAPDebug(LDAP_DEBUG_ANY,
                      "Warning: malformed index entry %s -- empty nsIndexType\n",
                      slapi_entry_get_dn(e), 0, 0);
             slapi_ch_free_string(index_name);
-            for (i = 0; i < argc; i++) {
-                slapi_ch_free((void **)&arglist[i]);
-            }
             return LDAP_OPERATIONS_ERROR;
         }
-        arglist[argc++] = slapi_ch_strdup(tmpBuf);
-    }
-
-    tmpBuf[0] = 0;
-    /* Get the list of matching rules from the entry. */
-    if (0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)) {
-        for (i = slapi_attr_first_value(attr, &sval); i != -1;
-             i = slapi_attr_next_value(attr, i, &sval)) {
-            attrValue = slapi_value_get_berval(sval);
-            if (NULL != attrValue->bv_val && strlen(attrValue->bv_val) > 0) {
-                if (0 == tmpBuf[0]) {
-                    ZCAT_SAFE(tmpBuf, "", attrValue->bv_val);
-                } else {
-                    ZCAT_SAFE(tmpBuf, ",", attrValue->bv_val);
-                }
-            }
-        }
-    }
-
-    /* Get the substr begin length. note: pick the first value. */
-    if (0 == slapi_entry_attr_find(e, INDEX_ATTR_SUBSTRBEGIN, &attr)) {
-        i = slapi_attr_first_value(attr, &sval);
-        if (-1 != i) {
-            attrValue = slapi_value_get_berval(sval);
-            if (NULL != attrValue->bv_val && strlen(attrValue->bv_val) > 0) {
-                if (0 == tmpBuf[0]) {
-                    PR_snprintf(tmpBuf, MAX_TMPBUF, "%s=%s",
-                                INDEX_ATTR_SUBSTRBEGIN,  attrValue->bv_val);
-                } else {
-                    int tmpbuflen = strlen(tmpBuf);
-                    char *p = tmpBuf + tmpbuflen;
-                    PR_snprintf(p, MAX_TMPBUF - tmpbuflen, ",%s=%s",
-                                INDEX_ATTR_SUBSTRBEGIN,  attrValue->bv_val);
-                }
-            }
-        }
     }
 
-    /* Get the substr middle length. note: pick the first value. */
-    if (0 == slapi_entry_attr_find(e, INDEX_ATTR_SUBSTRMIDDLE, &attr)) {
-        i = slapi_attr_first_value(attr, &sval);
-        if (-1 != i) {
-            attrValue = slapi_value_get_berval(sval);
-            if (NULL != attrValue->bv_val && strlen(attrValue->bv_val) > 0) {
-                if (0 == tmpBuf[0]) {
-                    PR_snprintf(tmpBuf, MAX_TMPBUF, "%s=%s",
-                                INDEX_ATTR_SUBSTRMIDDLE,  attrValue->bv_val);
-                } else {
-                    int tmpbuflen = strlen(tmpBuf);
-                    char *p = tmpBuf + tmpbuflen;
-                    PR_snprintf(p, MAX_TMPBUF - tmpbuflen, ",%s=%s",
-                                INDEX_ATTR_SUBSTRMIDDLE,  attrValue->bv_val);
-                }
-            }
-        }
-    }
-
-    /* Get the substr end length. note: pick the first value. */
-    if (0 == slapi_entry_attr_find(e, INDEX_ATTR_SUBSTREND, &attr)) {
-        i = slapi_attr_first_value(attr, &sval);
-        if (-1 != i) {
-            attrValue = slapi_value_get_berval(sval);
-            if (NULL != attrValue->bv_val && strlen(attrValue->bv_val) > 0) {
-                if (0 == tmpBuf[0]) {
-                    PR_snprintf(tmpBuf, MAX_TMPBUF, "%s=%s",
-                                INDEX_ATTR_SUBSTREND,  attrValue->bv_val);
-                } else {
-                    int tmpbuflen = strlen(tmpBuf);
-                    char *p = tmpBuf + tmpbuflen;
-                    PR_snprintf(p, MAX_TMPBUF - tmpbuflen, ",%s=%s",
-                                INDEX_ATTR_SUBSTREND,  attrValue->bv_val);
-                }
-            }
-        }
-    }
-    if (0 != tmpBuf[0]) {
-        arglist[argc++] = slapi_ch_strdup(tmpBuf);
-    }
+    /* ok the entry is good to process, pass it to attr_index_config */
+    attr_index_config(inst->inst_be, (char *)trace_string, 0, e, 0, 0);
 
-    arglist[argc] = NULL;
-    attr_index_config(inst->inst_be, (char *)trace_string, 0, argc, arglist, 0);
-    for (i = 0; i < argc; i++) {
-        slapi_ch_free((void **)&arglist[i]);
-    }
     return LDAP_SUCCESS;
 }
 
@@ -294,8 +112,7 @@ ldbm_index_init_entry_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* en
     ldbm_instance *inst = (ldbm_instance *) arg;
 
     returntext[0] = '\0';
-    *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init",
-                                         NULL);
+    *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL);
     if (*returncode == LDAP_SUCCESS) {
         return SLAPI_DSE_CALLBACK_OK;
     } else {
@@ -318,16 +135,15 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_
     *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name);
     if (*returncode == LDAP_SUCCESS) {
         struct attrinfo *ai = NULL;
-
         /* if the index is a "system" index, we assume it's being added by
          * by the server, and it's okay for the index to go online immediately.
          * if not, we set the index "offline" so it won't actually be used
          * until someone runs db2index on it.
          */
         if (! ldbm_attribute_always_indexed(index_name)) {
-            ainfo_get(inst->inst_be, index_name, &ai);
-            PR_ASSERT(ai != NULL);
-            ai->ai_indexmask |= INDEX_OFFLINE;
+        		ainfo_get(inst->inst_be, index_name, &ai);
+        		PR_ASSERT(ai != NULL);
+        		ai->ai_indexmask |= INDEX_OFFLINE;
         }
         slapi_ch_free((void **)&index_name);
         return SLAPI_DSE_CALLBACK_OK;
@@ -343,11 +159,9 @@ int
 ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg) 
 { 
   ldbm_instance *inst = (ldbm_instance *) arg;
-  char *arglist[4];
   Slapi_Attr *attr;
   Slapi_Value *sval;
   const struct berval *attrValue;
-  int argc = 0;
   int rc = SLAPI_DSE_CALLBACK_OK;
   struct attrinfo *ainfo = NULL;
   
@@ -358,15 +172,9 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry* e, Sla
   slapi_attr_first_value(attr, &sval);
   attrValue = slapi_value_get_berval(sval);
   
-  arglist[argc++] = slapi_ch_strdup(attrValue->bv_val);
-  arglist[argc++] = slapi_ch_strdup("none");
-  arglist[argc] = NULL;
-  attr_index_config(inst->inst_be, "From DSE delete", 0, argc, arglist, 0);
-  slapi_ch_free((void **)&arglist[0]);
-  slapi_ch_free((void **)&arglist[1]);
+  attr_index_config(inst->inst_be, "From DSE delete", 0, e, 0, INDEXTYPE_NONE);
   
   ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
-  
   if (NULL == ainfo) {
     *returncode = LDAP_UNAVAILABLE;
     rc = SLAPI_DSE_CALLBACK_ERROR;
@@ -394,325 +202,139 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
     Slapi_Value *sval;
     const struct berval *attrValue;
     struct attrinfo *ainfo = NULL;
-    LDAPMod **mods;
-    char *arglist[4] = {0};
-    char *config_attr;
-    char *origIndexTypes = NULL;
-    char *origMatchingRules = NULL;
-    char **origIndexTypesArray = NULL;
-    char **origMatchingRulesArray = NULL;
-    char **addIndexTypesArray = NULL;
-    char **addMatchingRulesArray = NULL;
-    char **deleteIndexTypesArray = NULL;
-    char **deleteMatchingRulesArray = NULL;
-    int i, j;
-    int dodeletes = 0;
-    char tmpBuf[MAX_TMPBUF];
-    int rc = SLAPI_DSE_CALLBACK_OK;
 
     returntext[0] = '\0';
     *returncode = LDAP_SUCCESS;
-    slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
 
-    slapi_entry_attr_find(e, "cn", &attr);
+    if(slapi_entry_attr_find(entryAfter, "cn", &attr) != 0){
+    	 LDAPDebug(LDAP_DEBUG_ANY,
+    			 "Warning: malformed index entry %s - missing cn attribute\n",
+    			 slapi_entry_get_dn(entryAfter), 0, 0);
+    	 *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+    	 return SLAPI_DSE_CALLBACK_ERROR;
+    }
     slapi_attr_first_value(attr, &sval);
     attrValue = slapi_value_get_berval(sval);
 
-    ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
-    if (NULL == ainfo) {
-        rc = SLAPI_DSE_CALLBACK_ERROR;
-        goto out;
-    }
-
-    origIndexTypes = attrinfo2ConfIndexes(ainfo);
-    if (NULL == origIndexTypes) {
-        rc = SLAPI_DSE_CALLBACK_ERROR;
-        goto out;
-    }
-
-    origMatchingRules = attrinfo2ConfMatchingRules(ainfo);
-    if (NULL == origMatchingRules) {
-        rc = SLAPI_DSE_CALLBACK_ERROR;
-        goto out;
-    }
-
-    origIndexTypesArray = slapi_str2charray(origIndexTypes, ",");
-    if (NULL == origIndexTypesArray) {
-        rc = SLAPI_DSE_CALLBACK_ERROR;
-        goto out;
-    }
-
-    origMatchingRulesArray = slapi_str2charray(origMatchingRules, ",");
-    if (NULL == origMatchingRulesArray) {
-        rc = SLAPI_DSE_CALLBACK_ERROR;
-        goto out;
-    }
-
-    for (i = 0; mods[i] != NULL; i++) {
-        config_attr = (char *)mods[i]->mod_type;
-
-        if (strcasecmp(config_attr, "nsIndexType") == 0) {
-            if (SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
-                for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) {
-                    charray_add(&addIndexTypesArray,
-                        slapi_ch_strdup(mods[i]->mod_bvalues[j]->bv_val));
-                }
-                continue;
-            }
-            if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op)) {
-                if ((mods[i]->mod_bvalues == NULL) ||
-                    (mods[i]->mod_bvalues[0] == NULL)) {
-                    if (deleteIndexTypesArray) {
-                        charray_free(deleteIndexTypesArray);
-                    }
-                    deleteIndexTypesArray = charray_dup(origIndexTypesArray);
-                } else {
-                    for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) {
-                        charray_add(&deleteIndexTypesArray,
-                            slapi_ch_strdup(mods[i]->mod_bvalues[j]->bv_val));
-                    }
-                }
-                continue;
-            }
-        }
-        if (strcasecmp(config_attr, "nsMatchingRule") == 0) {
-            if (SLAPI_IS_MOD_ADD(mods[i]->mod_op)) {
-                for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) {
-                    charray_add(&addMatchingRulesArray,
-                        slapi_ch_strdup(mods[i]->mod_bvalues[j]->bv_val));
-                }
-                continue;
-            }
-            if (SLAPI_IS_MOD_DELETE(mods[i]->mod_op)) {
-                if ((mods[i]->mod_bvalues == NULL) ||
-                    (mods[i]->mod_bvalues[0] == NULL)) {
-                    if (deleteMatchingRulesArray) {
-                        charray_free(deleteMatchingRulesArray);
-                    }
-                    deleteMatchingRulesArray = charray_dup(origMatchingRulesArray);
-                } else {
-                    for (j = 0; mods[i]->mod_bvalues[j] != NULL; j++) {
-                        charray_add(&deleteMatchingRulesArray,
-                            slapi_ch_strdup(mods[i]->mod_bvalues[j]->bv_val));
-                    }
-                }
-                continue;
-            }
-        }
-    }
-
-    /* create the new set of index types */
-    if (deleteIndexTypesArray) {
-        for (i = 0; origIndexTypesArray[i] != NULL; i++) {
-            if (charray_inlist(deleteIndexTypesArray,
-                               origIndexTypesArray[i])) {
-                slapi_ch_free((void **)&(origIndexTypesArray[i]));
-                dodeletes = 1;
-                if (origIndexTypesArray[i+1] != NULL) {
-                    for (j = i+1; origIndexTypesArray[j] != NULL; j++) {
-                        origIndexTypesArray[j-1] = origIndexTypesArray[j];
-                    }
-                    origIndexTypesArray[j-1] = NULL;
-                    i--;
-                }
-            }
-        }
-    }
-
-    if (addIndexTypesArray) {
-        for (i = 0; addIndexTypesArray[i] != NULL; i++) {
-            if (!charray_inlist(origIndexTypesArray, addIndexTypesArray[i])) {
-                charray_add(&origIndexTypesArray,
-                    slapi_ch_strdup(addIndexTypesArray[i]));
-            }
-        }
-    }
-
-    if (deleteMatchingRulesArray) {
-        for (i = 0; origMatchingRulesArray[i] != NULL; i++) {
-            if (charray_inlist(deleteMatchingRulesArray, 
-                               origMatchingRulesArray[i])) {
-                slapi_ch_free((void **)&(origMatchingRulesArray[i]));
-                dodeletes = 1;
-                if (origMatchingRulesArray[i+1] != NULL) {
-                    for (j = i+1; origMatchingRulesArray[j] != NULL; j++) {
-                        origMatchingRulesArray[j-1] = origMatchingRulesArray[j];
-                    }
-                    origMatchingRulesArray[j-1] = NULL;
-                    i--;
-                }
-            }
-        }
-    }
-
-    if (addMatchingRulesArray) {
-        for (i = 0; addMatchingRulesArray[i] != NULL; i++) {
-            if (!charray_inlist(origMatchingRulesArray, 
-                                addMatchingRulesArray[i])) {
-                charray_add(&origMatchingRulesArray,
-                    slapi_ch_strdup(addMatchingRulesArray[i]));
-            }
-        }
-    }
-
-    if (dodeletes) {
-        i = 0;
-        arglist[i++] = slapi_ch_strdup(attrValue->bv_val);
-        arglist[i++] = slapi_ch_strdup("none");
-        arglist[i] = NULL;
-        attr_index_config(inst->inst_be, "from DSE modify", 0, i, arglist, 0);
-
-	/* Free args */
-	slapi_ch_free((void **)&arglist[0]);
-	slapi_ch_free((void **)&arglist[1]);
-    }
-
-    i = 0;
-    arglist[i++] = slapi_ch_strdup(attrValue->bv_val);
-    if (origIndexTypesArray && origIndexTypesArray[0]) {
-        tmpBuf[0] = 0;
-        ZCAT_SAFE(tmpBuf, "", origIndexTypesArray[0]);
-        for (j = 1; origIndexTypesArray[j] != NULL; j++) {
-            ZCAT_SAFE(tmpBuf, ",", origIndexTypesArray[j]);
-        }
-        arglist[i++] = slapi_ch_strdup(tmpBuf);
-    } else {
-        arglist[i++] = slapi_ch_strdup("none");
+    if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
+        LDAPDebug(LDAP_DEBUG_ANY,
+        		"Warning: malformed index entry %s, missing index name\n",
+        		slapi_entry_get_dn(e), 0, 0);
+        *returncode =  LDAP_UNWILLING_TO_PERFORM;
+        return SLAPI_DSE_CALLBACK_ERROR;
     }
 
-    if (origMatchingRulesArray && origMatchingRulesArray[0]) {
-        tmpBuf[0] = 0;
-        ZCAT_SAFE(tmpBuf, "", origMatchingRulesArray[0]);
-        for (j = 1; origMatchingRulesArray[j] != NULL; j++) {
-            ZCAT_SAFE(tmpBuf, ",", origMatchingRulesArray[j]);
-        }
-        arglist[i++] = slapi_ch_strdup(tmpBuf);
+    ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
+    if (NULL == ainfo) {
+    	LDAPDebug(LDAP_DEBUG_ANY,
+    			"Warning: malformed index entry %s - missing cn attribute info\n",
+    			slapi_entry_get_dn(e), 0, 0);
+    	*returncode = LDAP_UNWILLING_TO_PERFORM;
+        return SLAPI_DSE_CALLBACK_ERROR;
     }
 
-    arglist[i] = NULL;
-    attr_index_config(inst->inst_be, "from DSE modify", 0, i, arglist, 0);
-
-out:
-    /* Free args */
-    for (i=0; arglist[i]; i++) {
-	slapi_ch_free((void **)&arglist[i]);
+    if(slapi_entry_attr_find(entryAfter, "nsIndexType", &attr) != 0){
+    	 LDAPDebug(LDAP_DEBUG_ANY,
+    			 "Warning: malformed index entry %s - missing nsIndexType attribute\n",
+    			 slapi_entry_get_dn(entryAfter), 0, 0);
+    	 *returncode = LDAP_OBJECT_CLASS_VIOLATION;
+    	 return SLAPI_DSE_CALLBACK_ERROR;
     }
 
-    if(origIndexTypesArray) {
-	charray_free(origIndexTypesArray);
-    }
-    if(origMatchingRulesArray) {
-	charray_free(origMatchingRulesArray);
-    }
-    if(addIndexTypesArray) {
-	charray_free(addIndexTypesArray);
-    }
-    if(deleteIndexTypesArray) {
-	charray_free(deleteIndexTypesArray);
-    }
-    if(addMatchingRulesArray) {
-	charray_free(addMatchingRulesArray);
-    }
-    if(deleteMatchingRulesArray) {
-	charray_free(deleteMatchingRulesArray);
-    }
-    if (origIndexTypes) {
-	slapi_ch_free ((void **)&origIndexTypes);	
-    }
-    if (origMatchingRules) {
-	slapi_ch_free ((void **)&origMatchingRules);	
-    }
+    attr_index_config(inst->inst_be, "from DSE modify", 0, entryAfter, 0, 0);
 
-    return rc;
+    return SLAPI_DSE_CALLBACK_OK;
 }
 
 /* add index entries to the per-instance DSE (used only from instance.c) */
 int ldbm_instance_config_add_index_entry(
     ldbm_instance *inst, 
-    int argc, 
-    char **argv,
+    Slapi_Entry *e,
     int flags
 )
 {
-    char **attrs = NULL;
-    char **indexes = NULL;
-    char **matchingRules = NULL;
     char *eBuf;
-    int i = 0;
     int j = 0;
     char *basetype = NULL;
-    char tmpAttrsStr[256];
-    char tmpIndexesStr[256];
-    char tmpMatchingRulesStr[1024];
     struct ldbminfo *li = inst->inst_li;
     char *dn = NULL;
+    Slapi_Attr *attr;
+    const struct berval *attrValue;
+    Slapi_Value *sval;
     int rc = 0;
 
-    if ((argc < 2) || (NULL == argv) || (NULL == argv[0]) || 
-        (NULL == argv[1])) {
-        return(-1);
+    /* get the cn value */
+    if (slapi_entry_attr_find(e, "cn", &attr) != 0) {
+        LDAPDebug(LDAP_DEBUG_ANY, "Warning: malformed index entry %s, missing cn attrbiute\n",
+                  slapi_entry_get_dn(e), 0, 0);
+        return -1;
     }
 
-    PL_strncpyz(tmpAttrsStr,argv[0], sizeof(tmpAttrsStr));
-    attrs = slapi_str2charray( tmpAttrsStr, "," );
-    PL_strncpyz(tmpIndexesStr,argv[1], sizeof(tmpIndexesStr));
-    indexes = slapi_str2charray( tmpIndexesStr, ",");
-
-    if(argc > 2) {
-        PL_strncpyz(tmpMatchingRulesStr,argv[2], sizeof(tmpMatchingRulesStr));
-        matchingRules = slapi_str2charray( tmpMatchingRulesStr, ",");
+    slapi_attr_first_value(attr, &sval);
+    attrValue = slapi_value_get_berval(sval);
+    if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
+        LDAPDebug(LDAP_DEBUG_ANY,
+                  "Warning: malformed index entry %s, missing index name\n",
+                  slapi_entry_get_dn(e), 0, 0);
+        return -1;
     }
 
-    for(i=0; attrs && attrs[i] !=NULL; i++)
-    {
-        if('\0' == attrs[i][0]) continue;
-        basetype = slapi_attr_basetype(attrs[i], NULL, 0);
-        dn = slapi_create_dn_string("cn=%s,cn=index,cn=%s,cn=%s,cn=plugins,cn=config", 
+	basetype = slapi_attr_basetype(attrValue->bv_val, NULL, 0);
+	dn = slapi_create_dn_string("cn=%s,cn=index,cn=%s,cn=%s,cn=plugins,cn=config",
                             basetype, inst->inst_name, li->li_plugin->plg_name);
-        if (NULL == dn) {
-            LDAPDebug(LDAP_DEBUG_ANY,
-                      "ldbm_instance_config_add_index_entry: "
-                      "failed create index dn with type %s for plugin %s, "
-                      "instance %s\n",
-                      basetype, inst->inst_li->li_plugin->plg_name,
-                      inst->inst_name);
-            slapi_ch_free((void**)&basetype);
-            rc = -1;
-            goto done;
-        }
-        eBuf = PR_smprintf(
-                "dn: %s\n"
-                "objectclass: top\n"
-                "objectclass: nsIndex\n"
-                "cn: %s\n"
-                "nsSystemIndex: %s\n",
+	if (NULL == dn) {
+		LDAPDebug(LDAP_DEBUG_ANY,
+				"ldbm_instance_config_add_index_entry: "
+				"failed create index dn with type %s for plugin %s, "
+				"instance %s\n",
+				basetype, inst->inst_li->li_plugin->plg_name,
+				inst->inst_name);
+		slapi_ch_free((void**)&basetype);
+		return -1;
+	}
+
+	eBuf = PR_smprintf(
+			"dn: %s\n"
+			"objectclass: top\n"
+			"objectclass: nsIndex\n"
+			"cn: %s\n"
+			"nsSystemIndex: %s\n",
                 dn, basetype,
                 (ldbm_attribute_always_indexed(basetype)?"true":"false"));
-        slapi_ch_free_string(&dn);
-        for(j=0; indexes && indexes[j] != NULL; j++)
-        {
-            eBuf = PR_sprintf_append(eBuf, "nsIndexType:%s\n", indexes[j]);
-        }
-        if((argc>2)&&(argv[2]))
-        {
-            for(j=0; matchingRules && matchingRules[j] != NULL; j++)
-            { 
-                eBuf = PR_sprintf_append(eBuf, "nsMatchingRule:%s\n", matchingRules[j]);
-            }
-        }
+	slapi_ch_free_string(&dn);
+
+	/* get nsIndexType and its values, and add them */
+	if( 0 == slapi_entry_attr_find(e, "nsIndexType", &attr)){
+		for (j = slapi_attr_first_value(attr, &sval); j != -1;j = slapi_attr_next_value(attr, j, &sval)) {
+			attrValue = slapi_value_get_berval(sval);
+			eBuf = PR_sprintf_append(eBuf, "nsIndexType: %s\n", attrValue->bv_val);
+		}
+	} else {
+		LDAPDebug(LDAP_DEBUG_ANY,
+				"ldbm_instance_config_add_index_entry: "
+				"failed create index dn with type %s for plugin %s, "
+				"instance %s.  Missing nsIndexType\n",
+				basetype, inst->inst_li->li_plugin->plg_name,
+				inst->inst_name);
+		slapi_ch_free((void**)&basetype);
+		return -1;
+	}
 
-        ldbm_config_add_dse_entry(li, eBuf, flags);
-        if (eBuf) {
-            PR_smprintf_free(eBuf);
-        }
+	/* get nsMatchingRule and its values, and add them */
+	if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)) {
+		for (j = slapi_attr_first_value(attr, &sval); j != -1;j = slapi_attr_next_value(attr, j, &sval)) {
+			attrValue = slapi_value_get_berval(sval);
+			eBuf = PR_sprintf_append(eBuf, "nsMatchingRule: %s\n", attrValue->bv_val);
+		}
+ 	}
+
+	ldbm_config_add_dse_entry(li, eBuf, flags);
+	if (eBuf) {
+		PR_smprintf_free(eBuf);
+	}
 
-        slapi_ch_free((void**)&basetype);
-    }
+	slapi_ch_free((void**)&basetype);
 
-done:
-    charray_free(attrs);
-    charray_free(indexes);
-    charray_free(matchingRules);
     return rc;
 }
 
@@ -724,10 +346,9 @@ ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry* e)
 
     rc=ldbm_index_parse_entry(inst, e, "from DSE add", &index_name);
     if (rc == LDAP_SUCCESS) {
+    	/* Assume the caller knows if it is OK to go online immediately */
         struct attrinfo *ai = NULL;
 
-        /* Assume the caller knows if it is OK to go online immediatly */
-
         ainfo_get(inst->inst_be, index_name, &ai);
         PR_ASSERT(ai != NULL);
         ai->ai_indexmask &= ~INDEX_OFFLINE;
@@ -736,30 +357,19 @@ ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry* e)
     return rc;
 }
 
-
 /*
-** create the default user-defined indexes
+** Create the default user-defined indexes
+**
+** Search for user-defined default indexes and add them
+** to the backend instance being created.
 */
 
 int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
 {
-
-    /*
-    ** Search for user-defined default indexes and add them
-    ** to the backend instance beeing created.
-    */
-
     Slapi_PBlock *aPb;
     Slapi_Entry **entries = NULL;
     Slapi_Attr *attr;
-    Slapi_Value *sval = NULL;
-    const struct berval *attrValue;
-    char *argv[ 8 ];
-    char tmpBuf[MAX_TMPBUF];
-    char tmpBuf2[MAX_TMPBUF];
-    int argc;
     char *basedn = NULL;
-
     struct ldbminfo *li;
 
     /* write the dse file only on the final index */
@@ -772,7 +382,6 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
     }
 
     li = inst->inst_li;
-    strcpy(tmpBuf,"");
 
     /* Construct the base dn of the subtree that holds the default user indexes. */
 	basedn = slapi_create_dn_string("cn=default indexes,cn=config,cn=%s,cn=plugins,cn=config", 
@@ -792,69 +401,27 @@ int ldbm_instance_create_default_user_indexes(ldbm_instance *inst)
     slapi_search_internal_pb (aPb);
     slapi_pblock_get(aPb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
     if (entries!=NULL) {
-        int i,j;
+        int i;
         for (i=0; entries[i]!=NULL; i++) {
-
-                /* Get the name of the attribute to index which will be the value
-                 * of the cn attribute. */
-
+                /*
+                 * Get the name of the attribute to index which will be the value
+                 * of the cn attribute.
+                 */
                 if (slapi_entry_attr_find(entries[i], "cn", &attr) != 0) {
                         LDAPDebug(LDAP_DEBUG_ANY,"Warning: malformed index entry %s. Index ignored.\n",
                                 slapi_entry_get_dn(entries[i]), 0, 0);
                         continue;
                 }
-                slapi_attr_first_value(attr, &sval);
-                attrValue = slapi_value_get_berval(sval);
-                argv[0] = attrValue->bv_val;
-                argc=1;
-
-                /* Get the list of index types from the entry. */
-
-                if (0 == slapi_entry_attr_find(entries[i], "nsIndexType", &attr)) {
-                        for (j = slapi_attr_first_value(attr, &sval); j != -1;
-                                j = slapi_attr_next_value(attr, j, &sval)) {
-                                attrValue = slapi_value_get_berval(sval);
-                                if (0 == j) {
-                                        tmpBuf[0] = 0;
-                                        ZCAT_SAFE(tmpBuf, "", attrValue->bv_val);
-                                } else {
-                                        ZCAT_SAFE(tmpBuf, ",", attrValue->bv_val);
-                                }
-                        }
-                        argv[argc]=tmpBuf;
-                        argc++;
-                }
-
-                /* Get the list of matching rules from the entry. */
-
-                if (0 == slapi_entry_attr_find(entries[i], "nsMatchingRule", &attr)) {
-                        for (j = slapi_attr_first_value(attr, &sval); j != -1;
-                                j = slapi_attr_next_value(attr, j, &sval)) {
-                                attrValue = slapi_value_get_berval(sval);
-                                if (0 == j) {
-                                        tmpBuf2[0] = 0;
-                                        ZCAT_SAFE(tmpBuf2, "", attrValue->bv_val);
-                                } else {
-                                        ZCAT_SAFE(tmpBuf2, ",", attrValue->bv_val);
-                                }
-                        }
-                        argv[argc]=tmpBuf2;
-                        argc++;
-                }
-
-                argv[argc]=NULL;
 
                 /* Create the index entry in the backend */
-
                 if (entries[i+1] == NULL) {
                     /* write the dse file only on the final index */
                     flags = 0;
                 }
 
-                ldbm_instance_config_add_index_entry(inst, argc, argv, flags);
+                ldbm_instance_config_add_index_entry(inst, entries[i], flags);
 
                 /* put the index online */
-
                 ldbm_instance_index_config_enable_index(inst, entries[i]);
         }
     }
diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
index b4bdc52..1e28070 100644
--- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
@@ -2489,32 +2489,45 @@ db2index_add_indexed_attr(backend *be, char *attrString)
 {
     char *iptr = NULL;
     char *mptr = NULL;
-    char *nsslapd_index_value[4];
-    int argc = 0;
-    int i;
+    Slapi_Entry *e;
+    struct berval *vals[2];
+    struct berval val;
+
+    vals[0] = &val;
+    vals[1] = NULL;
 
     if (NULL == (iptr = strchr(attrString, ':'))) {
         return(0);
     }
+    e = slapi_entry_alloc();
     iptr[0] = '\0';
     iptr++;
-    
-    nsslapd_index_value[argc++] = slapi_ch_strdup(attrString+1);
-    
+
+    /* set the index name */
+    val.bv_val = attrString+1;
+    val.bv_len = strlen(attrString);
+    slapi_entry_add_values(e,"cn",vals);
+
     if (NULL != (mptr = strchr(iptr, ':'))) {
         mptr[0] = '\0';
         mptr++;
     }
-    nsslapd_index_value[argc++] = slapi_ch_strdup(iptr);
+
+    /* set the index type */
+    val.bv_val = iptr;
+    val.bv_len = strlen(iptr);
+    slapi_entry_add_values(e,"nsIndexType",vals);
+
     if (NULL != mptr) {
-        nsslapd_index_value[argc++] = slapi_ch_strdup(mptr);
+        /* set the matching rule */
+        val.bv_val = mptr;
+        val.bv_len = strlen(mptr);
+        slapi_entry_add_values(e,"nsMatchingRule",vals);
     }
-    nsslapd_index_value[argc] = NULL;
-    attr_index_config(be, "from db2index()", 0, argc, nsslapd_index_value, 0);
 
-    for ( i=0; i<argc; i++ ) {
-        slapi_ch_free_string(&nsslapd_index_value[i]);
-    }
+    attr_index_config(be, "from db2index()", 0, e, 0, 0);
+    slapi_entry_free(e);
+
     return(0);
 }
 
diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
index f286377..0734162 100644
--- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
@@ -55,7 +55,7 @@ void attr_masks( backend *be, char *type, int *indexmask,
 void attr_masks_ex( backend *be, char *type, int *indexmask,
  int *syntaxmask, struct attrinfo **at );
 void attr_index_config( backend *be, char *fname, int lineno,
- int argc, char **argv, int init );
+ Slapi_Entry *e, int init, int none );
 int ldbm_compute_init();
 void attrinfo_deletetree(ldbm_instance *inst);
 void attr_create_empty(backend *be,char *type,struct attrinfo **ai);
-- 
1.7.1

