]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#3596 - fix callback cleanups
authorHoward Chu <hyc@openldap.org>
Mon, 14 Mar 2005 20:06:24 +0000 (20:06 +0000)
committerHoward Chu <hyc@openldap.org>
Mon, 14 Mar 2005 20:06:24 +0000 (20:06 +0000)
servers/slapd/backover.c
servers/slapd/passwd.c
servers/slapd/result.c

index d710bbe6791a59e00a23b427ed5bb1ced7db72bb..116484710bcc9e380be1e1c792128dc533ae9de3 100644 (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;
index 6c06c0eaf9715ee04035f2418be100a107c9c4ab..028b374ed7e44fddc810f6830d48cb3ce3b584e1 100644 (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;
 }
 
index 89b7b2b113143bb1fb20d4ea5d58621f2a75aa6b..13cb5ccd1e3b249a25f374ed1a53f4f786df3ef8 100644 (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;
        }