From: Ondřej Kuzník Date: Thu, 1 Apr 2021 14:17:14 +0000 (+0100) Subject: ITS#9295 Handle add+delete on a single-value attr X-Git-Tag: OPENLDAP_REL_ENG_2_4_59~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95fb5f0e4d453b201c0b27955ef7f8c37b959c6c;p=thirdparty%2Fopenldap.git ITS#9295 Handle add+delete on a single-value attr --- diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index 3d342f4d97..0e64a0f5f0 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -1965,9 +1965,16 @@ syncrepl_accesslog_mods( mod->sml_nvalues = NULL; mod->sml_numvals = 0; - /* Keep 'op' to reflect what we read out from accesslog */ - if ( op == LDAP_MOD_ADD && is_at_single_value( ad->ad_type )) - mod->sml_op = LDAP_MOD_REPLACE; + if ( is_at_single_value( ad->ad_type ) ) { + if ( op == LDAP_MOD_ADD ) { + /* ITS#9295 an ADD might conflict with an existing value */ + mod->sml_op = LDAP_MOD_REPLACE; + } else if ( op == LDAP_MOD_DELETE ) { + /* ITS#9295 the above REPLACE could invalidate subsequent + * DELETEs */ + mod->sml_op = SLAP_MOD_SOFTDEL; + } + } *modtail = mod; modtail = &mod->sml_next; @@ -2129,6 +2136,7 @@ syncrepl_resolve_cb( Operation *op, SlapReply *rs ) continue; } if ( m2->sml_op == LDAP_MOD_DELETE || + m2->sml_op == SLAP_MOD_SOFTDEL || m2->sml_op == LDAP_MOD_REPLACE ) { int numvals = m2->sml_numvals; if ( m2->sml_op == LDAP_MOD_REPLACE ) @@ -2140,7 +2148,8 @@ drop: op->o_tmpfree( m1, op->o_tmpmemctx ); continue; } - if ( m1->sml_op == LDAP_MOD_DELETE ) { + if ( m1->sml_op == LDAP_MOD_DELETE || + m1->sml_op == SLAP_MOD_SOFTDEL ) { if ( m1->sml_numvals == 0 ) { /* turn this to SOFTDEL later */ m1->sml_flags = SLAP_MOD_INTERNAL; diff --git a/tests/scripts/test043-delta-syncrepl b/tests/scripts/test043-delta-syncrepl index 2b93a9abfa..b835daad98 100755 --- a/tests/scripts/test043-delta-syncrepl +++ b/tests/scripts/test043-delta-syncrepl @@ -177,6 +177,17 @@ sn: Jones - add: sn sn: Jones +- +add: displayName +displayName: The one + +dn: cn=James A Jones 1, ou=Alumni Association, ou=People, dc=example,dc=com +changetype: modify +add: displayName +displayName: James the First +- +delete: displayName +displayName: The one dn: cn=Bjorn Jensen, ou=Information Technology Division, ou=People, dc=example,dc=com changetype: modify diff --git a/tests/scripts/test063-delta-multiprovider b/tests/scripts/test063-delta-multiprovider index 42105a93ac..63b0762297 100755 --- a/tests/scripts/test063-delta-multiprovider +++ b/tests/scripts/test063-delta-multiprovider @@ -279,7 +279,9 @@ n=`expr $n + 1` done echo "Using ldapadd to populate server 2..." -$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD -f $LDIFADD1 \ +cp $LDIFADD1 $TESTDIR/add.ldif +echo "displayName: The other" >>$TESTDIR/add.ldif +$LDAPADD -D "$MANAGERDN" -H $URI2 -w $PASSWD -f $TESTDIR/add.ldif \ >> $TESTOUT 2>&1 RC=$? if test $RC != 0 ; then @@ -377,6 +379,12 @@ dn: $THEDN changetype: modify add: description description: Amazing +- +add: displayName +displayName: James the Second +- +delete: displayName +displayName: The other EOF RC=$? @@ -394,6 +402,12 @@ replace: employeetype - add: description description: Stupendous +- +add: displayName +displayName: James II +- +delete: displayName +displayName: The other EOF RC=$?