- ctrls[0] = NULL;
- ctrls[1] = NULL;
- syncprov_done_ctrl( op, rs, ctrls, 0, 0,
- NULL, LDAP_SYNC_REFRESH_DELETES );
- rs->sr_ctrls = ctrls;
- rs->sr_err = LDAP_SUCCESS;
- send_ldap_result( op, rs );
- rs->sr_ctrls = NULL;
- return rs->sr_err;
+ /* If there are SIDs we don't recognize in the cookie, drop them */
+ for (i=0; i<srs->sr_state.numcsns; ) {
+ for (j=0; j<numcsns; j++) {
+ if ( srs->sr_state.sids[i] == sids[j] ) {
+ break;
+ }
+ }
+ /* not found */
+ if ( j == numcsns ) {
+ struct berval tmp = srs->sr_state.ctxcsn[i];
+ j = srs->sr_state.numcsns - 1;
+ srs->sr_state.ctxcsn[i] = srs->sr_state.ctxcsn[j];
+ tmp.bv_len = 0;
+ srs->sr_state.ctxcsn[j] = tmp;
+ srs->sr_state.numcsns = j;
+ srs->sr_state.sids[i] = srs->sr_state.sids[j];
+ continue;
+ }
+ i++;
+ }
+
+ /* Find the smallest CSN */
+ mincsn = srs->sr_state.ctxcsn[0];
+ for ( i=1; i<srs->sr_state.numcsns; i++ ) {
+ if ( ber_bvcmp( &mincsn, &srs->sr_state.ctxcsn[i] ) > 0 )
+ mincsn = srs->sr_state.ctxcsn[i];
+ }
+
+ /* If nothing has changed, shortcut it */
+ if ( srs->sr_state.numcsns == numcsns ) {
+ int i, j;
+ for ( i=0; i<srs->sr_state.numcsns; i++ ) {
+ for ( j=0; j<numcsns; j++ ) {
+ if ( srs->sr_state.sids[i] != sids[j] )
+ continue;
+ if ( !bvmatch( &srs->sr_state.ctxcsn[i], &ctxcsn[j] ))
+ changed = SS_CHANGED;
+ break;
+ }
+ if ( changed )
+ break;
+ }
+ if ( !changed ) {
+ do_present = 0;
+no_change: if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
+ LDAPControl *ctrls[2];
+
+ ctrls[0] = NULL;
+ ctrls[1] = NULL;
+ syncprov_done_ctrl( op, rs, ctrls, 0, 0,
+ NULL, LDAP_SYNC_REFRESH_DELETES );
+ rs->sr_ctrls = ctrls;
+ rs->sr_err = LDAP_SUCCESS;
+ send_ldap_result( op, rs );
+ rs->sr_ctrls = NULL;
+ return rs->sr_err;
+ }
+ goto shortcut;