ITS#3596 - fix callback cleanups

This commit is contained in:
Howard Chu 2005-03-14 20:06:24 +00:00
parent 2c3b196d04
commit 5eec7b29e1
3 changed files with 74 additions and 33 deletions

View file

@ -220,6 +220,20 @@ over_op_func(
if ( rc == SLAP_CB_CONTINUE ) {
rc = op_rc[ which ];
}
/* The underlying backend didn't handle the request, make sure
* overlay cleanup is processed.
*/
if ( rc == LDAP_UNWILLING_TO_PERFORM ) {
slap_callback *sc_next;
for ( ; op->o_callback && op->o_callback != cb.sc_next;
op->o_callback = sc_next ) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
op->o_callback->sc_cleanup( op, rs );
}
}
}
op->o_bd = be;
op->o_callback = cb.sc_next;
return rc;

View file

@ -43,8 +43,8 @@ int passwd_extop(
{
struct berval id = {0, NULL}, hash, *rsp = NULL;
req_pwdexop_s *qpw = &op->oq_pwdexop;
req_extended_s qext = op->oq_extended;
Modifications *ml;
Operation op2;
slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
slap_callback cb2 = { NULL, slap_replog_cb, NULL, NULL };
int i, nhash;
@ -190,31 +190,34 @@ int passwd_extop(
if ( hashes[i] ) {
rs->sr_err = LDAP_OTHER;
} else {
slap_callback *sc = op->o_callback;
op2 = *op;
op2.o_tag = LDAP_REQ_MODIFY;
op2.o_callback = &cb2;
op2.orm_modlist = qpw->rs_mods;
op->o_tag = LDAP_REQ_MODIFY;
op->o_callback = &cb2;
op->orm_modlist = qpw->rs_mods;
cb2.sc_private = qpw; /* let Modify know this was pwdMod,
* if it cares... */
rs->sr_err = slap_mods_opattrs( &op2, ml, qpw->rs_modtail, &rs->sr_text,
rs->sr_err = slap_mods_opattrs( op, ml, qpw->rs_modtail, &rs->sr_text,
NULL, 0, 1 );
if ( rs->sr_err == LDAP_SUCCESS ) {
rs->sr_err = op2.o_bd->be_modify( &op2, rs );
rs->sr_err = op->o_bd->be_modify( op, rs );
}
if ( rs->sr_err == LDAP_SUCCESS ) {
rs->sr_rspdata = rsp;
} else if ( rsp ) {
ber_bvfree( rsp );
}
op->o_tag = LDAP_REQ_EXTENDED;
op->o_callback = sc;
}
slap_mods_free( qpw->rs_mods );
if ( rsp ) {
free( qpw->rs_new.bv_val );
}
op->oq_extended = qext;
return rs->sr_err;
}

View file

@ -477,6 +477,24 @@ cleanup:
*/
rc = SLAP_CB_CONTINUE;
clean2:;
if ( op->o_callback ) {
int first = 1;
slap_callback *sc = op->o_callback, *sc_next;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
(void)op->o_callback->sc_cleanup( op, rs );
if ( first && op->o_callback != sc ) {
sc = op->o_callback;
}
}
first = 0;
}
op->o_callback = sc;
}
if ( rs->sr_matched && rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
free( (char *)rs->sr_matched );
rs->sr_matched = NULL;
@ -487,17 +505,6 @@ cleanup:
rs->sr_ref = NULL;
}
clean2:
if (op->o_callback) {
slap_callback *sc = op->o_callback;
for ( ; op->o_callback; op->o_callback = op->o_callback->sc_next ) {
if ( op->o_callback->sc_cleanup ) {
op->o_callback->sc_cleanup( op, rs );
}
}
op->o_callback = sc;
}
return rc;
}
@ -1340,6 +1347,27 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
rc = 0;
error_return:;
if ( op->o_callback ) {
int first = 1;
slap_callback *sc = op->o_callback, *sc_next;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
(void)op->o_callback->sc_cleanup( op, rs );
if ( first && op->o_callback != sc ) {
sc = op->o_callback;
}
}
first = 0;
}
op->o_callback = sc;
}
if ( e_flags ) {
slap_sl_free( e_flags, op->o_tmpmemctx );
}
/* FIXME: I think rs->sr_type should be explicitly set to
* REP_SEARCH here. That's what it was when we entered this
* function. send_ldap_error may have changed it, but we
@ -1355,17 +1383,6 @@ error_return:;
rs->sr_flags &= ~REP_ENTRY_MUSTBEFREED;
}
if ( e_flags ) sl_free( e_flags, op->o_tmpmemctx );
if (op->o_callback) {
slap_callback *sc = op->o_callback;
for ( ; op->o_callback; op->o_callback = op->o_callback->sc_next ) {
if ( op->o_callback->sc_cleanup ) {
op->o_callback->sc_cleanup( op, rs );
}
}
op->o_callback = sc;
}
return( rc );
}
@ -1545,12 +1562,19 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
#endif
rel:
if (op->o_callback) {
slap_callback *sc = op->o_callback;
for ( ; op->o_callback; op->o_callback = op->o_callback->sc_next ) {
if ( op->o_callback ) {
int first = 1;
slap_callback *sc = op->o_callback, *sc_next;
for ( sc_next = op->o_callback; sc_next; op->o_callback = sc_next ) {
sc_next = op->o_callback->sc_next;
if ( op->o_callback->sc_cleanup ) {
op->o_callback->sc_cleanup( op, rs );
(void)op->o_callback->sc_cleanup( op, rs );
if ( first && op->o_callback != sc ) {
sc = op->o_callback;
}
}
first = 0;
}
op->o_callback = sc;
}