diff --git a/clients/tools/ldapdelete.c b/clients/tools/ldapdelete.c
index f9a93a030303ac629e02034add1322db8bb941ef..b43be367dadc8698e266f2b19437da2426de5fa8 100644
--- a/clients/tools/ldapdelete.c
+++ b/clients/tools/ldapdelete.c
@@ -170,7 +170,8 @@ static int dodelete(
     int	rc;
 
     if ( verbose ) {
-	printf( "%sdeleting entry %s\n", not ? "!" : "", dn );
+	printf( "%sdeleting entry \"%s\"\n",
+		(not ? "!" : ""), dn );
     }
     if ( not ) {
 	rc = LDAP_SUCCESS;
@@ -178,7 +179,7 @@ static int dodelete(
 	if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
 	    ldap_perror( ld, "ldap_delete" );
 	} else if ( verbose ) {
-	    printf( "entry removed\n" );
+	    printf( "\tremoved\n" );
 	}
     }
 
diff --git a/include/ldapconfig.h.edit b/include/ldapconfig.h.edit
index ff3233768aa72ae3e612ec9cc7a2eb983bb3a018..6d73cf991def1dd66472b34d88bbe12c0976b645 100644
--- a/include/ldapconfig.h.edit
+++ b/include/ldapconfig.h.edit
@@ -219,11 +219,15 @@ Please try again later.\r\n"
 #define SLAPD_PIDEXT            ".pid"
 	/* extension of the slapd args file */
 #define SLAPD_ARGSEXT           ".args"
-	/* dn of the special "monitor" entry */
-#define SLAPD_MONITOR_DN		"cn=monitor"
-	/* dn of the special "config" entry */
-#define SLAPD_CONFIG_DN			"cn=config"
 	/* minimum max ids that a single index entry can map to in ldbm */
 #define SLAPD_LDBM_MIN_MAXIDS		4000
 
+/* the following DNs must be normalized and in uppercase! */
+	/* dn of the special "monitor" entry */
+#define SLAPD_MONITOR_DN		"CN=MONITOR"
+	/* dn of the special "config" entry */
+#define SLAPD_CONFIG_DN			"CN=CONFIG"
+	/* dn of the special "schema" entry */
+/* #define SLAPD_SCHEMA_DN			"CN=SCHEMA" */
+
 #endif /* _LDAP_CONFIG_H */
diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index e94bfe3cd1f6ee356ba03b9c1afa8a016780d12c..dc424912891613c96deb1c022ad78a880b10f402 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -16,7 +16,7 @@ static void	string_expand(char *newbuf, int bufsiz, char *pattern,
 
 
 /*
- * access_allowed - check whether dn is allowed the requested access
+ * access_allowed - check whether op->o_ndn is allowed the requested access
  * to entry e, attribute attr, value val.  if val is null, access to
  * the whole attribute is assumed (all values).  this routine finds
  * the applicable acl and calls acl_access_allowed() to make the
@@ -34,7 +34,6 @@ access_allowed(
     Entry		*e,
     char		*attr,
     struct berval	*val,
-    char		*dn,
     int			access
 )
 {
@@ -50,7 +49,8 @@ access_allowed(
 		return( 0 );
 	}
 
-	edn = dn_normalize_case( ch_strdup( e->e_dn ) );
+	edn = e->e_ndn;
+
 	Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: entry (%s) attr (%s)\n",
 		e->e_dn, attr, 0 );
 
@@ -62,13 +62,12 @@ access_allowed(
 	{
  		Debug( LDAP_DEBUG_ACL, "LASTMOD attribute: %s access allowed\n",
 			attr, 0, 0 );
-		free( edn );
 		return(1);
 	}
 
 	memset(matches, 0, sizeof(matches));
 
-	a = acl_get_applicable( be, op, e, attr, edn, MAXREMATCHES, matches );
+	a = acl_get_applicable( be, op, e, attr, MAXREMATCHES, matches );
 
 	if (a) {
 		for (i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++) {
@@ -85,7 +84,6 @@ access_allowed(
 	}
 
 	rc = acl_access_allowed( a, be, conn, e, val, op, access, edn, matches );
-	free( edn );
 
 	Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: exit (%s) attr (%s)\n",
 		e->e_dn, attr, 0);
@@ -105,24 +103,26 @@ acl_get_applicable(
     Operation		*op,
     Entry		*e,
     char		*attr,
-    char		*edn,
     int			nmatch,
     regmatch_t	*matches
 )
 {
 	int		i, j;
 	struct acl	*a;
+    char		*edn;
 
 	Debug( LDAP_DEBUG_ACL, "\n=> acl_get: entry (%s) attr (%s)\n",
 		e->e_dn, attr, 0 );
 
-	if ( be_isroot( be, op->o_dn ) ) {
+	if ( be_isroot( be, op->o_ndn ) ) {
 		Debug( LDAP_DEBUG_ACL,
 		    "<= acl_get: no acl applicable to database root\n", 0, 0,
 		    0 );
 		return( NULL );
 	}
 
+    edn = e->e_ndn;
+
 	Debug( LDAP_DEBUG_ARGS, "=> acl_get: edn %s\n", edn, 0, 0 );
 
 	/* check for a backend-specific acl that matches the entry */
@@ -230,9 +230,9 @@ acl_access_allowed(
 		"\n=> acl_access_allowed: %s access to value \"%s\" by \"%s\"\n",
 	    access2str( access ),
 		val ? val->bv_val : "any",
-		op->o_dn ?  op->o_dn : "" );
+		op->o_ndn ?  op->o_ndn : "" );
 
-	if ( be_isroot( be, op->o_dn ) ) {
+	if ( be_isroot( be, op->o_ndn ) ) {
 		Debug( LDAP_DEBUG_ACL,
 			"<= acl_access_allowed: granted to database root\n",
 		    0, 0, 0 );
@@ -248,12 +248,13 @@ acl_access_allowed(
 		return( default_access >= access );
 	}
 
-	odn = NULL;
-	if ( op->o_dn != NULL ) {
-		odn = dn_normalize_case( ch_strdup( op->o_dn ) );
+	odn = op->o_ndn;
+
+	if ( odn != NULL ) {
 		bv.bv_val = odn;
 		bv.bv_len = strlen( odn );
 	}
+
 	for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
 		if ( b->a_dnpat != NULL ) {
 			Debug( LDAP_DEBUG_TRACE, "<= check a_dnpat: %s\n",
@@ -264,15 +265,14 @@ acl_access_allowed(
 			 * the entry, OR the given dn matches the dn pattern
 			 */
 			if ( strcasecmp( b->a_dnpat, "self" ) == 0 && 
-				op->o_dn != NULL && *(op->o_dn) && e->e_dn != NULL ) 
+				op->o_ndn != NULL && *(op->o_ndn) && e->e_dn != NULL ) 
 			{
-				if ( strcasecmp( edn, op->o_dn ) == 0 ) {
+				if ( strcasecmp( edn, op->o_ndn ) == 0 ) {
 					Debug( LDAP_DEBUG_ACL,
 					"<= acl_access_allowed: matched by clause #%d access %s\n",
 					    i, (b->a_access & ~ACL_SELF) >=
 					    access ? "granted" : "denied", 0 );
 
-					if ( odn ) free( odn );
 					return( (b->a_access & ~ACL_SELF) >= access );
 				}
 			} else {
@@ -282,7 +282,6 @@ acl_access_allowed(
 				    i, (b->a_access & ~ACL_SELF) >= access ?
 					    "granted" : "denied", 0 );
 
-					if ( odn ) free( odn );
 					return( (b->a_access & ~ACL_SELF) >= access );
 				}
 			}
@@ -294,7 +293,6 @@ acl_access_allowed(
 				    i, (b->a_access & ~ACL_SELF) >= access ?
 				    "granted" : "denied", 0 );
 
-				if ( odn ) free( odn );
 				return( (b->a_access & ~ACL_SELF) >= access );
 			}
 		}
@@ -308,11 +306,10 @@ acl_access_allowed(
 				    i, (b->a_access & ~ACL_SELF) >= access ?
 				    "granted" : "denied", 0 );
 
-				if ( odn ) free( odn );
 				return( (b->a_access & ~ACL_SELF) >= access );
 			}
 		}
-		if ( b->a_dnattr != NULL && op->o_dn != NULL ) {
+		if ( b->a_dnattr != NULL && op->o_ndn != NULL ) {
 			Debug( LDAP_DEBUG_ARGS, "<= check a_dnattr: %s\n",
 				b->a_dnattr, 0, 0);
 			/* see if asker is listed in dnattr */
@@ -325,7 +322,6 @@ acl_access_allowed(
 					continue;
 				}
 
-				if ( odn ) free( odn );
 				Debug( LDAP_DEBUG_ACL,
 				    "<= acl_acces_allowed: matched by clause #%d access %s\n",
 				    i, (b->a_access & ~ACL_SELF) >= access ?
@@ -341,7 +337,6 @@ acl_access_allowed(
 				continue;
 			}
 
-			if ( odn ) free( odn );
 			Debug( LDAP_DEBUG_ACL,
 				"<= acl_access_allowed: matched by clause #%d (self) access %s\n",
 			    i, (b->a_access & ~ACL_SELF) >= access ? "granted"
@@ -350,8 +345,8 @@ acl_access_allowed(
 			return( (b->a_access & ~ACL_SELF) >= access );
 		}
 #ifdef SLAPD_ACLGROUPS
-		if ( b->a_group != NULL && op->o_dn != NULL ) {
-			char buf[512];
+		if ( b->a_group != NULL && op->o_ndn != NULL ) {
+			char buf[1024];
 
 			/* b->a_group is an unexpanded entry name, expanded it should be an 
 			 * entry with objectclass group* and we test to see if odn is one of
@@ -359,6 +354,7 @@ acl_access_allowed(
 			 */
 			/* see if asker is listed in dnattr */
 			string_expand(buf, sizeof(buf), b->a_group, edn, matches);
+			(void) dn_normalize_case(buf);
 
 			if (be_group(be, e, buf, odn,
 				b->a_objectclassvalue, b->a_groupattrname) == 0)
@@ -366,14 +362,12 @@ acl_access_allowed(
 				Debug( LDAP_DEBUG_ACL,
 					"<= acl_access_allowed: matched by clause #%d (group) access granted\n",
 					i, 0, 0 );
-				if ( odn ) free( odn );
 				return( (b->a_access & ~ACL_SELF) >= access );
 			}
 		}
 #endif /* SLAPD_ACLGROUPS */
 	}
 
-	if ( odn ) free( odn );
 	Debug( LDAP_DEBUG_ACL,
 		"<= acl_access_allowed: %s by default (no matching by)\n",
 	    default_access >= access ? "granted" : "denied", 0, 0 );
@@ -400,9 +394,7 @@ acl_check_modlist(
 {
 	int		i;
 	struct acl	*a;
-	char            *edn;
-
-	edn = dn_normalize_case( ch_strdup( e->e_dn ) );
+	char	*edn = e->e_ndn;
 
 	for ( ; mlist != NULL; mlist = mlist->ml_next ) {
 		regmatch_t       matches[MAXREMATCHES];
@@ -418,7 +410,7 @@ acl_check_modlist(
 			continue;
 		}
 
-		a = acl_get_applicable( be, op, e, mlist->ml_type, edn,
+		a = acl_get_applicable( be, op, e, mlist->ml_type,
 			MAXREMATCHES, matches );
 
 		switch ( mlist->ml_op & ~LDAP_MOD_BVALUES ) {
@@ -431,7 +423,6 @@ acl_check_modlist(
 				if ( ! acl_access_allowed( a, be, conn, e, mlist->ml_bvalues[i], 
 					op, ACL_WRITE, edn, matches) ) 
 				{
-					free(edn);
 					return( LDAP_INSUFFICIENT_ACCESS );
 				}
 			}
@@ -442,7 +433,6 @@ acl_check_modlist(
 				if ( ! acl_access_allowed( a, be, conn, e,
 					NULL, op, ACL_WRITE, edn, matches) ) 
 				{
-					free(edn);
 					return( LDAP_INSUFFICIENT_ACCESS );
 				}
 				break;
@@ -451,7 +441,6 @@ acl_check_modlist(
 				if ( ! acl_access_allowed( a, be, conn, e, mlist->ml_bvalues[i], 
 					op, ACL_WRITE, edn, matches) ) 
 				{
-					free(edn);
 					return( LDAP_INSUFFICIENT_ACCESS );
 				}
 			}
@@ -459,7 +448,6 @@ acl_check_modlist(
 		}
 	}
 
-	free(edn);
 	return( LDAP_SUCCESS );
 }
 
diff --git a/servers/slapd/add.c b/servers/slapd/add.c
index 823389b76b82aa3c3bd018d5fd4df6ff6298d8d2..ae1ec1ea9f1358eb34c40c046f8fa29c8c001800 100644
--- a/servers/slapd/add.c
+++ b/servers/slapd/add.c
@@ -117,11 +117,11 @@ do_add( Connection *conn, Operation *op )
 	 */
 	if ( be->be_add != NULL ) {
 		/* do the update here */
-		if ( be->be_updatedn == NULL ||
-			strcasecmp( be->be_updatedn, op->o_dn ) == 0 ) {
-
+		if ( be->be_update_ndn == NULL ||
+			strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
+		{
 			if ( (be->be_lastmod == ON || (be->be_lastmod == UNDEFINED &&
-				global_lastmod == ON)) && be->be_updatedn == NULL ) {
+				global_lastmod == ON)) && be->be_update_ndn == NULL ) {
 
 				add_created_attrs( op, e );
 			}
diff --git a/servers/slapd/back-ldbm/add.c b/servers/slapd/back-ldbm/add.c
index cc18e41f53bdc0dc735c6293cb17d5b9a5945e4a..26dfd66154166f9b2184f7b965a9f242805a5111 100644
--- a/servers/slapd/back-ldbm/add.c
+++ b/servers/slapd/back-ldbm/add.c
@@ -86,8 +86,8 @@ ldbm_back_add(
 			free( matched );
 		}
 
-		if ( ! access_allowed( be, conn, op, p, "children", NULL,
-		    op->o_dn, ACL_WRITE ) )
+		if ( ! access_allowed( be, conn, op, p,
+			"children", NULL, ACL_WRITE ) )
 		{
 			Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
 			    0, 0 );
@@ -103,7 +103,7 @@ ldbm_back_add(
 
 	} else {
 		/* no parent, must be adding entry to root */
-		if ( ! be_isroot( be, op->o_dn ) ) {
+		if ( ! be_isroot( be, op->o_ndn ) ) {
 			pthread_mutex_unlock(&li->li_add_mutex);
 			Debug( LDAP_DEBUG_TRACE, "no parent & not root\n", 0,
 			    0, 0 );
diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c
index 23bb40491ab97658c6fb056cfe614102083c2e67..6b8a972a28a1c2c3fc6dcf02447ef2f5a3891417 100644
--- a/servers/slapd/back-ldbm/bind.c
+++ b/servers/slapd/back-ldbm/bind.c
@@ -64,7 +64,8 @@ ldbm_back_bind(
     Operation		*op,
     char		*dn,
     int			method,
-    struct berval	*cred
+    struct berval	*cred,
+	char**	edn
 )
 {
 	struct ldbminfo	*li = (struct ldbminfo *) be->be_private;
@@ -79,6 +80,8 @@ ldbm_back_bind(
 
 	Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_bind: dn: %s\n", dn, 0, 0);
 
+	*edn = NULL;
+
 	/* get entry with reader lock */
 	if ( (e = dn2entry_r( be, dn, &matched )) == NULL ) {
 		/* allow noauth binds */
@@ -91,6 +94,7 @@ ldbm_back_bind(
 			rc = 1;
 		} else if ( be_isroot_pw( be, dn, cred ) ) {
 			/* front end will send result */
+			*edn = ch_strdup( be_root_dn( be ) );
 			rc = 0;
 		} else {
 			send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT, matched, NULL );
@@ -102,6 +106,8 @@ ldbm_back_bind(
 		return( rc );
 	}
 
+	*edn = ch_strdup( e->e_dn );
+
 	/* check for deleted */
 
 	switch ( method ) {
@@ -114,6 +120,7 @@ ldbm_back_bind(
 			goto return_results;
 		} else if ( be_isroot_pw( be, dn, cred ) ) {
 			/* front end will send result */
+			*edn = ch_strdup( be_root_dn( be ) );
 			rc = 0;
 			goto return_results;
 		}
@@ -121,6 +128,7 @@ ldbm_back_bind(
 		if ( (a = attr_find( e->e_attrs, "userpassword" )) == NULL ) {
 			if ( be_isroot_pw( be, dn, cred ) ) {
 				/* front end will send result */
+				*edn = ch_strdup( be_root_dn( be ) );
 				rc = 0;
 				goto return_results;
 			}
@@ -130,14 +138,11 @@ ldbm_back_bind(
 			goto return_results;
 		}
 
-#ifdef SLAPD_CRYPT
 		if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
-#else
-		if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 )
-#endif
 		{
 			if ( be_isroot_pw( be, dn, cred ) ) {
 				/* front end will send result */
+				*edn = ch_strdup( be_root_dn( be ) );
 				rc = 0;
 				goto return_results;
 			}
diff --git a/servers/slapd/back-ldbm/compare.c b/servers/slapd/back-ldbm/compare.c
index 29f654751c90fb625c1e8ada77d927b4032a27fa..fc6e17144419ad430ae5ac6ac9e3b9f5e31e4d36 100644
--- a/servers/slapd/back-ldbm/compare.c
+++ b/servers/slapd/back-ldbm/compare.c
@@ -35,8 +35,9 @@ ldbm_back_compare(
 	}
 
 	/* check for deleted */
-	if ( ! access_allowed( be, conn, op, e, ava->ava_type, &ava->ava_value,
-	    op->o_dn, ACL_COMPARE ) ) {
+	if ( ! access_allowed( be, conn, op, e,
+		ava->ava_type, &ava->ava_value, ACL_COMPARE ) )
+	{
 		send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS, "", "" );
 		rc = 1;
 		goto return_results;
diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c
index 8511c140808e25a0c4230a3e254b69380c71d8c9..699e57ca96c14e285d10ef69b9355e319cc10c11 100644
--- a/servers/slapd/back-ldbm/delete.c
+++ b/servers/slapd/back-ldbm/delete.c
@@ -54,8 +54,9 @@ ldbm_back_delete(
 	}
 
 #ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
-	if ( ! access_allowed( be, conn, op, e, "entry", NULL, op->o_dn,
-	    ACL_WRITE ) ) {
+	if ( ! access_allowed( be, conn, op, e,
+		"entry", NULL, ACL_WRITE ) )
+	{
 		Debug(LDAP_DEBUG_ARGS,
 			"<=- ldbm_back_delete: insufficient access %s\n",
 			dn, 0, 0);
@@ -80,8 +81,8 @@ ldbm_back_delete(
 
 #ifndef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
 		/* check parent for "children" acl */
-		if ( ! access_allowed( be, conn, op, p, "children", NULL,
-			op->o_dn, ACL_WRITE ) )
+		if ( ! access_allowed( be, conn, op, p,
+			"children", NULL, ACL_WRITE ) )
 		{
 			Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
 				0, 0 );
@@ -93,7 +94,7 @@ ldbm_back_delete(
 
 	} else {
 		/* no parent, must be root to delete */
-		if( ! be_isroot( be, op->o_dn ) ) {
+		if( ! be_isroot( be, op->o_ndn ) ) {
 			Debug( LDAP_DEBUG_TRACE, "no parent & not root\n",
 				0, 0, 0);
 			send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
diff --git a/servers/slapd/back-ldbm/group.c b/servers/slapd/back-ldbm/group.c
index 623aa2c95bcafa21f1c903151cfb8560ccbaa684..9087c8524c793a854a7afd0b38d1d007911b74a3 100644
--- a/servers/slapd/back-ldbm/group.c
+++ b/servers/slapd/back-ldbm/group.c
@@ -13,67 +13,68 @@
 
 
 #ifdef SLAPD_ACLGROUPS
-/* return 0 IFF edn is a value in member attribute
- * of entry with bdn AND that entry has an objectClass
+/* return 0 IFF op_dn is a value in member attribute
+ * of entry with gr_dn AND that entry has an objectClass
  * value of groupOfNames
  */
 int
 ldbm_back_group(
-	Backend     *be,
+	Backend	*be,
 	Entry	*target,
-        char        *bdn,
-        char        *edn,
-        char        *objectclassValue,
-        char        *groupattrName
+	char	*gr_ndn,
+	char	*op_ndn,
+	char	*objectclassValue,
+	char	*groupattrName
 )
 {
         struct ldbminfo *li = (struct ldbminfo *) be->be_private;    
         Entry        *e;
-		char		*tdn, *xdn; 
         char        *matched;
         Attribute   *objectClass;
         Attribute   *member;
         int          rc;
 
-	Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: bdn: %s\n", bdn, 0, 0 ); 
-	Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: edn: %s\n", edn, 0, 0 ); 
-	Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: objectClass: %s attrName: %s\n", 
-                objectclassValue, groupattrName, 0 ); 
-
-	tdn = dn_normalize_case( ch_strdup( target->e_dn ) );
-	xdn = dn_normalize_case( ch_strdup( bdn ) );
-	Debug( LDAP_DEBUG_TRACE, "=> ldbm_back_group: tdn: %s\n", tdn, 0, 0 ); 
-	if (strcmp(tdn, xdn) == 0) {
+	Debug( LDAP_DEBUG_TRACE,
+		"=> ldbm_back_group: gr dn: \"%s\"\n",
+		gr_ndn, 0, 0 ); 
+	Debug( LDAP_DEBUG_TRACE,
+		"=> ldbm_back_group: op dn: \"%s\"\n",
+		op_ndn, 0, 0 ); 
+	Debug( LDAP_DEBUG_TRACE,
+		"=> ldbm_back_group: objectClass: \"%s\" attrName: \"%s\"\n", 
+		objectclassValue, groupattrName, 0 ); 
+
+	Debug( LDAP_DEBUG_TRACE,
+		"=> ldbm_back_group: tr dn: \"%s\"\n",
+		target->e_ndn, 0, 0 ); 
+
+	if (strcmp(target->e_ndn, gr_ndn) == 0) {
 		/* we already have a LOCKED copy of the entry */
 		e = target;
         	Debug( LDAP_DEBUG_ARGS,
-			"=> ldbm_back_group: target is bdn: %s\n",
-			bdn, 0, 0 ); 
+			"=> ldbm_back_group: target is group: \"%s\"\n",
+			gr_ndn, 0, 0 ); 
 	} else {
-		/* can we find bdn entry with reader lock */
-		if ((e = dn2entry_r(be, bdn, &matched )) == NULL) {
+		/* can we find group entry with reader lock */
+		if ((e = dn2entry_r(be, gr_ndn, &matched )) == NULL) {
 			Debug( LDAP_DEBUG_TRACE,
-				"=> ldbm_back_group: cannot find bdn: %s matched: %s\n",
-					bdn, (matched ? matched : ""), 0 ); 
+				"=> ldbm_back_group: cannot find group: \"%s\" matched: \"%s\"\n",
+					gr_ndn, (matched ? matched : ""), 0 ); 
 			if (matched != NULL)
 				free(matched);
-			free(tdn);
-			free(xdn);
 			return( 1 );
 		}
-        	Debug( LDAP_DEBUG_ARGS,
-			"=> ldbm_back_group: found bdn: %s\n",
-			bdn, 0, 0 ); 
+		Debug( LDAP_DEBUG_ARGS,
+			"=> ldbm_back_group: found group: \"%s\"\n",
+			gr_ndn, 0, 0 ); 
         }
-	free(tdn);
-	free(xdn);
 
 
         /* check for deleted */
 
         /* find it's objectClass and member attribute values
          * make sure this is a group entry
-         * finally test if we can find edn in the member attribute value list *
+         * finally test if we can find op_dn in the member attribute value list *
          */
         
         rc = 1;
@@ -92,8 +93,8 @@ ldbm_back_group(
             bvObjectClass.bv_val = objectclassValue;
             bvObjectClass.bv_len = strlen( bvObjectClass.bv_val );         
 
-            bvMembers.bv_val = edn;
-            bvMembers.bv_len = strlen( edn );         
+            bvMembers.bv_val = op_ndn;
+            bvMembers.bv_len = strlen( op_ndn );         
 
             if (value_find(objectClass->a_vals, &bvObjectClass, SYNTAX_CIS, 1) != 0) {
                 Debug( LDAP_DEBUG_TRACE,
@@ -101,12 +102,14 @@ ldbm_back_group(
                         objectclassValue, 0, 0 ); 
             }
             else if (value_find(member->a_vals, &bvMembers, SYNTAX_CIS, 1) != 0) {
-                Debug( LDAP_DEBUG_ACL, "<= ldbm_back_group: %s not in %s: %s\n", 
-                        edn, bdn, groupattrName ); 
+                Debug( LDAP_DEBUG_ACL,
+					"<= ldbm_back_group: \"%s\" not in \"%s\": %s\n", 
+					op_ndn, gr_ndn, groupattrName ); 
             }
             else {
-                Debug( LDAP_DEBUG_ACL, "<= ldbm_back_group: %s is in %s: %s\n", 
-                        edn, bdn, groupattrName ); 
+				Debug( LDAP_DEBUG_ACL,
+					"<= ldbm_back_group: \"%s\" is in \"%s\": %s\n", 
+					op_ndn, gr_ndn, groupattrName ); 
                 rc = 0;
             }
         }
@@ -115,8 +118,9 @@ ldbm_back_group(
 		/* free entry and reader lock */
 		cache_return_entry_r( &li->li_cache, e );                 
 	}
-        Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: rc: %d\n", rc, 0, 0 ); 
-        return(rc);
+
+	Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: rc: %d\n", rc, 0, 0 ); 
+	return(rc);
 }
 #endif /* SLAPD_ACLGROUPS */
 
diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c
index 16aeee9d4c88666931a06fad5a1786253a83f503..7caeacb9df32092b0fb96251c39bc1b2fd07daeb 100644
--- a/servers/slapd/back-ldbm/modify.c
+++ b/servers/slapd/back-ldbm/modify.c
@@ -55,15 +55,15 @@ ldbm_back_modify(
 
 		switch ( mod->mod_op & ~LDAP_MOD_BVALUES ) {
 		case LDAP_MOD_ADD:
-			err = add_values( e, mod, op->o_dn );
+			err = add_values( e, mod, op->o_ndn );
 			break;
 
 		case LDAP_MOD_DELETE:
-			err = delete_values( e, mod, op->o_dn );
+			err = delete_values( e, mod, op->o_ndn );
 			break;
 
 		case LDAP_MOD_REPLACE:
-			err = replace_values( e, mod, op->o_dn );
+			err = replace_values( e, mod, op->o_ndn );
 			break;
 		}
 
diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c
index ea8b2c4fba2084c403c180ddedd7d03dd4874c58..cff00ee3bb667f75f790f9e724778e1478fd7a13 100644
--- a/servers/slapd/back-ldbm/modrdn.c
+++ b/servers/slapd/back-ldbm/modrdn.c
@@ -40,8 +40,8 @@ ldbm_back_modrdn(
 
 #ifdef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
 		/* check parent for "children" acl */
-	if ( ! access_allowed( be, conn, op, e, "entry", NULL,
-		op->o_dn, ACL_WRITE ) )
+	if ( ! access_allowed( be, conn, op, e,
+		"entry", NULL, ACL_WRITE ) )
 	{
 		Debug( LDAP_DEBUG_TRACE, "no access to entry\n", 0,
 			0, 0 );
@@ -63,8 +63,8 @@ ldbm_back_modrdn(
 
 #ifndef SLAPD_CHILD_MODIFICATION_WITH_ENTRY_ACL
 		/* check parent for "children" acl */
-		if ( ! access_allowed( be, conn, op, p, "children", NULL,
-			op->o_dn, ACL_WRITE ) )
+		if ( ! access_allowed( be, conn, op, p,
+			"children", NULL, ACL_WRITE ) )
 		{
 			Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
 				0, 0 );
@@ -96,7 +96,7 @@ ldbm_back_modrdn(
 		}
 	} else {
 		/* no parent, modrdn entry directly under root */
-		if( ! be_isroot( be, op->o_dn ) ) {
+		if( ! be_isroot( be, op->o_ndn ) ) {
 			Debug( LDAP_DEBUG_TRACE, "no parent & not root\n",
 				0, 0, 0);
 			send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c
index 8f8430dedf62d8a059c239e7bad0046a3475e626..584f690c4eaeb2db6b251a9f4f118b5046317510 100644
--- a/servers/slapd/back-ldbm/search.c
+++ b/servers/slapd/back-ldbm/search.c
@@ -57,14 +57,14 @@ ldbm_back_search(
 
 	Debug(LDAP_DEBUG_ARGS, "=> ldbm_back_search\n", 0, 0, 0);
 
-	if ( tlimit == 0 && be_isroot( be, op->o_dn ) ) {
+	if ( tlimit == 0 && be_isroot( be, op->o_ndn ) ) {
 		tlimit = -1;	/* allow root to set no limit */
 	} else {
 		tlimit = (tlimit > be->be_timelimit || tlimit < 1) ?
 		    be->be_timelimit : tlimit;
 		stoptime = op->o_time + tlimit;
 	}
-	if ( slimit == 0 && be_isroot( be, op->o_dn ) ) {
+	if ( slimit == 0 && be_isroot( be, op->o_ndn ) ) {
 		slimit = -1;	/* allow root to set no limit */
 	} else {
 		slimit = (slimit > be->be_sizelimit || slimit < 1) ?
@@ -85,7 +85,7 @@ ldbm_back_search(
 		realBase = ch_strdup(base);
 	}
 
-	(void) dn_normalize (realBase);
+	(void) dn_normalize_case( realBase );
 
 	Debug( LDAP_DEBUG_TRACE, "using base \"%s\"\n",
 		realBase, 0, 0 );
@@ -181,10 +181,10 @@ ldbm_back_search(
 		 * this for subtree searches, and don't check the filter explicitly
 		 * here since it's only a candidate anyway.
 		 */
-		if ( e->e_dn != NULL &&
-			strncasecmp( e->e_dn, "ref=", 4 ) == 0 &&
-			(ref = attr_find( e->e_attrs, "ref" )) != NULL &&
-			scope == LDAP_SCOPE_SUBTREE )
+		if ( scope == LDAP_SCOPE_SUBTREE &&
+			e->e_ndn != NULL &&
+			strncmp( e->e_ndn, "REF=", 4 ) == 0 &&
+			(ref = attr_find( e->e_attrs, "ref" )) != NULL )
 		{
 			int	i, len;
 
@@ -215,8 +215,10 @@ ldbm_back_search(
 				scopeok = 1;
 				if ( scope == LDAP_SCOPE_ONELEVEL ) {
 					if ( (dn = dn_parent( be, e->e_dn )) != NULL ) {
-						(void) dn_normalize( dn );
-						scopeok = (dn == realBase) ? 1 : (! strcasecmp( dn, realBase ));
+						(void) dn_normalize_case( dn );
+						scopeok = (dn == realBase)
+							? 1
+							: (strcmp( dn, realBase ) ? 0 : 1 );
 						free( dn );
 					} else {
 						scopeok = (realBase == NULL || *realBase == '\0');
diff --git a/servers/slapd/back-perl/bind.c b/servers/slapd/back-perl/bind.c
index 0e08971253376d3ae262eaa51759443d7b554545..4304348128e1a3bf587f1787727096fe885d75e5 100644
--- a/servers/slapd/back-perl/bind.c
+++ b/servers/slapd/back-perl/bind.c
@@ -34,7 +34,8 @@ perl_back_bind(
 	Operation *op,
 	char *dn,
 	int method,
-	struct berval *cred
+	struct berval *cred,
+	char** edn
 )
 {
 	int return_code;
@@ -42,6 +43,8 @@ perl_back_bind(
 
 	PerlBackend *perl_back = (PerlBackend *) be->be_private;
 
+	*edn = NULL;
+
 	pthread_mutex_lock( &perl_interpreter_mutex );	
 
 	{
diff --git a/servers/slapd/back-shell/bind.c b/servers/slapd/back-shell/bind.c
index ac1ab4e9828b403c90946e6ad5ea3fc75dc4cb73..025cbe973c2bc4ae2e1b3dc310534cac542d9cff 100644
--- a/servers/slapd/back-shell/bind.c
+++ b/servers/slapd/back-shell/bind.c
@@ -17,13 +17,16 @@ shell_back_bind(
     Operation		*op,
     char		*dn,
     int			method,
-    struct berval	*cred
+    struct berval	*cred,
+	char		**edn
 )
 {
 	struct shellinfo	*si = (struct shellinfo *) be->be_private;
 	FILE			*rfp, *wfp;
 	int			rc;
 
+	*edn = NULL;
+
 	if ( si->si_bind == NULL ) {
 		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 		    "bind not implemented" );
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index dc63e252317a8be054352b1169c883377f48f6c1..cf485cd0e7879189663e8543776f2b284d2eae26 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -223,28 +223,37 @@ be_issuffix(
 }
 
 int
-be_isroot( Backend *be, char *dn )
+be_isroot( Backend *be, char *ndn )
 {
 	int rc;
-	char *ndn;
 
-	if ( dn == NULL || be->be_rootdn == NULL ) {
+	if ( ndn == NULL || be->be_root_ndn == NULL ) {
 		return( 0 );
 	}
 
-	ndn = dn_normalize_case( ch_strdup( dn ) );
-	rc = strcmp( be->be_rootdn, ndn ) ? 0 : 1;
+	rc = strcmp( be->be_root_ndn, ndn ) ? 0 : 1;
 
-	free(ndn);
 	return(rc);
 }
 
+char *
+be_root_dn( Backend *be )
+{
+	int rc;
+
+	if ( be->be_root_dn == NULL ) {
+		return( "" );
+	}
+
+	return be->be_root_dn;
+}
+
 int
-be_isroot_pw( Backend *be, char *dn, struct berval *cred )
+be_isroot_pw( Backend *be, char *ndn, struct berval *cred )
 {
 	int result;
 
-	if ( ! be_isroot( be, dn ) ) {
+	if ( ! be_isroot( be, ndn ) ) {
 		return( 0 );
 	}
 
@@ -252,7 +261,7 @@ be_isroot_pw( Backend *be, char *dn, struct berval *cred )
 	pthread_mutex_lock( &crypt_mutex );
 #endif
 
-	result = lutil_passwd( cred->bv_val, be->be_rootpw );
+	result = lutil_passwd( cred->bv_val, be->be_root_pw );
 
 #ifdef SLAPD_CRYPT
 	pthread_mutex_unlock( &crypt_mutex );
@@ -293,17 +302,17 @@ be_unbind(
 int 
 be_group(
 	Backend	*be,
-	Entry	*e,
-	char	*bdn,
-	char	*edn,
+	Entry	*target,
+	char	*gr_ndn,
+	char	*op_ndn,
 	char	*objectclassValue,
 	char	*groupattrName
 )
 {
-        if (be->be_group)
-                return(be->be_group(be, e, bdn, edn,
-					objectclassValue, groupattrName));
-        else
-                return(1);
+	if (be->be_group)
+		return( be->be_group(be, target, gr_ndn, op_ndn,
+			objectclassValue, groupattrName) );
+	else
+		return(1);
 }
 #endif
diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c
index 9d4f01fddf7339dbee0f11cdda890a154775ea9e..29abd7869e58c45dd55980d48ea7cbb62165eff1 100644
--- a/servers/slapd/bind.c
+++ b/servers/slapd/bind.c
@@ -29,8 +29,8 @@ do_bind(
 {
 	BerElement	*ber = op->o_ber;
 	int		version, method, len;
+	char		*cdn, *ndn;
 	unsigned long	rc;
-	char		*dn;
 	struct berval	cred;
 	Backend		*be;
 
@@ -65,14 +65,15 @@ do_bind(
 	if ( ber_peek_tag( &tber, &tlen ) == LBER_SEQUENCE ) {
 		Debug( LDAP_DEBUG_ANY, "version 3.0 detected\n", 0, 0, 0 );
 		conn->c_version = 30;
-		rc = ber_scanf(ber, "{{iato}}", &version, &dn, &method, &cred);
+		rc = ber_scanf(ber, "{{iato}}", &version, &cdn, &method, &cred);
 	} else {
-		rc = ber_scanf( ber, "{iato}", &version, &dn, &method, &cred );
+		rc = ber_scanf( ber, "{iato}", &version, &cdn, &method, &cred );
 	}
 	}
 #else
-	rc = ber_scanf( ber, "{iato}", &version, &dn, &method, &cred );
+	rc = ber_scanf( ber, "{iato}", &version, &cdn, &method, &cred );
 #endif
+
 	if ( rc == LBER_ERROR ) {
 		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
 		send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
@@ -96,14 +97,21 @@ do_bind(
 		}
 	}
 #endif /* compat30 */
-	dn_normalize( dn );
+
+	Debug( LDAP_DEBUG_TRACE, "do_bind: version %d dn (%s) method %d\n",
+	    version, cdn, method );
+
+	ndn = dn_normalize_case( ch_strdup( cdn ) );
 
 	Statslog( LDAP_DEBUG_STATS, "conn=%d op=%d BIND dn=\"%s\" method=%d\n",
-	    conn->c_connid, op->o_opid, dn, method, 0 );
+	    conn->c_connid, op->o_opid, ndn, method, 0 );
 
 	if ( version != LDAP_VERSION2 ) {
-		if ( dn != NULL ) {
-			free( dn );
+		if ( cdn != NULL ) {
+			free( cdn );
+		}
+		if ( ndn != NULL ) {
+			free( ndn );
 		}
 		if ( cred.bv_val != NULL ) {
 			free( cred.bv_val );
@@ -115,13 +123,13 @@ do_bind(
 		return;
 	}
 
-	Debug( LDAP_DEBUG_TRACE, "do_bind: version %d dn (%s) method %d\n",
-	    version, dn, method );
-
 	/* accept null binds */
-	if ( dn == NULL || *dn == '\0' ) {
-		if ( dn != NULL ) {
-			free( dn );
+	if ( ndn == NULL || *ndn == '\0' ) {
+		if ( cdn != NULL ) {
+			free( cdn );
+		}
+		if ( ndn != NULL ) {
+			free( ndn );
 		}
 		if ( cred.bv_val != NULL ) {
 			free( cred.bv_val );
@@ -137,8 +145,9 @@ do_bind(
 	 * if we don't hold it.
 	 */
 
-	if ( (be = select_backend( dn )) == NULL ) {
-		free( dn );
+	if ( (be = select_backend( ndn )) == NULL ) {
+		free( cdn );
+		free( ndn );
 		if ( cred.bv_val != NULL ) {
 			free( cred.bv_val );
 		}
@@ -155,27 +164,57 @@ do_bind(
 		return;
 	}
 
-        /* alias suffix */
-        dn = suffixAlias ( dn, op, be );
-
 	if ( be->be_bind != NULL ) {
-		if ( (*be->be_bind)( be, conn, op, dn, method, &cred ) == 0 ) {
+		/* alias suffix */
+		char *edn;
+
+		ndn = suffixAlias( ndn, op, be );
+		dn_normalize_case( ndn );
+
+		if ( (*be->be_bind)( be, conn, op, ndn, method, &cred, &edn ) == 0 ) {
 			pthread_mutex_lock( &conn->c_dnmutex );
-			if ( conn->c_dn != NULL ) {
+
+			if ( conn->c_cdn != NULL ) {
+				free( conn->c_cdn );
+			}
+
+			conn->c_cdn = cdn;
+			cdn = NULL;
+
+			if ( conn->c_cdn != NULL ) {
 				free( conn->c_dn );
 			}
-			conn->c_dn = ch_strdup( dn );
+
+			if(edn != NULL) {
+				conn->c_dn = edn;
+			} else {
+				conn->c_dn = ndn;
+				ndn = NULL;
+			}
+
+			Debug( LDAP_DEBUG_TRACE, "do_bind: bound \"%s\" to \"%s\"\n",
+	    		conn->c_cdn, conn->c_dn, method );
+
 			pthread_mutex_unlock( &conn->c_dnmutex );
 
 			/* send this here to avoid a race condition */
 			send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL );
+
+		} else if (edn != NULL) {
+			free( edn );
 		}
+
 	} else {
 		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 		    "Function not implemented" );
 	}
 
-	free( dn );
+	if( cdn != NULL ) {
+		free( cdn );
+	}
+	if( ndn != NULL ) {
+		free( ndn );
+	}
 	if ( cred.bv_val != NULL ) {
 		free( cred.bv_val );
 	}
diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c
index 88a63e8b21b21f693a6f11e5aba988149b75592c..56d3c65ab5621375e7d44dc12c1771580272bed1 100644
--- a/servers/slapd/compare.c
+++ b/servers/slapd/compare.c
@@ -24,7 +24,7 @@ do_compare(
     Operation	*op
 )
 {
-	char	*dn;
+	char	*ndn;
 	Ava	ava;
 	int	rc;
 	Backend	*be;
@@ -43,28 +43,29 @@ do_compare(
 	 *	}
 	 */
 
-	if ( ber_scanf( op->o_ber, "{a{ao}}", &dn, &ava.ava_type,
+	if ( ber_scanf( op->o_ber, "{a{ao}}", &ndn, &ava.ava_type,
 	    &ava.ava_value ) == LBER_ERROR ) {
 		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
 		send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL, "" );
 		return;
 	}
 	value_normalize( ava.ava_value.bv_val, attr_syntax( ava.ava_type ) );
-	dn_normalize( dn );
 
 	Debug( LDAP_DEBUG_ARGS, "do_compare: dn (%s) attr (%s) value (%s)\n",
-	    dn, ava.ava_type, ava.ava_value.bv_val );
+	    ndn, ava.ava_type, ava.ava_value.bv_val );
+
+	ndn = dn_normalize( ndn );
 
 	Statslog( LDAP_DEBUG_STATS, "conn=%d op=%d CMP dn=\"%s\" attr=\"%s\"\n",
-	    conn->c_connid, op->o_opid, dn, ava.ava_type, 0 );
+	    conn->c_connid, op->o_opid, ndn, ava.ava_type, 0 );
 
 	/*
 	 * We could be serving multiple database backends.  Select the
 	 * appropriate one, or send a referral to our "referral server"
 	 * if we don't hold it.
 	 */
-	if ( (be = select_backend( dn )) == NULL ) {
-		free( dn );
+	if ( (be = select_backend( ndn )) == NULL ) {
+		free( ndn );
 		ava_free( &ava, 0 );
 
 		send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
@@ -72,13 +73,17 @@ do_compare(
 		return;
 	}
 
+	/* alias suffix if approp */
+	ndn = suffixAlias( ndn, op, be );
+	dn_normalize_case( ndn );
+
 	if ( be->be_compare != NULL ) {
-		(*be->be_compare)( be, conn, op, dn, &ava );
+		(*be->be_compare)( be, conn, op, ndn, &ava );
 	} else {
 		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 		    "Function not implemented" );
 	}
 
-	free( dn );
+	free( ndn );
 	ava_free( &ava, 0 );
 }
diff --git a/servers/slapd/config.c b/servers/slapd/config.c
index 5b4f409d9b17b3a9f3c085b2bd2813d809f39eed..2b13bdca59c4914270ffb119ea8489011b06a763 100644
--- a/servers/slapd/config.c
+++ b/servers/slapd/config.c
@@ -194,7 +194,8 @@ read_config( char *fname, Backend **bep, FILE *pfp )
 "%s: line %d: rootdn line must appear inside a database definition (ignored)\n",
 				    fname, lineno, 0 );
 			} else {
-				be->be_rootdn = dn_normalize_case( ch_strdup( cargv[1] ) );
+				be->be_root_dn = ch_strdup( cargv[1] );
+				be->be_root_ndn = dn_normalize_case( ch_strdup( cargv[1] ) );
 			}
 
 		/* set super-secret magic database password */
@@ -210,7 +211,7 @@ read_config( char *fname, Backend **bep, FILE *pfp )
 "%s: line %d: rootpw line must appear inside a database definition (ignored)\n",
 				    fname, lineno, 0 );
 			} else {
-				be->be_rootpw = ch_strdup( cargv[1] );
+				be->be_root_pw = ch_strdup( cargv[1] );
 			}
 
 		/* make this database read-only */
@@ -350,8 +351,8 @@ read_config( char *fname, Backend **bep, FILE *pfp )
 "%s: line %d: updatedn line must appear inside a database definition (ignored)\n",
 				    fname, lineno, 0 );
 			} else {
-				be->be_updatedn = ch_strdup( cargv[1] );
-				(void) dn_normalize( be->be_updatedn );
+				be->be_update_ndn = ch_strdup( cargv[1] );
+				(void) dn_normalize_case( be->be_update_ndn );
 			}
 
 		/* replication log file to which changes are appended */
diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c
index 0c428cfd5ccc8a127fd1e618bc3aadccc9a76032..fd6ad73df55d06a8bdcba888f1a3040f4e0a0527 100644
--- a/servers/slapd/daemon.c
+++ b/servers/slapd/daemon.c
@@ -87,6 +87,7 @@ slapd_daemon(
 
 	for ( i = 0; i < dtblsize; i++ ) {
 		c[i].c_dn = NULL;
+		c[i].c_cdn = NULL;
 		c[i].c_addr = NULL;
 		c[i].c_domain = NULL;
 		c[i].c_ops = NULL;
@@ -344,6 +345,10 @@ slapd_daemon(
 				free( c[ns].c_dn );
 				c[ns].c_dn = NULL;
 			}
+			if ( c[ns].c_cdn != NULL ) {
+				free( c[ns].c_cdn );
+				c[ns].c_cdn = NULL;
+			}
 			pthread_mutex_unlock( &c[ns].c_dnmutex );
 			c[ns].c_starttime = currenttime;
 			c[ns].c_opsinitiated = 0;
diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c
index 41ec2e2a29555d960a59a3d726aeef0399a619c2..6d79326f6417d8904e9a06c27fefdc4236b04d09 100644
--- a/servers/slapd/delete.c
+++ b/servers/slapd/delete.c
@@ -25,7 +25,7 @@ do_delete(
     Operation	*op
 )
 {
-	char	*dn, *odn;
+	char	*ndn;
 	Backend	*be;
 
 	Debug( LDAP_DEBUG_TRACE, "do_delete\n", 0, 0, 0 );
@@ -36,46 +36,47 @@ do_delete(
 	 *	DelRequest := DistinguishedName
 	 */
 
-	if ( ber_scanf( op->o_ber, "a", &dn ) == LBER_ERROR ) {
+	if ( ber_scanf( op->o_ber, "a", &ndn ) == LBER_ERROR ) {
 		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
 		send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL, "" );
 		return;
 	}
-	odn = ch_strdup( dn );
-	dn_normalize( dn );
 
-	Debug( LDAP_DEBUG_ARGS, "do_delete: dn (%s)\n", dn, 0, 0 );
+	Debug( LDAP_DEBUG_ARGS, "do_delete: dn (%s)\n", ndn, 0, 0 );
 
-	Debug( LDAP_DEBUG_STATS, "DEL dn=\"%s\"\n", dn, 0, 0 );
+	dn_normalize_case( ndn );
+
+	Debug( LDAP_DEBUG_STATS, "DEL dn=\"%s\"\n", ndn, 0, 0 );
 
 	/*
 	 * We could be serving multiple database backends.  Select the
 	 * appropriate one, or send a referral to our "referral server"
 	 * if we don't hold it.
 	 */
-	if ( (be = select_backend( dn )) == NULL ) {
-		free( dn );
-		free( odn );
+	if ( (be = select_backend( ndn )) == NULL ) {
+		free( ndn );
 		send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
 		    default_referral );
 		return;
 	}
 
-        /* alias suffix if approp */
-        dn = suffixAlias ( dn, op, be );
+	/* alias suffix if approp */
+	ndn = suffixAlias( ndn, op, be );
+	dn_normalize_case( ndn );
 
 	/*
 	 * do the delete if 1 && (2 || 3)
 	 * 1) there is a delete function implemented in this backend;
 	 * 2) this backend is master for what it holds;
-	 * 3) it's a replica and the dn supplied is the updatedn.
+	 * 3) it's a replica and the dn supplied is the update_ndn.
 	 */
 	if ( be->be_delete != NULL ) {
 		/* do the update here */
-		if ( be->be_updatedn == NULL || strcasecmp( be->be_updatedn,
-		    op->o_dn ) == 0 ) {
-			if ( (*be->be_delete)( be, conn, op, dn ) == 0 ) {
-				replog( be, LDAP_REQ_DELETE, odn, NULL, 0 );
+		if ( be->be_update_ndn == NULL ||
+			strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
+		{
+			if ( (*be->be_delete)( be, conn, op, ndn ) == 0 ) {
+				replog( be, LDAP_REQ_DELETE, ndn, NULL, 0 );
 			}
 		} else {
 			send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
@@ -86,6 +87,5 @@ do_delete(
 		    "Function not implemented" );
 	}
 
-	free( dn );
-	free( odn );
+	free( ndn );
 }
diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c
index 7d429f27c58cab6567651aca4c05fdaca8552cdb..a6528b2877bc4a11841dc6aa5c258c9ee51d6aa9 100644
--- a/servers/slapd/filterentry.c
+++ b/servers/slapd/filterentry.c
@@ -110,8 +110,9 @@ test_ava_filter(
 	int		i, rc;
 	Attribute	*a;
 
-	if ( be != NULL && ! access_allowed( be, conn, op, e, ava->ava_type,
-	    &ava->ava_value, op->o_dn, ACL_SEARCH ) ) {
+	if ( be != NULL && ! access_allowed( be, conn, op, e,
+		ava->ava_type, &ava->ava_value, ACL_SEARCH ) )
+	{
 		return( -2 );
 	}
 
@@ -159,8 +160,9 @@ test_presence_filter(
     char	*type
 )
 {
-	if ( be != NULL && ! access_allowed( be, conn, op, e, type, NULL,
-	    op->o_dn, ACL_SEARCH ) ) {
+	if ( be != NULL && ! access_allowed( be, conn, op, e,
+		type, NULL, ACL_SEARCH ) )
+	{
 		return( -2 );
 	}
 
@@ -180,8 +182,9 @@ test_approx_filter(
 	int		i, rc, match;
 	Attribute	*a;
 
-	if ( be != NULL && ! access_allowed( be, conn, op, e, ava->ava_type,
-	    NULL, op->o_dn, ACL_SEARCH ) ) {
+	if ( be != NULL && ! access_allowed( be, conn, op, e,
+		ava->ava_type, NULL, ACL_SEARCH ) )
+	{
 		return( -2 );
 	}
 
@@ -316,8 +319,9 @@ test_substring_filter(
 
 	Debug( LDAP_DEBUG_FILTER, "begin test_substring_filter\n", 0, 0, 0 );
 
-	if ( be != NULL && ! access_allowed( be, conn, op, e, f->f_sub_type,
-	    NULL, op->o_dn, ACL_SEARCH ) ) {
+	if ( be != NULL && ! access_allowed( be, conn, op, e,
+		f->f_sub_type, NULL, ACL_SEARCH ) )
+	{
 		return( -2 );
 	}
 
diff --git a/servers/slapd/main.c b/servers/slapd/main.c
index 4b12eca0cfdbf5c776bb98fd33defc349b0d554b..d74326619e345c33f2a9406b557bb0fd9a3c95a0 100644
--- a/servers/slapd/main.c
+++ b/servers/slapd/main.c
@@ -227,6 +227,7 @@ main( int argc, char **argv )
 		struct hostent		*hp;
 
 		c.c_dn = NULL;
+		c.c_cdn = NULL;
 		c.c_ops = NULL;
 		c.c_sb.sb_sd = 0;
 		c.c_sb.sb_options = 0;
diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c
index 692d4fbe4fb584e3d35ee650c9d60ea904dbf1aa..e03caca86ea4da0f06f956a1f330e762177e78bc 100644
--- a/servers/slapd/modify.c
+++ b/servers/slapd/modify.c
@@ -30,7 +30,7 @@ do_modify(
     Operation	*op
 )
 {
-	char		*dn, *odn;
+	char		*ndn;
 	char		*last;
 	unsigned long	tag, len;
 	LDAPModList	*modlist, *tmp;
@@ -58,15 +58,15 @@ do_modify(
 	 *	}
 	 */
 
-	if ( ber_scanf( op->o_ber, "{a" /*}*/, &dn ) == LBER_ERROR ) {
+	if ( ber_scanf( op->o_ber, "{a" /*}*/, &ndn ) == LBER_ERROR ) {
 		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
 		send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL, "" );
 		return;
 	}
-	odn = ch_strdup( dn );
-	dn_normalize( dn );
 
-	Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", dn, 0, 0 );
+	Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", ndn, 0, 0 );
+
+	(void) dn_normalize_case( ndn );
 
 	/* collect modifications & save for later */
 	modlist = NULL;
@@ -84,8 +84,7 @@ do_modify(
 		{
 			send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
 			    "decoding error" );
-			free( dn );
-			free( odn );
+			free( ndn );
 			free( *modtail );
 			*modtail = NULL;
 			modlist_free( modlist );
@@ -98,8 +97,7 @@ do_modify(
 		{
 			send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
 			    "unrecognized modify operation" );
-			free( dn );
-			free( odn );
+			free( ndn );
 			modlist_free( modlist );
 			return;
 		}
@@ -109,8 +107,7 @@ do_modify(
 		{
 			send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
 			    "no values given" );
-			free( dn );
-			free( odn );
+			free( ndn );
 			modlist_free( modlist );
 			return;
 		}
@@ -131,42 +128,42 @@ do_modify(
 #endif
 
 	Statslog( LDAP_DEBUG_STATS, "conn=%d op=%d MOD dn=\"%s\"\n",
-	    conn->c_connid, op->o_opid, dn, 0, 0 );
+	    conn->c_connid, op->o_opid, ndn, 0, 0 );
 
 	/*
 	 * We could be serving multiple database backends.  Select the
 	 * appropriate one, or send a referral to our "referral server"
 	 * if we don't hold it.
 	 */
-	if ( (be = select_backend( dn )) == NULL ) {
-		free( dn );
-		free( odn );
+	if ( (be = select_backend( ndn )) == NULL ) {
+		free( ndn );
 		modlist_free( modlist );
 		send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
 		    default_referral );
 		return;
 	}
 
-        /* alias suffix if approp */
-        dn = suffixAlias ( dn, op, be );
+	/* alias suffix if approp */
+	ndn = suffixAlias ( ndn, op, be );
+	(void) dn_normalize_case( ndn );
 
 	/*
 	 * do the modify if 1 && (2 || 3)
 	 * 1) there is a modify function implemented in this backend;
 	 * 2) this backend is master for what it holds;
-	 * 3) it's a replica and the dn supplied is the updatedn.
+	 * 3) it's a replica and the dn supplied is the update_ndn.
 	 */
 	if ( be->be_modify != NULL ) {
 		/* do the update here */
-		if ( be->be_updatedn == NULL ||
-			strcasecmp( be->be_updatedn, op->o_dn ) == 0 ) {
-
+		if ( be->be_update_ndn == NULL ||
+			strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
+		{
 			if ( (be->be_lastmod == ON || ( be->be_lastmod == UNDEFINED &&
-				global_lastmod == ON ) ) && be->be_updatedn == NULL ) {
+				global_lastmod == ON ) ) && be->be_update_ndn == NULL ) {
 				add_lastmods( op, &modlist );
 			}
-			if ( (*be->be_modify)( be, conn, op, odn, modlist ) == 0 ) {
-				replog( be, LDAP_REQ_MODIFY, dn, modlist, 0 );
+			if ( (*be->be_modify)( be, conn, op, ndn, modlist ) == 0 ) {
+				replog( be, LDAP_REQ_MODIFY, ndn, modlist, 0 );
 			}
 
 		/* send a referral */
@@ -179,8 +176,7 @@ do_modify(
 		    "Function not implemented" );
 	}
 
-	free( dn );
-	free( odn );
+	free( ndn );
 	modlist_free( modlist );
 }
 
diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c
index 3a7e96704e71d08ca039dfd249ea758011959ab9..ef9f57c2110d18671d0c542b2d2a75a72a2f236f 100644
--- a/servers/slapd/modrdn.c
+++ b/servers/slapd/modrdn.c
@@ -25,7 +25,7 @@ do_modrdn(
     Operation	*op
 )
 {
-	char	*dn, *odn, *newrdn;
+	char	*ndn, *newrdn;
 	int	deloldrdn;
 	Backend	*be;
 
@@ -40,21 +40,21 @@ do_modrdn(
 	 *	}
 	 */
 
-	if ( ber_scanf( op->o_ber, "{aab}", &dn, &newrdn, &deloldrdn )
+	if ( ber_scanf( op->o_ber, "{aab}", &ndn, &newrdn, &deloldrdn )
 	    == LBER_ERROR ) {
 		Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
 		send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL, "" );
 		return;
 	}
-	odn = ch_strdup( dn );
-	dn_normalize( dn );
 
 	Debug( LDAP_DEBUG_ARGS,
-	    "do_modrdn: dn (%s) newrdn (%s) deloldrdn (%d)\n", dn, newrdn,
+	    "do_modrdn: dn (%s) newrdn (%s) deloldrdn (%d)\n", ndn, newrdn,
 	    deloldrdn );
 
+	dn_normalize_case( ndn );
+
 	Statslog( LDAP_DEBUG_STATS, "conn=%d op=%d MODRDN dn=\"%s\"\n",
-	    conn->c_connid, op->o_opid, dn, 0, 0 );
+	    conn->c_connid, op->o_opid, ndn, 0, 0 );
 
 	/*
 	 * We could be serving multiple database backends.  Select the
@@ -62,28 +62,32 @@ do_modrdn(
 	 * if we don't hold it.
 	 */
 
-	if ( (be = select_backend( dn )) == NULL ) {
-		free( dn );
-		free( odn );
+	if ( (be = select_backend( ndn )) == NULL ) {
+		free( ndn );
 		free( newrdn );
 		send_ldap_result( conn, op, LDAP_PARTIAL_RESULTS, NULL,
 		    default_referral );
 		return;
 	}
 
+	/* alias suffix if approp */
+	ndn = suffixAlias( ndn, op, be );
+	dn_normalize_case( ndn );
+
 	/*
 	 * do the add if 1 && (2 || 3)
 	 * 1) there is an add function implemented in this backend;
 	 * 2) this backend is master for what it holds;
-	 * 3) it's a replica and the dn supplied is the updatedn.
+	 * 3) it's a replica and the dn supplied is the update_ndn.
 	 */
 	if ( be->be_modrdn != NULL ) {
 		/* do the update here */
-		if ( be->be_updatedn == NULL || strcasecmp( be->be_updatedn,
-		    op->o_dn ) == 0 ) {
-			if ( (*be->be_modrdn)( be, conn, op, dn, newrdn,
+		if ( be->be_update_ndn == NULL ||
+			strcmp( be->be_update_ndn, op->o_ndn ) == 0 )
+		{
+			if ( (*be->be_modrdn)( be, conn, op, ndn, newrdn,
 			    deloldrdn ) == 0 ) {
-				replog( be, LDAP_REQ_MODRDN, odn, newrdn,
+				replog( be, LDAP_REQ_MODRDN, ndn, newrdn,
 				    deloldrdn );
 			}
 		} else {
@@ -95,7 +99,6 @@ do_modrdn(
 		    "Function not implemented" );
 	}
 
-	free( dn );
-	free( odn );
+	free( ndn );
 	free( newrdn );
 }
diff --git a/servers/slapd/monitor.c b/servers/slapd/monitor.c
index 1d3e55f9676a717031adbb69b52232e31d7b89c6..f9514fd519a5d2f89dce06597a026296edbdc29f 100644
--- a/servers/slapd/monitor.c
+++ b/servers/slapd/monitor.c
@@ -91,7 +91,7 @@ monitor_info( Connection *conn, Operation *op )
 			pthread_mutex_lock( &c[i].c_dnmutex );
 			sprintf( buf, "%d : %s : %d : %d : %s : %s%s", i,
 			    buf2, c[i].c_opsinitiated, c[i].c_opscompleted,
-			    c[i].c_dn ? c[i].c_dn : "NULLDN",
+			    c[i].c_cdn ? c[i].c_cdn : "NULLDN",
 			    c[i].c_gettingber ? "r" : "",
 			    c[i].c_writewaiter ? "w" : "" );
 			pthread_mutex_unlock( &c[i].c_dnmutex );
diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c
index 47d084d6b494a5c818a82a9fb15bd1649e504a87..56085eeb736cc60b7f8048b17a1517192681475d 100644
--- a/servers/slapd/operation.c
+++ b/servers/slapd/operation.c
@@ -18,6 +18,9 @@ slap_op_free( Operation *op )
 	if ( op->o_dn != NULL ) {
 		free( op->o_dn );
 	}
+	if ( op->o_ndn != NULL ) {
+		free( op->o_ndn );
+	}
 	/* pthread_mutex_destroy( &op->o_abandonmutex ); */
 	free( (char *) op );
 }
@@ -45,7 +48,10 @@ slap_op_add(
 	(*tmp)->o_msgid = msgid;
 	(*tmp)->o_tag = tag;
 	(*tmp)->o_abandon = 0;
+
 	(*tmp)->o_dn = ch_strdup( dn != NULL ? dn : "" );
+	(*tmp)->o_ndn = dn_normalize_case( ch_strdup( (*tmp)->o_dn ) );
+
 	pthread_mutex_lock( &currenttime_mutex );
 	(*tmp)->o_time = currenttime;
 	pthread_mutex_unlock( &currenttime_mutex );
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index be300243c098c124d22f02f2e5129592265d6d66..cfdea5d3a619bbce6c0f0f1ef3727d1684ed1748 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -7,11 +7,14 @@
  * acl.c
  */
 
-int access_allowed LDAP_P(( Backend *be, Connection *conn, Operation *op, Entry *e,
-	char *attr, struct berval *val, char *dn, int  access ));
+int access_allowed LDAP_P(( Backend *be, Connection *conn,
+	Operation *op, Entry *e,
+	char *attr, struct berval *val, int access ));
+
+struct acl * acl_get_applicable LDAP_P(( Backend *be,
+	Operation *op, Entry *e,
+	char *attr, int nmatches, regmatch_t *matches ));
 
-struct acl * acl_get_applicable LDAP_P(( Backend *be, Operation *op, Entry *e,
-	char *attr, char *edn, int nmatches, regmatch_t *matches ));
 int acl_access_allowed LDAP_P(( struct acl *a, Backend *be, Connection *conn, Entry *e,
 	struct berval *val, Operation *op, int  access, char *edn,
 	regmatch_t *matches ));
@@ -58,8 +61,9 @@ void ava_free LDAP_P(( Ava *ava, int freeit ));
 Backend * new_backend LDAP_P(( char *type ));
 Backend * select_backend LDAP_P(( char * dn ));
 int be_issuffix LDAP_P(( Backend *be, char *suffix ));
-int be_isroot LDAP_P(( Backend *be, char *dn ));
-int be_isroot_pw LDAP_P(( Backend *be, char *dn, struct berval *cred ));
+int be_isroot LDAP_P(( Backend *be, char *ndn ));
+int be_isroot_pw LDAP_P(( Backend *be, char *ndn, struct berval *cred ));
+char* be_root_dn LDAP_P(( Backend *be ));
 void be_close LDAP_P(( void ));
 
 /*
@@ -261,8 +265,9 @@ extern struct acl	*global_acl;
 extern struct objclass	*global_oc;
 extern time_t		currenttime;
 
-extern int	be_group LDAP_P((Backend *be, Entry *e,
-	char *bdn, char *edn, char *objectclassValue, char *groupattrName));
+extern int	be_group LDAP_P((Backend *be, Entry *target,
+	char *gr_ndn, char *op_ndn,
+	char *objectclassValue, char *groupattrName));
 extern void	init LDAP_P((void));
 extern void	be_unbind LDAP_P((Connection *conn, Operation *op));
 extern void	config_info LDAP_P((Connection *conn, Operation *op));
@@ -289,7 +294,9 @@ extern time_t		starttime;
 #endif
 
 #ifdef SLAPD_LDBM
-extern int  ldbm_back_bind   LDAP_P((Backend *be, Connection *c, Operation *o, char *dn, int method, struct berval *cred ));
+extern int  ldbm_back_bind   LDAP_P((Backend *be,
+	Connection *c, Operation *o,
+	char *dn, int method, struct berval *cred, char** edn ));
 extern void ldbm_back_unbind LDAP_P((Backend *be, Connection *c, Operation *o ));
 extern int  ldbm_back_search LDAP_P((Backend *be, Connection *c, Operation *o, char *base, int scope, int deref, int slimit, int tlimit, Filter *f, char *filterstr, char **attrs, int attrsonly));
 extern int  ldbm_back_compare LDAP_P((Backend *be, Connection *c, Operation *o, char *dn, Ava *ava));
@@ -302,7 +309,8 @@ extern void ldbm_back_config LDAP_P((Backend *be, char *fname, int lineno, int a
 extern void ldbm_back_init   LDAP_P((Backend *be));
 extern void ldbm_back_close  LDAP_P((Backend *be));
 extern int  ldbm_back_group  LDAP_P((Backend *be, Entry *target,
-	char *bdn, char *edn, char *objectclassValue, char *groupattrName ));
+	char *gr_ndn, char *op_ndn,
+	char *objectclassValue, char *groupattrName ));
 #endif
 
 #ifdef SLAPD_PASSWD
@@ -311,7 +319,9 @@ extern void passwd_back_config LDAP_P((Backend *be, char *fname, int lineno, int
 #endif
 
 #ifdef SLAPD_SHELL
-extern int  shell_back_bind   LDAP_P((Backend *be, Connection *c, Operation *o, char *dn, int method, struct berval *cred ));
+extern int  shell_back_bind   LDAP_P((Backend *be,
+	Connection *c, Operation *o,
+	char *dn, int method, struct berval *cred, char** edn ));
 extern void shell_back_unbind LDAP_P((Backend *be, Connection *c, Operation *o ));
 extern int  shell_back_search LDAP_P((Backend *be, Connection *c, Operation *o, char *base, int scope, int deref, int slimit, int tlimit, Filter *f, char *filterstr, char **attrs, int attrsonly));
 extern int  shell_back_compare LDAP_P((Backend *be, Connection *c, Operation *o, char *dn, Ava *ava));
@@ -325,7 +335,9 @@ extern void shell_back_init   LDAP_P((Backend *be));
 #endif
 
 #ifdef SLAPD_PERL
-extern int	perl_back_bind LDAP_P(( Backend *be, Connection *conn, Operation *op, char *dn, int method,    struct berval *crede ));
+extern int perl_back_bind LDAP_P(( Backend *be,
+	Connection *conn, Operation *op,
+	char *dn, int method, struct berval *cred, char** edn ));
 extern void	perl_back_unbind LDAP_P(( Backend *be, Connection *conn, Operation *op ));
 extern int	perl_back_search LDAP_P(( Backend *be, Connection *conn, Operation *op, char *base, int scope, int deref, int sizelimit, int timelimit,  Filter *filter, char *filterstr, char **attrs, int attrsonly ));
 extern int	perl_back_compare LDAP_P((Backend *be, Connection *conn, Operation *op, char *dn, Ava 	*ava ));
diff --git a/servers/slapd/result.c b/servers/slapd/result.c
index 04490d3b7274205cc968d2c98d6a76745b74de6d..12e90a805b2e8f514934538d2b80bfabf330a1bd 100644
--- a/servers/slapd/result.c
+++ b/servers/slapd/result.c
@@ -193,14 +193,15 @@ send_search_entry(
 
 	Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 );
 
-	if ( ! access_allowed( be, conn, op, e, "entry", NULL, op->o_dn,
-	    ACL_READ ) ) {
+	if ( ! access_allowed( be, conn, op, e,
+		"entry", NULL, ACL_READ ) )
+	{
 		Debug( LDAP_DEBUG_ACL, "acl: access to entry not allowed\n",
 		    0, 0, 0 );
 		return( 1 );
 	}
 
-	edn = dn_normalize_case( ch_strdup( e->e_dn ) );
+	edn = e->e_ndn;
 
 #ifdef LDAP_COMPAT30
 	if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
@@ -251,12 +252,12 @@ send_search_entry(
 				a->a_type, 0, 0 );
 			acl = NULL;
 		} else {
-			acl = acl_get_applicable( be, op, e, a->a_type, edn,
+			acl = acl_get_applicable( be, op, e, a->a_type,
 				MAXREMATCHES, matches );
 		}
 
-		if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, ACL_READ,
-			edn, matches ) ) 
+		if ( ! acl_access_allowed( acl, be, conn, e,
+			NULL, op, ACL_READ, edn, matches ) ) 
 		{
 			continue;
 		}
@@ -302,8 +303,6 @@ send_search_entry(
 		}
 	}
 
-	free(edn);
-
 #ifdef LDAP_COMPAT30
 	if ( conn->c_version == 30 ) {
 		rc = ber_printf( ber, "}}}}" );
@@ -382,7 +381,6 @@ send_search_entry(
 	return( rc );
 
 error_return:;
-	free(edn);
 	return( 1 );
 }
 
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index a5cdd9c0afe23f577a248ab3d4a78ae8d99c95ab..7684e524727c636aaf420c9f4c3e1980a340ce7d 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -73,7 +73,8 @@ do_search(
 		    "Unknown search scope" );
 		goto return_results;
 	}
-	(void) dn_normalize( base );
+
+	(void) dn_normalize_case( base );
 
 	Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d", base, scope, deref );
 	Debug( LDAP_DEBUG_ARGS, "    %d %d %d\n", sizelimit, timelimit,
@@ -108,19 +109,19 @@ do_search(
 #if defined( SLAPD_MONITOR_DN ) || defined( SLAPD_CONFIG_DN ) || defined( SLAPD_SCHEMA_DN )
 	if ( scope == LDAP_SCOPE_BASE ) {
 #if defined( SLAPD_MONITOR_DN )
-		if ( strcasecmp( base, SLAPD_MONITOR_DN ) == 0 ) {
+		if ( strcmp( base, SLAPD_MONITOR_DN ) == 0 ) {
 			monitor_info( conn, op );
 			goto return_results;
 		}
 #endif
 #if defined( SLAPD_CONFIG_DN )
-		if ( strcasecmp( base, SLAPD_CONFIG_DN ) == 0 ) {
+		if ( strcmp( base, SLAPD_CONFIG_DN ) == 0 ) {
 			config_info( conn, op );
 			goto return_results;
 		}
 #endif
 #if defined( SLAPD_SCHEMA_DN )
-		if ( strcasecmp( base, SLAPD_SCHEMA_DN ) == 0 ) {
+		if ( strcmp( base, SLAPD_SCHEMA_DN ) == 0 ) {
 			schema_info( conn, op );
 			goto return_results;
 		}
@@ -142,6 +143,7 @@ do_search(
 
 	/* translate the base if it matches an aliased base part */
 	base = suffixAlias ( base, op, be );
+	(void) dn_normalize_case( base );
 
 	/* actually do the search and send the result(s) */
 	if ( be->be_search != NULL ) {
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index bf30582fc0526d2619274e670d0a261ee059659f..5170b91997d17a4ce1a1d394356fafffae8b599a 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -218,8 +218,9 @@ typedef struct backend Backend;
 struct backend {
 	char	**be_suffix;	/* the DN suffixes of data in this backend */
         char    **be_suffixAlias;       /* the DN suffix aliases of data in this backend */
-	char	*be_rootdn;	/* the magic "root" dn for this db   	   */
-	char	*be_rootpw;	/* the magic "root" password for this db   */
+	char	*be_root_dn;	/* the magic "root" dn for this db 	*/
+	char	*be_root_ndn;	/* the magic "root" normalized dn for this db	*/
+	char	*be_root_pw;	/* the magic "root" password for this db	*/
 	int	be_readonly;	/* 1 => db is in "read only" mode	   */
         int     be_maxDerefDepth;       /* limit for depth of an alias deref  */
 	int	be_sizelimit;	/* size limit for this backend   	   */
@@ -228,7 +229,7 @@ struct backend {
 	int	be_dfltaccess;	/* access given if no acl matches	   */
 	char	**be_replica;	/* replicas of this backend (in master)	   */
 	char	*be_replogfile;	/* replication log file (in master)	   */
-	char	*be_updatedn;	/* allowed to make changes (in replicas)   */
+	char	*be_update_ndn;	/* allowed to make changes (in replicas)   */
 	int	be_lastmod;	/* keep track of lastmodified{by,time}	   */
 	char	*be_type;	/* type of database			   */
 
@@ -237,7 +238,7 @@ struct backend {
 	/* backend routines */
 	int	(*be_bind)   LDAP_P((Backend *be,
 		struct slap_conn *c, struct slap_op *o,
-		char *dn, int method, struct berval *cred ));
+		char *dn, int method, struct berval *cred, char** edn ));
 	void	(*be_unbind) LDAP_P((Backend *be,
 		struct slap_conn *c, struct slap_op *o ));
 	int	(*be_search) LDAP_P((Backend *be,
@@ -285,6 +286,7 @@ typedef struct slap_op {
 	unsigned long	o_tag;		/* tag of the request		  */
 	time_t		o_time;		/* time op was initiated	  */
 	char		*o_dn;		/* dn bound when op was initiated */
+	char		*o_ndn;		/* normalized dn bound when op was initiated */
         char            *o_suffix;      /* suffix if aliased              */
         char            *o_suffixAliased;       /* pending suffix translation     */
 	int		o_authtype;	/* auth method used to bind dn	  */
@@ -311,7 +313,8 @@ typedef struct slap_op {
 
 typedef struct slap_conn {
 	Sockbuf		c_sb;		/* ber connection stuff		  */
-	char		*c_dn;		/* current DN bound to this conn  */
+	char		*c_cdn;		/* DN provided by the client */
+	char		*c_dn;		/* DN bound to this conn  */
 	pthread_mutex_t	c_dnmutex;	/* mutex for c_dn field		  */
 	int		c_authtype;	/* auth method used to bind c_dn  */
 #ifdef LDAP_COMPAT
diff --git a/tests/data/modify.out.master b/tests/data/modify.out.master
index 71475341009893fbd4ebcf671bb23ace276cad41..d652b8a997be110b418028506283942cb0b98d82 100644
--- a/tests/data/modify.out.master
+++ b/tests/data/modify.out.master
@@ -7,7 +7,7 @@ cn: All Staff
 joinable: FALSE
 multilinedescription: Everyone in the sample data
 objectclass: rfc822mailgroup
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 
 dn: cn=Alumni Assoc Staff,ou=Groups,o=University of Michigan,c=US
 member: cn=Manager, o=University of Michigan, c=US
@@ -67,7 +67,7 @@ drink: water
 lastmodifiedtime: 960404035839Z
 lastmodifiedby: cn=Barbara Jensen, ou=Information Technology Division, ou=Peop
  le, o=University of Michigan, c=US
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
 facsimiletelephonenumber: +1 313 555 2274
@@ -97,7 +97,7 @@ homephone: +1 313 555 5444
 pager: +1 313 555 4474
 facsimiletelephonenumber: +1 313 555 2177
 telephonenumber: +1 313 555 0355
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 multilinedescription: The replaced multiLineDescription $ Blah Woof.
 drink: Iced Tea
 drink: Mad Dog 20/20
@@ -125,7 +125,7 @@ multilinedescription: Very tall
 facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 0454
 
 dn: cn=Gern Jensen, ou=Information Technology Division, ou=People, o=Universit
@@ -150,7 +150,7 @@ facsimiletelephonenumber: +1 313 555 7557
 telephonenumber: +1 313 555 8343
 mail: gjensen@mailgw.umich.edu
 homephone: +1 313 555 8844
-creatorsname: cn=Manager,o=University of Michigan,c=US
+creatorsname: cn=Manager, o=University of Michigan, c=US
 
 dn: ou=Groups, o=University of Michigan, c=US
 objectclass: top
@@ -186,7 +186,7 @@ member: cn=Dorothy Stevens, ou=Alumni Association, ou=People, o=University of
 member: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of 
  Michigan, c=US
 labeledurl: http://www.itd.umich.edu ITD Home Page
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
  igan, c=US
@@ -214,7 +214,7 @@ pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
 facsimiletelephonenumber: +1 313 555 4332
 telephonenumber: +1 313 555 0895
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 drink: Orange Juice
 
 dn: cn=Jane Doe, ou=Alumni Association, ou=People, o=University of Michigan, c
@@ -238,7 +238,7 @@ onvacation: FALSE
 drink: diet coke
 multilinedescription: Enthusiastic
 mail: jdoe@woof.net
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
 facsimiletelephonenumber: +1 313 555 2311
@@ -264,7 +264,7 @@ drink: Sam Adams
 homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
 mail: jen@mail.alumni.umich.edu
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 6442
 facsimiletelephonenumber: +1 313 555 2756
@@ -290,7 +290,7 @@ homepostaladdress: 912 East Bllvd $ Ann Arbor, MI 48104
 title: System Administrator, Information Technology Division
 multilinedescription: overworked!
 mail: johnd@mailgw.umich.edu
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
 facsimiletelephonenumber: +1 313 555 4544
@@ -332,7 +332,7 @@ homephone: +1 313 555 0388
 drink: Gasoline
 title: Director, UM Alumni Association
 mail: melliot@mail.alumni.umich.edu
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 pager: +1 313 555 7671
 facsimiletelephonenumber: +1 313 555 7762
 telephonenumber: +1 313 555 4177
@@ -384,7 +384,7 @@ krbname: jdoe@umich.edu
 nobatchupdates: TRUE
 onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
 facsimiletelephonenumber: +1 313 555 9700
diff --git a/tests/data/search.out.master b/tests/data/search.out.master
index 52619e9837f9cfa1c96d9ff0009cea19ff39e4f5..cdb982d7ad193307d1077df0a19c1e70be6ceaf4 100644
--- a/tests/data/search.out.master
+++ b/tests/data/search.out.master
@@ -27,7 +27,7 @@ lastmodifiedtime: 960404035839Z
 lastmodifiedby: cn=Barbara Jensen, ou=Information Technology Division, ou=Peop
  le, o=University of Michigan, c=US
 modifytimestamp: 960404171405Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
 facsimiletelephonenumber: +1 313 555 2274
@@ -56,7 +56,7 @@ title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
 modifytimestamp: 960404171424Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 5444
 pager: +1 313 555 4474
 facsimiletelephonenumber: +1 313 555 2177
@@ -132,7 +132,7 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
 modifytimestamp: 960404171730Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
@@ -160,7 +160,7 @@ title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
 modifytimestamp: 960404171231Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 facsimiletelephonenumber: +1 313 555 4332
 telephonenumber: +1 313 555 0895
 dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
@@ -310,7 +310,7 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
  niversity of Michigan, c=US
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: ou=People, o=University of Michigan, c=US
diff --git a/tests/data/test-ordered.ldif b/tests/data/test-ordered.ldif
index c9f9325633fa0aeac92543fe31b4f45678df383f..19d109685e2f04064d8b678427b5fa5e42286c3c 100644
--- a/tests/data/test-ordered.ldif
+++ b/tests/data/test-ordered.ldif
@@ -134,7 +134,7 @@ lastmodifiedtime: 960404035839Z
 lastmodifiedby: cn=Barbara Jensen, ou=Information Technology Division, ou=Peop
  le, o=University of Michigan, c=US
 modifytimestamp: 960404171405Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
 facsimiletelephonenumber: +1 313 555 2274
@@ -163,7 +163,7 @@ title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
 modifytimestamp: 960404171424Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 5444
 pager: +1 313 555 4474
 facsimiletelephonenumber: +1 313 555 2177
@@ -193,7 +193,7 @@ facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
 modifytimestamp: 960404171218Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 0454
 
 dn: cn=ITD Staff,ou=Groups,o=University of Michigan,c=US
@@ -213,7 +213,7 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
 modifytimestamp: 960404171730Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
@@ -241,7 +241,7 @@ title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
 modifytimestamp: 960404171231Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 facsimiletelephonenumber: +1 313 555 4332
 telephonenumber: +1 313 555 0895
 
@@ -268,7 +268,7 @@ multilinedescription: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 modifytimestamp: 960404171442Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 pager: +1 313 555 2833
 facsimiletelephonenumber: +1 313 555 8688
 telephonenumber: +1 313 555 7334
@@ -295,7 +295,7 @@ drink: diet coke
 multilinedescription: Enthusiastic
 mail: jdoe@woof.net
 modifytimestamp: 960404171249Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
 facsimiletelephonenumber: +1 313 555 2311
@@ -322,7 +322,7 @@ homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
 mail: jen@mail.alumni.umich.edu
 modifytimestamp: 960404171309Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 6442
 facsimiletelephonenumber: +1 313 555 2756
@@ -349,7 +349,7 @@ title: System Administrator, Information Technology Division
 multilinedescription: overworked!
 mail: johnd@mailgw.umich.edu
 modifytimestamp: 960404171509Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
 facsimiletelephonenumber: +1 313 555 4544
@@ -392,7 +392,7 @@ drink: Gasoline
 title: Director, UM Alumni Association
 mail: melliot@mail.alumni.umich.edu
 modifytimestamp: 960404171327Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 pager: +1 313 555 7671
 facsimiletelephonenumber: +1 313 555 7762
 telephonenumber: +1 313 555 4177
@@ -416,7 +416,7 @@ nobatchupdates: TRUE
 onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 modifytimestamp: 960404171346Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
 facsimiletelephonenumber: +1 313 555 9700
diff --git a/tests/data/test.ldif b/tests/data/test.ldif
index 272412de45e9eabfab142be623e9eb9170b937ed..043c54e65b0eddd0d19189d7660555eb5b409ce8 100644
--- a/tests/data/test.ldif
+++ b/tests/data/test.ldif
@@ -88,7 +88,7 @@ lastmodifiedtime: 960404035839Z
 lastmodifiedby: cn=Barbara Jensen, ou=Information Technology Division, ou=Peop
  le, o=University of Michigan, c=US
 modifytimestamp: 960404171405Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 3233
 facsimiletelephonenumber: +1 313 555 2274
@@ -117,7 +117,7 @@ title: Director, Embedded Systems
 postaladdress: Info Tech Division $ 535 W. William St. $ Ann Arbor, MI 48103
 mail: bjorn@mailgw.umich.edu
 modifytimestamp: 960404171424Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 5444
 pager: +1 313 555 4474
 facsimiletelephonenumber: +1 313 555 2177
@@ -147,7 +147,7 @@ facsimiletelephonenumber: +1 313 555 3223
 telephonenumber: +1 313 555 3664
 mail: dots@mail.alumni.umich.edu
 modifytimestamp: 960404171218Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 0454
 
 dn: ou=Groups, o=University of Michigan, c=US
@@ -184,7 +184,7 @@ member: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=U
 member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
  ty of Michigan, c=US
 modifytimestamp: 960404171730Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 labeledurl: http://www.itd.umich.edu ITD Home Page
 
 dn: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of Mich
@@ -212,7 +212,7 @@ title: Mad Cow Researcher, UM Alumni Association
 pager: +1 313 555 3923
 mail: jaj@mail.alumni.umich.edu
 modifytimestamp: 960404171231Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 facsimiletelephonenumber: +1 313 555 4332
 telephonenumber: +1 313 555 0895
 
@@ -239,7 +239,7 @@ multilinedescription: Not around very much
 mail: jjones@mailgw.umich.edu
 postaladdress: Info Tech Division $ 535 W William $ Ann Arbor, MI 48103
 modifytimestamp: 960404171442Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 pager: +1 313 555 2833
 facsimiletelephonenumber: +1 313 555 8688
 telephonenumber: +1 313 555 7334
@@ -266,7 +266,7 @@ drink: diet coke
 multilinedescription: Enthusiastic
 mail: jdoe@woof.net
 modifytimestamp: 960404171249Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 5445
 pager: +1 313 555 1220
 facsimiletelephonenumber: +1 313 555 2311
@@ -293,7 +293,7 @@ homepostaladdress: 1000 Maple #44 $ Ann Arbor, MI 48103
 title: Telemarketer, UM Alumni Association
 mail: jen@mail.alumni.umich.edu
 modifytimestamp: 960404171309Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 2333
 pager: +1 313 555 6442
 facsimiletelephonenumber: +1 313 555 2756
@@ -320,7 +320,7 @@ title: System Administrator, Information Technology Division
 multilinedescription: overworked!
 mail: johnd@mailgw.umich.edu
 modifytimestamp: 960404171509Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 3774
 pager: +1 313 555 6573
 facsimiletelephonenumber: +1 313 555 4544
@@ -363,7 +363,7 @@ drink: Gasoline
 title: Director, UM Alumni Association
 mail: melliot@mail.alumni.umich.edu
 modifytimestamp: 960404171327Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 pager: +1 313 555 7671
 facsimiletelephonenumber: +1 313 555 7762
 telephonenumber: +1 313 555 4177
@@ -416,7 +416,7 @@ nobatchupdates: TRUE
 onvacation: FALSE
 mail: uham@mail.alumni.umich.edu
 modifytimestamp: 960404171346Z
-modifiersname: cn=Manager,o=University of Michigan,c=US
+modifiersname: cn=Manager, o=University of Michigan, c=US
 homephone: +1 313 555 8421
 pager: +1 313 555 2844
 facsimiletelephonenumber: +1 313 555 9700