diff --git a/servers/slapd/ad.c b/servers/slapd/ad.c
index 370ebb22c499251761402eec2a669da6466d5d0f..6896f9a353f9e5632ab0b0d0d29534bf55f1a2e0 100644
--- a/servers/slapd/ad.c
+++ b/servers/slapd/ad.c
@@ -812,6 +812,7 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
 					slap_bv2ad(&adname, &anew->an_desc, &text);
 					if ( !anew->an_desc ) {
 						free( an );
+						free( str );
 						/*
 						 * overwrites input string
 						 * on error!
@@ -830,6 +831,7 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
 					anew->an_oc = oc_bvfind( &ocname );
 					if ( !anew->an_oc ) {
 						free( an );
+						free( str );
 						/*
 						 * overwrites input string
 						 * on error!
@@ -848,6 +850,7 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
 				anew->an_oc = oc_bvfind( &anew->an_name );
 				if ( !anew->an_oc ) {
 					free( an );
+					free( str );
 					/* overwrites input string on error! */
 					strcpy( in, s );
 					return NULL;
@@ -862,6 +865,171 @@ str2anlist( AttributeName *an, char *in, const char *brkstr )
 	return( an );
 }
 
+char **anlist2charray_x( AttributeName *an, int dup, void *ctx )
+{
+    char **attrs;
+    int i;
+                                                                                
+    if ( an != NULL ) {
+        for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
+            ;
+		attrs = (char **) slap_sl_malloc( (i + 1) * sizeof(char *), ctx );
+        for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
+			if ( dup )
+	            attrs[i] = ch_strdup( an[i].an_name.bv_val );
+			else
+	            attrs[i] = an[i].an_name.bv_val;
+        }
+        attrs[i] = NULL;
+    } else {
+        attrs = NULL;
+    }
+                                                                                
+    return attrs;
+}
+
+char **anlist2charray( AttributeName *an, int dup )
+{
+	return anlist2charray_x( an, dup, NULL );
+}
+
+char**
+anlist2attrs( AttributeName * anlist )
+{
+	int i, j, k = 0;
+	int n;
+	char **attrs;
+	ObjectClass *oc;
+
+	attrs = anlist2charray( anlist, 1 );
+                                                                                
+	for ( i = 0; anlist[i].an_name.bv_val; i++ ) {
+		if ( oc = anlist[i].an_oc ) {
+			for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ) ;
+			k += j;
+			for ( j = 0; oc->soc_allowed && oc->soc_allowed[j]; j++ ) ;
+			k += j;
+		}
+	}
+
+	if ( i == 0 )
+		return NULL;
+                                                                                
+	n = i;
+                                                                                
+	if ( k )
+		attrs = (char **) ch_realloc( attrs, (i + k + 1) * sizeof( char * ));
+
+   	for ( i = 0; anlist[i].an_name.bv_val; i++ ) {
+		if ( oc = anlist[i].an_oc ) {
+			for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ) {
+				attrs[n++] = ch_strdup(
+								oc->soc_required[j]->sat_cname.bv_val );
+			}
+			for ( j = 0; oc->soc_allowed && oc->soc_allowed[j]; j++ ) {
+				attrs[n++] = ch_strdup(
+								oc->soc_allowed[j]->sat_cname.bv_val );
+			}
+		}
+	}
+	
+	if ( attrs )
+		attrs[n] = NULL;
+
+	i = 0;
+	while ( attrs && attrs[i] ) {
+		if ( *attrs[i] == '@' ) {
+			for ( j = i; attrs[j]; j++ ) {
+				if ( j == i )
+					ch_free( attrs[i] );
+				attrs[j] = attrs[j+1];
+			}
+		} else {
+			i++;
+		}
+	}
+
+	for ( i = 0; attrs && attrs[i]; i++ ) {
+		j = i + 1;
+		while ( attrs && attrs[j] ) {
+			if ( !strcmp( attrs[i], attrs[j] )) {
+				for ( k = j; attrs && attrs[k]; k++ ) {
+					if ( k == j )
+						ch_free( attrs[j] );
+					attrs[k] = attrs[k+1];
+				}
+			} else {
+				j++;
+			}
+		}
+	}
+
+	attrs = (char **) ch_realloc( attrs, (i+1) * sizeof( char * ));
+
+	return attrs;
+}
+
+#define LBUFSIZ	80
+AttributeName*
+file2anlist( AttributeName *an, const char *fname, const char *brkstr )
+{
+	FILE	*fp;
+	char	*line = NULL;
+	char	*lcur = NULL;
+	char	*c;
+	size_t	lmax = LBUFSIZ;
+
+	fp = fopen( fname, "r" );
+	if ( fp == NULL ) {
+		Debug( LDAP_DEBUG_ANY,
+			"get_attrs_from_file: failed to open attribute list file "
+			"\"%s\": %s\n", fname, strerror(errno), 0 );
+		return NULL;
+	}
+
+	lcur = line = (char *) ch_malloc( lmax );
+	if ( !line ) {
+		Debug( LDAP_DEBUG_ANY,
+			"get_attrs_from_file: could not allocate memory\n",
+			0, 0, 0 );
+		fclose(fp);
+		return NULL;
+	}
+
+	while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) {
+		char *str, *s, *next;
+		const char *delimstr = brkstr;
+		if (c = strchr( lcur, '\n' )) {
+			if ( c == line ) {
+				*c = '\0';
+			} else if ( *(c-1) == '\r' ) {
+				*(c-1) = '\0';
+			} else {
+				*c = '\0';
+			}
+		} else {
+			lmax += LBUFSIZ;
+			line = (char *) ch_realloc( line, lmax );
+			if ( !line ) {
+				Debug( LDAP_DEBUG_ANY,
+					"get_attrs_from_file: could not allocate memory\n",
+					0, 0, 0 );
+				fclose(fp);
+				return NULL;
+			}
+			lcur = line + strlen( line );
+			continue;
+		}
+		an = str2anlist( an, line, brkstr );
+		if ( an == NULL )
+			return NULL;
+		lcur = line;
+	}
+	ch_free( line );
+	fclose(fp);
+	return an;
+}
+#undef LBUFSIZ
 
 /* Define an attribute option. */
 int
diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
index fa3e2ca63247b82b80bfca15bb495ccf2660c384..7c634390b759b3d18edc5043f7ae8a2665d5f7ec 100644
--- a/servers/slapd/back-bdb/init.c
+++ b/servers/slapd/back-bdb/init.c
@@ -427,6 +427,8 @@ bdb_db_destroy( BackendDB *be )
 {
 	int rc;
 	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
+	Operation *ps = NULL;
+	Operation *psn = NULL;
 
 	/* close db environment */
 	if( bdb->bi_dbenv ) {
@@ -461,6 +463,23 @@ bdb_db_destroy( BackendDB *be )
 		ldap_pvt_thread_mutex_destroy( &bdb->bi_idl_tree_lrulock );
 	}
 
+	ps = LDAP_LIST_FIRST( &bdb->bi_psearch_list );
+
+	if ( ps ) {
+		psn = LDAP_LIST_NEXT( ps, o_ps_link );
+		slap_op_free( ps );
+		if ( ps->o_tmpmemctx )
+			slap_sl_mem_destroy( NULL, ps->o_tmpmemctx );
+	}
+
+	while ( psn ) {
+		ps = psn;
+		psn = LDAP_LIST_NEXT( ps, o_ps_link );
+		slap_op_free( ps );
+		if ( ps->o_tmpmemctx )
+			slap_sl_mem_destroy( NULL, ps->o_tmpmemctx );
+	}
+
 	ch_free( bdb );
 	be->be_private = NULL;
 
diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c
index d8885f0ecb15249ab775eea869dc9a8d62005d78..d77dd20a7d3794d81718ae62b3335a3f4b74865b 100644
--- a/servers/slapd/back-bdb/search.c
+++ b/servers/slapd/back-bdb/search.c
@@ -340,10 +340,10 @@ bdb_abandon( Operation *op, SlapReply *rs )
 
 	ps = bdb_drop_psearch( op, op->oq_abandon.rs_msgid );
 	if ( ps ) {
+		slap_op_free ( ps );
 		if ( ps->o_tmpmemctx ) {
 			slap_sl_mem_destroy( NULL, ps->o_tmpmemctx );
 		}
-		slap_op_free ( ps );
 		return LDAP_SUCCESS;
 	}
 	return LDAP_UNAVAILABLE;
@@ -358,10 +358,10 @@ bdb_cancel( Operation *op, SlapReply *rs )
 	if ( ps ) {
 		rs->sr_err = LDAP_CANCELLED;
 		send_ldap_result( ps, rs );
+		slap_op_free ( ps );
 		if ( ps->o_tmpmemctx ) {
 			slap_sl_mem_destroy( NULL, ps->o_tmpmemctx );
 		}
-		slap_op_free ( ps );
 		return LDAP_SUCCESS;
 	}
 	return LDAP_UNAVAILABLE;
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 349b7a621cc2cfed2cc86edf907581df80fa310f..4e7d25acda88f1f155fde55d34f8b9dfbed530f8 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -470,6 +470,7 @@ int backend_destroy(void)
 	int i;
 	BackendDB *bd;
 	syncinfo_t *si_entry;
+	struct slap_csn_entry *csne;
 
 	ldap_pvt_thread_pool_destroy( &syncrepl_pool, 1 );
 
@@ -481,6 +482,13 @@ int backend_destroy(void)
 			LDAP_STAILQ_REMOVE_HEAD( &bd->be_syncinfo, si_next );
 			syncinfo_free( si_entry );
 		}
+
+		LDAP_TAILQ_FOREACH( csne, bd->be_pending_csn_list, ce_csn_link ) {
+			LDAP_TAILQ_REMOVE( bd->be_pending_csn_list, csne, ce_csn_link );
+			ch_free( csne->ce_csn->bv_val );
+			ch_free( csne->ce_csn );
+			ch_free( csne );
+		}
 		
 		if ( bd->bd_info->bi_db_destroy ) {
 			bd->bd_info->bi_db_destroy( bd );
diff --git a/servers/slapd/config.c b/servers/slapd/config.c
index 0839ecc6e7625f0f0117d28421480f53a32f1dbf..ef307d881138ca81a55636aae9c8d592b6b0e013 100644
--- a/servers/slapd/config.c
+++ b/servers/slapd/config.c
@@ -88,12 +88,6 @@ static int load_ucdata(char *path);
 static int add_syncrepl LDAP_P(( Backend *, char **, int ));
 static int parse_syncrepl_line LDAP_P(( char **, int, syncinfo_t *));
 
-static int get_attrs_from_file LDAP_P(( char ***, const char *, const char * ));
-static int get_ocs_from_file LDAP_P((
-					ObjectClass ***, const char *, const char *));
-static char **str2attrs( char ***, char *, const char * );
-static ObjectClass **str2ocs( ObjectClass ***, char *, const char * );
-
 int
 read_config( const char *fname, int depth )
 {
@@ -2282,12 +2276,12 @@ add_syncrepl(
 	si->si_base.bv_val = NULL;
 	si->si_scope = LDAP_SCOPE_SUBTREE;
 	si->si_attrsonly = 0;
-	si->si_attrs = (char **) ch_calloc( 1, sizeof( char * ));
-	si->si_attrs[0] = NULL;
-	si->si_ocs = (ObjectClass **) ch_calloc( 1, sizeof( ObjectClass ));
-	si->si_ocs[0] = NULL;
-	si->si_exattrs = (char **) ch_calloc( 1, sizeof( char * ));
-	si->si_exattrs[0] = NULL;
+	si->si_anlist = (AttributeName *) ch_calloc( 1, sizeof( AttributeName ));
+	si->si_exanlist = (AttributeName *) ch_calloc( 1, sizeof( AttributeName ));
+	si->si_attrs = NULL;
+	si->si_allattrs = 0;
+	si->si_allopattrs = 0;
+	si->si_exattrs = NULL;
 	si->si_type = LDAP_SYNC_REFRESH_ONLY;
 	si->si_interval = 86400;
 	si->si_retryinterval = NULL;
@@ -2356,8 +2350,8 @@ add_syncrepl(
 #define SEARCHBASESTR	"searchbase"
 #define SCOPESTR		"scope"
 #define ATTRSSTR		"attrs"
-#define ATTRSONLYSTR	"attrsonly"
 #define EXATTRSSTR		"exattrs"
+#define ATTRSONLYSTR	"attrsonly"
 #define TYPESTR			"type"
 #define INTERVALSTR		"interval"
 #define LASTMODSTR		"lastmod"
@@ -2545,18 +2539,34 @@ parse_syncrepl_line(
 			if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
 				char *attr_fname;
 				attr_fname = ch_strdup( val + STRLENOF(":include:") );
-				if ( get_attrs_from_file( &si->si_attrs, attr_fname, " ,\t" )) {
-					ch_free( attr_fname );
-					return -1;
-				}
-				if ( get_ocs_from_file( &si->si_ocs, attr_fname, " ,\t" )) {
+				si->si_anlist = file2anlist(
+								si->si_anlist, attr_fname, " ,\t" );
+				if ( si->si_anlist == NULL ) {
 					ch_free( attr_fname );
 					return -1;
 				}
 				ch_free( attr_fname );
 			} else {
-				str2attrs( &si->si_attrs, val, " ,\t" );
-				str2ocs( &si->si_ocs, val, " ,\t" );
+				char *str, *s, *next;
+				char delimstr[] = " ,\t";
+				str = ch_strdup( val );
+				for ( s = ldap_pvt_strtok( str, delimstr, &next );
+					  s != NULL;
+					  s = ldap_pvt_strtok( NULL, delimstr, &next )) {
+					if ( strlen(s) == 1 && *s == '*' ) {
+						si->si_allattrs = 1;
+						*(val + ( s - str )) = delimstr[0];
+					}
+					if ( strlen(s) == 1 && *s == '+' ) {
+						si->si_allopattrs = 1;
+						*(val + ( s - str )) = delimstr[0];
+					}
+				}
+				ch_free( str );
+				si->si_anlist = str2anlist( si->si_anlist, val, " ,\t" );
+				if ( si->si_anlist == NULL ) {
+					return -1;
+				}
 			}
 		} else if ( !strncasecmp( cargv[ i ],
 			EXATTRSSTR, sizeof( EXATTRSSTR ) - 1 ) )
@@ -2565,14 +2575,19 @@ parse_syncrepl_line(
 			if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
 				char *attr_fname;
 				attr_fname = ch_strdup( val + STRLENOF(":include:") );
-				if ( get_attrs_from_file( &si->si_exattrs,
-							attr_fname, " ,\t" )) {
+				si->si_exanlist = file2anlist(
+									si->si_exanlist, attr_fname, " ,\t" );
+				if ( si->si_exanlist == NULL ) {
 					ch_free( attr_fname );
 					return -1;
 				}
 				ch_free( attr_fname );
 			} else {
-				str2attrs( &si->si_exattrs, val, " ,\t" );
+				int j;
+				si->si_exanlist = str2anlist( si->si_exanlist, val, " ,\t" );
+				if ( si->si_exanlist == NULL ) {
+					return -1;
+				}
 			}
 		} else if ( !strncasecmp( cargv[ i ],
 			TYPESTR, sizeof( TYPESTR ) - 1 ) )
@@ -2721,128 +2736,6 @@ parse_syncrepl_line(
 	return 0;
 }
 
-static ObjectClass **
-str2ocs( ObjectClass ***out, char *in, const char *brkstr )
-{
-	char **clist;
-	int i, k = 0;
-	ObjectClass *oc;
-
-	clist = (char **) ch_calloc( 1, sizeof( char *));
-	clist[0] = NULL;
-
-	slap_str2clist( &clist, in, brkstr );
-
-	for ( i = 0; clist && clist[i]; i++ ) {
-		if (*clist[i] == '@' ) {
-			struct berval ocbv;
-			ber_str2bv( clist[i]+1, strlen(clist[i]+1), 1, &ocbv );
-			oc = oc_bvfind( &ocbv );
-			if ( oc ) {
-				k++;
-			}
-			ch_free( ocbv.bv_val );
-		}
-	}
-
-	*out = ch_realloc( *out, (k + 1) * sizeof( ObjectClass *));
-
-	for ( i = 0; clist && clist[i]; i++ ) {
-		if (*clist[i] == '@' ) {
-			struct berval ocbv;
-			ber_str2bv( clist[i]+1, strlen(clist[i]+1), 1, &ocbv );
-			(*out)[i] = oc_bvfind( &ocbv );
-			ch_free( ocbv.bv_val );
-		}
-	}
-
-	(*out)[i] = NULL;
-
-	for ( i = 0; clist && clist[i]; i++ ) {
-		ch_free( clist[i] );
-	}
-	ch_free( clist );
-
-	return (*out);
-}
-
-static char **
-str2attrs( char ***out, char *in, const char *brkstr )
-{
-	int i, j = 0, k = 0, l = 0;
-	ObjectClass *oc;
-
-	slap_str2clist( out, in , brkstr );
-
-	for ( i = 0; *out && (*out)[i]; i++ ) {
-		if ( *(*out)[i] == '@' ) {
-			struct berval ocbv;
-			ber_str2bv( (*out)[i]+1, strlen((*out)[i]+1), 1, &ocbv );
-			oc = oc_bvfind( &ocbv );
-			if ( oc ) {
-				k++;
-				for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ );
-				l += j;
-				for ( j = 0; oc->soc_allowed && oc->soc_allowed[j]; j++ );
-				l += j;
-			}
-			ch_free( ocbv.bv_val );
-		}
-	}
-	
-	*out = ch_realloc( *out, (i - k + l + 1) * sizeof( char * ));
-
-	for ( i = 0; *out && (*out)[i]; i++ ) {
-retest1:
-		if ( *(*out)[i] == '@' ) {
-			struct berval ocbv;
-			ber_str2bv( (*out)[i]+1, strlen((*out)[i]+1), 1, &ocbv );
-			oc = oc_bvfind( &ocbv );
-			for ( k = i; (*out)[k]; k++ ) {
-				if ( k == i )
-					ch_free( (*out)[i] );
-				(*out)[k] = (*out)[k+1];
-			}				
-			k--;
-			if ( oc ) {
-				for ( j = 0; oc->soc_required && oc->soc_required[j]; j++ ) {
-					(*out)[k++] = ch_strdup(
-							oc->soc_required[j]->sat_cname.bv_val );
-				}
-				for ( j = 0; oc->soc_allowed && oc->soc_allowed[j]; j++ ) {
-					(*out)[k++] = ch_strdup(
-							oc->soc_allowed[j]->sat_cname.bv_val );
-				}
-				(*out)[k] = NULL;
-			}
-			ch_free( ocbv.bv_val );
-			goto retest1;
-		}
-	}
-
-	for ( i = 0; *out && (*out)[i]; i++ ) {
-		for ( j = i+1; *out && (*out)[j]; j++ ) {
-retest2:
-			if ( !strcmp( (*out)[i], (*out)[j] )) {
-				ch_free( (*out)[j] );	
-				for ( k = j; (*out)[k]; k++ ) {
-					(*out)[k] = (*out)[k+1];
-				}
-				if ( (*out)[j] != NULL )
-					goto retest2;
-				else
-					break;
-			}
-		}
-	}
-
-	for ( i = 0; *out && (*out)[i]; i++ );
-
-	*out = ch_realloc( *out, (i + 1) * sizeof( char * ));
-
-	return (*out);
-}
-
 char **
 slap_str2clist( char ***out, char *in, const char *brkstr )
 {
@@ -2887,118 +2780,3 @@ slap_str2clist( char ***out, char *in, const char *brkstr )
 	return( *out );
 }
 
-#define LBUFSIZ	80
-static int
-get_attrs_from_file( char ***attrs, const char *fname, const char *brkstr )
-{
-	FILE	*fp;
-	char	*line = NULL;
-	char	*lcur = NULL;
-	char	*c;
-	size_t	lmax = LBUFSIZ;
-
-	fp = fopen( fname, "r" );
-	if ( fp == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"get_attrs_from_file: failed to open attribute list file "
-			"\"%s\": %s\n", fname, strerror(errno), 0 );
-		return 1;
-	}
-
-	lcur = line = (char *) ch_malloc( lmax );
-	if ( !line ) {
-		Debug( LDAP_DEBUG_ANY,
-			"get_attrs_from_file: could not allocate memory\n",
-			0, 0, 0 );
-		fclose(fp);
-		return 1;
-	}
-
-	while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) {
-		if (c = strchr( lcur, '\n' )) {
-			if ( c == line ) {
-				*c = '\0';
-			} else if ( *(c-1) == '\r' ) {
-				*(c-1) = '\0';
-			} else {
-				*c = '\0';
-			}
-		} else {
-			lmax += LBUFSIZ;
-			line = (char *) ch_realloc( line, lmax );
-			if ( !line ) {
-				Debug( LDAP_DEBUG_ANY,
-					"get_attrs_from_file: could not allocate memory\n",
-					0, 0, 0 );
-				fclose(fp);
-				return 1;
-			}
-			lcur = line + strlen( line );
-			continue;
-		}
-		str2attrs( attrs, line, brkstr );
-		lcur = line;
-	}
-	ch_free( line );
-	fclose(fp);
-	return 0;
-}
-#undef LBUFSIZ
-
-#define LBUFSIZ	80
-static int
-get_ocs_from_file( ObjectClass ***ocs, const char *fname, const char *brkstr )
-{
-	FILE	*fp;
-	char	*line = NULL;
-	char	*lcur = NULL;
-	char	*c;
-	size_t	lmax = LBUFSIZ;
-
-	fp = fopen( fname, "r" );
-	if ( fp == NULL ) {
-		Debug( LDAP_DEBUG_ANY,
-			"get_ocs_from_file: failed to open attribute list file "
-			"\"%s\": %s\n", fname, strerror(errno), 0 );
-		return 1;
-	}
-
-	lcur = line = (char *) ch_malloc( lmax );
-	if ( !line ) {
-		Debug( LDAP_DEBUG_ANY,
-			"get_ocs_from_file: could not allocate memory\n",
-			0, 0, 0 );
-		fclose(fp);
-		return 1;
-	}
-
-	while ( fgets( lcur, LBUFSIZ, fp ) != NULL ) {
-		if (c = strchr( lcur, '\n' )) {
-			if ( c == line ) {
-				*c = '\0';
-			} else if ( *(c-1) == '\r' ) {
-				*(c-1) = '\0';
-			} else {
-				*c = '\0';
-			}
-		} else {
-			lmax += LBUFSIZ;
-			line = (char *) ch_realloc( line, lmax );
-			if ( !line ) {
-				Debug( LDAP_DEBUG_ANY,
-					"get_ocs_from_file: could not allocate memory\n",
-					0, 0, 0 );
-				fclose(fp);
-				return 1;
-			}
-			lcur = line + strlen( line );
-			continue;
-		}
-		str2ocs( ocs, line, brkstr );
-		lcur = line;
-	}
-	ch_free( line );
-	fclose(fp);
-	return 0;
-}
-#undef LBUFSIZ
diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c
index 89247b54f8ac90c6547b28f14b7de25566fa1369..d848e7a6cc2e4f7491bea1daf914d253899cc744 100644
--- a/servers/slapd/passwd.c
+++ b/servers/slapd/passwd.c
@@ -311,7 +311,7 @@ int slap_passwd_parse( struct berval *reqdata,
 		tag = ber_scanf( ber, "m", oldpass );
 
 		if( tag == LBER_ERROR ) {
-			Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: ID parse failed.\n",
+			Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n",
 				0, 0, 0 );
 
 			goto decoding_error;
@@ -333,7 +333,7 @@ int slap_passwd_parse( struct berval *reqdata,
 		tag = ber_scanf( ber, "m", newpass );
 
 		if( tag == LBER_ERROR ) {
-			Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: OLD parse failed.\n",
+			Debug( LDAP_DEBUG_TRACE, "slap_passwd_parse: NEW parse failed.\n",
 				0, 0, 0 );
 
 			goto decoding_error;
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 707a1c47a91162cc55cf3f814d60fe7d54753fd6..2d7d4f2a44325c3f82aaae6c512678ae1b007e88 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -105,6 +105,12 @@ LDAP_SLAPD_F (AttributeDescription *) ad_find_tags LDAP_P((
 
 LDAP_SLAPD_F (AttributeName *) str2anlist LDAP_P(( AttributeName *an,
 	char *str, const char *brkstr ));
+LDAP_SLAPD_F (char **) anlist2charray_x LDAP_P((
+									AttributeName *an, int dup, void *ctx ));
+LDAP_SLAPD_F (char **) anlist2charray LDAP_P(( AttributeName *an, int dup ));
+LDAP_SLAPD_F (char **) anlist2attrs LDAP_P(( AttributeName *anlist ));
+LDAP_SLAPD_F (AttributeName *) file2anlist LDAP_P((
+                        AttributeName *, const char *, const char * ));
 LDAP_SLAPD_F (int) an_find LDAP_P(( AttributeName *a, struct berval *s ));
 LDAP_SLAPD_F (int) ad_define_option LDAP_P(( const char *name,
 	const char *fname, int lineno ));
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index 361dfe3096634352866e0ea5a331da893bcddbe3..30532922b9522a66837d07b8453bf5dbd5927bb0 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -37,7 +37,6 @@
 #ifdef LDAP_SLAPI
 #include "slapi/slapi.h"
 
-static char **anlist2charray( Operation *op, AttributeName *an );
 static void init_search_pblock( Operation *op, char **attrs, int managedsait );
 static int call_search_preop_plugins( Operation *op );
 static int call_search_rewrite_plugins( Operation *op );
@@ -279,7 +278,7 @@ fe_op_search( Operation *op, SlapReply *rs )
 
 #ifdef LDAP_SLAPI
 			if ( op->o_pb ) {
-				attrs = anlist2charray( op, op->ors_attrs );
+				attrs = anlist2charray_x( op->ors_attrs, 0, op->o_tmpmemctx );
 				init_search_pblock( op, attrs, manageDSAit );
 				rs->sr_err = call_search_preop_plugins( op );
 				if ( rs->sr_err ) break;
@@ -297,7 +296,7 @@ fe_op_search( Operation *op, SlapReply *rs )
 
 #ifdef LDAP_SLAPI
 			if ( op->o_pb ) {
-				attrs = anlist2charray( op, op->ors_attrs );
+				attrs = anlist2charray_x( op->ors_attrs, 0, op->o_tmpmemctx );
 				init_search_pblock( op, attrs, manageDSAit );
 				rs->sr_err = call_search_preop_plugins( op );
 				if ( rs->sr_err ) break;
@@ -391,7 +390,7 @@ fe_op_search( Operation *op, SlapReply *rs )
 
 #ifdef LDAP_SLAPI
 	if ( op->o_pb ) {
-		attrs = anlist2charray( op, op->ors_attrs );
+		attrs = anlist2charray_x( op->ors_attrs, 0, op->o_tmpmemctx );
 		init_search_pblock( op, attrs, manageDSAit );
 		rs->sr_err = call_search_preop_plugins( op );
 		if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -428,26 +427,6 @@ return_results:;
 
 #ifdef LDAP_SLAPI
 
-static char **anlist2charray( Operation *op, AttributeName *an )
-{
-	char **attrs;
-	int i;
-
-	if ( an != NULL ) {
-		for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
-			;
-		attrs = (char **)op->o_tmpalloc( (i + 1) * sizeof(char *), op->o_tmpmemctx );
-		for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
-			attrs[i] = an[i].an_name.bv_val;
-		}
-		attrs[i] = NULL;
-	} else {
-		attrs = NULL;
-	}
-
-	return attrs;
-}
-
 static void init_search_pblock( Operation *op,
 	char **attrs, int managedsait )
 {
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index 57f0b0fd8ea2a6d655d7f1d778d41a5b578e31e8..7234f15db7a6df98cb37edf08cc37ef9866e06b9 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1443,8 +1443,11 @@ typedef struct syncinfo_s {
         struct berval		si_base;
         int					si_scope;
         int					si_attrsonly;
-        char				**si_attrs;
-		ObjectClass			**si_ocs;
+		AttributeName		*si_anlist;
+		AttributeName		*si_exanlist;
+		char 				**si_attrs;
+		int					si_allattrs;
+		int					si_allopattrs;
 		char				**si_exattrs;
         int					si_type;
         time_t				si_interval;
diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index d9935e84a72d147d694fb2dadae922f9374ab3cc..4d7187ced05eb9c523332baeb8f8936deaf89735 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -53,7 +53,8 @@ void
 init_syncrepl(syncinfo_t *si)
 {
 	int i, j, k, l, n;
-	char **tmp;
+	char **attrs, **exattrs;
+	ObjectClass *oc;
 
 	if ( !sync_descs[0] ) {
 		sync_descs[0] = slap_schema.si_ad_objectClass;
@@ -62,78 +63,128 @@ init_syncrepl(syncinfo_t *si)
 		sync_descs[3] = NULL;
 	}
 
-	for ( n = 0; si->si_attrs[ n ] != NULL; n++ ) /* empty */;
+	if ( si->si_allattrs && si->si_allopattrs )
+		attrs = NULL;
+	else
+		attrs = anlist2attrs( si->si_anlist );
 
-	if ( n ) {
-		/* Delete Attributes */
-		for ( i = 0; sync_descs[i] != NULL; i++ ) {
-			for ( j = 0; si->si_attrs[j] != NULL; j++ ) {
-				if ( strcmp( si->si_attrs[j], sync_descs[i]->ad_cname.bv_val )
-					== 0 )
-				{
-					for ( k = j; si->si_attrs[k] != NULL; k++ ) {
-						if ( k == j )
-							ch_free( si->si_attrs[k] );
-						si->si_attrs[k] = si->si_attrs[k+1];
+	if ( attrs ) {
+
+		if ( si->si_allattrs ) {
+			i = 0;
+			while ( attrs[i] ) {
+				if ( !is_at_operational( at_find( attrs[i] ))) {
+					for ( j = i; attrs[j] != NULL; j++ ) {
+						if ( j == i )
+							ch_free( attrs[i] );
+						attrs[j] = attrs[j+1];
 					}
+				} else {
+					i++;
 				}
 			}
-		}
-		for ( n = 0; si->si_attrs[ n ] != NULL; n++ ) /* empty */;
-		tmp = ( char ** ) ch_realloc( si->si_attrs, (n + 4)*sizeof( char * ));
-		if ( tmp == NULL ) {
-			Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
+			attrs = ( char ** ) ch_realloc( attrs, (i + 1)*sizeof( char * ));
+		} else if ( si->si_allopattrs ) {
+			i = 0;
+			while ( attrs[i] ) {
+				if ( is_at_operational( at_find( attrs[i] ))) {
+					for ( j = i; attrs[j] != NULL; j++ ) {
+						if ( j == i )
+							ch_free( attrs[i] );
+						attrs[j] = attrs[j+1];
+					}
+				} else {
+					i++;
+				}
+			}
+			attrs = ( char ** ) ch_realloc( attrs, (i + 1)*sizeof( char * ));
 		}
 
-		/* Add Attributes */
-		for ( i = 0; sync_descs[ i ] != NULL; i++ ) {
-			tmp[ n++ ] = ch_strdup ( sync_descs[i]->ad_cname.bv_val );
-			tmp[ n ] = NULL;
+		if ( !si->si_allopattrs ) {
+			for ( i = 0; sync_descs[i] != NULL; i++ ) {
+				j = 0;
+				while ( attrs[j] ) {
+					if ( !strcmp( attrs[j], sync_descs[i]->ad_cname.bv_val )) {
+						for ( k = j; attrs[k] != NULL; k++ ) {
+							if ( k == j )
+								ch_free( attrs[k] );
+							attrs[k] = attrs[k+1];
+						}
+					} else {
+						j++;
+					}
+				}
+
+			}
+			for ( n = 0; attrs[ n ] != NULL; n++ ) /* empty */;
+			attrs = ( char ** ) ch_realloc( attrs, (n + 4)*sizeof( char * ));
+			if ( attrs == NULL ) {
+				Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
+			}
+	
+			/* Add Attributes */
+			for ( i = 0; sync_descs[ i ] != NULL; i++ ) {
+				attrs[ n++ ] = ch_strdup ( sync_descs[i]->ad_cname.bv_val );
+				attrs[ n ] = NULL;
+			}
 		}
 
 	} else {
-		tmp = ( char ** ) ch_realloc( si->si_attrs, 3 * sizeof( char * ));
-		if ( tmp == NULL ) {
+		attrs = ( char ** ) ch_realloc( attrs, 3 * sizeof( char * ));
+		if ( attrs == NULL ) {
 			Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 );
 		}
-		tmp[ n++ ] = ch_strdup( "*" );
-		tmp[ n++ ] = ch_strdup( "+" );
-		tmp[ n ] = NULL;
+		attrs[0] = ch_strdup( "*" );
+		attrs[1] = ch_strdup( "+" );
+		attrs[2] = NULL;
 	}
 	
-	si->si_attrs = tmp;
+	si->si_attrs = attrs;
+
+	exattrs = anlist2attrs( si->si_exanlist );
+
+	if ( exattrs ) {
 
-	for ( n = 0; si->si_exattrs[ n ] != NULL; n++ ) /* empty */;
-	if ( n ) {
-		/* Delete Attributes from exattrs list */
 		for ( i = 0; sync_descs[i] != NULL; i++ ) {
-			for ( j = 0; si->si_exattrs[j] != NULL; j++ ) {
-				if ( strcmp( si->si_exattrs[j], sync_descs[i]->ad_cname.bv_val )
-					== 0 )
-				{
-					for ( k = j; si->si_exattrs[k] != NULL; k++ ) {
+			j = 0;
+			while ( exattrs[j] != NULL ) {
+				if ( !strcmp( exattrs[j], sync_descs[i]->ad_cname.bv_val )) {
+					for ( k = j; exattrs[k] != NULL; k++ ) {
 						if ( k == j )
-							ch_free( si->si_exattrs[k] );
-						si->si_exattrs[k] = si->si_exattrs[k+1];
+							ch_free( exattrs[k] );
+						exattrs[k] = exattrs[k+1];
 					}
+				} else {
+					j++;
 				}
 			}
 		}
-		for ( i = 0; si->si_exattrs[i] != NULL; i++ ) {
-			for ( j = 0; si->si_ocs[j]; j++ ) {
-				for ( k = 0; si->si_ocs[j]->soc_required[k]; k++ ) {
-					if (!strcmp( si->si_exattrs[i],
-						si->si_ocs[j]->soc_required[k]->sat_cname.bv_val )) {
-						for ( l = i; si->si_exattrs[l] != NULL; l++ ) {
-							if ( l == i )
-								ch_free( si->si_exattrs[l] );
-							si->si_exattrs[l] = si->si_exattrs[l+1];
+
+		for ( i = 0; exattrs[i] != NULL; i++ ) {
+			for ( j = 0; si->si_anlist[j].an_name.bv_val; j++ ) {
+				if ( oc = si->si_anlist[j].an_oc ) {
+					k = 0;
+					while ( oc->soc_required[k] ) {
+						if ( !strcmp( exattrs[i],
+							 oc->soc_required[k]->sat_cname.bv_val )) {
+							for ( l = i; exattrs[l]; l++ ) {
+								if ( l == i )
+									ch_free( exattrs[i] );
+								exattrs[l] = exattrs[l+1];
+							}
+						} else {
+							k++;
 						}
 					}
 				}
 			}
 		}
+
+		for ( i = 0; exattrs[i] != NULL; i++ ) ;
+		exattrs = (char **) ch_realloc( exattrs, (i + 1)*sizeof(char *));
 	}
+
+	si->si_exattrs = exattrs;	
 }
 
 static int
@@ -2049,9 +2100,6 @@ syncinfo_free( syncinfo_t *sie )
 		}
 		ch_free( sie->si_attrs );
 	}
-	if ( sie->si_ocs ) {
-		ch_free( sie->si_ocs );
-	}
 	if ( sie->si_exattrs ) {
 		int i = 0;
 		while ( sie->si_exattrs[i] != NULL ) {
@@ -2060,6 +2108,22 @@ syncinfo_free( syncinfo_t *sie )
 		}
 		ch_free( sie->si_exattrs );
 	}
+	if ( sie->si_anlist ) {
+		int i = 0;
+		while ( sie->si_anlist[i].an_name.bv_val != NULL ) {
+			ch_free( sie->si_anlist[i].an_name.bv_val );
+			i++;
+		}
+		ch_free( sie->si_anlist );
+	}
+	if ( sie->si_exanlist ) {
+		int i = 0;
+		while ( sie->si_exanlist[i].an_name.bv_val != NULL ) {
+			ch_free( sie->si_exanlist[i].an_name.bv_val );
+			i++;
+		}
+		ch_free( sie->si_exanlist );
+	}
 	if ( sie->si_retryinterval ) {
 		ch_free( sie->si_retryinterval );
 	}