]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
fix typo
[openldap] / servers / slapd / syncrepl.c
index f430c7ea250cd32ddc48a33bd0d6eb82770d311b..a9214532946dc2489b74d4d8db3bb1381954d85d 100644 (file)
@@ -473,7 +473,7 @@ check_syncprov(
                        for ( i=0; i<num; i++ ) {
                                if ( ber_bvcmp( &a.a_nvals[i],
                                        &si->si_cookieState->cs_vals[i] )) {
-                                       changed =1;
+                                       changed = 1;
                                        break;
                                }
                        }
@@ -568,15 +568,25 @@ do_syncrep1(
                op->o_tls_ssf = ldap_pvt_tls_get_strength( ssl );
        }
 #endif /* HAVE_TLS */
-       ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &op->o_sasl_ssf );
+       {
+               ber_len_t ssf; /* ITS#5403, 3864 LDAP_OPT_X_SASL_SSF probably ought
+                                                 to use sasl_ssf_t but currently uses ber_len_t */
+               ldap_get_option( si->si_ld, LDAP_OPT_X_SASL_SSF, &ssf );
+               op->o_sasl_ssf = ssf;
+       }
        op->o_ssf = ( op->o_sasl_ssf > op->o_tls_ssf )
                ?  op->o_sasl_ssf : op->o_tls_ssf;
 
        ldap_set_option( si->si_ld, LDAP_OPT_TIMELIMIT, &si->si_tlimit );
 
+       rc = LDAP_DEREF_NEVER;  /* actually could allow DEREF_FINDING */
+       ldap_set_option( si->si_ld, LDAP_OPT_DEREF, &rc );
+
        si->si_syncCookie.rid = si->si_rid;
-       si->si_syncCookie.sid = SLAP_SINGLE_SHADOW( si->si_be ) ? -1 :
-               slap_serverID;
+
+       /* whenever there are multiple data sources possible, advertise sid */
+       si->si_syncCookie.sid = ( SLAP_MULTIMASTER( si->si_be ) || si->si_be != si->si_wbe ) ?
+               slap_serverID : -1;
 
        /* We've just started up, or the remote server hasn't sent us
         * any meaningful state.
@@ -682,8 +692,8 @@ compare_csns( struct sync_cookie *sc1, struct sync_cookie *sc2, int *which )
                return -1;
        }
 
-       for (i=0; i<sc1->numcsns; i++) {
-               for (j=0; j<sc2->numcsns; j++) {
+       for (j=0; j<sc2->numcsns; j++) {
+               for (i=0; i<sc1->numcsns; i++) {
                        if ( sc1->sids[i] != sc2->sids[j] )
                                continue;
                        value_match( &match, slap_schema.si_ad_entryCSN,
@@ -696,6 +706,11 @@ compare_csns( struct sync_cookie *sc1, struct sync_cookie *sc2, int *which )
                        }
                        break;
                }
+               if ( i == sc1->numcsns ) {
+                       /* sc2 has a sid sc1 lacks */
+                       *which = j;
+                       return -1;
+               }
        }
        return match;
 }
@@ -899,6 +914,11 @@ do_syncrep2(
                                rc = err;
                                goto done;
                        }
+                       if ( err ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "do_syncrep2: %s LDAP_RES_SEARCH_RESULT (%d) %s\n",
+                                       si->si_ridtxt, err, ldap_err2string( err ) );
+                       }
                        if ( rctrls ) {
                                rctrlp = *rctrls;
                                ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER );
@@ -1235,7 +1255,8 @@ do_syncrepl(
         *
         * Typically there is a single syncprov mastering the entire
         * glued tree. In that case, our contextCSN updates should
-        * go to the master DB.
+        * go to the master DB. But if there is no syncprov on the
+        * master DB, then nothing special is needed here.
         *
         * Alternatively, there may be individual syncprov overlays
         * on each glued branch. In that case, each syncprov only
@@ -1244,7 +1265,11 @@ do_syncrepl(
         */
        if ( !si->si_wbe ) {
                if ( SLAP_GLUE_SUBORDINATE( be ) && !overlay_is_inst( be, "syncprov" )) {
-                       si->si_wbe = select_backend( &be->be_nsuffix[0], 1 );
+                       BackendDB * top_be = select_backend( &be->be_nsuffix[0], 1 );
+                       if ( overlay_is_inst( top_be, "syncprov" ))
+                               si->si_wbe = select_backend( &be->be_nsuffix[0], 1 );
+                       else
+                               si->si_wbe = be;
                } else {
                        si->si_wbe = be;
                }
@@ -2426,8 +2451,9 @@ syncrepl_del_nonpresent(
                                sc->numcsns * sizeof(AttributeAssertion), op->o_tmpmemctx );
                        f = cf;
                        f->f_choice = LDAP_FILTER_AND;
-                       f->f_and = ++f;
-                       of = f;
+                       f->f_next = NULL;
+                       f->f_and = f+1;
+                       of = f->f_and;
                        for ( i=0; i<sc->numcsns; i++ ) {
                                f = of;
                                f->f_choice = LDAP_FILTER_LE;
@@ -2720,6 +2746,7 @@ syncrepl_updateCookie(
        mod.sml_op = LDAP_MOD_REPLACE;
        mod.sml_desc = slap_schema.si_ad_contextCSN;
        mod.sml_type = mod.sml_desc->ad_cname;
+       mod.sml_flags = SLAP_MOD_INTERNAL;
        mod.sml_nvalues = NULL;
        mod.sml_next = NULL;
 
@@ -2743,8 +2770,13 @@ syncrepl_updateCookie(
                        if ( memcmp( syncCookie->ctxcsn[i].bv_val,
                                si->si_cookieState->cs_vals[j].bv_val, len ) > 0 ) {
                                mod.sml_values[j] = syncCookie->ctxcsn[i];
-                               if ( BER_BVISNULL( &first ))
+                               if ( BER_BVISNULL( &first ) ) {
                                        first = syncCookie->ctxcsn[i];
+
+                               } else if ( memcmp( syncCookie->ctxcsn[i].bv_val, first.bv_val, first.bv_len ) > 0 )
+                               {
+                                       first = syncCookie->ctxcsn[i];
+                               }
                        }
                        break;
                }
@@ -2754,8 +2786,12 @@ syncrepl_updateCookie(
                                ( mod.sml_numvals+2 )*sizeof(struct berval), op->o_tmpmemctx );
                        mod.sml_values[mod.sml_numvals++] = syncCookie->ctxcsn[i];
                        BER_BVZERO( &mod.sml_values[mod.sml_numvals] );
-                       if ( BER_BVISNULL( &first ))
+                       if ( BER_BVISNULL( &first ) ) {
                                first = syncCookie->ctxcsn[i];
+                       } else if ( memcmp( syncCookie->ctxcsn[i].bv_val, first.bv_val, first.bv_len ) > 0 )
+                       {
+                               first = syncCookie->ctxcsn[i];
+                       }
                }
        }
        /* Should never happen, ITS#5065 */
@@ -2864,6 +2900,14 @@ attr_cmp( Operation *op, Attribute *old, Attribute *new,
                        }
                }
 
+               /* Don't delete/add an objectClass, always use the replace op.
+                * 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.
+                */
+               if ( nn && no < o && old->a_desc == slap_schema.si_ad_objectClass )
+                       no = o;
+
                i = j;
                /* all old values were deleted, just use the replace op */
                if ( no == o ) {