]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/syncprov.c
check for ee == NULL
[openldap] / servers / slapd / overlays / syncprov.c
index ed68e77dc7aa3cc5f9bed9220619b828a9881e30..9cae2c53dc3212cf2ba6ddad9d467be00bf67b58 100644 (file)
@@ -585,11 +585,7 @@ syncprov_findcsn( Operation *op, find_csn_t mode )
        char cbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
        struct berval maxcsn;
        Filter cf;
-#ifdef LDAP_COMP_MATCH
-       AttributeAssertion eq = { NULL, BER_BVNULL, NULL };
-#else
-       AttributeAssertion eq = { NULL, BER_BVNULL };
-#endif
+       AttributeAssertion eq = ATTRIBUTEASSERTION_INIT;
        fpres_cookie pcookie;
        sync_control *srs = NULL;
        struct slap_limits_set fc_limits;
@@ -659,6 +655,7 @@ again:
                } else {
                        cf.f_choice = LDAP_FILTER_LE;
                        fop.ors_limit = &fc_limits;
+                       memset( &fc_limits, 0, sizeof( fc_limits ));
                        fc_limits.lms_s_unchecked = 1;
                        fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
                                cf.f_av_value.bv_val );
@@ -896,15 +893,15 @@ syncprov_qtask( void *ctx, void *arg )
        BackendDB be;
        int rc;
 
-       op = (Operation *) &opbuf;
+       op = &opbuf.ob_op;
        *op = *so->s_op;
-       op->o_hdr = (Opheader *)(op+1);
-       op->o_controls = (void **)(op->o_hdr+1);
-       memset( op->o_controls, 0, SLAP_MAX_CIDS * sizeof(void *));
+       op->o_hdr = &opbuf.ob_hdr;
+       op->o_controls = opbuf.ob_controls;
+       memset( op->o_controls, 0, sizeof(opbuf.ob_controls) );
 
        *op->o_hdr = *so->s_op->o_hdr;
 
-       op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx);
+       op->o_tmpmemctx = slap_sl_mem_create(SLAP_SLAB_SIZE, SLAP_SLAB_STACK, ctx, 1);
        op->o_tmpmfuncs = &slap_sl_mfuncs;
        op->o_threadctx = ctx;
 
@@ -1030,7 +1027,7 @@ syncprov_drop_psearch( syncops *so, int lock )
                        ldap_pvt_thread_mutex_lock( &so->s_op->o_conn->c_mutex );
                so->s_op->o_conn->c_n_ops_executing--;
                so->s_op->o_conn->c_n_ops_completed++;
-               LDAP_STAILQ_REMOVE( &so->s_op->o_conn->c_ops, so->s_op, slap_op,
+               LDAP_STAILQ_REMOVE( &so->s_op->o_conn->c_ops, so->s_op, Operation,
                        o_next );
                if ( lock )
                        ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex );
@@ -1220,9 +1217,11 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit )
        ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
 
        if ( op->o_tag != LDAP_REQ_ADD && e ) {
-               op->o_bd->bd_info = (BackendInfo *)on->on_info;
-               be_entry_release_rw( op, e, 0 );
-               op->o_bd->bd_info = (BackendInfo *)on;
+               if ( !SLAP_ISOVERLAY( op->o_bd )) {
+                       op->o_bd = &db;
+               }
+               overlay_entry_release_ov( op, e, 0, on );
+               op->o_bd = b0;
        }
        if ( freefdn ) {
                op->o_tmpfree( fc.fdn->bv_val, op->o_tmpmemctx );
@@ -1282,12 +1281,13 @@ syncprov_op_cleanup( Operation *op, SlapReply *rs )
 static void
 syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
 {
-    syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
+       syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
        Modifications mod;
        Operation opm;
        SlapReply rsm = { 0 };
        slap_callback cb = {0};
 
+       mod.sml_numvals = si->si_numcsns;
        mod.sml_values = si->si_ctxcsn;
        mod.sml_nvalues = NULL;
        mod.sml_desc = slap_schema.si_ad_contextCSN;
@@ -1305,10 +1305,12 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
        opm.o_req_ndn = op->o_bd->be_nsuffix[0];
        opm.o_bd->bd_info = on->on_info->oi_orig;
        opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;
+       opm.o_no_schema_check = 1;
        opm.o_bd->be_modify( &opm, &rsm );
        if ( mod.sml_next != NULL ) {
                slap_mods_free( mod.sml_next, 1 );
        }
+       opm.orm_no_opattrs = 0;
 }
 
 static void
@@ -1478,11 +1480,7 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
                SlapReply frs = { REP_RESULT };
                int rc;
                Filter mf, af;
-#ifdef LDAP_COMP_MATCH
-               AttributeAssertion eq = { NULL, BER_BVNULL, NULL };
-#else
-               AttributeAssertion eq;
-#endif
+               AttributeAssertion eq = ATTRIBUTEASSERTION_INIT;
                slap_callback cb = {0};
 
                fop = *op;
@@ -1682,10 +1680,10 @@ syncprov_op_compare( Operation *op, SlapReply *rs )
 
                rs->sr_err = LDAP_COMPARE_FALSE;
 
-               if ( value_find_ex( op->oq_compare.rs_ava->aa_desc,
+               if ( attr_valfind( &a,
                        SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
                                SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
-                               a.a_nvals, &op->oq_compare.rs_ava->aa_value, op->o_tmpmemctx ) == 0 )
+                               &op->oq_compare.rs_ava->aa_value, NULL, op->o_tmpmemctx ) == 0 )
                {
                        rs->sr_err = LDAP_COMPARE_TRUE;
                }
@@ -1808,9 +1806,17 @@ syncprov_search_cleanup( Operation *op, SlapReply *rs )
        return 0;
 }
 
+typedef struct SyncOperationBuffer {
+       Operation               sob_op;
+       Opheader                sob_hdr;
+       AttributeName   sob_extra;      /* not always present */
+       /* Further data allocated here */
+} SyncOperationBuffer;
+
 static void
 syncprov_detach_op( Operation *op, syncops *so, slap_overinst *on )
 {
+       SyncOperationBuffer *sopbuf2;
        Operation *op2;
        int i, alen = 0;
        size_t size;
@@ -1822,14 +1828,15 @@ syncprov_detach_op( Operation *op, syncops *so, slap_overinst *on )
                alen += op->ors_attrs[i].an_name.bv_len + 1;
        }
        /* Make a new copy of the operation */
-       size = sizeof(Operation) + sizeof(Opheader) +
+       size = offsetof( SyncOperationBuffer, sob_extra ) +
                (i ? ( (i+1) * sizeof(AttributeName) + alen) : 0) +
                op->o_req_dn.bv_len + 1 +
                op->o_req_ndn.bv_len + 1 +
                op->o_ndn.bv_len + 1 +
                so->s_filterstr.bv_len + 1;
-       op2 = (Operation *)ch_calloc( 1, size );
-       op2->o_hdr = (Opheader *)(op2+1);
+       sopbuf2 = ch_calloc( 1, size );
+       op2 = &sopbuf2->sob_op;
+       op2->o_hdr = &sopbuf2->sob_hdr;
 
        /* Copy the fields we care about explicitly, leave the rest alone */
        *op2->o_hdr = *op->o_hdr;
@@ -1839,18 +1846,18 @@ syncprov_detach_op( Operation *op, syncops *so, slap_overinst *on )
        op2->o_request = op->o_request;
        op2->o_private = on;
 
+       ptr = (char *) sopbuf2 + offsetof( SyncOperationBuffer, sob_extra );
        if ( i ) {
-               op2->ors_attrs = (AttributeName *)(op2->o_hdr + 1);
-               ptr = (char *)(op2->ors_attrs+i+1);
+               op2->ors_attrs = (AttributeName *) ptr;
+               ptr = (char *) &op2->ors_attrs[i+1];
                for (i=0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++) {
                        op2->ors_attrs[i] = op->ors_attrs[i];
                        op2->ors_attrs[i].an_name.bv_val = ptr;
                        ptr = lutil_strcopy( ptr, op->ors_attrs[i].an_name.bv_val ) + 1;
                }
                BER_BVZERO( &op2->ors_attrs[i].an_name );
-       } else {
-               ptr = (char *)(op2->o_hdr + 1);
        }
+
        op2->o_authz = op->o_authz;
        op2->o_ndn.bv_val = ptr;
        ptr = lutil_strcopy(ptr, op->o_ndn.bv_val) + 1;
@@ -2179,6 +2186,8 @@ no_change:                nochange = 1;
                        /* No, so a reload is required */
                        /* the 2.2 consumer doesn't send this hint */
                        if ( si->si_usehint && srs->sr_rhint == 0 ) {
+                               if ( ctxcsn )
+                                       ber_bvarray_free_x( ctxcsn, op->o_tmpmemctx );
                                send_ldap_error( op, rs, LDAP_SYNC_REFRESH_REQUIRED, "sync cookie is stale" );
                                return rs->sr_err;
                        }
@@ -2187,6 +2196,8 @@ no_change:                nochange = 1;
                        /* If changed and doing Present lookup, send Present UUIDs */
                        if ( do_present && syncprov_findcsn( op, FIND_PRESENT ) !=
                                LDAP_SUCCESS ) {
+                               if ( ctxcsn )
+                                       ber_bvarray_free_x( ctxcsn, op->o_tmpmemctx );
                                send_ldap_result( op, rs );
                                return rs->sr_err;
                        }
@@ -2290,10 +2301,15 @@ syncprov_operational(
                                                a = attr_find( rs->sr_entry->e_attrs,
                                                        slap_schema.si_ad_contextCSN );
                                        }
-                                       free( a->a_vals );
+                                       if ( a->a_nvals != a->a_vals ) {
+                                               ber_bvarray_free( a->a_nvals );
+                                       }
+                                       a->a_nvals = NULL;
+                                       ber_bvarray_free( a->a_vals );
+                                       a->a_vals = NULL;
+                                       a->a_numvals = 0;
                                }
-                               ber_bvarray_dup_x( &a->a_vals, si->si_ctxcsn, NULL );
-                               a->a_nvals = a->a_vals;
+                               attr_valadd( a, si->si_ctxcsn, si->si_ctxcsn, si->si_numcsns );
                        }
                        ldap_pvt_thread_rdwr_runlock( &si->si_csn_rwlock );
                }
@@ -2352,9 +2368,9 @@ sp_cf_gen(ConfigArgs *c)
                case SP_CHKPT:
                        if ( si->si_chkops || si->si_chktime ) {
                                struct berval bv;
-                               bv.bv_len = sprintf( c->msg, "%d %d",
+                               bv.bv_len = sprintf( c->cr_msg, "%d %d",
                                        si->si_chkops, si->si_chktime );
-                               bv.bv_val = c->msg;
+                               bv.bv_val = c->cr_msg;
                                value_add_one( &c->rvalue_vals, &bv );
                        } else {
                                rc = 1;
@@ -2413,31 +2429,31 @@ sp_cf_gen(ConfigArgs *c)
        switch ( c->type ) {
        case SP_CHKPT:
                if ( lutil_atoi( &si->si_chkops, c->argv[1] ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ), "%s unable to parse checkpoint ops # \"%s\"",
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s unable to parse checkpoint ops # \"%s\"",
                                c->argv[0], c->argv[1] );
                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
-                               "%s: %s\n", c->log, c->msg, 0 );
+                               "%s: %s\n", c->log, c->cr_msg, 0 );
                        return ARG_BAD_CONF;
                }
                if ( si->si_chkops <= 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ), "%s invalid checkpoint ops # \"%d\"",
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s invalid checkpoint ops # \"%d\"",
                                c->argv[0], si->si_chkops );
                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
-                               "%s: %s\n", c->log, c->msg, 0 );
+                               "%s: %s\n", c->log, c->cr_msg, 0 );
                        return ARG_BAD_CONF;
                }
                if ( lutil_atoi( &si->si_chktime, c->argv[2] ) != 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ), "%s unable to parse checkpoint time \"%s\"",
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s unable to parse checkpoint time \"%s\"",
                                c->argv[0], c->argv[1] );
                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
-                               "%s: %s\n", c->log, c->msg, 0 );
+                               "%s: %s\n", c->log, c->cr_msg, 0 );
                        return ARG_BAD_CONF;
                }
                if ( si->si_chktime <= 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ), "%s invalid checkpoint time \"%d\"",
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s invalid checkpoint time \"%d\"",
                                c->argv[0], si->si_chkops );
                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
-                               "%s: %s\n", c->log, c->msg, 0 );
+                               "%s: %s\n", c->log, c->cr_msg, 0 );
                        return ARG_BAD_CONF;
                }
                si->si_chktime *= 60;
@@ -2447,10 +2463,10 @@ sp_cf_gen(ConfigArgs *c)
                int size = c->value_int;
 
                if ( size < 0 ) {
-                       snprintf( c->msg, sizeof( c->msg ), "%s size %d is negative",
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s size %d is negative",
                                c->argv[0], size );
                        Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
-                               "%s: %s\n", c->log, c->msg, 0 );
+                               "%s: %s\n", c->log, c->cr_msg, 0 );
                        return ARG_BAD_CONF;
                }
                sl = si->si_logs;
@@ -2494,15 +2510,16 @@ syncprov_db_otask(
  */
 static int
 syncprov_db_open(
-    BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
        slap_overinst   *on = (slap_overinst *) be->bd_info;
        syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
 
        Connection conn = { 0 };
-       OperationBuffer opbuf = { 0 };
-       Operation *op = (Operation *) &opbuf;
+       OperationBuffer opbuf;
+       Operation *op;
        Entry *e = NULL;
        Attribute *a;
        int rc;
@@ -2524,7 +2541,8 @@ syncprov_db_open(
        }
 
        thrctx = ldap_pvt_thread_pool_context();
-       connection_fake_init( &conn, op, thrctx );
+       connection_fake_init( &conn, &opbuf, thrctx );
+       op = &opbuf.ob_op;
        op->o_bd = be;
        op->o_dn = be->be_rootdn;
        op->o_ndn = be->be_rootndn;
@@ -2537,11 +2555,9 @@ syncprov_db_open(
 
                a = attr_find( e->e_attrs, slap_schema.si_ad_contextCSN );
                if ( a ) {
-                       int i;
                        ber_bvarray_dup_x( &si->si_ctxcsn, a->a_vals, NULL );
-                       for ( i=0; !BER_BVISEMPTY( &a->a_vals[i] ); i++ );
-                       si->si_numcsns = i;
-                       si->si_sids = slap_parse_csn_sids( si->si_ctxcsn, i );
+                       si->si_numcsns = a->a_numvals;
+                       si->si_sids = slap_parse_csn_sids( si->si_ctxcsn, a->a_numvals, NULL );
                }
                overlay_entry_release_ov( op, e, 0, on );
                if ( si->si_ctxcsn ) {
@@ -2586,7 +2602,8 @@ out:
  */
 static int
 syncprov_db_close(
-    BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
     slap_overinst   *on = (slap_overinst *) be->bd_info;
@@ -2596,14 +2613,15 @@ syncprov_db_close(
                return 0;
        }
        if ( si->si_numops ) {
-               Connection conn;
+               Connection conn = {0};
                OperationBuffer opbuf;
-               Operation *op = (Operation *) &opbuf;
+               Operation *op;
                SlapReply rs = {REP_RESULT};
                void *thrctx;
 
                thrctx = ldap_pvt_thread_pool_context();
-               connection_fake_init( &conn, op, thrctx );
+               connection_fake_init( &conn, &opbuf, thrctx );
+               op = &opbuf.ob_op;
                op->o_bd = be;
                op->o_dn = be->be_rootdn;
                op->o_ndn = be->be_rootndn;
@@ -2615,7 +2633,8 @@ syncprov_db_close(
 
 static int
 syncprov_db_init(
-       BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
@@ -2647,7 +2666,8 @@ syncprov_db_init(
 
 static int
 syncprov_db_destroy(
-       BackendDB *be
+       BackendDB *be,
+       ConfigReply *cr
 )
 {
        slap_overinst   *on = (slap_overinst *)be->bd_info;
@@ -2665,6 +2685,10 @@ syncprov_db_destroy(
                                
                        ch_free( si->si_logs );
                }
+               if ( si->si_ctxcsn )
+                       ber_bvarray_free( si->si_ctxcsn );
+               if ( si->si_sids )
+                       ch_free( si->si_sids );
                ldap_pvt_thread_mutex_destroy( &si->si_mods_mutex );
                ldap_pvt_thread_mutex_destroy( &si->si_ops_mutex );
                ldap_pvt_thread_rdwr_destroy( &si->si_csn_rwlock );
@@ -2698,8 +2722,13 @@ static int syncprov_parseCtrl (
                return LDAP_PROTOCOL_ERROR;
        }
 
+       if ( BER_BVISNULL( &ctrl->ldctl_value ) ) {
+               rs->sr_text = "Sync control value is absent";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
        if ( BER_BVISEMPTY( &ctrl->ldctl_value ) ) {
-               rs->sr_text = "Sync control value is empty (or absent)";
+               rs->sr_text = "Sync control value is empty";
                return LDAP_PROTOCOL_ERROR;
        }
 
@@ -2757,8 +2786,8 @@ static int syncprov_parseCtrl (
        sr->sr_rhint = rhint;
        if (!BER_BVISNULL(&cookie)) {
                ber_dupbv_x( &sr->sr_state.octet_str, &cookie, op->o_tmpmemctx );
-               slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx );
-               if ( sr->sr_state.rid == -1 ) {
+               if ( slap_parse_sync_cookie( &sr->sr_state, op->o_tmpmemctx ) ||
+                       sr->sr_state.rid == -1 ) {
                        rs->sr_text = "Sync control : cookie parsing error";
                        return LDAP_PROTOCOL_ERROR;
                }