char *matched;
int nrefs;
BerVarray refs;
- slap_callback *prevcb;
} glue_state;
static int
glue_back_response ( Operation *op, SlapReply *rs )
{
glue_state *gs = op->o_callback->sc_private;
- slap_callback *tmp = op->o_callback;
switch(rs->sr_type) {
case REP_SEARCH:
case REP_SEARCHREF:
- op->o_callback = gs->prevcb;
- if (op->o_callback && op->o_callback->sc_response) {
- rs->sr_err = op->o_callback->sc_response( op, rs );
- } else rs->sr_err = SLAP_CB_CONTINUE;
- op->o_callback = tmp;
- return rs->sr_err;
+ return SLAP_CB_CONTINUE;
default:
if (rs->sr_err == LDAP_SUCCESS || gs->err != LDAP_SUCCESS)
glueinfo *gi = (glueinfo *) b0->bd_info;
int i;
long stoptime = 0;
- glue_state gs = {0, 0, NULL, 0, NULL, NULL};
- slap_callback cb = { glue_back_response, NULL };
+ glue_state gs = {0, 0, NULL, 0, NULL};
+ slap_callback cb = { NULL, glue_back_response, NULL, NULL };
int scope0, slimit0, tlimit0;
struct berval dn, ndn;
cb.sc_private = &gs;
- gs.prevcb = op->o_callback;
+ cb.sc_next = op->o_callback;
if (op->ors_tlimit) {
stoptime = slap_get_time () + op->ors_tlimit;
break;
}
- op->o_callback = gs.prevcb;
+ op->o_callback = cb.sc_next;
rs->sr_err = gs.err;
rs->sr_matched = gs.matched;
rs->sr_ref = gs.refs;
slap_overinst *on = oi->oi_list;
int rc = SLAP_CB_CONTINUE;
BackendDB *be = op->o_bd, db = *op->o_bd;
- slap_callback *sc = op->o_callback->sc_private;
- slap_callback *s0 = op->o_callback;
op->o_bd = &db;
- op->o_callback = sc;
for (; on; on=on->on_next ) {
if ( on->on_response ) {
db.bd_info = (BackendInfo *)on;
if ( rc != SLAP_CB_CONTINUE ) break;
}
}
- if ( sc && (rc == SLAP_CB_CONTINUE) ) {
- rc = sc->sc_response( op, rs );
- }
op->o_bd = be;
- op->o_callback = s0;
return rc;
}
slap_overinst *on = oi->oi_list;
BI_op_bind **func;
BackendDB *be = op->o_bd, db = *op->o_bd;
- slap_callback cb = {over_back_response, NULL};
+ slap_callback cb = {NULL, over_back_response, NULL, NULL};
int rc = SLAP_CB_CONTINUE;
op->o_bd = &db;
- cb.sc_private = op->o_callback;
+ cb.sc_next = op->o_callback;
op->o_callback = &cb;
for (; on; on=on->on_next ) {
if ( rc == SLAP_CB_CONTINUE ) {
rc = LDAP_UNWILLING_TO_PERFORM;
}
- op->o_callback = cb.sc_private;
+ op->o_callback = cb.sc_next;
return rc;
}
SlapReply sreply = {REP_RESULT};
- slap_callback cb = { slap_null_cb, NULL };
+ slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
attr = e->e_attrs;
e->e_attrs = NULL;
char filter_str[64];
Filter filter = {LDAP_FILTER_EQUALITY};
SlapReply sreply = {REP_RESULT};
- slap_callback cb = { remove_func, NULL };
+ slap_callback cb = { NULL, remove_func, NULL, NULL };
sreply.sr_entry = NULL;
sreply.sr_nentries = 0;
struct search_info {
slap_overinst *on;
- slap_callback *prev;
Query query;
int template_id;
int max;
op->o_tmpfree(op->ors_attrs, op->o_tmpmemctx);
add_filter_attrs(op, &op->ors_attrs, query.attrs, filter_attrs);
cb = op->o_tmpalloc( sizeof(*cb) + sizeof(*si), op->o_tmpmemctx);
+ cb->sc_next = op->o_callback;
cb->sc_response = proxy_cache_response;
+ cb->sc_cleanup = NULL;
cb->sc_private = (cb+1);
si = cb->sc_private;
si->on = on;
- si->prev = op->o_callback;
si->query = query;
si->template_id = template_id;
si->max = cm->num_entries_limit ;
dn, ndn, hash, vals[2], tmpbv, *rsp = NULL;
Modifications ml, **modtail;
Operation op2;
- slap_callback cb = { slap_null_cb, NULL };
+ slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) == 0 );
int rc;
long bytes;
- if (op->o_callback && op->o_callback->sc_response) {
- rc = op->o_callback->sc_response( op, rs );
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ for ( ; op->o_callback; ) {
+ if ( op->o_callback->sc_response ) {
+ rc = op->o_callback->sc_response( op, rs );
+ if ( rc != SLAP_CB_CONTINUE ) break;
+ }
+ op->o_callback = op->o_callback->sc_next;
+ }
+ op->o_callback = sc;
if ( rc != SLAP_CB_CONTINUE ) goto cleanup;
}
cleanup:;
if ( rs->sr_matched && rs->sr_flags & REP_MATCHED_MUSTBEFREED ) {
- free( rs->sr_matched );
+ free( (char *)rs->sr_matched );
rs->sr_matched = NULL;
}
+ 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;
}
char **e_flags = NULL;
rs->sr_type = REP_SEARCH;
- if (op->o_callback && op->o_callback->sc_response) {
- rc = op->o_callback->sc_response( op, rs );
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ for ( ; op->o_callback; ) {
+ if ( op->o_callback->sc_response ) {
+ rc = op->o_callback->sc_response( op, rs );
+ if ( rc != SLAP_CB_CONTINUE ) break;
+ }
+ op->o_callback = op->o_callback->sc_next;
+ }
+ op->o_callback = sc;
if ( rc != SLAP_CB_CONTINUE ) goto error_return;
}
rc = 0;
error_return:;
+ /* 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
+ * should set it back so that the cleanup functions know
+ * what they're doing.
+ */
if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH
&& rs->sr_entry
&& (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 );
}
AttributeDescription *ad_entry = slap_schema.si_ad_entry;
rs->sr_type = REP_SEARCHREF;
- if (op->o_callback && op->o_callback->sc_response) {
- rc = op->o_callback->sc_response( op, rs );
- if ( rc != SLAP_CB_CONTINUE ) return rc;
+ if (op->o_callback) {
+ slap_callback *sc = op->o_callback;
+ for ( ; op->o_callback; ) {
+ if ( op->o_callback->sc_response ) {
+ rc = op->o_callback->sc_response( op, rs );
+ if ( rc != SLAP_CB_CONTINUE ) break;
+ }
+ op->o_callback = op->o_callback->sc_next;
+ }
+ op->o_callback = sc;
+ if ( rc != SLAP_CB_CONTINUE ) goto rel;
}
#ifdef NEW_LOGGING
"send_search_reference: access to entry not allowed\n",
0, 0, 0 );
#endif
- return 1;
+ rc = 1;
+ goto rel;
}
if ( rs->sr_entry && ! access_allowed( op, rs->sr_entry,
"to reference not allowed\n",
0, 0, 0 );
#endif
- return 1;
+ rc = 1;
+ goto rel;
}
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
"send_search_reference: domainScope control in (%s)\n",
rs->sr_entry->e_dn, 0, 0 );
#endif
- return 0;
+ rc = 0;
+ goto rel;
}
#endif
"send_search_reference: null ref in (%s)\n",
rs->sr_entry ? rs->sr_entry->e_dn : "(null)", 0, 0 );
#endif
- return 1;
+ rc = 1;
+ goto rel;
}
if( op->o_protocol < LDAP_VERSION3 ) {
+ rc = 0;
/* save the references for the result */
if( rs->sr_ref[0].bv_val != NULL ) {
if( value_add( &rs->sr_v2ref, rs->sr_ref ) )
- return LDAP_OTHER;
+ rc = LDAP_OTHER;
}
- return 0;
+ goto rel;
}
#ifdef LDAP_CONNECTIONLESS
#endif
ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode DN error" );
- return rc;
+ goto rel;
}
#ifdef LDAP_CONNECTIONLESS
Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n", 0, 0, 0 );
#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->sc_cleanup ) {
+ op->o_callback->sc_cleanup( op, rs );
+ }
+ }
+ op->o_callback = sc;
+ }
return rc;
}
}
if (doit) {
- slap_callback cb = { sasl_ap_lookup, NULL };
+ slap_callback cb = { NULL, sasl_ap_lookup, NULL, NULL };
cb.sc_private = &sl;
Connection *conn = NULL;
const struct propval *pr;
Modifications *modlist = NULL, **modtail = &modlist, *mod;
- slap_callback cb = { slap_null_cb, NULL };
+ slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
char textbuf[SLAP_TEXT_BUFLEN];
const char *text;
size_t textlen = sizeof(textbuf);
op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
if ( op.o_bd && op.o_bd->be_search ) {
- slap_callback cb = { sasl_cb_checkpass, NULL };
+ slap_callback cb = { NULL, sasl_cb_checkpass, NULL, NULL };
SlapReply rs = {REP_RESULT};
ci.cred.bv_val = (char *)pass;
int rc;
regex_t reg;
smatch_info sm;
- slap_callback cb = { sasl_sc_smatch, NULL };
+ slap_callback cb = { NULL, sasl_sc_smatch, NULL, NULL };
Operation op = {0};
SlapReply rs = {REP_RESULT};
struct berval *saslname, struct berval *sasldn )
{
int rc;
- slap_callback cb = { sasl_sc_sasl2dn, NULL };
+ slap_callback cb = { NULL, sasl_sc_sasl2dn, NULL, NULL };
Operation op = {0};
SlapReply rs = {REP_RESULT};
struct berval regout = { 0, NULL };
typedef int (slap_response)( struct slap_op *, struct slap_rep * );
typedef struct slap_callback {
+ struct slap_callback *sc_next;
slap_response *sc_response;
+ slap_response *sc_cleanup;
void *sc_private;
} slap_callback;
int rc, err, i;
ber_len_t len;
- slap_callback cb;
-
int rc_efree;
struct berval *psub;
Debug( LDAP_DEBUG_TRACE, "=>do_syncrep2\n", 0, 0, 0 );
#endif
- op->o_callback = &cb;
-
psub = &si->si_be->be_nsuffix[0];
slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie );
)
{
Backend *be = op->o_bd;
- slap_callback cb;
+ slap_callback cb = { NULL };
struct berval *syncuuid_bv = NULL;
struct berval syncUUID_strrep = { 0, NULL };
)
{
Backend* be = op->o_bd;
- slap_callback cb;
+ slap_callback cb = { NULL };
SlapReply rs = {REP_RESULT};
struct nonpresent_entry *np_list, *np_prev;
)
{
Backend *be = op->o_bd;
- slap_callback cb;
+ slap_callback cb = { NULL };
Attribute *a;
int rc;
int suffrdns;
struct berval slap_syncrepl_dn_bv = BER_BVNULL;
struct berval slap_syncrepl_cn_bv = BER_BVNULL;
- slap_callback cb;
+ slap_callback cb = { NULL };
SlapReply rs = {REP_RESULT};
slap_sync_cookie_free( &si->si_syncCookie, 0 );