diff --git a/doc/man/man5/slapd-null.5 b/doc/man/man5/slapd-null.5
index 02ef95283e7a2d4b1610c18c034f31123d925bcf..ba5b64bc48ae0e64d9c8e6cd323865d60adec555 100644
--- a/doc/man/man5/slapd-null.5
+++ b/doc/man/man5/slapd-null.5
@@ -20,6 +20,12 @@ is surely the most useful part of
 .br
 - Binds fail unless the database option "bind on" is given.
 .br
+- The
+.BR slapadd (8)
+and
+.BR slapcat (8)
+tools are equally exciting.
+.br
 Inspired by the /dev/null device.
 .SH CONFIGURATION
 This
@@ -55,4 +61,6 @@ ETCDIR/slapd.conf
 default slapd configuration file
 .SH SEE ALSO
 .BR slapd.conf (5),
-.BR slapd (8).
+.BR slapd (8),
+.BR slapadd (8),
+.BR slapcat (8).
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 89d5db8a0db7400b8faf71b32b7a12d7be4a712d..fe47f8dc392c23755443e68e63a06f9b8033207d 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -397,6 +397,9 @@ ldap_int_destroy_global_options(void)
 {
 	struct ldapoptions *gopts = LDAP_INT_GLOBAL_OPT();
 
+	if ( gopts == NULL )
+		return;
+
 	gopts->ldo_valid = LDAP_UNINITIALIZED;
 
 	if ( gopts->ldo_defludp ) {
diff --git a/servers/slapd/back-meta/bind.c b/servers/slapd/back-meta/bind.c
index 0cb7f3337ea55c9f91f3b7fd243a4b2f5e4e34e6..424210da025ed2ea8c56730fe9bcfc880a977adc 100644
--- a/servers/slapd/back-meta/bind.c
+++ b/servers/slapd/back-meta/bind.c
@@ -488,6 +488,7 @@ retry:;
 		}
 
 	} else {
+		rs->sr_err = rc;
 		rc = slap_map_api2result( rs );
 	}
 
@@ -580,8 +581,6 @@ meta_back_dobind(
 		}
 
 		if ( rc != LDAP_SUCCESS ) {
-			rs->sr_err = slap_map_api2result( rs );
-
 			Debug( LDAP_DEBUG_ANY, "%s meta_back_dobind[%d]: "
 					"(anonymous) err=%d\n",
 					op->o_log_prefix, i, rc );
@@ -593,7 +592,8 @@ meta_back_dobind(
 			 * due to technical reasons (remote host down?)
 			 * so better clear the handle
 			 */
-			candidates[ i ].sr_tag = META_NOT_CANDIDATE;
+			/* leave the target candidate, but record the error for later use */
+			candidates[ i ].sr_err = rc;
 			if ( META_BACK_ONERR_STOP( mi ) ) {
 				bound = 0;
 				goto done;
@@ -665,8 +665,11 @@ meta_back_op_result(
 
 	int			i,
 				rerr = LDAP_SUCCESS;
-	char			*rmsg = NULL;
-	char			*rmatch = NULL;
+	char			*rmsg = NULL,
+				*rmatch = NULL;
+	const char		*save_rmsg = NULL,
+				*save_rmatch = NULL;
+	void			*rmatch_ctx = NULL;
 
 	if ( candidate != META_TARGET_NONE ) {
 		metasingleconn_t	*msc = &mc->mc_conns[ candidate ];
@@ -779,36 +782,31 @@ meta_back_op_result(
 	}
 	
 	rs->sr_err = rerr;
-	rs->sr_text = rmsg;
+	if ( rmsg != NULL ) {
+		save_rmsg = rs->sr_text;
+		rs->sr_text = rmsg;
+	}
 	if ( rmatch != NULL ) {
 		struct berval	dn, pdn;
 
 		ber_str2bv( rmatch, 0, 0, &dn );
 		if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) {
-			rs->sr_matched = pdn.bv_val;
 			ldap_memfree( rmatch );
-			rmatch = NULL;
-		} else {
-			rs->sr_matched = rmatch;
+			rmatch_ctx = op->o_tmpmemctx;
+			rmatch = pdn.bv_val;
 		}
-
-	} else {
-		rs->sr_matched = NULL;
+		save_rmatch = rs->sr_matched;
+		rs->sr_matched = rmatch;
 	}
 	send_ldap_result( op, rs );
 	if ( rmsg != NULL ) {
 		ber_memfree( rmsg );
+		rs->sr_text = save_rmsg;
 	}
-	if ( rs->sr_matched != NULL ) {
-		if ( rmatch == NULL ) {
-			ber_memfree_x( rs->sr_matched, op->o_tmpmemctx );
-
-		} else {
-			ldap_memfree( rmatch );
-		}
-		rs->sr_matched = NULL;
+	if ( rmatch != NULL ) {
+		ber_memfree_x( rmatch, rmatch_ctx );
+		rs->sr_matched = save_rmatch;
 	}
-	rs->sr_text = NULL;
 
 	return ( ( rerr == LDAP_SUCCESS ) ? 0 : -1 );
 }
diff --git a/servers/slapd/back-meta/conn.c b/servers/slapd/back-meta/conn.c
index 5f10ce40d22098c084969528b92e6015e673d4e2..a0ae2801249fe69e0b607e747dff707e43900006 100644
--- a/servers/slapd/back-meta/conn.c
+++ b/servers/slapd/back-meta/conn.c
@@ -547,6 +547,8 @@ meta_back_get_candidate(
 	return candidate;
 }
 
+static void	*meta_back_candidates_dummy;
+
 static void
 meta_back_candidates_keyfree(
 	void		*key,
@@ -568,7 +570,7 @@ meta_back_candidates_get( Operation *op )
 		void		*data = NULL;
 
 		ldap_pvt_thread_pool_getkey( op->o_threadctx,
-				meta_back_candidates_keyfree, &data, NULL );
+				&meta_back_candidates_dummy, &data, NULL );
 		mc = (metacandidates_t *)data;
 
 	} else {
@@ -584,7 +586,7 @@ meta_back_candidates_get( Operation *op )
 
 			data = (void *)mc;
 			ldap_pvt_thread_pool_setkey( op->o_threadctx,
-					meta_back_candidates_keyfree, data,
+					&meta_back_candidates_dummy, data,
 					meta_back_candidates_keyfree );
 
 		} else {
@@ -728,9 +730,11 @@ meta_back_getconn(
 			 * The target is activated; if needed, it is
 			 * also init'd
 			 */
-			int lerr = meta_back_init_one_conn( op, rs, &mi->mi_targets[ i ],
-					&mc->mc_conns[ i ], sendok );
-			if ( lerr == LDAP_SUCCESS ) {
+			candidates[ i ].sr_err =
+				meta_back_init_one_conn( op, rs,
+						&mi->mi_targets[ i ],
+						&mc->mc_conns[ i ], sendok );
+			if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
 				candidates[ i ].sr_tag = META_CANDIDATE;
 				ncandidates++;
 				
@@ -742,7 +746,7 @@ meta_back_getconn(
 				 * be tried?
 				 */
 				candidates[ i ].sr_tag = META_NOT_CANDIDATE;
-				err = lerr;
+				err = candidates[ i ].sr_err;
 				continue;
 			}
 		}
@@ -799,10 +803,7 @@ meta_back_getconn(
 			}
 	
 			if ( rs->sr_err != LDAP_SUCCESS ) {
-				if ( new_conn ) {
-					meta_back_freeconn( op, mc );
-
-				} else {
+				if ( mc != NULL ) {
 					meta_back_release_conn( op, mc );
 				}
 
@@ -821,10 +822,7 @@ meta_back_getconn(
 
 		if ( newparent && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
 		{
-			if ( new_conn ) {
-				meta_back_freeconn( op, mc );
-
-			} else {
+			if ( mc != NULL ) {
 				meta_back_release_conn( op, mc );
 			}
 
@@ -892,6 +890,7 @@ meta_back_getconn(
 			return NULL;
 		}
 
+		candidates[ i ].sr_err = LDAP_SUCCESS;
 		candidates[ i ].sr_tag = META_CANDIDATE;
 		ncandidates++;
 
@@ -927,6 +926,7 @@ meta_back_getconn(
 						&mc->mc_conns[ i ], sendok );
 				if ( lerr == LDAP_SUCCESS ) {
 					candidates[ i ].sr_tag = META_CANDIDATE;
+					candidates[ i ].sr_err = LDAP_SUCCESS;
 					ncandidates++;
 
 					Debug( LDAP_DEBUG_TRACE, "%s: meta_back_init_one_conn(%d)\n",
@@ -942,7 +942,8 @@ meta_back_getconn(
 					if ( new_conn ) {
 						( void )meta_clear_one_candidate( &mc->mc_conns[ i ] );
 					}
-					candidates[ i ].sr_tag = META_NOT_CANDIDATE;
+					/* leave the target candidate, but record the error for later use */
+					candidates[ i ].sr_err = lerr;
 					err = lerr;
 
 					Debug( LDAP_DEBUG_ANY, "%s: meta_back_init_one_conn(%d) failed: %d\n",
diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c
index edf3975be43a8f24c5014cbae6d1334b97cb812f..55edc25767777b32ecacfee03d01f4637ee8e16f 100644
--- a/servers/slapd/back-meta/search.c
+++ b/servers/slapd/back-meta/search.c
@@ -272,17 +272,17 @@ meta_back_search( Operation *op, SlapReply *rs )
 		metasingleconn_t	*msc = &mc->mc_conns[ i ];
 
 		candidates[ i ].sr_msgid = -1;
-
-		if ( candidates[ i ].sr_tag != META_CANDIDATE ) {
-			continue;
-		}
-
-		candidates[ i ].sr_err = LDAP_SUCCESS;
 		candidates[ i ].sr_matched = NULL;
 		candidates[ i ].sr_text = NULL;
 		candidates[ i ].sr_ref = NULL;
 		candidates[ i ].sr_ctrls = NULL;
 
+		if ( candidates[ i ].sr_tag != META_CANDIDATE
+			|| candidates[ i ].sr_err != LDAP_SUCCESS )
+		{
+			continue;
+		}
+
 		switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) )
 		{
 		case 0:
@@ -333,9 +333,20 @@ meta_back_search( Operation *op, SlapReply *rs )
 			op->o_log_prefix, op->o_req_dn.bv_val,
 			op->ors_scope );
 
-		send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, NULL );
-
+		/* FIXME: we're sending the first error we encounter;
+		 * maybe we should pick the worst... */
 		rc = LDAP_NO_SUCH_OBJECT;
+		for ( i = 0; i < mi->mi_ntargets; i++ ) {
+			if ( candidates[ i ].sr_tag == META_CANDIDATE
+				&& candidates[ i ].sr_err != LDAP_SUCCESS )
+			{
+				rc = candidates[ i ].sr_err;
+				break;
+			}
+		}
+
+		send_ldap_error( op, rs, rc, NULL );
+
 		goto finish;
 	}
 
diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c
index ce8967c3045ee82604b92cb022eea1001a43c0a0..293d543535a1f9672b6fe87f6e98ae438a25fec1 100644
--- a/servers/slapd/back-monitor/init.c
+++ b/servers/slapd/back-monitor/init.c
@@ -1380,8 +1380,10 @@ monitor_back_db_init(
 	BackendDB	*be )
 {
 	int		rc;
-	struct berval	dn, ndn;
-	struct berval	bv;
+	struct berval	dn = BER_BVC( SLAPD_MONITOR_DN ),
+			pdn,
+			ndn;
+	BackendDB	*be2;
 
 	/*
 	 * database monitor can be defined once only
@@ -1396,19 +1398,15 @@ monitor_back_db_init(
 	/* indicate system schema supported */
 	SLAP_BFLAGS(be) |= SLAP_BFLAG_MONITOR;
 
-	dn.bv_val = SLAPD_MONITOR_DN;
-	dn.bv_len = sizeof( SLAPD_MONITOR_DN ) - 1;
-
-	rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
+	rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL );
 	if( rc != LDAP_SUCCESS ) {
 		Debug( LDAP_DEBUG_ANY,
-			"unable to normalize monitor DN \"%s\" (%d)\n",
+			"unable to normalize/pretty monitor DN \"%s\" (%d)\n",
 			dn.bv_val, rc, 0 );
 		return -1;
 	}
 
-	ber_dupbv( &bv, &dn );
-	ber_bvarray_add( &be->be_suffix, &bv );
+	ber_bvarray_add( &be->be_suffix, &pdn );
 	ber_bvarray_add( &be->be_nsuffix, &ndn );
 
 	/* NOTE: only one monitor database is allowed,
@@ -1417,6 +1415,22 @@ monitor_back_db_init(
 
 	be->be_private = &monitor_info;
 
+	be2 = select_backend( &ndn, 0, 0 );
+	if ( be2 != be ) {
+		char	*type = be2->bd_info->bi_type;
+
+		if ( overlay_is_over( be2 ) ) {
+			slap_overinfo	*oi = (slap_overinfo *)be2->bd_info->bi_private;
+			type = oi->oi_orig->bi_type;
+		}
+
+		Debug( LDAP_DEBUG_ANY,
+			"\"monitor\" database serving namingContext \"%s\" "
+			"is hidden by \"%s\" database serving namingContext \"%s\".\n",
+			pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val );
+		return -1;
+	}
+
 	return 0;
 }
 
diff --git a/servers/slapd/back-null/null.c b/servers/slapd/back-null/null.c
index 76b448dd12f6d2232c3f9e01e26fc4d122932339..3889a34c3e36e89bfc1c635369f79b92fbe22259 100644
--- a/servers/slapd/back-null/null.c
+++ b/servers/slapd/back-null/null.c
@@ -26,15 +26,19 @@
 #include "slap.h"
 
 struct null_info {
-	int bind_allowed;
+	int	ni_bind_allowed;
+	ID	ni_nextid;
 };
 
+
+/* LDAP operations */
+
 static int
 null_back_bind( Operation *op, SlapReply *rs )
 {
 	struct null_info *ni = (struct null_info *) op->o_bd->be_private;
 
-	if ( ni->bind_allowed ) {
+	if ( ni->ni_bind_allowed ) {
 		/* front end will send result on success (0) */
 		return LDAP_SUCCESS;
 	}
@@ -63,6 +67,50 @@ null_back_false( Operation *op, SlapReply *rs )
 	return 0;
 }
 
+
+/* Slap tools */
+
+static int
+null_tool_entry_open( BackendDB *be, int mode )
+{
+	return 0;
+}
+
+static int
+null_tool_entry_close( BackendDB *be )
+{
+	assert( be != NULL );
+	return 0;
+}
+
+static ID
+null_tool_entry_next( BackendDB *be )
+{
+	return NOID;
+}
+
+static Entry *
+null_tool_entry_get( BackendDB *be, ID id )
+{
+	assert( slapMode & SLAP_TOOL_MODE );
+	return NULL;
+}
+
+static ID
+null_tool_entry_put( BackendDB *be, Entry *e, struct berval *text )
+{
+	assert( slapMode & SLAP_TOOL_MODE );
+	assert( text != NULL );
+	assert( text->bv_val != NULL );
+	assert( text->bv_val[0] == '\0' );	/* overconservative? */
+
+	e->e_id = ((struct null_info *) be->be_private)->ni_nextid++;
+	return e->e_id;
+}
+
+
+/* Setup */
+
 static int
 null_back_db_config(
 	BackendDB	*be,
@@ -87,7 +135,7 @@ null_back_db_config(
 			         fname, lineno );
 			return 1;
 		}
-		ni->bind_allowed = strcasecmp( argv[1], "off" );
+		ni->ni_bind_allowed = strcasecmp( argv[1], "off" );
 
 	/* anything else */
 	} else {
@@ -100,10 +148,9 @@ null_back_db_config(
 static int
 null_back_db_init( BackendDB *be )
 {
-	struct null_info *ni;
-
-	ni = ch_calloc( 1, sizeof(struct null_info) );
-	ni->bind_allowed = 0;
+	struct null_info *ni = ch_calloc( 1, sizeof(struct null_info) );
+	ni->ni_bind_allowed = 0;
+	ni->ni_nextid = 1;
 	be->be_private = ni;
 	return 0;
 }
@@ -147,6 +194,13 @@ null_back_initialize( BackendInfo *bi )
 	bi->bi_connection_init = 0;
 	bi->bi_connection_destroy = 0;
 
+	bi->bi_tool_entry_open = null_tool_entry_open;
+	bi->bi_tool_entry_close = null_tool_entry_close;
+	bi->bi_tool_entry_first = null_tool_entry_next;
+	bi->bi_tool_entry_next = null_tool_entry_next;
+	bi->bi_tool_entry_get = null_tool_entry_get;
+	bi->bi_tool_entry_put = null_tool_entry_put;
+
 	return 0;
 }
 
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
index 4229c9be024f99684e66170da64084a165c54392..4b47318626d144375a8c1a16dfd0b0ce819f5765 100644
--- a/servers/slapd/bconfig.c
+++ b/servers/slapd/bconfig.c
@@ -1663,8 +1663,16 @@ config_suffix(ConfigArgs *c)
 		free(pdn.bv_val);
 		free(ndn.bv_val);
 	} else if(tbe) {
-		sprintf( c->msg, "<%s> suffix already served by a preceding backend",
-			c->argv[0] );
+		char	*type = tbe->bd_info->bi_type;
+
+		if ( overlay_is_over( tbe ) ) {
+			slap_overinfo	*oi = (slap_overinfo *)tbe->bd_info->bi_private;
+			type = oi->oi_orig->bi_type;
+		}
+
+		sprintf( c->msg, "<%s> namingContext \"%s\" already served by "
+			"a preceding %s database serving namingContext",
+			c->argv[0], pdn.bv_val, type );
 		Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
 			c->log, c->msg, tbe->be_suffix[0].bv_val);
 		free(pdn.bv_val);
diff --git a/servers/slapd/init.c b/servers/slapd/init.c
index edc1689311e648eae8e9ba2fa3ea7f0ce3418f67..6b4589730810492f39cd09979ae97816f7482bd6 100644
--- a/servers/slapd/init.c
+++ b/servers/slapd/init.c
@@ -216,7 +216,6 @@ slap_init( int mode, const char *name )
 		return 1;
 	}
 
-#ifdef SLAP_DYNACL
 	if ( acl_init() ) {
 		ldap_debug |= 1;
 		Debug( LDAP_DEBUG_ANY,
@@ -224,7 +223,7 @@ slap_init( int mode, const char *name )
 		    name, 0, 0 );
 		return 1;
 	}
-#endif /* SLAP_DYNACL */
+
 	return rc;
 }
 
diff --git a/servers/slapd/overlays/glue.c b/servers/slapd/overlays/glue.c
index 74fee3f652e371cfcd4b24646f5e8b4f221851ee..52f3034ceb1218a0303a727f3fe0f8b9d26c3c48 100644
--- a/servers/slapd/overlays/glue.c
+++ b/servers/slapd/overlays/glue.c
@@ -821,6 +821,12 @@ glue_db_config(
 				fname, lineno, argv[1] );
 			return -1;
 		}
+		if ( SLAP_GLUE_INSTANCE( b2 )) {
+			fprintf( stderr, "%s: line %d: backend for %s is already glued; "
+				"only one glue overlay is allowed per tree.\n",
+				fname, lineno, argv[1] );
+			return -1;
+		}
 		SLAP_DBFLAGS(b2) |= SLAP_DBFLAG_GLUE_SUBORDINATE;
 		if ( advertise ) {
 			SLAP_DBFLAGS(b2) |= SLAP_DBFLAG_GLUE_ADVERTISE;
diff --git a/tests/scripts/test041-aci b/tests/scripts/test041-aci
index 0329c5ccae3c053d70eef8dca246ff5f3d9fe819..c56121bb1d28103b0fa93928039b0cc02cba4347 100755
--- a/tests/scripts/test041-aci
+++ b/tests/scripts/test041-aci
@@ -19,6 +19,7 @@ bdb|hdb|ldbm)
 *)
 	echo "Test does not support $BACKEND backend"
 	exit 0
+	;;
 esac
 
 echo "running defines.sh"
@@ -78,8 +79,11 @@ $LDAPSEARCH -s base -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
 	'(objectclass=*)' >> $SEARCHOUT 2>> $TESTOUT
 RC=$?
 if test $RC != 32 ; then
-	echo "ldapsearch should have failed ($RC)!"
+	echo "ldapsearch should have failed with noSuchObject ($RC)!"
 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
+	if test $RC = 0 ; then
+		exit -1
+	fi
 	exit $RC
 fi
 
@@ -92,7 +96,7 @@ RC=$?
 if test $RC = 0 ; then
 	echo "ldapwhoami should have failed!"
 	test $KILLSERVERS != no && kill -HUP $KILLPIDS
-	exit $RC
+	exit -1
 fi
 
 # Populate ACIs