]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/syncprov.c
check for NULL backend (ITS#6490)
[openldap] / servers / slapd / overlays / syncprov.c
index 0b751bd8236aadb346d7fef29afa742659beac52..6cb7cfb17df44c83678150a0aad9a98b5c01dcc5 100644 (file)
@@ -783,7 +783,8 @@ syncprov_free_syncop( syncops *so )
        GroupAssertion *ga, *gnext;
 
        ldap_pvt_thread_mutex_lock( &so->s_mutex );
-       if ( --so->s_inuse > 0 ) {
+       /* already being freed, or still in use */
+       if ( !so->s_inuse || --so->s_inuse > 0 ) {
                ldap_pvt_thread_mutex_unlock( &so->s_mutex );
                return;
        }
@@ -853,9 +854,14 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, int mode )
        }
 
        rs.sr_ctrls = ctrls;
+       rs.sr_entry = &e_uuid;
+       if ( mode == LDAP_SYNC_ADD || mode == LDAP_SYNC_MODIFY ) {
+               e_uuid = *opc->se;
+               e_uuid.e_private = NULL;
+       }
+
        switch( mode ) {
        case LDAP_SYNC_ADD:
-               rs.sr_entry = opc->se;
                if ( opc->sreference && so->s_op->o_managedsait <= SLAP_CONTROL_IGNORED ) {
                        rs.sr_ref = get_entry_referrals( op, rs.sr_entry );
                        rs.sr_err = send_search_reference( op, &rs );
@@ -864,7 +870,6 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, int mode )
                }
                /* fallthru */
        case LDAP_SYNC_MODIFY:
-               rs.sr_entry = opc->se;
                rs.sr_attrs = op->ors_attrs;
                rs.sr_err = send_search_entry( op, &rs );
                break;
@@ -872,7 +877,6 @@ syncprov_sendresp( Operation *op, opcookie *opc, syncops *so, int mode )
                e_uuid.e_attrs = NULL;
                e_uuid.e_name = opc->sdn;
                e_uuid.e_nname = opc->sndn;
-               rs.sr_entry = &e_uuid;
                if ( opc->sreference && so->s_op->o_managedsait <= SLAP_CONTROL_IGNORED ) {
                        struct berval bv = BER_BVNULL;
                        rs.sr_ref = &bv;
@@ -928,9 +932,9 @@ syncprov_qplay( Operation *op, syncops *so )
                ldap_pvt_thread_mutex_unlock( &so->s_mutex );
 
                if ( sr->s_mode == LDAP_SYNC_NEW_COOKIE ) {
-                   SlapReply rs = { REP_INTERMEDIATE };
+                       SlapReply rs = { REP_INTERMEDIATE };
 
-                   rc = syncprov_sendinfo( op, &rs, LDAP_TAG_SYNC_NEW_COOKIE,
+                       rc = syncprov_sendinfo( op, &rs, LDAP_TAG_SYNC_NEW_COOKIE,
                                &sr->s_csn, 0, NULL, 0 );
                } else {
                        opc.sdn = sr->s_dn;
@@ -942,11 +946,11 @@ syncprov_qplay( Operation *op, syncops *so )
 
                        rc = syncprov_sendresp( op, &opc, so, sr->s_mode );
 
-                       if ( opc.se ) {
-                               if ( !dec_mutexint( opc.se->e_private )) {
-                                       opc.se->e_private = NULL;
-                                       entry_free ( opc.se );
-                               }
+               }
+               if ( sr->s_e ) {
+                       if ( !dec_mutexint( sr->s_e->e_private )) {
+                               sr->s_e->e_private = NULL;
+                               entry_free ( sr->s_e );
                        }
                }
 
@@ -981,7 +985,6 @@ syncprov_qtask( void *ctx, void *arg )
        Operation *op;
        BackendDB be;
        int rc;
-       OpExtra oex;
 
        op = &opbuf.ob_op;
        *op = *so->s_op;
@@ -1000,11 +1003,6 @@ syncprov_qtask( void *ctx, void *arg )
        be.be_flags |= SLAP_DBFLAG_OVERLAY;
        op->o_bd = &be;
        LDAP_SLIST_FIRST(&op->o_extra) = NULL;
-
-       /* Let syncprov_operational know it's us */
-       oex.oe_key = (void *)syncprov_qtask;
-       LDAP_SLIST_INSERT_HEAD(&op->o_extra, &oex, oe_next);
-
        op->o_callback = NULL;
 
        rc = syncprov_qplay( op, so );
@@ -2476,6 +2474,8 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                                                changed = SS_CHANGED;
                                        else if ( newer > 0 ) {
                                        /* our state is older, tell consumer nothing */
+                                               rs->sr_err = LDAP_SUCCESS;
+bailout:
                                                if ( sop ) {
                                                        syncops **sp = &si->si_ops;
                                                        
@@ -2486,7 +2486,6 @@ syncprov_op_search( Operation *op, SlapReply *rs )
                                                        ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
                                                        ch_free( sop );
                                                }
-                                               rs->sr_err = LDAP_SUCCESS;
                                                rs->sr_ctrls = NULL;
                                                send_ldap_result( op, rs );
                                                return rs->sr_err;
@@ -2541,8 +2540,9 @@ no_change:                if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
                                        ber_bvarray_free_x( ctxcsn, op->o_tmpmemctx );
                                if ( sids )
                                        op->o_tmpfree( sids, op->o_tmpmemctx );
-                               send_ldap_error( op, rs, LDAP_SYNC_REFRESH_REQUIRED, "sync cookie is stale" );
-                               return rs->sr_err;
+                               rs->sr_err = LDAP_SYNC_REFRESH_REQUIRED;
+                               rs->sr_text = "sync cookie is stale";
+                               goto bailout;
                        }
                        if ( srs->sr_state.ctxcsn ) {
                                ber_bvarray_free_x( srs->sr_state.ctxcsn, op->o_tmpmemctx );
@@ -2562,8 +2562,7 @@ no_change:                if ( !(op->o_sync_mode & SLAP_SYNC_PERSIST) ) {
                                        ber_bvarray_free_x( ctxcsn, op->o_tmpmemctx );
                                if ( sids )
                                        op->o_tmpfree( sids, op->o_tmpmemctx );
-                               send_ldap_result( op, rs );
-                               return rs->sr_err;
+                               goto bailout;
                        }
                }
        } else {
@@ -2637,13 +2636,6 @@ syncprov_operational(
 {
        slap_overinst           *on = (slap_overinst *)op->o_bd->bd_info;
        syncprov_info_t         *si = (syncprov_info_t *)on->on_bi.bi_private;
-       OpExtra         *oex;
-
-       /* short-circuit, don't want backends handling this */
-       LDAP_SLIST_FOREACH(oex, &op->o_extra, oe_next) {
-               if ( oex->oe_key == (void *)syncprov_qtask )
-                       return LDAP_SUCCESS;
-       }
 
        /* This prevents generating unnecessarily; frontend will strip
         * any statically stored copy.