diff --git a/servers/slapd/back-monitor/back-monitor.h b/servers/slapd/back-monitor/back-monitor.h
index dc7d4cf2fb20bfff137ca28a232dfc8012c77de4..c98faa1c550c25b7e3b7710d87733aae5901638b 100644
--- a/servers/slapd/back-monitor/back-monitor.h
+++ b/servers/slapd/back-monitor/back-monitor.h
@@ -36,6 +36,12 @@ typedef struct monitor_callback_t {
 	int			(*mc_update)( Operation *op, Entry *e, void *priv );
 						/* update callback
 						   for user-defined entries */
+	int			(*mc_modify)( Operation *op, Entry *e, void *priv );
+						/* modify callback
+						   for user-defined entries */
+	int			(*mc_free)( Entry *e, void *priv );
+						/* update callback
+						   for user-defined entries */
 	void			*mc_private;	/* opaque pointer to
 						   private data */
 	struct monitor_callback_t	*mc_next;
@@ -250,6 +256,43 @@ extern BackendDB *be_monitor;
 /* increase this bufsize if entries in string form get too big */
 #define BACKMONITOR_BUFSIZE	1024
 
+extern int
+monitor_back_register_entry(
+	Entry			*e,
+	monitor_callback_t	*cb );
+
+extern int
+monitor_back_register_entry_parent(
+	Entry			*e,
+	monitor_callback_t	*cb,
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter );
+
+extern int
+monitor_filter2ndn(
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter,
+	struct berval		*ndn );
+
+extern int
+monitor_back_register_entry_attrs(
+	struct berval		*ndn_in,
+	Attribute		*a,
+	monitor_callback_t	*cb,
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter );
+
+extern int
+monitor_back_register_entry_callback(
+	struct berval		*ndn,
+	monitor_callback_t	*cb,
+	struct berval		*base,
+	int			scope,
+	struct berval		*filter );
+
 LDAP_END_DECL
 
 #include "proto-back-monitor.h"
diff --git a/servers/slapd/back-monitor/database.c b/servers/slapd/back-monitor/database.c
index 8d5ee6076b80f0d92708e75971569cc6e2e984d3..90ac1695508580319c38bd2c2e0a908df149719b 100644
--- a/servers/slapd/back-monitor/database.c
+++ b/servers/slapd/back-monitor/database.c
@@ -555,7 +555,7 @@ monitor_subsys_database_modify(
 	
 	i = sscanf( e->e_nname.bv_val, "cn=database %d,", &n );
 	if ( i != 1 )
-		return LDAP_UNWILLING_TO_PERFORM;
+		return /* LDAP_UNWILLING_TO_PERFORM */ 0;
 
 	if ( n < 0 || n >= nBackendDB )
 		return LDAP_NO_SUCH_OBJECT;
diff --git a/servers/slapd/back-monitor/entry.c b/servers/slapd/back-monitor/entry.c
index 3c2b4ebf1c793b217cffae1f9c5d4cc4d253dbb3..193a41369dab4539d2e0dda82ddab89b2c53db92 100644
--- a/servers/slapd/back-monitor/entry.c
+++ b/servers/slapd/back-monitor/entry.c
@@ -32,7 +32,7 @@ monitor_entry_update(
 {
 	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
 	monitor_entry_t *mp;
-	int			rc = 0;
+	int		rc = 0;
 
 	assert( mi != NULL );
 	assert( e != NULL );
@@ -91,6 +91,7 @@ monitor_entry_modify(
 {
 	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
 	monitor_entry_t *mp;
+	int		rc = 0;
 
 	assert( mi != NULL );
 	assert( e != NULL );
@@ -99,10 +100,21 @@ monitor_entry_modify(
 	mp = ( monitor_entry_t * )e->e_private;
 
 	if ( mp->mp_info && mp->mp_info->mss_modify ) {
-		return ( *mp->mp_info->mss_modify )( op, e );
+		rc = ( *mp->mp_info->mss_modify )( op, e );
 	}
 
-	return( 0 );
+	if ( rc == 0 && mp->mp_cb ) {
+		struct monitor_callback_t	*mc;
+
+		for ( mc = mp->mp_cb; mc; mc = mc->mc_next ) {
+			rc = ( *mc->mc_modify )( op, e, mc->mc_private );
+			if ( rc != 0 ) {
+				break;
+			}
+		}
+	}
+
+	return rc;
 }
 
 int
diff --git a/servers/slapd/back-monitor/init.c b/servers/slapd/back-monitor/init.c
index 8747e2a8912bcbc2a36b1e308f76fb4a1afcbb72..abbc20457b885e330a9092f13ac84c3a0162b782 100644
--- a/servers/slapd/back-monitor/init.c
+++ b/servers/slapd/back-monitor/init.c
@@ -201,6 +201,7 @@ monitor_back_register_subsys( monitor_subsys_t *ms )
 
 enum {
 	LIMBO_ENTRY,
+	LIMBO_ENTRY_PARENT,
 	LIMBO_ATTRS,
 	LIMBO_CB
 };
@@ -281,7 +282,7 @@ monitor_back_register_entry(
 		}
 
 		e_new = entry_dup( e );
-		if ( e == NULL ) {
+		if ( e_new == NULL ) {
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_back_register_entry(\"%s\"): "
 				"entry_dup() failed\n",
@@ -293,6 +294,7 @@ monitor_back_register_entry(
 		e_new->e_private = ( void * )mp;
 		mp->mp_info = mp_parent->mp_info;
 		mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
+		mp->mp_cb = cb;
 
 		ep = &mp_parent->mp_children;
 		for ( ; *ep; ) {
@@ -326,7 +328,7 @@ done:;
 		}
 
 	} else {
-		entry_limbo_t	*elp, el = { 0 };
+		entry_limbo_t	**elpp, el = { 0 };
 
 		el.el_type = LIMBO_ENTRY;
 
@@ -341,16 +343,209 @@ done:;
 		
 		el.el_cb = cb;
 
-		elp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
-		if ( elp ) {
+		for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+				*elpp;
+				elpp = &(*elpp)->el_next )
+			/* go to last */;
+
+		*elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
+		if ( *elpp == NULL ) {
+			el.el_e->e_private = NULL;
+			entry_free( el.el_e );
+			return -1;
+		}
+
+		el.el_next = NULL;
+		**elpp = el;
+	}
+
+	return 0;
+}
+
+int
+monitor_back_register_entry_parent(
+		Entry			*e,
+		monitor_callback_t	*cb,
+		struct berval		*base,
+		int			scope,
+		struct berval		*filter )
+{
+	monitor_info_t 	*mi = ( monitor_info_t * )be_monitor->be_private;
+	struct berval	ndn = BER_BVNULL;
+
+	assert( mi != NULL );
+	assert( e != NULL );
+	assert( e->e_private == NULL );
+
+	if ( BER_BVISNULL( filter ) ) {
+		/* need a filter */
+		Debug( LDAP_DEBUG_ANY,
+			"monitor_back_register_entry_parent(\"\"): "
+			"need a valid filter\n",
+			0, 0, 0 );
+		return -1;
+	}
+
+	if ( monitor_subsys_opened ) {
+		Entry		*e_parent = NULL,
+				*e_new = NULL,
+				**ep = NULL;
+		struct berval	e_name = BER_BVNULL,
+				e_nname = BER_BVNULL;
+		monitor_entry_t *mp = NULL,
+				*mp_parent = NULL;
+		int		rc = 0;
+
+		if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) {
+			/* entry does not exist */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry_*(\"\"): "
+				"base=%s scope=%d filter=%s : "
+				"unable to find entry\n",
+				base->bv_val ? base->bv_val : "\"\"",
+				scope, filter->bv_val );
+			return -1;
+		}
+
+		if ( monitor_cache_get( mi, &ndn, &e_parent ) != 0 ) {
+			/* entry does not exist */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry_parent(\"%s\"): "
+				"parent entry does not exist\n",
+				ndn.bv_val, 0, 0 );
+			rc = -1;
+			goto done;
+		}
+
+		assert( e_parent->e_private != NULL );
+		mp_parent = ( monitor_entry_t * )e_parent->e_private;
+
+		if ( mp_parent->mp_flags & MONITOR_F_VOLATILE ) {
+			/* entry is volatile; cannot append callback */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry_*(\"%s\"): "
+				"entry is volatile\n",
+				e_parent->e_name.bv_val, 0, 0 );
+			rc = -1;
+			goto done;
+		}
+
+		build_new_dn( &e_name, &e_parent->e_name, &e->e_name, NULL );
+		build_new_dn( &e_nname, &e_parent->e_nname, &e->e_nname, NULL );
+
+		if ( monitor_cache_get( mi, &e_nname, &e_new ) == 0 ) {
+			/* entry already exists */
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry_parent(\"%s\"): "
+				"entry already exists\n",
+				e_name.bv_val, 0, 0 );
+			monitor_cache_release( mi, e_new );
+			rc = -1;
+			goto done;
+		}
+
+		mp = monitor_entrypriv_create();
+		if ( mp == NULL ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry_parent(\"%s\"): "
+				"monitor_entrypriv_create() failed\n",
+				e->e_name.bv_val, 0, 0 );
+			rc = -1;
+			goto done;
+		}
+
+		e_new = entry_dup( e );
+		if ( e_new == NULL ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry(\"%s\"): "
+				"entry_dup() failed\n",
+				e->e_name.bv_val, 0, 0 );
+			rc = -1;
+			goto done;
+		}
+		ch_free( e_new->e_name.bv_val );
+		ch_free( e_new->e_nname.bv_val );
+		e_new->e_name = e_name;
+		e_new->e_nname = e_nname;
+		
+		e_new->e_private = ( void * )mp;
+		mp->mp_info = mp_parent->mp_info;
+		mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB;
+		mp->mp_cb = cb;
+
+		ep = &mp_parent->mp_children;
+		for ( ; *ep; ) {
+			mp_parent = ( monitor_entry_t * )(*ep)->e_private;
+			ep = &mp_parent->mp_next;
+		}
+		*ep = e_new;
+
+		if ( monitor_cache_add( mi, e_new ) ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry(\"%s\"): "
+				"unable to add entry\n",
+				e->e_name.bv_val, 0, 0 );
+			rc = -1;
+			goto done;
+		}
+
+done:;
+		if ( !BER_BVISNULL( &ndn ) ) {
+			ch_free( ndn.bv_val );
+		}
+
+		if ( rc ) {
+			if ( mp ) {
+				ch_free( mp );
+			}
+			if ( e_new ) {
+				e_new->e_private = NULL;
+				entry_free( e_new );
+			}
+		}
+
+		if ( e_parent ) {
+			monitor_cache_release( mi, e_parent );
+		}
+
+	} else {
+		entry_limbo_t	**elpp, el = { 0 };
+
+		el.el_type = LIMBO_ENTRY_PARENT;
+
+		el.el_e = entry_dup( e );
+		if ( el.el_e == NULL ) {
+			Debug( LDAP_DEBUG_ANY,
+				"monitor_back_register_entry(\"%s\"): "
+				"entry_dup() failed\n",
+				e->e_name.bv_val, 0, 0 );
+			return -1;
+		}
+		
+		if ( !BER_BVISNULL( base ) ) {
+			ber_dupbv( &el.el_base, base );
+		}
+		el.el_scope = scope;
+		if ( !BER_BVISNULL( filter ) ) {
+			ber_dupbv( &el.el_filter, filter );
+		}
+
+		el.el_cb = cb;
+
+		for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+				*elpp;
+				elpp = &(*elpp)->el_next )
+			/* go to last */;
+
+		*elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
+		if ( *elpp == NULL ) {
 			el.el_e->e_private = NULL;
 			entry_free( el.el_e );
 			return -1;
 		}
 
-		el.el_next = (entry_limbo_t *)mi->mi_entry_limbo;
-		*elp = el;
-		mi->mi_entry_limbo = (void *)elp;
+		el.el_next = NULL;
+		**elpp = el;
 	}
 
 	return 0;
@@ -373,11 +568,10 @@ monitor_filter2ndn( struct berval *base, int scope, struct berval *filter,
 		struct berval *ndn )
 {
 	Connection	conn = { 0 };
-	char opbuf[OPERATION_BUFFER_SIZE];
+	char		opbuf[OPERATION_BUFFER_SIZE];
 	Operation	*op;
 	SlapReply	rs = { 0 };
 	slap_callback	cb = { NULL, monitor_filter2ndn_cb, NULL, NULL };
-	AttributeName	anlist[ 2 ];
 	int		rc;
 
 	BER_BVZERO( ndn );
@@ -415,9 +609,7 @@ monitor_filter2ndn( struct berval *base, int scope, struct berval *filter,
 	op->ors_scope = scope;
 	ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx );
 	op->ors_filter = str2filter_x( op, filter->bv_val );
-	op->ors_attrs = anlist;
-	BER_BVSTR( &anlist[ 0 ].an_name, LDAP_NO_ATTRS );
-	BER_BVZERO( &anlist[ 1 ].an_name );
+	op->ors_attrs = slap_anlist_no_attrs;
 	op->ors_attrsonly = 0;
 	op->ors_tlimit = SLAP_NO_LIMIT;
 	op->ors_slimit = 1;
@@ -579,7 +771,7 @@ done:;
 		}
 
 	} else {
-		entry_limbo_t	*elp, el = { 0 };
+		entry_limbo_t	**elpp, el = { 0 };
 
 		el.el_type = LIMBO_ATTRS;
 		if ( !BER_BVISNULL( &ndn ) ) {
@@ -596,15 +788,20 @@ done:;
 		el.el_a = attrs_dup( a );
 		el.el_cb = cb;
 
-		elp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
-		if ( elp == NULL ) {
-			attrs_free( a );
+		for ( elpp = (entry_limbo_t **)&mi->mi_entry_limbo;
+				*elpp;
+				elpp = &(*elpp)->el_next )
+			/* go to last */;
+
+		*elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) );
+		if ( *elpp == NULL ) {
+			el.el_e->e_private = NULL;
+			entry_free( el.el_e );
 			return -1;
 		}
 
-		el.el_next = (entry_limbo_t *)mi->mi_entry_limbo;
-		*elp = el;
-		mi->mi_entry_limbo = (void *)elp;;
+		el.el_next = NULL;
+		**elpp = el;
 	}
 
 	return 0;
@@ -886,7 +1083,7 @@ monitor_back_db_init(
 			offsetof(monitor_info_t, mi_ad_monitorTimestamp) },
 		{ "monitorOverlay", "( 1.3.6.1.4.1.4203.666.1.27 "
 			"NAME 'monitorOverlay' "
-			"DESC 'name of overlays defined for a give database' "
+			"DESC 'name of overlays defined for a given database' "
 			"SUP monitoredInfo "
 			"NO-USER-MODIFICATION "
 			"USAGE directoryOperation )", SLAP_AT_HIDE,
@@ -1352,6 +1549,16 @@ monitor_back_db_open(
 						el->el_cb );
 				break;
 
+			case LIMBO_ENTRY_PARENT:
+				monitor_back_register_entry_parent(
+						el->el_e,
+						el->el_cb,
+						&el->el_base,
+						el->el_scope,
+						&el->el_filter );
+				break;
+				
+
 			case LIMBO_ATTRS:
 				monitor_back_register_entry_attrs(
 						&el->el_ndn,
diff --git a/servers/slapd/back-monitor/modify.c b/servers/slapd/back-monitor/modify.c
index 0fe61e2b46acec739d81f47137f8022af2aa9524..d4aee8c990c5c86e861cb989c4de20ee0c8db103 100644
--- a/servers/slapd/back-monitor/modify.c
+++ b/servers/slapd/back-monitor/modify.c
@@ -67,6 +67,7 @@ monitor_back_modify( Operation *op, SlapReply *rs )
 
 	if ( !acl_check_modlist( op, e, op->oq_modify.rs_modlist )) {
 		rc = LDAP_INSUFFICIENT_ACCESS;
+
 	} else {
 		rc = monitor_entry_modify( op, e );
 	}