]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
ITS#5710 fix stupid updateCookie hack, use explicit o_dont_replicate flag
[openldap] / servers / slapd / syncrepl.c
index 30f4c63dc502236652770ef193c4fe31e4c2b2c8..199c882c9361943af772d30c4c0d0413c863f0c1 100644 (file)
@@ -407,7 +407,7 @@ ldap_sync_search(
                        abs(si->si_type), rhint );
        }
 
-       if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 ) ) == LBER_ERROR ) {
+       if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 ) ) == -1 ) {
                ber_free_buf( ber );
                return rc;
        }
@@ -1204,7 +1204,7 @@ do_syncrepl(
        OperationBuffer opbuf;
        Operation *op;
        int rc = LDAP_SUCCESS;
-       int dostop = 0, do_setup = 0;
+       int dostop = 0;
        ber_socket_t s;
        int i, defer = 1, fail = 0;
        Backend *be;
@@ -1214,9 +1214,8 @@ do_syncrepl(
        if ( si == NULL )
                return NULL;
 
-       /* There must never be more than one instance active */
-       if ( ldap_pvt_thread_mutex_trylock( &si->si_mutex ))
-               return NULL;
+       /* There will never be more than one instance active */
+       ldap_pvt_thread_mutex_lock( &si->si_mutex );
 
        switch( abs( si->si_type ) ) {
        case LDAP_SYNC_REFRESH_ONLY:
@@ -1320,9 +1319,8 @@ reload:
                                if ( rc == LDAP_SUCCESS ) {
                                        if ( si->si_conn ) {
                                                connection_client_enable( si->si_conn );
-                                               goto success;
                                        } else {
-                                               do_setup = 1;
+                                               si->si_conn = connection_client_setup( s, do_syncrepl, arg );
                                        } 
                                } else if ( si->si_conn ) {
                                        dostop = 1;
@@ -1354,6 +1352,7 @@ reload:
        if ( rc == SYNC_PAUSED ) {
                rtask->interval.tv_sec = 0;
                ldap_pvt_runqueue_resched( &slapd_rq, rtask, 0 );
+               rtask->interval.tv_sec = si->si_interval;
                rc = 0;
        } else if ( rc == LDAP_SUCCESS ) {
                if ( si->si_type == LDAP_SYNC_REFRESH_ONLY ) {
@@ -1388,11 +1387,6 @@ reload:
        }
 
        ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
-
-       if ( do_setup )
-               si->si_conn = connection_client_setup( s, do_syncrepl, arg );
-
-success:
        ldap_pvt_thread_mutex_unlock( &si->si_mutex );
 
        if ( rc ) {
@@ -2481,7 +2475,7 @@ syncrepl_del_nonpresent(
                        op->o_tmpfree( cf, op->o_tmpmemctx );
                        op->ors_filter = of;
                }
-               if ( op->ors_filter ) filter_free_x( op, op->ors_filter );
+               if ( op->ors_filter ) filter_free_x( op, op->ors_filter, 1 );
 
        }
 
@@ -2739,7 +2733,8 @@ syncrepl_updateCookie(
        Modifications mod;
        struct berval first = BER_BVNULL;
 
-       int rc, i, j, len;
+       int rc, i, j;
+       ber_len_t len;
 
        slap_callback cb = { NULL };
        SlapReply       rs_modify = {REP_RESULT};
@@ -2814,13 +2809,13 @@ syncrepl_updateCookie(
        op->o_req_ndn = op->o_bd->be_nsuffix[0];
 
        /* update contextCSN */
-       op->o_msgid = SLAP_SYNC_UPDATE_MSGID;
+       op->o_dont_replicate = 1;
 
        op->orm_modlist = &mod;
        op->orm_no_opattrs = 1;
        rc = op->o_bd->be_modify( op, &rs_modify );
        op->orm_no_opattrs = 0;
-       op->o_msgid = 0;
+       op->o_dont_replicate = 0;
 
        if ( rs_modify.sr_err == LDAP_SUCCESS ) {
                slap_sync_cookie_free( &si->si_syncCookie, 0 );
@@ -2905,8 +2900,13 @@ attr_cmp( Operation *op, Attribute *old, Attribute *new,
                 * Modify would fail if provider has replaced entry with a new,
                 * and the new explicitly includes a superior of a class that was
                 * only included implicitly in the old entry.  Ref ITS#5517.
+                *
+                * Also use replace op if attr has no equality matching rule.
+                * (ITS#5781)
                 */
-               if ( nn && no < o && old->a_desc == slap_schema.si_ad_objectClass )
+               if ( nn && no < o &&
+                       ( old->a_desc == slap_schema.si_ad_objectClass ||
+                        !old->a_desc->ad_type->sat_equality ))
                        no = o;
 
                i = j;
@@ -3062,7 +3062,8 @@ dn_callback(
                                new = attr_find( dni->new_entry->e_attrs,
                                        slap_schema.si_ad_entryCSN );
                                if ( new && old ) {
-                                       int rc, len = old->a_vals[0].bv_len;
+                                       int rc;
+                                       ber_len_t len = old->a_vals[0].bv_len;
                                        if ( len > new->a_vals[0].bv_len )
                                                len = new->a_vals[0].bv_len;
                                        rc = memcmp( old->a_vals[0].bv_val,
@@ -4082,9 +4083,9 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
 {
        struct berval bc, uri;
        char buf[BUFSIZ*2], *ptr;
+       ber_len_t len;
        int i;
-
-#define WHATSLEFT      ( sizeof( buf ) - ( ptr - buf ) )
+#      define WHATSLEFT        ((ber_len_t) (&buf[sizeof( buf )] - ptr))
 
        BER_BVZERO( bv );
 
@@ -4098,9 +4099,10 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
 
        ptr = buf;
        assert( si->si_rid >= 0 && si->si_rid <= SLAP_SYNC_SID_MAX );
-       ptr += snprintf( ptr, WHATSLEFT, IDSTR "=%03d " PROVIDERSTR "=%s",
+       len = snprintf( ptr, WHATSLEFT, IDSTR "=%03d " PROVIDERSTR "=%s",
                si->si_rid, si->si_bindconf.sb_uri.bv_val );
-       if ( ptr - buf >= sizeof( buf ) ) return;
+       if ( len >= sizeof( buf ) ) return;
+       ptr += len;
        if ( !BER_BVISNULL( &bc ) ) {
                if ( WHATSLEFT <= bc.bv_len ) {
                        free( bc.bv_val );
@@ -4158,8 +4160,8 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
                if ( WHATSLEFT <= STRLENOF( " " ATTRSONLYSTR "=\"" "\"" ) ) return;
                ptr = lutil_strcopy( ptr, " " ATTRSSTR "=\"" );
                old = ptr;
-               /* FIXME: add check for overflow */
                ptr = anlist_unparse( si->si_anlist, ptr, WHATSLEFT );
+               if ( ptr == NULL ) return;
                if ( si->si_allattrs ) {
                        if ( WHATSLEFT <= STRLENOF( ",*\"" ) ) return;
                        if ( old != ptr ) *ptr++ = ',';
@@ -4175,8 +4177,8 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
        if ( si->si_exanlist && !BER_BVISNULL(&si->si_exanlist[0].an_name) ) {
                if ( WHATSLEFT <= STRLENOF( " " EXATTRSSTR "=" ) ) return;
                ptr = lutil_strcopy( ptr, " " EXATTRSSTR "=" );
-               /* FIXME: add check for overflow */
                ptr = anlist_unparse( si->si_exanlist, ptr, WHATSLEFT );
+               if ( ptr == NULL ) return;
        }
        if ( WHATSLEFT <= STRLENOF( " " SCHEMASTR "=" ) + STRLENOF( "off" ) ) return;
        ptr = lutil_strcopy( ptr, " " SCHEMASTR "=" );
@@ -4197,36 +4199,42 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
                dd /= 60;
                hh = dd % 24;
                dd /= 24;
-               ptr = lutil_strcopy( ptr, " " INTERVALSTR "=" );
-               ptr += snprintf( ptr, WHATSLEFT, "%02d:%02d:%02d:%02d", dd, hh, mm, ss );
-               if ( ptr - buf >= sizeof( buf ) ) return;
+               len = snprintf( ptr, WHATSLEFT, " %s=%02d:%02d:%02d:%02d",
+                       INTERVALSTR, dd, hh, mm, ss );
+               if ( len >= WHATSLEFT ) return;
+               ptr += len;
        } else if ( si->si_retryinterval ) {
-               int space=0;
+               const char *space = "";
                if ( WHATSLEFT <= STRLENOF( " " RETRYSTR "=\"" "\"" ) ) return;
                ptr = lutil_strcopy( ptr, " " RETRYSTR "=\"" );
                for (i=0; si->si_retryinterval[i]; i++) {
-                       if ( space ) *ptr++ = ' ';
-                       space = 1;
-                       ptr += snprintf( ptr, WHATSLEFT, "%ld ", (long) si->si_retryinterval[i] );
+                       len = snprintf( ptr, WHATSLEFT, "%s%ld ", space,
+                               (long) si->si_retryinterval[i] );
+                       space = " ";
+                       if ( WHATSLEFT - 1 <= len ) return;
+                       ptr += len;
                        if ( si->si_retrynum_init[i] == RETRYNUM_FOREVER )
                                *ptr++ = '+';
-                       else
-                               ptr += snprintf( ptr, WHATSLEFT, "%d", si->si_retrynum_init[i] );
+                       else {
+                               len = snprintf( ptr, WHATSLEFT, "%d", si->si_retrynum_init[i] );
+                               if ( WHATSLEFT <= len ) return;
+                               ptr += len;
+                       }
                }
                if ( WHATSLEFT <= STRLENOF( "\"" ) ) return;
                *ptr++ = '"';
        }
 
        if ( si->si_slimit ) {
-               if ( WHATSLEFT <= STRLENOF( " " SLIMITSTR "=" ) ) return;
-               ptr = lutil_strcopy( ptr, " " SLIMITSTR "=" );
-               ptr += snprintf( ptr, WHATSLEFT, "%d", si->si_slimit );
+               len = snprintf( ptr, WHATSLEFT, " " SLIMITSTR "=%d", si->si_slimit );
+               if ( WHATSLEFT <= len ) return;
+               ptr += len;
        }
 
        if ( si->si_tlimit ) {
-               if ( WHATSLEFT <= STRLENOF( " " TLIMITSTR "=" ) ) return;
-               ptr = lutil_strcopy( ptr, " " TLIMITSTR "=" );
-               ptr += snprintf( ptr, WHATSLEFT, "%d", si->si_tlimit );
+               len = snprintf( ptr, WHATSLEFT, " " TLIMITSTR "=%d", si->si_tlimit );
+               if ( WHATSLEFT <= len ) return;
+               ptr += len;
        }
 
        if ( si->si_syncdata ) {