ITS#5809 fix 1.421, avoid modrdn falling thru to modify unnecessarily

This commit is contained in:
Howard Chu 2008-11-15 23:54:23 +00:00
parent 245bb35eca
commit b7e8411dca

View File

@ -1935,6 +1935,8 @@ typedef struct dninfo {
int delOldRDN; /* Was old RDN deleted? */ int delOldRDN; /* Was old RDN deleted? */
Modifications **modlist; /* the modlist we received */ Modifications **modlist; /* the modlist we received */
Modifications *mods; /* the modlist we compared */ Modifications *mods; /* the modlist we compared */
AttributeDescription *oldDesc; /* for renames */
AttributeDescription *newDesc; /* for renames */
} dninfo; } dninfo;
/* return 1 if inserted, 0 otherwise */ /* return 1 if inserted, 0 otherwise */
@ -2202,6 +2204,7 @@ retry_add:;
op->o_req_ndn = dni.ndn; op->o_req_ndn = dni.ndn;
if ( dni.renamed ) { if ( dni.renamed ) {
struct berval noldp, newp, nnewp; struct berval noldp, newp, nnewp;
Modifications *mod, **modtail, **ml;
op->o_tag = LDAP_REQ_MODRDN; op->o_tag = LDAP_REQ_MODRDN;
dnRdn( &entry->e_name, &op->orr_newrdn ); dnRdn( &entry->e_name, &op->orr_newrdn );
@ -2219,8 +2222,30 @@ retry_add:;
} }
op->orr_deleteoldrdn = dni.delOldRDN; op->orr_deleteoldrdn = dni.delOldRDN;
op->orr_modlist = NULL; op->orr_modlist = NULL;
if ( ( rc = slap_modrdn2mods( op, &rs_modify ) ) ) {
goto done; /* Move any RDN mods over to this op */
modtail = &op->orr_modlist;
for ( ml = &dni.mods; *ml; ml = &(*ml)->sml_next ) {
if ( (*ml)->sml_desc == dni.oldDesc ) {
mod = *ml;
*ml = mod->sml_next;
mod->sml_next = NULL;
*modtail = mod;
modtail = &mod->sml_next;
break;
}
}
if ( dni.oldDesc != dni.newDesc ) {
for ( ml = &dni.mods; *ml; ml = &(*ml)->sml_next ) {
if ( (*ml)->sml_desc == dni.newDesc ) {
mod = *ml;
*ml = mod->sml_next;
mod->sml_next = NULL;
*modtail = mod;
modtail = &mod->sml_next;
break;
}
}
} }
/* RDNs must be NUL-terminated for back-ldap */ /* RDNs must be NUL-terminated for back-ldap */
@ -2239,18 +2264,11 @@ retry_add:;
&nullattr &nullattr
}; };
AttributeDescription *opattr; AttributeDescription *opattr;
Modifications *mod, **modtail, **ml;
int i; 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 */ /* pull mod off incoming modlist, append to orr_modlist */
for ( i = 0; (opattr = *opattrs[i]) != NULL; i++ ) { for ( i = 0; (opattr = *opattrs[i]) != NULL; i++ ) {
for ( ml = modlist; *ml; ml = &(*ml)->sml_next ) for ( ml = &dni.mods; *ml; ml = &(*ml)->sml_next )
{ {
if ( (*ml)->sml_desc == opattr ) { if ( (*ml)->sml_desc == opattr ) {
mod = *ml; mod = *ml;
@ -2274,6 +2292,8 @@ retry_add:;
si->si_ridtxt, rc, 0 ); si->si_ridtxt, rc, 0 );
op->o_bd = be; op->o_bd = be;
/* Renamed entries may still have other mods so just fallthru */ /* Renamed entries may still have other mods so just fallthru */
op->o_req_dn = entry->e_name;
op->o_req_ndn = entry->e_nname;
} }
if ( dni.mods ) { if ( dni.mods ) {
op->o_tag = LDAP_REQ_MODIFY; op->o_tag = LDAP_REQ_MODIFY;
@ -2293,7 +2313,7 @@ retry_add:;
si->si_ridtxt, rs_modify.sr_err, 0 ); si->si_ridtxt, rs_modify.sr_err, 0 );
} }
op->o_bd = be; op->o_bd = be;
} else { } else if ( !dni.renamed ) {
Debug( LDAP_DEBUG_SYNC, Debug( LDAP_DEBUG_SYNC,
"syncrepl_entry: %s entry unchanged, ignored (%s)\n", "syncrepl_entry: %s entry unchanged, ignored (%s)\n",
si->si_ridtxt, op->o_req_dn.bv_val, 0 ); si->si_ridtxt, op->o_req_dn.bv_val, 0 );
@ -3040,6 +3060,7 @@ dn_callback(
{ {
struct berval oldRDN, oldVal; struct berval oldRDN, oldVal;
AttributeDescription *ad = NULL; AttributeDescription *ad = NULL;
int oldpos, newpos;
Attribute *a; Attribute *a;
dni->renamed = 1; dni->renamed = 1;
@ -3048,10 +3069,14 @@ dn_callback(
oldVal.bv_val = strchr(oldRDN.bv_val, '=') + 1; oldVal.bv_val = strchr(oldRDN.bv_val, '=') + 1;
oldVal.bv_len = oldRDN.bv_len - ( oldVal.bv_val - oldVal.bv_len = oldRDN.bv_len - ( oldVal.bv_val -
oldRDN.bv_val ); oldRDN.bv_val );
oldRDN.bv_len -= oldVal.bv_len + 2; oldRDN.bv_len -= oldVal.bv_len + 1;
slap_bv2ad( &oldRDN, &ad, &rs->sr_text ); slap_bv2ad( &oldRDN, &ad, &rs->sr_text );
a = attr_find( dni->new_entry->e_attrs, ad ); dni->oldDesc = ad;
if ( !a || attr_valfind( a, for ( oldpos=0, a=rs->sr_entry->e_attrs;
a && a->a_desc != ad; oldpos++, a=a->a_next );
for ( newpos=0, a=dni->new_entry->e_attrs;
a && a->a_desc != ad; newpos++, a=a->a_next );
if ( !a || oldpos != newpos || attr_valfind( a,
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH |
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
SLAP_MR_VALUE_OF_SYNTAX, SLAP_MR_VALUE_OF_SYNTAX,
@ -3059,6 +3084,14 @@ dn_callback(
{ {
dni->delOldRDN = 1; dni->delOldRDN = 1;
} }
/* Get the newRDN's desc */
dnRdn( &dni->new_entry->e_nname, &oldRDN );
oldVal.bv_val = strchr(oldRDN.bv_val, '=');
oldRDN.bv_len = oldVal.bv_val - oldRDN.bv_val;
ad = NULL;
slap_bv2ad( &oldRDN, &ad, &rs->sr_text );
dni->newDesc = ad;
/* A ModDN has happened, but other changes may have /* A ModDN has happened, but other changes may have
* occurred before we picked it up. So fallthru to * occurred before we picked it up. So fallthru to
* regular Modify processing. * regular Modify processing.