From fc8def62bb569197a27d083ee113b90606fb1fb8 Mon Sep 17 00:00:00 2001 From: Ludwig Krispenz Date: May 27 2014 15:38:55 +0000 Subject: Ticket 47805 - syncrepl doesn't send notification when attribute in search filter changes Bug Description: if an entry is modified so that it no longer matches the search filter specified in teh sync repl request a delete info should be sent Fix Description: check pre and post entry for mods to determine if an entry moves in or out of scope. Same logic as modrdn https://fedorahosted.org/389/ticket/47805 Reviewed by: Mark, thanks --- diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c index 4216a87..4fb4574 100644 --- a/ldap/servers/plugins/sync/sync_persist.c +++ b/ldap/servers/plugins/sync/sync_persist.c @@ -97,14 +97,15 @@ int sync_del_persist_post_op(Slapi_PBlock *pb) int sync_mod_persist_post_op(Slapi_PBlock *pb) { - Slapi_Entry *e; + Slapi_Entry *e, *e_prev; if ( !SYNC_IS_INITIALIZED()) { return(0); } slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e); - sync_queue_change(e, NULL, LDAP_REQ_MODIFY); + slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e_prev); + sync_queue_change(e, e_prev, LDAP_REQ_MODIFY); return( 0 ); } @@ -180,7 +181,7 @@ sync_queue_change( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype ) /* if the change is a modrdn then we need to check if the entry was * moved into scope, out of scope, or stays in scope */ - if (chgtype == LDAP_REQ_MODRDN) + if (chgtype == LDAP_REQ_MODRDN || chgtype == LDAP_REQ_MODIFY) prev_match = slapi_sdn_scope_test( slapi_entry_get_sdn_const(eprev), base, scope ) && ( 0 == slapi_vattr_filter_test( req->req_pblock, eprev, req->req_filter, 0 /* verify_access */ )); @@ -194,9 +195,8 @@ sync_queue_change( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype ) matched++; node = (SyncQueueNode *)slapi_ch_calloc( 1, sizeof( SyncQueueNode )); - node->sync_entry = slapi_entry_dup( e ); - if ( chgtype == LDAP_REQ_MODRDN) { + if ( chgtype == LDAP_REQ_MODRDN || chgtype == LDAP_REQ_MODIFY) { if (prev_match && cur_match) node->sync_chgtype = LDAP_REQ_MODIFY; else if (prev_match) @@ -206,6 +206,12 @@ sync_queue_change( Slapi_Entry *e, Slapi_Entry *eprev, ber_int_t chgtype ) } else { node->sync_chgtype = chgtype; } + if (node->sync_chgtype == LDAP_REQ_DELETE && chgtype == LDAP_REQ_MODIFY ) { + /* use previous entry to pass the filter test in sync_send_results */ + node->sync_entry = slapi_entry_dup( eprev ); + } else { + node->sync_entry = slapi_entry_dup( e ); + } /* Put it on the end of the list for this sync search */ PR_Lock( req->req_lock ); pOldtail = req->ps_eq_tail;