diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c
index 61a31f1c577cab5d790e49b480f8337f50e4f9bc..b7b0d9507ab8b5684e577cb2e860fbf4995a504f 100644
--- a/servers/slapd/aclparse.c
+++ b/servers/slapd/aclparse.c
@@ -108,7 +108,7 @@ parse_acl(
 					break;
 				}
 
-				if ( strcmp( argv[i], "*" ) == 0 ) {
+				if ( strcasecmp( argv[i], "*" ) == 0 ) {
 					int e;
 					if ((e = regcomp( &a->acl_dnre, ".*",
 						REG_EXTENDED|REG_ICASE)))
@@ -152,7 +152,6 @@ parse_acl(
 						acl_usage();
 
 					} else {
-						/* ### Should be normalized, but how? */
 						a->acl_dnpat = dn_upcase(ch_strdup( right ));
 					}
 				} else if ( strncasecmp( left, "attr", 4 )
@@ -193,13 +192,12 @@ parse_acl(
 
 			/* get <who> */
 			split( argv[i], '=', &left, &right );
-			if ( strcmp( argv[i], "*" ) == 0 ) {
+			if ( strcasecmp( argv[i], "*" ) == 0 ) {
 				b->a_dnpat = ch_strdup( ".*" );
 			} else if ( strcasecmp( argv[i], "self" ) == 0 ) {
 				b->a_dnpat = ch_strdup( "self" );
 			} else if ( strcasecmp( left, "dn" ) == 0 ) {
 				regtest(fname, lineno, right);
-				/* ### Should be normalized, but how? */
 				b->a_dnpat = dn_upcase( ch_strdup( right ) );
 			} else if ( strcasecmp( left, "dnattr" ) == 0 ) {
 				b->a_dnattr = ch_strdup( right );
@@ -218,7 +216,6 @@ parse_acl(
                                             *name++ = '\0';
                                 }
 
-				/* ### Should it be normalized? */
 				b->a_group = dn_upcase(ch_strdup( right ));
 
                                 if (value && *value) {
diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c
index 581f4570e720af40da687b8b56d5bbfad81200c6..c1178c94e919005772ca5bb535f616829a8ba29d 100644
--- a/servers/slapd/attr.c
+++ b/servers/slapd/attr.c
@@ -279,7 +279,7 @@ attr_syntax_config(
 	    strcasecmp( argv[lasti], "tel" ) == 0 ) {
 		a->asi_syntax = (SYNTAX_CIS | SYNTAX_TEL);
 	} else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
-		a->asi_syntax = SYNTAX_DN;
+		a->asi_syntax = (SYNTAX_CIS | SYNTAX_DN);
 	} else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
 	    strcasecmp( argv[lasti], "ces" ) == 0 ) {
 		a->asi_syntax = SYNTAX_CES;
diff --git a/servers/slapd/back-bdb2/alias.c b/servers/slapd/back-bdb2/alias.c
index 4bec355fa64b276f9c2fa406fb8b95134182fd46..5b3588f7ee385af36e11b4bc7dae90bd51295763 100644
--- a/servers/slapd/back-bdb2/alias.c
+++ b/servers/slapd/back-bdb2/alias.c
@@ -222,7 +222,7 @@ char *bdb2i_derefDN ( BackendDB     *be,
 
 	  Debug( LDAP_DEBUG_TRACE, "<= l&g we have %s vs %s \n", matched, eNew->e_dn, 0 );
 
-	  i = dn_casecmp (matched, eNew->e_dn);
+	  i = strcasecmp (matched, eNew->e_dn);
           /* free reader lock */
           bdb2i_cache_return_entry_r(&li->li_cache, eNew);
 
diff --git a/servers/slapd/back-bdb2/bind.c b/servers/slapd/back-bdb2/bind.c
index 29e5304a640c6b66fd03d4741c32dba67aea33f0..b51d9ea1360ce31e1559a7a43db5954da42732ad 100644
--- a/servers/slapd/back-bdb2/bind.c
+++ b/servers/slapd/back-bdb2/bind.c
@@ -163,7 +163,6 @@ bdb2i_back_bind_internal(
 			/*
 			 * no krbName values present:  check against DN
 			 */
-			/*###??? Should this be some variant of dn_casecmp? */
 			if ( strcasecmp( dn, krbname ) == 0 ) {
 				rc = 0; /* XXX wild ass guess */
 				break;
diff --git a/servers/slapd/back-bdb2/group.c b/servers/slapd/back-bdb2/group.c
index 6865cf2ac261de02ba10924383f47bd1dc05aa53..4634107ba435e2edd44b600ab553422a2406d926 100644
--- a/servers/slapd/back-bdb2/group.c
+++ b/servers/slapd/back-bdb2/group.c
@@ -101,7 +101,7 @@ bdb2i_back_group_internal(
 					"<= bdb2i_back_group: failed to find %s in objectClass\n", 
                         objectclassValue, 0, 0 ); 
             }
-            else if (value_find(member->a_vals, &bvMembers, member->a_syntax, 1) != 0) {
+            else if (value_find(member->a_vals, &bvMembers, SYNTAX_CIS, 1) != 0) {
                 Debug( LDAP_DEBUG_ACL,
 					"<= bdb2i_back_group: \"%s\" not in \"%s\": %s\n", 
 					op_ndn, gr_ndn, groupattrName ); 
diff --git a/servers/slapd/back-bdb2/search.c b/servers/slapd/back-bdb2/search.c
index 8e6b7950d9ec88a1562d91ff9cb2da3deb1fb3e1..5080a5faadb3aceb2ba99a25587709926e152c8e 100644
--- a/servers/slapd/back-bdb2/search.c
+++ b/servers/slapd/back-bdb2/search.c
@@ -525,7 +525,7 @@ subtree_candidates(
 			f->f_and->f_sub_initial = NULL;
 			f->f_and->f_sub_any = NULL;
 			f->f_and->f_sub_final = ch_strdup( base );
-			value_normalize( f->f_and->f_sub_final, SYNTAX_DN );
+			value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
 			f->f_and->f_next = filter;
 			filter = f;
 		}
diff --git a/servers/slapd/back-ldbm/alias.c b/servers/slapd/back-ldbm/alias.c
index 5224839c5b58cc9da8fa9ca700974a9a0303bcfc..9c4f1adeacb014b5ce9855cd6964f824ab9eaeb8 100644
--- a/servers/slapd/back-ldbm/alias.c
+++ b/servers/slapd/back-ldbm/alias.c
@@ -221,7 +221,7 @@ char *derefDN ( Backend     *be,
 
 	  Debug( LDAP_DEBUG_TRACE, "<= l&g we have %s vs %s \n", matched, eNew->e_dn, 0 );
 
-	  i = dn_casecmp (matched, eNew->e_dn);
+	  i = strcasecmp (matched, eNew->e_dn);
           /* free reader lock */
           cache_return_entry_r(&li->li_cache, eNew);
 
diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c
index 8c4fb3fcc0ca5720b7b96aa6bee9d40854625f69..70d3d06d4a79e8e7596c510e30fd43feedc32857 100644
--- a/servers/slapd/back-ldbm/bind.c
+++ b/servers/slapd/back-ldbm/bind.c
@@ -164,7 +164,6 @@ ldbm_back_bind(
 			/*
 			 * no krbName values present:  check against DN
 			 */
-			/*###??? Should this be some variant of dn_casecmp? */
 			if ( strcasecmp( dn, krbname ) == 0 ) {
 				rc = 0; /* XXX wild ass guess */
 				break;
diff --git a/servers/slapd/back-ldbm/group.c b/servers/slapd/back-ldbm/group.c
index beecb2d1fa01dd010b8c7dc5312002ed71255c00..eb35dc3d7e31715a296e1dfa7e6b2d08c0142d02 100644
--- a/servers/slapd/back-ldbm/group.c
+++ b/servers/slapd/back-ldbm/group.c
@@ -101,7 +101,7 @@ ldbm_back_group(
 					"<= ldbm_back_group: failed to find %s in objectClass\n", 
                         objectclassValue, 0, 0 ); 
             }
-            else if (value_find(member->a_vals, &bvMembers, member->a_syntax, 1) != 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", 
 					op_ndn, gr_ndn, groupattrName ); 
diff --git a/servers/slapd/back-ldbm/search.c b/servers/slapd/back-ldbm/search.c
index 5434966e5d8ab1b33e9de354beef9e005d1fb3b9..04e05931930dca8e1a949e167071657ea815e565 100644
--- a/servers/slapd/back-ldbm/search.c
+++ b/servers/slapd/back-ldbm/search.c
@@ -483,7 +483,7 @@ subtree_candidates(
 			f->f_and->f_sub_initial = NULL;
 			f->f_and->f_sub_any = NULL;
 			f->f_and->f_sub_final = ch_strdup( base );
-			value_normalize( f->f_and->f_sub_final, SYNTAX_DN );
+			value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
 			f->f_and->f_next = filter;
 			filter = f;
 		}
diff --git a/servers/slapd/config.c b/servers/slapd/config.c
index 94ff13b46825d61097fdbec4b0b303a06a990045..b02313b5cea80a278d19228788c011051459f7c5 100644
--- a/servers/slapd/config.c
+++ b/servers/slapd/config.c
@@ -208,17 +208,19 @@ read_config( char *fname )
                                 char *alias, *aliased_dn;
 
 								alias = ch_strdup( cargv[1] );
-                                (void) dn_normalize_case( alias );
+                                (void) dn_normalize( alias );
 
                                 aliased_dn = ch_strdup( cargv[2] );
-                                (void) dn_normalize_case( aliased_dn );
+                                (void) dn_normalize( aliased_dn );
 
 
-				if ( strcmp( alias, aliased_dn) == 0 ) {
+								if ( strcasecmp( alias, aliased_dn) == 0 ) {
                                 	Debug( LDAP_DEBUG_ANY,
 "%s: line %d: suffixAlias %s is not different from aliased dn (ignored)\n",
                                     fname, lineno, alias );
 								} else {
+                                	(void) dn_normalize_case( alias );
+                                	(void) dn_normalize_case( aliased_dn );
                                 	charray_add( &be->be_suffixAlias, alias );
                                 	charray_add( &be->be_suffixAlias, aliased_dn );
 								}
diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c
index 38c4bdab89921976f6b9e6226be4e387d8db8c06..e7bb61d5845c1ee2653fb57f05ac235ac4d6386a 100644
--- a/servers/slapd/dn.c
+++ b/servers/slapd/dn.c
@@ -11,32 +11,24 @@
 
 #include "slap.h"
 
-typedef enum DnState {
-	B4TYPE,			/* before attribute type */
-	INTYPE,			/* in     attribute type */
-	B4EQUAL,		/* before '=' */
-	B4VALUE,		/* before attribute value */
-	INVALUE,		/* in     attribute value */
-	INQUOTEDVALUE,		/* in "" in attribute value */
-	B4SEPARATOR,		/* before separator ('+', ',' or ';') */
-} DnState;
+#define B4TYPE		0
+#define INTYPE		1
+#define B4EQUAL		2
+#define B4VALUE		3
+#define INVALUE		4
+#define INQUOTEDVALUE	5
+#define B4SEPARATOR	6
 
 /*
- * dn_normalize_internal - put dn into a canonical form suitable for storing
- * in a hash database.  If correct_case == 1, this involves normalizing the case
- * as well as the format.  The dn is normalized in place as well as returned.
- *
- * The dn_normalize() and dn_normalize_case() macros use this function.
+ * dn_normalize - put dn into a canonical format.  the dn is
+ * normalized in place, as well as returned.
  */
 
 char *
-dn_normalize_internal( char *dn, int correct_case )
+dn_normalize( char *dn )
 {
-	char	*s, *d;		/* source and destination pointers */
-	char	*type;		/* start of attr.type when state==INTYPE */
-	int	gotesc;		/* last char was '\\' */
-	int	ic;		/* ignore case  */
-	DnState	state;
+	char	*d, *s;
+	int	state, gotesc;
 
 	/* Debug( LDAP_DEBUG_TRACE, "=> dn_normalize \"%s\"\n", dn, 0, 0 ); */
 
@@ -47,28 +39,18 @@ dn_normalize_internal( char *dn, int correct_case )
 		case B4TYPE:
 			if ( ! SPACE( *s ) ) {
 				state = INTYPE;
-				ic = 1;
-				type = d;
-				*d++ = TOUPPER( (unsigned char) *s );
+				*d++ = *s;
 			}
 			break;
 		case INTYPE:
 			if ( *s == '=' ) {
 				state = B4VALUE;
+				*d++ = *s;
 			} else if ( SPACE( *s ) ) {
 				state = B4EQUAL;
 			} else {
-				*d++ = TOUPPER( (unsigned char) *s );
-				break;
-			}
-			/* Check if case is ignored in this type */
-			if ( correct_case ) {
-				*d = '\0';
-				if ( ! (attr_syntax( type ) | SYNTAX_CIS) )
-					ic = 0;
+				*d++ = *s;
 			}
-			if (state == B4VALUE)
-				*d++ = '=';
 			break;
 		case B4EQUAL:
 			if ( *s == '=' ) {
@@ -76,7 +58,7 @@ dn_normalize_internal( char *dn, int correct_case )
 				*d++ = *s;
 			} else if ( ! SPACE( *s ) ) {
 				/* not a valid dn - but what can we do here? */
-				*d++ = TOUPPER( (unsigned char) *s );
+				*d++ = *s;
 			}
 			break;
 		case B4VALUE:
@@ -85,7 +67,7 @@ dn_normalize_internal( char *dn, int correct_case )
 				*d++ = *s;
 			} else if ( ! SPACE( *s ) ) { 
 				state = INVALUE;
-				*d++ = (ic ? TOUPPER((unsigned char) *s) : *s);
+				*d++ = *s;
 			}
 			break;
 		case INVALUE:
@@ -100,10 +82,10 @@ dn_normalize_internal( char *dn, int correct_case )
 				}
 			} else if ( gotesc && !NEEDSESCAPE( *s ) &&
 			    !SEPARATOR( *s ) ) {
-				*--d = (ic ? TOUPPER((unsigned char) *s) : *s);
+				*--d = *s;
 				d++;
 			} else {
-				*d++ = (ic ? TOUPPER((unsigned char) *s) : *s);
+				*d++ = *s;
 			}
 			break;
 		case INQUOTEDVALUE:
@@ -111,10 +93,10 @@ dn_normalize_internal( char *dn, int correct_case )
 				state = B4SEPARATOR;
 				*d++ = *s;
 			} else if ( gotesc && !NEEDSESCAPE( *s ) ) {
-				*--d = (ic ? TOUPPER((unsigned char) *s) : *s);
+				*--d = *s;
 				d++;
 			} else {
-				*d++ = (ic ? TOUPPER((unsigned char) *s) : *s);
+				*d++ = *s;
 			}
 			break;
 		case B4SEPARATOR:
@@ -140,22 +122,27 @@ dn_normalize_internal( char *dn, int correct_case )
 	return( dn );
 }
 
-
 /*
- * dn_casecmp - compare two DNs after normalizing (private copies of) them
+ * dn_normalize_case - put dn into a canonical form suitable for storing
+ * in a hash database.  this involves normalizing the case as well as
+ * the format.  the dn is normalized in place as well as returned.
  */
 
-int
-dn_casecmp( const char *dn1, const char *dn2 )
+char *
+dn_normalize_case( char *dn )
 {
-	char *ndn1 = dn_normalize_case( ch_strdup( dn1 ) );
-	char *ndn2 = dn_normalize_case( ch_strdup( dn2 ) );
-	int i = strcmp( ndn1, ndn2 );
-	free( ndn1 );
-	free( ndn2 );
-	return i;
-}
+	char	*s;
 
+	/* normalize format */
+	dn_normalize( dn );
+
+	/* normalize case */
+	for ( s = dn; *s; s++ ) {
+		*s = TOUPPER( (unsigned char) *s );
+	}
+
+	return( dn );
+}
 
 /*
  * dn_parent - return a copy of the dn of dn's parent
diff --git a/servers/slapd/main.c b/servers/slapd/main.c
index c37b0031b7461d15e4fe03951cc50705dd5d09e9..6c06c02799e950f3beaea6b943026b6eadfd3d02 100644
--- a/servers/slapd/main.c
+++ b/servers/slapd/main.c
@@ -312,19 +312,23 @@ static RETSIGTYPE
 wait4child( int sig )
 {
     int save_errno = errno;
-
-#ifdef WNOHANG
     errno = 0;
-#ifdef HAVE_WAITPID
+    /*
+     * ### The wait3 vs. waitpid choice needs improvement.
+     * ### There are apparently systems where waitpid(-1, ...) fails, and
+     * ### others where waitpid should preferred over wait3 for some reason.
+     * ### Now wait3 is only here for reference, configure does not detect it.
+     */
+#if defined(HAVE_WAITPID) && defined(WNOHANG)
     while ( waitpid( (pid_t)-1, NULL, WNOHANG ) >= 0 || errno == EINTR )
 	;	/* NULL */
-#else
+#elif defined(HAVE_WAIT3) && defined(WNOHANG)
     while ( wait3( NULL, WNOHANG, NULL ) >= 0 || errno == EINTR )
 	;	/* NULL */
-#endif
+#else
     (void) wait( NULL );
 #endif
-    (void) SIGNAL( sig, wait4child );
+    (void) signal( sig, wait4child );
     errno = save_errno;
 }
 
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 108ca114b0d0454ec4fd7deb8d50426b2d206eee..7907d6a623cddbf1ccd05ab2a5c822d15771e70f 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -130,8 +130,8 @@ void connection_done LDAP_P((Connection *));
  * dn.c
  */
 
-char * dn_normalize_internal LDAP_P(( char *dn, int correct_case ));
-int dn_casecmp LDAP_P(( const char *dn1, const char *dn2 ));
+char * dn_normalize LDAP_P(( char *dn ));
+char * dn_normalize_case LDAP_P(( char *dn ));
 char * dn_parent LDAP_P(( Backend *be, char *dn ));
 char * dn_rdn LDAP_P(( Backend *be, char *dn ));
 int dn_issuffix LDAP_P(( char *dn, char *suffix ));
diff --git a/servers/slapd/result.c b/servers/slapd/result.c
index f03423a0b6087f5171bd436cd92781e1134ca933..17f454ac83ee47a92238716e8221486b1e02551f 100644
--- a/servers/slapd/result.c
+++ b/servers/slapd/result.c
@@ -273,10 +273,6 @@ send_search_entry(
 					! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op,
 						ACL_READ, edn, matches) )
 				{
-				/* ### What the hell? Attributes with DN-syntax
-				 * ### are only returned if we have access to
-				 * ### the entry with that DN?  Or...?
-				 */
 					continue;
 				}
 
diff --git a/servers/slapd/shell-backends/passwd-shell.c b/servers/slapd/shell-backends/passwd-shell.c
index f546d2de5b8fc41b1d2330af298a7fdd04afa013..89d2fd73d66ad91f0a66a8b0fccb8aa209d5371b 100644
--- a/servers/slapd/shell-backends/passwd-shell.c
+++ b/servers/slapd/shell-backends/passwd-shell.c
@@ -106,7 +106,7 @@ pwdfile_search( struct ldop *op, FILE *ofp )
     for ( pw = getpwent(); pw != NULL; pw = getpwent()) {
 	if (( entry = pw2entry( op, pw )) != NULL ) {
 	    if ( oneentry ) {
-		if ( dn_casecmp( op->ldop_dn, entry->lde_dn ) == 0 ) {
+		if ( strcasecmp( op->ldop_dn, entry->lde_dn ) == 0 ) {
 		    write_entry( op, entry, ofp );
 		    break;
 		}
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index 0f86b9001e282769845fb5edf7f68cbf1bad7668..a7d99114ddd2e40a1a9a59c82a8971c10a0d2378 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -460,9 +460,6 @@ typedef struct slap_conn {
 #define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 )
 #endif
 
-#define dn_normalize(dn)	dn_normalize_internal( dn, 0 )
-#define dn_normalize_case(dn)	dn_normalize_internal( dn, 1 )
-
 #include "proto-slap.h"
 
 LDAP_END_DECL
diff --git a/servers/slapd/tools/centipede.c b/servers/slapd/tools/centipede.c
index f01b44a72fcd0c1696c5ef7a37def37f0f1819e6..536417b43f7b8ccbce36aff62452662ebf18af57 100644
--- a/servers/slapd/tools/centipede.c
+++ b/servers/slapd/tools/centipede.c
@@ -502,10 +502,6 @@ generate_new_centroids(
 
 				/* normalize the value */
 				for ( s = val[j]; *s; s++ ) {
-					/* May need other normalization here,
-					 * unless that breaks compatibility
-					 * with other centipedes
-					 */
 					*s = TOLOWER( (unsigned char) *s );
 					last = *s;
 				}
diff --git a/servers/slapd/value.c b/servers/slapd/value.c
index 97fd1f4a39d590f2049d1279237eb65529c77b0a..ccabdf06a42ae84c2e6250a0591da93e163f6d84 100644
--- a/servers/slapd/value.c
+++ b/servers/slapd/value.c
@@ -82,16 +82,18 @@ value_normalize(
     int		syntax
 )
 {
-	char	*d;
+	char	*d, *save;
 
-	if ( syntax & SYNTAX_DN ) {
-		(void) dn_normalize_case( s );
+	if ( ! (syntax & SYNTAX_CIS) ) {
 		return;
 	}
-	if ( ! (syntax & SYNTAX_CIS) ) {
+
+	if ( syntax & SYNTAX_DN ) {
+		(void) dn_normalize_case( s );
 		return;
 	}
 
+	save = s;
 	for ( d = s; *s; s++ ) {
 		if ( (syntax & SYNTAX_TEL) && (*s == ' ' || *s == '-') ) {
 			continue;
@@ -110,16 +112,7 @@ value_cmp(
 )
 {
 	int		rc;
-	unsigned char	*s1, *s2;
-
-	if ( syntax & SYNTAX_DN )	/* #### TEST ### */
-		normalize = 3;
 
-    if ( normalize ) {
-	if ( ! (syntax & ~(SYNTAX_CIS | SYNTAX_CES | SYNTAX_BIN)) )
-		/* Normalization not needed,
-		 * in SYNTAX_CIS's case because it's handled by strcascmp */
-		normalize = 0;
 	if ( normalize & 1 ) {
 		v1 = ber_bvdup( v1 );
 		value_normalize( v1->bv_val, syntax );
@@ -128,22 +121,18 @@ value_cmp(
 		v2 = ber_bvdup( v2 );
 		value_normalize( v2->bv_val, syntax );
 	}
-    }
 
 	switch ( syntax ) {
 	case SYNTAX_CIS:
 	case (SYNTAX_CIS | SYNTAX_TEL):
+	case (SYNTAX_CIS | SYNTAX_DN):
 		rc = strcasecmp( v1->bv_val, v2->bv_val );
 		break;
 
-	case SYNTAX_DN:
 	case SYNTAX_CES:
 		rc = strcmp( v1->bv_val, v2->bv_val );
 		break;
 
-	default:
-		Debug( LDAP_DEBUG_ANY, "value_cmp: unknown syntax %d.\n", syntax, 0, 0);
-		/* Fall through */
 	case SYNTAX_BIN:
 		rc = (v1->bv_len == v2->bv_len
 		      ? memcmp( v1->bv_val, v2->bv_val, v1->bv_len )