]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/syncrepl.c
fix previous commit (ITS#5819)
[openldap] / servers / slapd / syncrepl.c
index b53032a3b7f128a4cb903b4448a03fc0081444c9..a9f9cf66cc8ca86ff031b14efca36a15e7e59fd5 100644 (file)
@@ -1932,7 +1932,6 @@ typedef struct dninfo {
        struct berval dn;
        struct berval ndn;
        int renamed;    /* Was an existing entry renamed? */
-       int delOldRDN;  /* Was old RDN deleted? */
        Modifications **modlist;        /* the modlist we received */
        Modifications *mods;    /* the modlist we compared */
 } dninfo;
@@ -2217,7 +2216,8 @@ retry_add:;
                                op->orr_newSup = NULL;
                                op->orr_nnewSup = NULL;
                        }
-                       op->orr_deleteoldrdn = dni.delOldRDN;
+                       /* Let the modify handler take care of deleting old RDNs */
+                       op->orr_deleteoldrdn = 0;
                        op->orr_modlist = NULL;
                        if ( ( rc = slap_modrdn2mods( op, &rs_modify ) ) ) {
                                goto done;
@@ -2229,39 +2229,9 @@ retry_add:;
                        noldp = op->orr_nnewrdn;
                        ber_dupbv_x( &op->orr_nnewrdn, &noldp, op->o_tmpmemctx );
 
-                       /* Setup opattrs too */
-                       {
-                               static AttributeDescription *nullattr = NULL;
-                               static AttributeDescription **const opattrs[] = {
-                                       &slap_schema.si_ad_entryCSN,
-                                       &slap_schema.si_ad_modifiersName,
-                                       &slap_schema.si_ad_modifyTimestamp,
-                                       &nullattr
-                               };
-                               AttributeDescription *opattr;
-                               Modifications *mod, **modtail, **ml;
-                               int i;
-
-                               for ( mod = op->orr_modlist;
-                                       mod->sml_next;
-                                       mod = mod->sml_next )
-                                       ;
-                               modtail = &mod->sml_next;
-
-                               /* pull mod off incoming modlist, append to orr_modlist */
-                               for ( i = 0; (opattr = *opattrs[i]) != NULL; i++ ) {
-                                       for ( ml = modlist; *ml; ml = &(*ml)->sml_next )
-                                       {
-                                               if ( (*ml)->sml_desc == opattr ) {
-                                                       mod = *ml;
-                                                       *ml = mod->sml_next;
-                                                       mod->sml_next = NULL;
-                                                       *modtail = mod;
-                                                       modtail = &mod->sml_next;
-                                                       break;
-                                               }
-                                       }
-                               }
+                       /* Remove the CSN for now, only propagate the Modify */
+                       if ( syncCSN ) {
+                               slap_graduate_commit_csn( op );
                        }
                        op->o_bd = si->si_wbe;
                        rc = op->o_bd->be_modrdn( op, &rs_modify );
@@ -2273,7 +2243,12 @@ retry_add:;
                                        "syncrepl_entry: %s be_modrdn (%d)\n", 
                                        si->si_ridtxt, rc, 0 );
                        op->o_bd = be;
-                       goto done;
+                       /* Renamed entries still have other mods so just fallthru */
+                       op->o_req_dn = entry->e_name;
+                       op->o_req_ndn = entry->e_nname;
+                       if ( syncCSN ) {
+                               slap_queue_csn( op, syncCSN );
+                       }
                }
                if ( dni.mods ) {
                        op->o_tag = LDAP_REQ_MODIFY;
@@ -2809,13 +2784,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 );
@@ -2900,8 +2875,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;
@@ -3013,39 +2993,32 @@ dn_callback(
                        if ( dni->new_entry ) {
                                Modifications **modtail, **ml;
                                Attribute *old, *new;
+                               struct berval old_rdn, new_rdn;
+                               struct berval old_p, new_p;
                                int is_ctx;
 
                                is_ctx = dn_match( &rs->sr_entry->e_nname,
                                        &op->o_bd->be_nsuffix[0] );
 
                                /* Did the DN change?
+                                * case changes in the parent are ignored,
+                                * we only want to know if the RDN was
+                                * actually changed.
                                 */
-                               if ( !dn_match( &rs->sr_entry->e_name,
-                                               &dni->new_entry->e_name ) )
-                               {
-                                       struct berval oldRDN, oldVal;
-                                       AttributeDescription *ad = NULL;
-                                       Attribute *a;
+                               dnRdn( &rs->sr_entry->e_name, &old_rdn );
+                               dnRdn( &dni->new_entry->e_name, &new_rdn );
+                               dnParent( &rs->sr_entry->e_nname, &old_p );
+                               dnParent( &dni->new_entry->e_nname, &new_p );
 
+                               if ( !dn_match( &old_rdn, &new_rdn ) ||
+                                       ber_bvstrcasecmp( &old_p, &new_p ))
+                               {
                                        dni->renamed = 1;
-                                       /* See if the oldRDN was deleted */
-                                       dnRdn( &rs->sr_entry->e_nname, &oldRDN );
-                                       oldVal.bv_val = strchr(oldRDN.bv_val, '=') + 1;
-                                       oldVal.bv_len = oldRDN.bv_len - ( oldVal.bv_val -
-                                               oldRDN.bv_val );
-                                       oldRDN.bv_len -= oldVal.bv_len + 2;
-                                       slap_bv2ad( &oldRDN, &ad, &rs->sr_text );
-                                       a = attr_find( dni->new_entry->e_attrs, ad );
-                                       if ( !a || attr_valfind( a,
-                                               SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH |
-                                               SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
-                                               SLAP_MR_VALUE_OF_SYNTAX,
-                                               &oldVal, NULL, op->o_tmpmemctx ) != LDAP_SUCCESS )
-                                       {
-                                               dni->delOldRDN = 1;
-                                       }
-                                       /* OK, this was just a modDN, we're done */
-                                       return LDAP_SUCCESS;
+
+                                       /* A ModDN has happened, but other changes may have
+                                        * occurred before we picked it up. So fallthru to
+                                        * regular Modify processing.
+                                        */
                                }
 
                                modtail = &dni->mods;
@@ -3188,12 +3161,12 @@ nonpresent_callback(
                        }
 
                        if ( LogTest( LDAP_DEBUG_SYNC ) ) {
-                               char buf[sizeof("rid=999 not")];
+                               char buf[sizeof("rid=999 non")];
 
                                snprintf( buf, sizeof(buf), "%s %s", si->si_ridtxt,
-                                       present_uuid ? "got" : "not" );
+                                       present_uuid ? "" : "non" );
 
-                               Debug( LDAP_DEBUG_SYNC, "nonpresent_callback: %s UUID %s, dn %s\n",
+                               Debug( LDAP_DEBUG_SYNC, "nonpresent_callback: %spresent UUID %s, dn %s\n",
                                        buf, a ? a->a_vals[0].bv_val : "<missing>", rs->sr_entry->e_name.bv_val );
                        }
 
@@ -4058,9 +4031,6 @@ add_syncrepl(
                        "Config: ** successfully added syncrepl \"%s\"\n",
                        BER_BVISNULL( &si->si_bindconf.sb_uri ) ?
                        "(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 );
-               if ( !si->si_schemachecking ) {
-                       SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
-               }
                if ( c->be->be_syncinfo ) {
                        si->si_cookieState = c->be->be_syncinfo->si_cookieState;
                } else {