Index: servers/slapd/backglue.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/backglue.c,v
retrieving revision 1.91.2.17
diff -u -r1.91.2.17 backglue.c
--- servers/slapd/backglue.c	3 Jan 2007 08:55:03 -0000	1.91.2.17
+++ servers/slapd/backglue.c	26 Jun 2007 12:33:59 -0000
@@ -611,19 +611,38 @@
 }
 
 static int
+glue_entry_get_rw (
+	Operation		*op,
+	struct berval	*dn,
+	ObjectClass		*oc,
+	AttributeDescription	*ad,
+	int	rw,
+	Entry	**e )
+{
+	BackendDB *b0 = op->o_bd;
+	op->o_bd = glue_back_select( b0, dn );
+	int rc;
+
+	if ( op->o_bd->be_fetch ) {
+		rc = op->o_bd->be_fetch( op, dn, oc, ad, rw, e );
+	} else {
+		rc = LDAP_UNWILLING_TO_PERFORM;
+	}
+	op->o_bd =b0;
+	return rc;
+}
+
+static int
 glue_entry_release_rw (
 	Operation *op,
 	Entry *e,
 	int rw
 )
 {
-	BackendDB *b0, b2;
+	BackendDB *b0 = op->o_bd;
 	int rc = -1;
 
-	b0 = op->o_bd;
-	b2 = *op->o_bd;
-	b2.bd_info = (BackendInfo *)glue_tool_inst( op->o_bd->bd_info );
-	op->o_bd = glue_back_select (&b2, &e->e_nname);
+	op->o_bd = glue_back_select (b0, &e->e_nname);
 
 	if ( op->o_bd->be_release ) {
 		rc = op->o_bd->be_release( op, e, rw );
@@ -819,8 +838,6 @@
 	oi->oi_bi.bi_open = glue_open;
 	oi->oi_bi.bi_close = glue_close;
 
-	oi->oi_bi.bi_entry_release_rw = glue_entry_release_rw;
-
 	/* Only advertise these if the root DB supports them */
 	if ( bi->bi_tool_entry_open )
 		oi->oi_bi.bi_tool_entry_open = glue_tool_entry_open;
@@ -1033,6 +1050,9 @@
 
 	glue.on_bi.bi_chk_referrals = glue_chk_referrals;
 	glue.on_bi.bi_chk_controls = glue_chk_controls;
+	glue.on_bi.bi_entry_get_rw = glue_entry_get_rw;
+	glue.on_bi.bi_entry_release_rw = glue_entry_release_rw;
+
 	glue.on_response = glue_response;
 
 	return overlay_register( &glue );
Index: servers/slapd/backover.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/backover.c,v
retrieving revision 1.31.2.20
diff -u -r1.31.2.20 backover.c
--- servers/slapd/backover.c	2 Jan 2007 21:43:54 -0000	1.31.2.20
+++ servers/slapd/backover.c	26 Jun 2007 12:33:59 -0000
@@ -322,6 +322,147 @@
 	return rc;
 }
 
+int
+overlay_entry_get_ov(
+	Operation		*op,
+	struct berval	*dn,
+	ObjectClass		*oc,
+	AttributeDescription	*ad,
+	int	rw,
+	Entry	**e,
+	slap_overinst *on )
+{
+	slap_overinfo *oi = on->on_info;
+	BackendDB *be = op->o_bd, db;
+	BackendInfo *bi = op->o_bd->bd_info;
+	int rc = SLAP_CB_CONTINUE;
+
+	for ( ; on; on = on->on_next ) {
+		if ( on->on_bi.bi_entry_get_rw ) {
+			/* NOTE: do not copy the structure until required */
+		 	if ( !SLAP_ISOVERLAY( op->o_bd ) ) {
+ 				db = *op->o_bd;
+				db.be_flags |= SLAP_DBFLAG_OVERLAY;
+				op->o_bd = &db;
+			}
+
+			op->o_bd->bd_info = (BackendInfo *)on;
+			rc = on->on_bi.bi_entry_get_rw( op, dn,
+				oc, ad, rw, e );
+			if ( rc != SLAP_CB_CONTINUE ) break;
+		}
+	}
+
+	if ( rc == SLAP_CB_CONTINUE ) {
+		/* if the database structure was changed, o_bd points to a
+		 * copy of the structure; put the original bd_info in place */
+		if ( SLAP_ISOVERLAY( op->o_bd ) ) {
+			op->o_bd->bd_info = oi->oi_orig;
+		}
+
+		if ( oi->oi_orig->bi_entry_get_rw ) {
+			rc = oi->oi_orig->bi_entry_get_rw( op, dn,
+				oc, ad, rw, e );
+		}
+	}
+	/* should not fall thru this far without anything happening... */
+	if ( rc == SLAP_CB_CONTINUE ) {
+		rc = LDAP_UNWILLING_TO_PERFORM;
+	}
+
+	op->o_bd = be;
+	op->o_bd->bd_info = bi;
+
+	return rc;
+}
+
+static int
+over_entry_get_rw(
+	Operation		*op,
+	struct berval	*dn,
+	ObjectClass		*oc,
+	AttributeDescription	*ad,
+	int	rw,
+	Entry	**e )
+{
+	slap_overinfo *oi;
+	slap_overinst *on;
+
+	assert( op->o_bd != NULL );
+
+	oi = op->o_bd->bd_info->bi_private;
+	on = oi->oi_list;
+
+	return overlay_entry_get_ov( op, dn, oc, ad, rw, e, on );
+}
+
+int
+overlay_entry_release_ov(
+	Operation	*op,
+	Entry	*e,
+	int rw,
+	slap_overinst *on )
+{
+	slap_overinfo *oi = on->on_info;
+	BackendDB *be = op->o_bd, db;
+	BackendInfo *bi = op->o_bd->bd_info;
+	int rc = SLAP_CB_CONTINUE;
+
+	for ( ; on; on = on->on_next ) {
+		if ( on->on_bi.bi_entry_release_rw ) {
+			/* NOTE: do not copy the structure until required */
+		 	if ( !SLAP_ISOVERLAY( op->o_bd ) ) {
+ 				db = *op->o_bd;
+				db.be_flags |= SLAP_DBFLAG_OVERLAY;
+				op->o_bd = &db;
+			}
+
+			op->o_bd->bd_info = (BackendInfo *)on;
+			rc = on->on_bi.bi_entry_release_rw( op, e, rw );
+			if ( rc != SLAP_CB_CONTINUE ) break;
+		}
+	}
+
+	if ( rc == SLAP_CB_CONTINUE ) {
+		/* if the database structure was changed, o_bd points to a
+		 * copy of the structure; put the original bd_info in place */
+		if ( SLAP_ISOVERLAY( op->o_bd ) ) {
+			op->o_bd->bd_info = oi->oi_orig;
+		}
+
+		if ( oi->oi_orig->bi_entry_release_rw ) {
+			rc = oi->oi_orig->bi_entry_release_rw( op, e, rw );
+		}
+	}
+	/* should not fall thru this far without anything happening... */
+	if ( rc == SLAP_CB_CONTINUE ) {
+		entry_free( e );
+		rc = 0;
+	}
+
+	op->o_bd = be;
+	op->o_bd->bd_info = bi;
+
+	return rc;
+}
+
+static int
+over_entry_release_rw(
+	Operation	*op,
+	Entry	*e,
+	int rw )
+{
+	slap_overinfo *oi;
+	slap_overinst *on;
+
+	assert( op->o_bd != NULL );
+
+	oi = op->o_bd->bd_info->bi_private;
+	on = oi->oi_list;
+
+	return overlay_entry_release_ov( op, e, rw, on );
+}
+
 static int
 over_acl_group(
 	Operation		*op,
@@ -932,6 +1073,8 @@
 
 #ifdef SLAP_OVERLAY_ACCESS
 		/* these have specific arglists */
+		bi->bi_entry_get_rw = over_entry_get_rw;
+		bi->bi_entry_release_rw = over_entry_release_rw;
 		bi->bi_access_allowed = over_access_allowed;
 		bi->bi_acl_group = over_acl_group;
 		bi->bi_acl_attribute = over_acl_attribute;
Index: servers/slapd/proto-slap.h
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/proto-slap.h,v
retrieving revision 1.552.2.41
diff -u -r1.552.2.41 proto-slap.h
--- servers/slapd/proto-slap.h	2 Jan 2007 21:43:57 -0000	1.552.2.41
+++ servers/slapd/proto-slap.h	26 Jun 2007 12:34:01 -0000
@@ -426,6 +426,19 @@
 	slap_operation_t which,
 	slap_overinfo *oi,
 	slap_overinst *on ));
+LDAP_SLAPD_F (int) overlay_entry_get_ov LDAP_P((
+	Operation *op,
+	struct berval *dn,
+	ObjectClass *oc,
+	AttributeDescription *ad,
+	int rw,
+	Entry **e,
+	slap_overinst *ov ));
+LDAP_SLAPD_F (int) overlay_entry_release_ov LDAP_P((
+	Operation *op,
+	Entry *e,
+	int rw,
+	slap_overinst *ov ));
 
 /*
  * bconfig.c
Index: servers/slapd/slap.h
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/slap.h,v
retrieving revision 1.612.2.45
diff -u -r1.612.2.45 slap.h
--- servers/slapd/slap.h	3 Jan 2007 08:55:03 -0000	1.612.2.45
+++ servers/slapd/slap.h	26 Jun 2007 12:34:03 -0000
@@ -58,6 +58,7 @@
 
 LDAP_BEGIN_DECL
 
+#define SLAP_OVERLAY_ACCESS
 
 #ifdef LDAP_DEVEL
 #define SLAP_LIGHTWEIGHT_DISPATCHER /* experimental slapd architecture */
Index: servers/slapd/overlays/syncprov.c
===================================================================
RCS file: /repo/OpenLDAP/pkg/ldap/servers/slapd/overlays/syncprov.c,v
retrieving revision 1.56.2.42
diff -u -r1.56.2.42 syncprov.c
--- servers/slapd/overlays/syncprov.c	7 Feb 2007 01:51:36 -0000	1.56.2.42
+++ servers/slapd/overlays/syncprov.c	26 Jun 2007 12:34:04 -0000
@@ -401,6 +401,7 @@
 		slap_callback cb = {0};
 		Operation fop;
 		SlapReply frs = { REP_RESULT };
+		BackendInfo *bi;
 		int rc;
 
 		fc->fss->s_flags ^= PS_FIND_BASE;
@@ -412,6 +413,7 @@
 		fop.o_bd = op->o_bd;
 		fop.o_time = op->o_time;
 		fop.o_tincr = op->o_tincr;
+		bi = op->o_bd->bd_info;
 
 		cb.sc_response = findbase_cb;
 		cb.sc_private = fc;
@@ -429,9 +431,8 @@
 		fop.ors_filter = &generic_filter;
 		fop.ors_filterstr = generic_filterstr;
 
-		fop.o_bd->bd_info = on->on_info->oi_orig;
-		rc = fop.o_bd->be_search( &fop, &frs );
-		fop.o_bd->bd_info = (BackendInfo *)on;
+		rc = overlay_op_walk( &fop, &frs, op_search, on->on_info, on );
+		op->o_bd->bd_info = bi;
 	} else {
 		ldap_pvt_thread_mutex_unlock( &fc->fss->s_mutex );
 		fc->fbase = 1;
@@ -818,7 +819,6 @@
 	int rc = 0;
 
 	opc.son = on;
-	op->o_bd->bd_info = (BackendInfo *)on->on_info;
 
 	for (;;) {
 		ldap_pvt_thread_mutex_lock( &so->s_mutex );
@@ -840,7 +840,7 @@
 		e = NULL;
 
 		if ( sr->s_mode != LDAP_SYNC_DELETE ) {
-			rc = be_entry_get_rw( op, &opc.sndn, NULL, NULL, 0, &e );
+			rc = overlay_entry_get_ov( op, &opc.sndn, NULL, NULL, 0, &e, on );
 			if ( rc ) {
 				Debug( LDAP_DEBUG_SYNC, "syncprov_qplay: failed to get %s, "
 					"error (%d), ignoring...\n", opc.sndn.bv_val, rc, 0 );
@@ -852,7 +852,7 @@
 		rc = syncprov_sendresp( op, &opc, so, &e, sr->s_mode );
 
 		if ( e ) {
-			be_entry_release_rw( op, e, 0 );
+			overlay_entry_release_ov( op, e, 0, on );
 		}
 
 		ch_free( sr );
@@ -860,7 +860,6 @@
 		if ( rc )
 			break;
 	}
-	op->o_bd->bd_info = (BackendInfo *)on;
 	return rc;
 }
 
@@ -1060,7 +1059,7 @@
 
 	fbase_cookie fc;
 	syncops *ss, *sprev, *snext;
-	Entry *e;
+	Entry *e = NULL;
 	Attribute *a;
 	int rc;
 	struct berval newdn;
@@ -1082,15 +1081,13 @@
 			db = *op->o_bd;
 			op->o_bd = &db;
 		}
-		op->o_bd->bd_info = (BackendInfo *)on->on_info;
-		rc = be_entry_get_rw( op, fc.fdn, NULL, NULL, 0, &e );
+		rc = overlay_entry_get_ov( op, fc.fdn, NULL, NULL, 0, &e, on );
 		/* If we're sending responses now, make a copy and unlock the DB */
 		if ( e && !saveit ) {
 			Entry *e2 = entry_dup( e );
-			be_entry_release_rw( op, e, 0 );
+			overlay_entry_release_ov( op, e, 0, on );
 			e = e2;
 		}
-		op->o_bd->bd_info = (BackendInfo *)on;
 		if ( rc ) {
 			op->o_bd = b0;
 			return;
@@ -2372,7 +2369,7 @@
 	OperationBuffer opbuf = { 0 };
 	char ctxcsnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
 	Operation *op = (Operation *) &opbuf;
-	Entry *e;
+	Entry *e = NULL;
 	Attribute *a;
 	int rc;
 	void *thrctx = NULL;
@@ -2400,9 +2397,8 @@
 
 	ctxcsnbuf[0] = '\0';
 
-	op->o_bd->bd_info = on->on_info->oi_orig;
-	rc = be_entry_get_rw( op, be->be_nsuffix, NULL,
-		slap_schema.si_ad_contextCSN, 0, &e );
+	rc = overlay_entry_get_ov( op, be->be_nsuffix, NULL,
+		slap_schema.si_ad_contextCSN, 0, &e, on );
 
 	if ( e ) {
 		ldap_pvt_thread_t tid;
@@ -2417,9 +2413,8 @@
 			si->si_ctxcsnbuf[si->si_ctxcsn.bv_len] = '\0';
 			strcpy( ctxcsnbuf, si->si_ctxcsnbuf );
 		}
-		be_entry_release_rw( op, e, 0 );
+		overlay_entry_release_ov( op, e, 0, on );
 		if ( !BER_BVISEMPTY( &si->si_ctxcsn ) ) {
-			op->o_bd->bd_info = (BackendInfo *)on;
 			op->o_req_dn = be->be_suffix[0];
 			op->o_req_ndn = be->be_nsuffix[0];
 			op->ors_scope = LDAP_SCOPE_SUBTREE;