The send_ldap_response() fix is still incomplete:
When rc == LDAP_CANCELLED, the function should not send sr_matched, sr_text, sr_ref, and sr_ctrls. Looking at how Abandon works, it seems slap_cleanup_play() should still see them if they are not sent?
Note, not just when the function itself sets rc = LDAP_CANCELLED, since syncprov can set rs->sr_err = LDAP_CANCELLED too. Which also suggests the assert( rs->sr_err == LDAP_REFERRAL ) when sr_ref != NULL is rather dubious. Maybe sr_ref should just be ignored when sending something else than LDAP_REFERRAL.
Also, this: rc = rs->sr_err; if ( rc == SLAPD_ABANDON && op->o_cancel ) rc = LDAP_CANCELLED; will send a negative result code (SLAPD_ABANDON) if !o_cancel. I guess it should be if ( rc == SLAPD_ABANDON ) { if ( !op->o_cancel ) goto <cleanup or clean2>; rc = LDAP_CANCELLED; }
While we're at it, I suggest to generalize this to avoid sending result codes < 0. Send LDAP_OTHER instead. That's ITS#5328 again.