From cc79c9e86c3294a405a45b8bf61340015c2e137e Mon Sep 17 00:00:00 2001 From: Howard Chu <hyc@openldap.org> Date: Fri, 8 May 2020 16:22:44 +0100 Subject: [PATCH] ITS#9227 syncrepl: don't delete non-replicated attrs --- servers/slapd/syncrepl.c | 43 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index e968e7b09a..c659a32752 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -2788,6 +2788,7 @@ static struct berval generic_filterstr = BER_BVC("(objectclass=*)"); * operational attributes from the entry, and do a regular ModDN. */ typedef struct dninfo { + syncinfo_t *si; Entry *new_entry; struct berval dn; struct berval ndn; @@ -3010,6 +3011,7 @@ syncrepl_entry( op->o_callback = &cb; cb.sc_response = dn_callback; cb.sc_private = &dni; + dni.si = si; dni.new_entry = entry; dni.modlist = modlist; @@ -4292,6 +4294,37 @@ void syncrepl_diff_entry( Operation *op, Attribute *old, Attribute *new, *ml = NULL; } +/* shallow copy attrs, excluding non-replicated attrs */ +static Attribute * +attrs_exdup( Operation *op, dninfo *dni, Attribute *attrs ) +{ + int i; + Attribute *tmp, *anew; + + if ( attrs == NULL ) return NULL; + + /* count attrs */ + for ( tmp = attrs,i=0; tmp; tmp=tmp->a_next ) i++; + + anew = op->o_tmpalloc( i * sizeof(Attribute), op->o_tmpmemctx ); + for ( tmp = anew; attrs; attrs=attrs->a_next ) { + if ( dni->si->si_anlist && !ad_inlist( attrs->a_desc, dni->si->si_anlist )) + continue; + if ( dni->si->si_exanlist && ad_inlist( attrs->a_desc, dni->si->si_exanlist )) + continue; + *tmp = *attrs; + tmp->a_next = tmp+1; + tmp++; + } + if ( tmp == anew ) { + /* excluded everything */ + op->o_tmpfree( anew, op->o_tmpmemctx ); + return NULL; + } + tmp[-1].a_next = NULL; + return anew; +} + static int dn_callback( Operation* op, @@ -4414,9 +4447,13 @@ dn_callback( */ } - syncrepl_diff_entry( op, rs->sr_entry->e_attrs, - dni->new_entry->e_attrs, &dni->mods, dni->modlist, - is_ctx ); + { + Attribute *old = attrs_exdup( op, dni, rs->sr_entry->e_attrs ); + syncrepl_diff_entry( op, old, + dni->new_entry->e_attrs, &dni->mods, dni->modlist, + is_ctx ); + op->o_tmpfree( old, op->o_tmpmemctx ); + } } } } else if ( rs->sr_type == REP_RESULT ) { -- GitLab