X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Fsyncprov.c;h=3df59509f5e745cab9cfedc453e0871d50e00711;hb=7c05cb30d7e806da6e79ffb59f9532a05c61d46e;hp=457ea95ec7b75e16683ee75a464eeffecbfc64df;hpb=eecb4332514e24afb8a1f1c43cfc5879bb59eeda;p=openldap
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c
index 457ea95ec7..3df59509f5 100644
--- a/servers/slapd/overlays/syncprov.c
+++ b/servers/slapd/overlays/syncprov.c
@@ -2,7 +2,7 @@
/* syncprov.c - syncrepl provider */
/* This work is part of OpenLDAP Software .
*
- * Copyright 2004-2015 The OpenLDAP Foundation.
+ * Copyright 2004-2016 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -2494,28 +2494,6 @@ syncprov_op_search( Operation *op, SlapReply *rs )
return rs->sr_err;
}
- /* snapshot the ctxcsn */
- ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock );
- numcsns = si->si_numcsns;
- if ( numcsns ) {
- ber_bvarray_dup_x( &ctxcsn, si->si_ctxcsn, op->o_tmpmemctx );
- sids = op->o_tmpalloc( numcsns * sizeof(int), op->o_tmpmemctx );
- for ( i=0; isi_sids[i];
- } else {
- ctxcsn = NULL;
- sids = NULL;
- }
- dirty = si->si_dirty;
- ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock );
-
- /* We know nothing - do nothing */
- if ( !numcsns ) {
- rs->sr_err = LDAP_SUCCESS;
- send_ldap_result( op, rs );
- return rs->sr_err;
- }
-
srs = op->o_controls[slap_cids.sc_LDAPsync];
/* If this is a persistent search, set it up right away */
@@ -2582,16 +2560,35 @@ syncprov_op_search( Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
}
+ /* snapshot the ctxcsn
+ * Note: this must not be done before the psearch setup. (ITS#8365)
+ */
+ ldap_pvt_thread_rdwr_rlock( &si->si_csn_rwlock );
+ numcsns = si->si_numcsns;
+ if ( numcsns ) {
+ ber_bvarray_dup_x( &ctxcsn, si->si_ctxcsn, op->o_tmpmemctx );
+ sids = op->o_tmpalloc( numcsns * sizeof(int), op->o_tmpmemctx );
+ for ( i=0; isi_sids[i];
+ } else {
+ ctxcsn = NULL;
+ sids = NULL;
+ }
+ dirty = si->si_dirty;
+ ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock );
+
/* If we have a cookie, handle the PRESENT lookups */
if ( srs->sr_state.ctxcsn ) {
sessionlog *sl;
int i, j;
- /* If we don't have any CSN of our own yet, pretend nothing
- * has changed.
+ /* If we don't have any CSN of our own yet, bail out.
*/
- if ( !numcsns )
- goto no_change;
+ if ( !numcsns ) {
+ rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
+ rs->sr_text = "consumer has state info but provider doesn't!";
+ goto bailout;
+ }
if ( !si->si_nopres )
do_present = SS_PRESENT;
@@ -2681,7 +2678,7 @@ bailout:
/* If nothing has changed, shortcut it */
if ( !changed && !dirty ) {
do_present = 0;
-no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
+no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
LDAPControl *ctrls[2];
ctrls[0] = NULL;
@@ -2768,6 +2765,9 @@ no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
}
}
} else {
+ /* The consumer knows nothing, we know nothing. OK. */
+ if (!numcsns)
+ goto no_change;
/* No consumer state, assume something has changed */
changed = SS_CHANGED;
}