Ver código fonte

Revert "Ticket #55 - Limit of 1024 characters for nsMatchingRule"

This reverts commit 39870fe59195d54dd9d654b1d46737968683f48f.
Mark Reynolds 13 anos atrás
pai
commit
d17fa78abb

+ 51 - 85
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);
+
 
 
 /* Creates and initializes a new ldbm_instance structure.
@@ -148,59 +148,13 @@ 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 *type_val1, char *type_val2, char *type_val3){
-    Slapi_Entry *e = slapi_entry_alloc();
-    Slapi_Value *sval;
-    Slapi_Attr *indextype_attr;
-    Slapi_Attr *cn_attr;
-    Slapi_Attr *attrs = slapi_attr_new();;
-
-    cn_attr = slapi_attr_new();
-    slapi_attr_init(cn_attr, "cn");
-    sval = slapi_value_new_string(cn_val);
-    slapi_attr_add_value(cn_attr,sval);
-    attrlist_add(attrs,cn_attr);
-    slapi_value_free(&sval);
-
-    indextype_attr = slapi_attr_new();
-    slapi_attr_init(indextype_attr, "nsIndexType");
-    sval = slapi_value_new_string(type_val1);
-    slapi_attr_add_value(indextype_attr,sval);
-    attrlist_add(&attrs,indextype_attr);
-    slapi_value_free(&sval);
-
-    if(type_val2){
-	    indextype_attr = slapi_attr_new();
-	    slapi_attr_init(indextype_attr, "nsIndexType");
-	    sval = slapi_value_new_string(type_val2);
-	    slapi_attr_add_value(indextype_attr,sval);
-	    attrlist_add(&attrs,indextype_attr);
-	    slapi_value_free(&sval);
-    }
-    if(type_val3){
-	    indextype_attr = slapi_attr_new();
-	    slapi_attr_init(indextype_attr, "nsIndexType");
-	    sval = slapi_value_new_string(type_val3);
-	    slapi_attr_add_value(indextype_attr,sval);
-	    attrlist_add(&attrs,indextype_attr);
-	    slapi_value_free(&sval);
-    }
-
-    slapi_entry_init_ext(e, NULL, attrs);
-    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)
 {
-    Slapi_Entry *e;
+    char *argv[ 9 ];
     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;
@@ -212,64 +166,76 @@ int ldbm_instance_create_default_indexes(backend *be)
      * ACL routines.
      */
     if (entryrdn_get_switch()) { /* subtree-rename: on */
-        e = ldbm_instance_init_config_entry(LDBM_ENTRYDN_STR,"subtree", 0, 0);
-        ldbm_instance_config_add_index_entry(inst, e, flags);
-        slapi_entry_free(e);
+        argv[ 0 ] = LDBM_ENTRYRDN_STR;
+        argv[ 1 ] = "subtree";
+        argv[ 2 ] = NULL;
+        ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
     } else {
-        e = ldbm_instance_init_config_entry(LDBM_ENTRYDN_STR,"eq", 0, 0);
-        ldbm_instance_config_add_index_entry(inst, e, flags);
-        slapi_entry_free(e);
+        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_PARENTID_STR,"eq", 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("objectclass","eq", 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("aci","pres", 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);
 
 #if 0    /* don't need copiedfrom */
-    e = ldbm_instance_init_config_entry("copiedfrom","pres");
-    ldbm_instance_config_add_index_entry(inst, e, flags);
-    slapi_entry_free(e);
+    argv[ 0 ] = "copiedfrom";
+    argv[ 1 ] = "pres";
+    argv[ 2 ] = NULL;
+    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
 #endif
 
-    e = ldbm_instance_init_config_entry(LDBM_NUMSUBORDINATES_STR,"pres", 0, 0);
-    ldbm_instance_config_add_index_entry(inst, e, flags);
-    slapi_entry_free(e);
+    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(SLAPI_ATTR_UNIQUEID,"eq", 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);
 
     /* For MMR, we need this attribute (to replace use of dncomp in delete). */
-    e = ldbm_instance_init_config_entry(ATTR_NSDS5_REPLCONFLICT,"eq", "pres", 0);
-    ldbm_instance_config_add_index_entry(inst, e, flags);
-    slapi_entry_free(e);
+    argv[ 0 ] = ATTR_NSDS5_REPLCONFLICT;
+    argv[ 1 ] = "eq,pres";
+    argv[ 2 ] = NULL;
+    ldbm_instance_config_add_index_entry(inst, 2, argv, flags);
 
     /* write the dse file only on the final index */
-    e = ldbm_instance_init_config_entry(SLAPI_ATTR_NSCP_ENTRYDN,"eq", 0, 0);
-    ldbm_instance_config_add_index_entry(inst, e, flags);
-    slapi_entry_free(e);
-
+    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;
     /* ldbm_instance_config_add_index_entry(inst, 2, argv); */
-    e = ldbm_instance_init_config_entry(LDBM_PSEUDO_ATTR_DEFAULT,"none", 0, 0);
-    attr_index_config( be, "ldbm index init", 0, e, 1, 0 );
-    slapi_entry_free(e);
+    attr_index_config( be, "ldbm index init", 0, 2, argv, 1 );
 
     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.
          */
-        e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR,"eq", 0, 0);
-        attr_index_config( be, "ldbm index init", 0, e, 1, 0 );
-        slapi_entry_free(e);
+        argv[ 0 ] = LDBM_ANCESTORID_STR;
+        argv[ 1 ] = "eq";
+        argv[ 2 ] = NULL;
+        attr_index_config( be, "ldbm index init", 0, 2, argv, 1 );
     }
 
     return 0;

+ 162 - 161
ldap/servers/slapd/back-ldbm/ldbm_attr.c

@@ -171,65 +171,64 @@ attr_index_config(
     backend *be,
     char		*fname,
     int			lineno,
-    Slapi_Entry *e,
-    int			init,
-    int 		indextype_none
+    int			argc,
+    char		**argv,
+    int			init
 )
 {
 	ldbm_instance *inst = (ldbm_instance *) be->be_instance_info;
-	int	j = 0;
+	int	i, j;
+	char	**attrs = NULL;
+	char	**indexes = NULL;
 	char	**index_rules = NULL;
 	struct attrinfo	*a;
 	int return_value = -1;
 	int *substrlens = NULL;
-	int need_compare_fn = 0;
-	int hasIndexType = 0;
-	const char *attrsyntax_oid = NULL;
-	const struct berval *attrValue;
-	Slapi_Value *sval;
-	Slapi_Attr *attr;
-
-	/* 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 {
+
+	if ((argc == 0) || (argv == NULL)) {
 		LDAPDebug(LDAP_DEBUG_ANY, "attr_index_config: Missing indexing arguments\n", 0, 0, 0);
-		return;
+		goto done;
 	}
 
-	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 ) {
+	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;
+	}
+
+	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->ai_indexmask |= INDEX_PRESENCE;
-			} else if ( strncasecmp( attrValue->bv_val, "eq", 2 ) == 0 ) {
+			} else if ( strncasecmp( indexes[j], "eq", 2 ) == 0 ) {
 				a->ai_indexmask |= INDEX_EQUALITY;
-			} else if ( strncasecmp( attrValue->bv_val, "approx", 6 ) == 0 ) {
+			} else if ( strncasecmp( indexes[j], "approx", 6 ) == 0 ) {
 				a->ai_indexmask |= INDEX_APPROX;
-			} else if ( strncasecmp( attrValue->bv_val, "subtree", 7 ) == 0 ) {
+			} else if ( strncasecmp( indexes[j], "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( attrValue->bv_val, "sub", 3 ) == 0 ) {
+			} else if ( strncasecmp( indexes[j], "sub", 3 ) == 0 ) {
 				a->ai_indexmask |= INDEX_SUB;
-			} else if ( strncasecmp( attrValue->bv_val, "none", 4 ) == 0 ) {
+			} else if ( strncasecmp( indexes[j], "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",
@@ -239,81 +238,77 @@ attr_index_config(
 			} else {
 				LDAPDebug(LDAP_DEBUG_ANY,
 					"%s: line %d: unknown index type \"%s\" (ignored)\n",
-					fname, lineno, attrValue->bv_val);
+					fname, lineno, indexes[j]);
 				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.
-	 */
-
-	if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)){
-		char** official_rules = (char**)slapi_ch_malloc ((j + 1) * sizeof (char*));
-		size_t k = 0;
-		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(index_rules[j], INDEX_ATTR_SUBSTRBEGIN)) {
-				_set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
-				do_continue = 1; /* done with j - next j */
-			} else if (strstr(index_rules[j], INDEX_ATTR_SUBSTRMIDDLE)) {
-				_set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val,	&substrlens);
-				do_continue = 1; /* done with j - next j */
-			} else if (strstr(index_rules[j], 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 */
-			}
+		/* 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 */
+				}
 
-			if (do_continue) {
-				continue; /* done with index_rules[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, attrValue->bv_val) &&
+				/* 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]) &&
 					!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) &&
@@ -322,70 +317,76 @@ 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, attrValue->bv_val);
-					slapi_ch_free((void**)&preamble);
-				}
-			} else { /* we don't know what this is */
-				LDAPDebug (LDAP_DEBUG_ANY, "%s: line %d: "
+					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, attrValue->bv_val);
-			}
-
-			{  /*
-			    *  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);
+						   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);
+					}
 				}
+				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);
 			}
-			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;
+				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);
+		if ( avl_insert( &inst->inst_attrs, a, ainfo_cmp, ainfo_dup ) != 0 ) {
+			/* duplicate - existing version updated */
+			attrinfo_delete(&a);
+		}
+	}
+done:
+	charray_free( attrs );
+	if ( indexes != NULL ) {
+		charray_free( indexes );
+	}
+	if ( index_rules != NULL ) {
+		charray_free( index_rules );
 	}
 }
 

+ 2 - 1
ldap/servers/slapd/back-ldbm/ldbm_config.h

@@ -170,7 +170,8 @@ 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, Slapi_Entry *e, int flags);
+int ldbm_instance_config_add_index_entry(ldbm_instance *inst, int argc,
+                                         char **argv, 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);

+ 326 - 143
ldap/servers/slapd/back-ldbm/ldbm_index_config.c

@@ -51,7 +51,7 @@
 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
+
 
 
 
@@ -104,28 +104,50 @@ static char *attrinfo2ConfIndexes (struct attrinfo *pai)
 }
 
 
-/*
- *  attrinfo2ConfMatchingRules: returns an array of matching rules
+/* attrinfo2ConfMatchingRules: converts attrinfo into matching rule oids, as
+ * seen in index entries within dse.ldif
  */
-static char **attrinfo2ConfMatchingRules (struct attrinfo *pai)
+static char *attrinfo2ConfMatchingRules (struct attrinfo *pai)
 { 
     int i;
-    char **value = NULL;
+    char buffer[1024];
+
+    buffer[0] = '\0';
 
     if (pai->ai_index_rules) {
-    	for (i = 0; pai->ai_index_rules[i]; i++) {
-    		charray_add(&value,slapi_ch_strdup(pai->ai_index_rules[i]));
-    	}
+	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 (value);
+    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. */
@@ -143,28 +165,121 @@ static int ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e,
                       slapi_entry_get_dn(e), 0, 0);
         return LDAP_OPERATIONS_ERROR;
     }
-
-    if(index_name != NULL){
-    	*index_name = slapi_ch_strdup(attrValue->bv_val);
+    arglist[argc++] = slapi_ch_strdup(attrValue->bv_val);
+    if (index_name != NULL) {
+        *index_name = slapi_ch_strdup(attrValue->bv_val);
     }
 
-    /* check and see if we have the required indexType */
+    /* Get the list of index types from the entry. */
     if (0 == slapi_entry_attr_find(e, "nsIndexType", &attr)) {
-    	slapi_attr_first_value(attr, &sval);
-    	attrValue = slapi_value_get_berval(sval);
-    	if (NULL == attrValue->bv_val || strlen(attrValue->bv_val) == 0) {
-    		/* missing the index type, error out */
+        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]) {
             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);
+                }
+            }
+        }
     }
 
-    /* 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);
+    /* 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);
+    }
+
+    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;
 }
 
@@ -179,7 +294,8 @@ 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 {
@@ -202,15 +318,16 @@ 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;
@@ -226,9 +343,11 @@ 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;
   
@@ -239,7 +358,12 @@ 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);
   
-  attr_index_config(inst->inst_be, "From DSE delete", 0, e, 0, INDEXTYPE_NONE);
+  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]);
   
   ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
   
@@ -266,18 +390,15 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
         Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg)
 {
     ldbm_instance *inst = (ldbm_instance *)arg;
-    Slapi_Entry *modEntry;
-    Slapi_Attr *modAttr = NULL;
-    Slapi_Attr *indexTypeAttr;
-    Slapi_Attr *matchingRuleAttr;
     Slapi_Attr *attr;
-    Slapi_Value *modValue;
     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;
@@ -286,6 +407,7 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
     char **deleteMatchingRulesArray = NULL;
     int i, j;
     int dodeletes = 0;
+    char tmpBuf[MAX_TMPBUF];
     int rc = SLAPI_DSE_CALLBACK_OK;
 
     returntext[0] = '\0';
@@ -308,13 +430,23 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
         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 = attrinfo2ConfMatchingRules(ainfo);
+    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;
@@ -424,53 +556,48 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb, Slapi_Entry *e,
     }
 
     if (dodeletes) {
-        attr_index_config(inst->inst_be, "from DSE modify", 0, e, 0, INDEXTYPE_NONE);
-    }
+        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);
 
-    /* create a new entry with the correct attr values */
-    modEntry = slapi_entry_alloc();
+	/* Free args */
+	slapi_ch_free((void **)&arglist[0]);
+	slapi_ch_free((void **)&arglist[1]);
+    }
 
-    /* index types */
+    i = 0;
+    arglist[i++] = slapi_ch_strdup(attrValue->bv_val);
     if (origIndexTypesArray && origIndexTypesArray[0]) {
-    	indexTypeAttr = slapi_attr_new();
-    	slapi_attr_init(indexTypeAttr, "nsIndexType");
-    	for (j = 0; origIndexTypesArray[j] != NULL; j++) {
-    		/* add attr value */
-        	modValue = slapi_value_new_string(origIndexTypesArray[j]);
-        	slapi_attr_add_value(indexTypeAttr,modValue);
-        	slapi_value_free(&modValue);
-    	}
+        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 {
-    	indexTypeAttr = slapi_attr_new();
-    	slapi_attr_init(indexTypeAttr, "nsIndexType");
-    	modValue = slapi_value_new_string("none");
-    	slapi_attr_add_value(indexTypeAttr,modValue);
-    	slapi_value_free(&modValue);
+        arglist[i++] = slapi_ch_strdup("none");
     }
 
-    /* add indexType attribute values */
-    attrlist_add(&modAttr,indexTypeAttr);
-
-    /* matching rules */
     if (origMatchingRulesArray && origMatchingRulesArray[0]) {
-    	matchingRuleAttr = slapi_attr_new();
-    	slapi_attr_init(matchingRuleAttr, "nsMatchingRule");
-        for (j = 0; origMatchingRulesArray[j] != NULL; j++) {
-        	/* add attr value */
-        	modValue = slapi_value_new_string(origMatchingRulesArray[j]);
-        	slapi_attr_add_value(matchingRuleAttr,modValue);
-        	slapi_value_free(&modValue);
+        tmpBuf[0] = 0;
+        ZCAT_SAFE(tmpBuf, "", origMatchingRulesArray[0]);
+        for (j = 1; origMatchingRulesArray[j] != NULL; j++) {
+            ZCAT_SAFE(tmpBuf, ",", origMatchingRulesArray[j]);
         }
-
-        /* add the matchingRule attribute values */
-        attrlist_add(&modAttr,matchingRuleAttr);
+        arglist[i++] = slapi_ch_strdup(tmpBuf);
     }
 
-    slapi_entry_init_ext(modEntry, NULL, modAttr);
-    attr_index_config(inst->inst_be, "from DSE modify", 0, modEntry, 0, 0);
-    slapi_entry_free(modEntry);
+    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(origIndexTypesArray) {
 	charray_free(origIndexTypesArray);
     }
@@ -492,6 +619,9 @@ out:
     if (origIndexTypes) {
 	slapi_ch_free ((void **)&origIndexTypes);	
     }
+    if (origMatchingRules) {
+	slapi_ch_free ((void **)&origMatchingRules);	
+    }
 
     return rc;
 }
@@ -499,92 +629,90 @@ out:
 /* add index entries to the per-instance DSE (used only from instance.c) */
 int ldbm_instance_config_add_index_entry(
     ldbm_instance *inst, 
-    Slapi_Entry *e,
+    int argc, 
+    char **argv,
     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;
 
-    /* get the cn value */
-    if (slapi_entry_attr_find(e, "cn", &attr) != 0) {
-        LDAPDebug(LDAP_DEBUG_ANY, "Warning: malformed index entry %s\n",
-                  slapi_entry_get_dn(e), 0, 0);
-        return -1;
+    if ((argc < 2) || (NULL == argv) || (NULL == argv[0]) || 
+        (NULL == argv[1])) {
+        return(-1);
     }
 
-    slapi_attr_first_value(attr, &sval);
-    attrValue = slapi_value_get_berval(sval);
-    if (NULL == attrValue->bv_val || 0 == strlen(attrValue->bv_val)) {
-        LDAPDebug(LDAP_DEBUG_ANY,
-                  "Warning: malformed index entry %s -- empty index name\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, ",");
     }
 
-	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",
+    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, 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);
-		return -1;
-	}
-
-	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);
+            rc = -1;
+            goto done;
+        }
+        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);
-
-	/* 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;
-	}
+        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]);
+            }
+        }
 
-	/* 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);
-	}
+        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;
 }
 
@@ -596,9 +724,10 @@ 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;
@@ -607,19 +736,30 @@ ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry* e)
     return rc;
 }
 
+
 /*
-** Create the default user-defined indexes
-**
-** Search for user-defined default indexes and add them
-** to the backend instance being created.
+** create the default user-defined indexes
 */
 
 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 */
@@ -632,6 +772,7 @@ 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", 
@@ -651,27 +792,69 @@ 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;
+        int i,j;
         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, entries[i], flags);
+                ldbm_instance_config_add_index_entry(inst, argc, argv, flags);
 
                 /* put the index online */
+
                 ldbm_instance_index_config_enable_index(inst, entries[i]);
         }
     }

+ 13 - 37
ldap/servers/slapd/back-ldbm/ldif2ldbm.c

@@ -2474,56 +2474,32 @@ db2index_add_indexed_attr(backend *be, char *attrString)
 {
     char *iptr = NULL;
     char *mptr = NULL;
-    Slapi_Entry *e;
-    Slapi_Value *sval;
-    Slapi_Attr *indextype_attr;
-    Slapi_Attr *cn_attr;
-    Slapi_Attr *mr_attr;
-    Slapi_Attr *attrs;
+    char *nsslapd_index_value[4];
+    int argc = 0;
+    int i;
 
     if (NULL == (iptr = strchr(attrString, ':'))) {
         return(0);
     }
-    e = slapi_entry_alloc();
-    attrs = slapi_attr_new();
     iptr[0] = '\0';
     iptr++;
-
-    /* set the index name */
-    cn_attr = slapi_attr_new();
-    slapi_attr_init(cn_attr, "cn");
-    sval = slapi_value_new_string(slapi_ch_strdup(attrString+1));
-    slapi_attr_add_value(cn_attr,sval);
-    attrlist_add(&attrs,cn_attr);
-    slapi_value_free(&sval);
-
+    
+    nsslapd_index_value[argc++] = slapi_ch_strdup(attrString+1);
+    
     if (NULL != (mptr = strchr(iptr, ':'))) {
         mptr[0] = '\0';
         mptr++;
     }
-
-    /* set the index type */
-    indextype_attr = slapi_attr_new();
-    slapi_attr_init(indextype_attr, "nsIndexType");
-    sval = slapi_value_new_string(slapi_ch_strdup(iptr));
-    slapi_attr_add_value(indextype_attr,sval);
-    attrlist_add(&attrs,indextype_attr);
-    slapi_value_free(&sval);
-
+    nsslapd_index_value[argc++] = slapi_ch_strdup(iptr);
     if (NULL != mptr) {
-        /* set the matching rule */
-        mr_attr = slapi_attr_new();
-        slapi_attr_init(mr_attr, "nsMatchingRule");
-        sval = slapi_value_new_string(slapi_ch_strdup(mptr));
-        slapi_attr_add_value(mr_attr,sval);
-        attrlist_add(&attrs,mr_attr);
-        slapi_value_free(&sval);
+        nsslapd_index_value[argc++] = slapi_ch_strdup(mptr);
     }
+    nsslapd_index_value[argc] = NULL;
+    attr_index_config(be, "from db2index()", 0, argc, nsslapd_index_value, 0);
 
-    slapi_entry_init_ext(e, NULL, attrs);
-    attr_index_config(be, "from db2index()", 0, e, 0, 0);
-    slapi_entry_free(e);
-
+    for ( i=0; i<argc; i++ ) {
+        slapi_ch_free_string(&nsslapd_index_value[i]);
+    }
     return(0);
 }
 

+ 1 - 1
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,
- Slapi_Entry *e, int init, int none );
+ int argc, char **argv, int init );
 int ldbm_compute_init();
 void attrinfo_deletetree(ldbm_instance *inst);
 void attr_create_empty(backend *be,char *type,struct attrinfo **ai);