|
|
5d2be4 |
From 220dbafa048269105b3f7958a5d5bfd1d988da26 Mon Sep 17 00:00:00 2001
|
|
|
5d2be4 |
From: Simon Pichugin <spichugi@redhat.com>
|
|
|
5d2be4 |
Date: Tue, 30 Jun 2020 15:39:30 +0200
|
|
|
5d2be4 |
Subject: [PATCH 8/8] Issue 49300 - entryUSN is duplicated after memberOf
|
|
|
5d2be4 |
operation
|
|
|
5d2be4 |
|
|
|
5d2be4 |
Bug Description: When we assign a member to a group we have two
|
|
|
5d2be4 |
oprations - group modification and user modification.
|
|
|
5d2be4 |
As a result, they both have the same entryUSN because USN Plugin
|
|
|
5d2be4 |
assigns entryUSN value in bepreop but increments the counter
|
|
|
5d2be4 |
in the postop and a lot of things can happen in between.
|
|
|
5d2be4 |
|
|
|
5d2be4 |
Fix Description: Increment the counter in bepreop together with
|
|
|
5d2be4 |
entryUSN assignment. Also, decrement the counter in bepostop if
|
|
|
5d2be4 |
the failuer has happened.
|
|
|
5d2be4 |
Add test suite to cover the change.
|
|
|
5d2be4 |
|
|
|
5d2be4 |
https://pagure.io/389-ds-base/issue/49300
|
|
|
5d2be4 |
|
|
|
5d2be4 |
Reviewed by: tbordaz (Thanks!)
|
|
|
5d2be4 |
---
|
|
|
5d2be4 |
.../tests/suites/plugins/entryusn_test.py | 240 ++++++++++++++++++
|
|
|
5d2be4 |
ldap/servers/plugins/usn/usn.c | 109 ++++----
|
|
|
5d2be4 |
ldap/servers/slapd/pblock.c | 14 +-
|
|
|
5d2be4 |
ldap/servers/slapd/pblock_v3.h | 1 +
|
|
|
5d2be4 |
ldap/servers/slapd/slapi-plugin.h | 3 +
|
|
|
5d2be4 |
5 files changed, 322 insertions(+), 45 deletions(-)
|
|
|
5d2be4 |
create mode 100644 dirsrvtests/tests/suites/plugins/entryusn_test.py
|
|
|
5d2be4 |
|
|
|
5d2be4 |
diff --git a/dirsrvtests/tests/suites/plugins/entryusn_test.py b/dirsrvtests/tests/suites/plugins/entryusn_test.py
|
|
|
5d2be4 |
new file mode 100644
|
|
|
5d2be4 |
index 000000000..721315419
|
|
|
5d2be4 |
--- /dev/null
|
|
|
5d2be4 |
+++ b/dirsrvtests/tests/suites/plugins/entryusn_test.py
|
|
|
5d2be4 |
@@ -0,0 +1,240 @@
|
|
|
5d2be4 |
+# --- BEGIN COPYRIGHT BLOCK ---
|
|
|
5d2be4 |
+# Copyright (C) 2020 Red Hat, Inc.
|
|
|
5d2be4 |
+# All rights reserved.
|
|
|
5d2be4 |
+#
|
|
|
5d2be4 |
+# License: GPL (version 3 or any later version).
|
|
|
5d2be4 |
+# See LICENSE for details.
|
|
|
5d2be4 |
+# --- END COPYRIGHT BLOCK ---
|
|
|
5d2be4 |
+#
|
|
|
5d2be4 |
+import ldap
|
|
|
5d2be4 |
+import logging
|
|
|
5d2be4 |
+import pytest
|
|
|
5d2be4 |
+from lib389._constants import DEFAULT_SUFFIX
|
|
|
5d2be4 |
+from lib389.config import Config
|
|
|
5d2be4 |
+from lib389.plugins import USNPlugin, MemberOfPlugin
|
|
|
5d2be4 |
+from lib389.idm.group import Groups
|
|
|
5d2be4 |
+from lib389.idm.user import UserAccounts
|
|
|
5d2be4 |
+from lib389.idm.organizationalunit import OrganizationalUnit
|
|
|
5d2be4 |
+from lib389.tombstone import Tombstones
|
|
|
5d2be4 |
+from lib389.rootdse import RootDSE
|
|
|
5d2be4 |
+from lib389.topologies import topology_st, topology_m2
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+log = logging.getLogger(__name__)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+USER_NUM = 10
|
|
|
5d2be4 |
+GROUP_NUM = 3
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+def check_entryusn_no_duplicates(entryusn_list):
|
|
|
5d2be4 |
+ """Check that all values in the list are unique"""
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ if len(entryusn_list) > len(set(entryusn_list)):
|
|
|
5d2be4 |
+ raise AssertionError(f"EntryUSN values have duplicates, please, check logs")
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+def check_lastusn_after_restart(inst):
|
|
|
5d2be4 |
+ """Check that last usn is the same after restart"""
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ root_dse = RootDSE(inst)
|
|
|
5d2be4 |
+ last_usn_before = root_dse.get_attr_val_int("lastusn;userroot")
|
|
|
5d2be4 |
+ inst.restart()
|
|
|
5d2be4 |
+ last_usn_after = root_dse.get_attr_val_int("lastusn;userroot")
|
|
|
5d2be4 |
+ assert last_usn_after == last_usn_before
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+@pytest.fixture(scope="module")
|
|
|
5d2be4 |
+def setup(topology_st, request):
|
|
|
5d2be4 |
+ """
|
|
|
5d2be4 |
+ Enable USN plug-in
|
|
|
5d2be4 |
+ Enable MEMBEROF plugin
|
|
|
5d2be4 |
+ Add test entries
|
|
|
5d2be4 |
+ """
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ inst = topology_st.standalone
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ log.info("Enable the USN plugin...")
|
|
|
5d2be4 |
+ plugin = USNPlugin(inst)
|
|
|
5d2be4 |
+ plugin.enable()
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ log.info("Enable the MEMBEROF plugin...")
|
|
|
5d2be4 |
+ plugin = MemberOfPlugin(inst)
|
|
|
5d2be4 |
+ plugin.enable()
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ inst.restart()
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ users_list = []
|
|
|
5d2be4 |
+ log.info("Adding test entries...")
|
|
|
5d2be4 |
+ users = UserAccounts(inst, DEFAULT_SUFFIX)
|
|
|
5d2be4 |
+ for id in range(USER_NUM):
|
|
|
5d2be4 |
+ user = users.create_test_user(uid=id)
|
|
|
5d2be4 |
+ users_list.append(user)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ groups_list = []
|
|
|
5d2be4 |
+ log.info("Adding test groups...")
|
|
|
5d2be4 |
+ groups = Groups(inst, DEFAULT_SUFFIX)
|
|
|
5d2be4 |
+ for id in range(GROUP_NUM):
|
|
|
5d2be4 |
+ group = groups.create(properties={'cn': f'test_group{id}'})
|
|
|
5d2be4 |
+ groups_list.append(group)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ def fin():
|
|
|
5d2be4 |
+ for user in users_list:
|
|
|
5d2be4 |
+ try:
|
|
|
5d2be4 |
+ user.delete()
|
|
|
5d2be4 |
+ except ldap.NO_SUCH_OBJECT:
|
|
|
5d2be4 |
+ pass
|
|
|
5d2be4 |
+ for group in groups_list:
|
|
|
5d2be4 |
+ try:
|
|
|
5d2be4 |
+ group.delete()
|
|
|
5d2be4 |
+ except ldap.NO_SUCH_OBJECT:
|
|
|
5d2be4 |
+ pass
|
|
|
5d2be4 |
+ request.addfinalizer(fin)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ return {"users": users_list,
|
|
|
5d2be4 |
+ "groups": groups_list}
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+def test_entryusn_no_duplicates(topology_st, setup):
|
|
|
5d2be4 |
+ """Verify that entryUSN is not duplicated after memberOf operation
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ :id: 1a7d382d-1214-4d56-b9c2-9c4ed57d1683
|
|
|
5d2be4 |
+ :setup: Standalone instance, Groups and Users, USN and memberOf are enabled
|
|
|
5d2be4 |
+ :steps:
|
|
|
5d2be4 |
+ 1. Add a member to group 1
|
|
|
5d2be4 |
+ 2. Add a member to group 1 and 2
|
|
|
5d2be4 |
+ 3. Check that entryUSNs are different
|
|
|
5d2be4 |
+ 4. Check that lastusn before and after a restart are the same
|
|
|
5d2be4 |
+ :expectedresults:
|
|
|
5d2be4 |
+ 1. Success
|
|
|
5d2be4 |
+ 2. Success
|
|
|
5d2be4 |
+ 3. Success
|
|
|
5d2be4 |
+ 4. Success
|
|
|
5d2be4 |
+ """
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ inst = topology_st.standalone
|
|
|
5d2be4 |
+ config = Config(inst)
|
|
|
5d2be4 |
+ config.replace('nsslapd-accesslog-level', '260') # Internal op
|
|
|
5d2be4 |
+ config.replace('nsslapd-errorlog-level', '65536')
|
|
|
5d2be4 |
+ config.replace('nsslapd-plugin-logging', 'on')
|
|
|
5d2be4 |
+ entryusn_list = []
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ users = setup["users"]
|
|
|
5d2be4 |
+ groups = setup["groups"]
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ groups[0].replace('member', users[0].dn)
|
|
|
5d2be4 |
+ entryusn_list.append(users[0].get_attr_val_int('entryusn'))
|
|
|
5d2be4 |
+ log.info(f"{users[0].dn}_1: {entryusn_list[-1:]}")
|
|
|
5d2be4 |
+ entryusn_list.append(groups[0].get_attr_val_int('entryusn'))
|
|
|
5d2be4 |
+ log.info(f"{groups[0].dn}_1: {entryusn_list[-1:]}")
|
|
|
5d2be4 |
+ check_entryusn_no_duplicates(entryusn_list)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ groups[1].replace('member', [users[0].dn, users[1].dn])
|
|
|
5d2be4 |
+ entryusn_list.append(users[0].get_attr_val_int('entryusn'))
|
|
|
5d2be4 |
+ log.info(f"{users[0].dn}_2: {entryusn_list[-1:]}")
|
|
|
5d2be4 |
+ entryusn_list.append(users[1].get_attr_val_int('entryusn'))
|
|
|
5d2be4 |
+ log.info(f"{users[1].dn}_2: {entryusn_list[-1:]}")
|
|
|
5d2be4 |
+ entryusn_list.append(groups[1].get_attr_val_int('entryusn'))
|
|
|
5d2be4 |
+ log.info(f"{groups[1].dn}_2: {entryusn_list[-1:]}")
|
|
|
5d2be4 |
+ check_entryusn_no_duplicates(entryusn_list)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ check_lastusn_after_restart(inst)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+def test_entryusn_is_same_after_failure(topology_st, setup):
|
|
|
5d2be4 |
+ """Verify that entryUSN is the same after failed operation
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ :id: 1f227533-370a-48c1-b920-9b3b0bcfc32e
|
|
|
5d2be4 |
+ :setup: Standalone instance, Groups and Users, USN and memberOf are enabled
|
|
|
5d2be4 |
+ :steps:
|
|
|
5d2be4 |
+ 1. Get current group's entryUSN value
|
|
|
5d2be4 |
+ 2. Try to modify the group with an invalid syntax
|
|
|
5d2be4 |
+ 3. Get new group's entryUSN value and compare with old
|
|
|
5d2be4 |
+ 4. Check that lastusn before and after a restart are the same
|
|
|
5d2be4 |
+ :expectedresults:
|
|
|
5d2be4 |
+ 1. Success
|
|
|
5d2be4 |
+ 2. Invalid Syntax error
|
|
|
5d2be4 |
+ 3. Should be the same
|
|
|
5d2be4 |
+ 4. Success
|
|
|
5d2be4 |
+ """
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ inst = topology_st.standalone
|
|
|
5d2be4 |
+ users = setup["users"]
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ # We need this update so we get the latest USN pointed to our entry
|
|
|
5d2be4 |
+ users[0].replace('description', 'update')
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ entryusn_before = users[0].get_attr_val_int('entryusn')
|
|
|
5d2be4 |
+ users[0].replace('description', 'update')
|
|
|
5d2be4 |
+ try:
|
|
|
5d2be4 |
+ users[0].replace('uid', 'invalid update')
|
|
|
5d2be4 |
+ except ldap.NOT_ALLOWED_ON_RDN:
|
|
|
5d2be4 |
+ pass
|
|
|
5d2be4 |
+ users[0].replace('description', 'second update')
|
|
|
5d2be4 |
+ entryusn_after = users[0].get_attr_val_int('entryusn')
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ # entryUSN should be OLD + 2 (only two user updates)
|
|
|
5d2be4 |
+ assert entryusn_after == (entryusn_before + 2)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ check_lastusn_after_restart(inst)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+def test_entryusn_after_repl_delete(topology_m2):
|
|
|
5d2be4 |
+ """Verify that entryUSN is incremented on 1 after delete operation which creates a tombstone
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ :id: 1704cf65-41bc-4347-bdaf-20fc2431b218
|
|
|
5d2be4 |
+ :setup: An instance with replication, Users, USN enabled
|
|
|
5d2be4 |
+ :steps:
|
|
|
5d2be4 |
+ 1. Try to delete a user
|
|
|
5d2be4 |
+ 2. Check the tombstone has the incremented USN
|
|
|
5d2be4 |
+ 3. Try to delete ou=People with users
|
|
|
5d2be4 |
+ 4. Check the entry has a not incremented entryUSN
|
|
|
5d2be4 |
+ :expectedresults:
|
|
|
5d2be4 |
+ 1. Success
|
|
|
5d2be4 |
+ 2. Success
|
|
|
5d2be4 |
+ 3. Should fail with Not Allowed On Non-leaf error
|
|
|
5d2be4 |
+ 4. Success
|
|
|
5d2be4 |
+ """
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ inst = topology_m2.ms["master1"]
|
|
|
5d2be4 |
+ plugin = USNPlugin(inst)
|
|
|
5d2be4 |
+ plugin.enable()
|
|
|
5d2be4 |
+ inst.restart()
|
|
|
5d2be4 |
+ users = UserAccounts(inst, DEFAULT_SUFFIX)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ try:
|
|
|
5d2be4 |
+ user_1 = users.create_test_user()
|
|
|
5d2be4 |
+ user_rdn = user_1.rdn
|
|
|
5d2be4 |
+ tombstones = Tombstones(inst, DEFAULT_SUFFIX)
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ user_1.replace('description', 'update_ts')
|
|
|
5d2be4 |
+ user_usn = user_1.get_attr_val_int('entryusn')
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ user_1.delete()
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ ts = tombstones.get(user_rdn)
|
|
|
5d2be4 |
+ ts_usn = ts.get_attr_val_int('entryusn')
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ assert (user_usn + 1) == ts_usn
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ user_1 = users.create_test_user()
|
|
|
5d2be4 |
+ org = OrganizationalUnit(inst, f"ou=People,{DEFAULT_SUFFIX}")
|
|
|
5d2be4 |
+ org.replace('description', 'update_ts')
|
|
|
5d2be4 |
+ ou_usn_before = org.get_attr_val_int('entryusn')
|
|
|
5d2be4 |
+ try:
|
|
|
5d2be4 |
+ org.delete()
|
|
|
5d2be4 |
+ except ldap.NOT_ALLOWED_ON_NONLEAF:
|
|
|
5d2be4 |
+ pass
|
|
|
5d2be4 |
+ ou_usn_after = org.get_attr_val_int('entryusn')
|
|
|
5d2be4 |
+ assert ou_usn_before == ou_usn_after
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+ finally:
|
|
|
5d2be4 |
+ try:
|
|
|
5d2be4 |
+ user_1.delete()
|
|
|
5d2be4 |
+ except ldap.NO_SUCH_OBJECT:
|
|
|
5d2be4 |
+ pass
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
+if __name__ == '__main__':
|
|
|
5d2be4 |
+ # Run isolated
|
|
|
5d2be4 |
+ # -s for DEBUG mode
|
|
|
5d2be4 |
+ CURRENT_FILE = os.path.realpath(__file__)
|
|
|
5d2be4 |
+ pytest.main("-s %s" % CURRENT_FILE)
|
|
|
5d2be4 |
diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c
|
|
|
5d2be4 |
index 12ba040c6..f2cc8a62c 100644
|
|
|
5d2be4 |
--- a/ldap/servers/plugins/usn/usn.c
|
|
|
5d2be4 |
+++ b/ldap/servers/plugins/usn/usn.c
|
|
|
5d2be4 |
@@ -333,6 +333,12 @@ _usn_add_next_usn(Slapi_Entry *e, Slapi_Backend *be)
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
slapi_ch_free_string(&usn_berval.bv_val);
|
|
|
5d2be4 |
|
|
|
5d2be4 |
+ /*
|
|
|
5d2be4 |
+ * increment the counter now and decrement in the bepostop
|
|
|
5d2be4 |
+ * if the operation will fail
|
|
|
5d2be4 |
+ */
|
|
|
5d2be4 |
+ slapi_counter_increment(be->be_usn_counter);
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"<-- _usn_add_next_usn\n");
|
|
|
5d2be4 |
|
|
|
5d2be4 |
@@ -370,6 +376,12 @@ _usn_mod_next_usn(LDAPMod ***mods, Slapi_Backend *be)
|
|
|
5d2be4 |
|
|
|
5d2be4 |
*mods = slapi_mods_get_ldapmods_passout(&smods);
|
|
|
5d2be4 |
|
|
|
5d2be4 |
+ /*
|
|
|
5d2be4 |
+ * increment the counter now and decrement in the bepostop
|
|
|
5d2be4 |
+ * if the operation will fail
|
|
|
5d2be4 |
+ */
|
|
|
5d2be4 |
+ slapi_counter_increment(be->be_usn_counter);
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"<-- _usn_mod_next_usn\n");
|
|
|
5d2be4 |
return LDAP_SUCCESS;
|
|
|
5d2be4 |
@@ -420,6 +432,7 @@ usn_betxnpreop_delete(Slapi_PBlock *pb)
|
|
|
5d2be4 |
{
|
|
|
5d2be4 |
Slapi_Entry *e = NULL;
|
|
|
5d2be4 |
Slapi_Backend *be = NULL;
|
|
|
5d2be4 |
+ int32_t tombstone_incremented = 0;
|
|
|
5d2be4 |
int rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
@@ -441,7 +454,9 @@ usn_betxnpreop_delete(Slapi_PBlock *pb)
|
|
|
5d2be4 |
goto bail;
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
_usn_add_next_usn(e, be);
|
|
|
5d2be4 |
+ tombstone_incremented = 1;
|
|
|
5d2be4 |
bail:
|
|
|
5d2be4 |
+ slapi_pblock_set(pb, SLAPI_USN_INCREMENT_FOR_TOMBSTONE, &tombstone_incremented);
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"<-- usn_betxnpreop_delete\n");
|
|
|
5d2be4 |
|
|
|
5d2be4 |
@@ -483,7 +498,7 @@ bail:
|
|
|
5d2be4 |
return rc;
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
-/* count up the counter */
|
|
|
5d2be4 |
+/* count down the counter */
|
|
|
5d2be4 |
static int
|
|
|
5d2be4 |
usn_bepostop(Slapi_PBlock *pb)
|
|
|
5d2be4 |
{
|
|
|
5d2be4 |
@@ -493,25 +508,24 @@ usn_bepostop(Slapi_PBlock *pb)
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"--> usn_bepostop\n");
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- /* if op is not successful, don't increment the counter */
|
|
|
5d2be4 |
+ /* if op is not successful, decrement the counter, else - do nothing */
|
|
|
5d2be4 |
slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
if (LDAP_SUCCESS != rc) {
|
|
|
5d2be4 |
- /* no plugin failure */
|
|
|
5d2be4 |
- rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
- goto bail;
|
|
|
5d2be4 |
- }
|
|
|
5d2be4 |
+ slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
5d2be4 |
+ if (NULL == be) {
|
|
|
5d2be4 |
+ rc = LDAP_PARAM_ERROR;
|
|
|
5d2be4 |
+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
+ rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
+ goto bail;
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
5d2be4 |
- if (NULL == be) {
|
|
|
5d2be4 |
- rc = LDAP_PARAM_ERROR;
|
|
|
5d2be4 |
- slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
- rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
- goto bail;
|
|
|
5d2be4 |
+ if (be->be_usn_counter) {
|
|
|
5d2be4 |
+ slapi_counter_decrement(be->be_usn_counter);
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- if (be->be_usn_counter) {
|
|
|
5d2be4 |
- slapi_counter_increment(be->be_usn_counter);
|
|
|
5d2be4 |
- }
|
|
|
5d2be4 |
+ /* no plugin failure */
|
|
|
5d2be4 |
+ rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
bail:
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"<-- usn_bepostop\n");
|
|
|
5d2be4 |
@@ -519,13 +533,14 @@ bail:
|
|
|
5d2be4 |
return rc;
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
-/* count up the counter */
|
|
|
5d2be4 |
+/* count down the counter on a failure and mod ignore */
|
|
|
5d2be4 |
static int
|
|
|
5d2be4 |
usn_bepostop_modify(Slapi_PBlock *pb)
|
|
|
5d2be4 |
{
|
|
|
5d2be4 |
int rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
Slapi_Backend *be = NULL;
|
|
|
5d2be4 |
LDAPMod **mods = NULL;
|
|
|
5d2be4 |
+ int32_t do_decrement = 0;
|
|
|
5d2be4 |
int i;
|
|
|
5d2be4 |
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
@@ -534,9 +549,7 @@ usn_bepostop_modify(Slapi_PBlock *pb)
|
|
|
5d2be4 |
/* if op is not successful, don't increment the counter */
|
|
|
5d2be4 |
slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
if (LDAP_SUCCESS != rc) {
|
|
|
5d2be4 |
- /* no plugin failure */
|
|
|
5d2be4 |
- rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
- goto bail;
|
|
|
5d2be4 |
+ do_decrement = 1;
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods;;
|
|
|
5d2be4 |
@@ -545,25 +558,29 @@ usn_bepostop_modify(Slapi_PBlock *pb)
|
|
|
5d2be4 |
if (mods[i]->mod_op & LDAP_MOD_IGNORE) {
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"usn_bepostop_modify - MOD_IGNORE detected\n");
|
|
|
5d2be4 |
- goto bail; /* conflict occurred.
|
|
|
5d2be4 |
- skip incrementing the counter. */
|
|
|
5d2be4 |
+ do_decrement = 1; /* conflict occurred.
|
|
|
5d2be4 |
+ decrement he counter. */
|
|
|
5d2be4 |
} else {
|
|
|
5d2be4 |
break;
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
5d2be4 |
- if (NULL == be) {
|
|
|
5d2be4 |
- rc = LDAP_PARAM_ERROR;
|
|
|
5d2be4 |
- slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
- rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
- goto bail;
|
|
|
5d2be4 |
+ if (do_decrement) {
|
|
|
5d2be4 |
+ slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
5d2be4 |
+ if (NULL == be) {
|
|
|
5d2be4 |
+ rc = LDAP_PARAM_ERROR;
|
|
|
5d2be4 |
+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
+ rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
+ goto bail;
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
+ if (be->be_usn_counter) {
|
|
|
5d2be4 |
+ slapi_counter_decrement(be->be_usn_counter);
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- if (be->be_usn_counter) {
|
|
|
5d2be4 |
- slapi_counter_increment(be->be_usn_counter);
|
|
|
5d2be4 |
- }
|
|
|
5d2be4 |
+ /* no plugin failure */
|
|
|
5d2be4 |
+ rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
bail:
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"<-- usn_bepostop_modify\n");
|
|
|
5d2be4 |
@@ -573,34 +590,38 @@ bail:
|
|
|
5d2be4 |
|
|
|
5d2be4 |
/* count up the counter */
|
|
|
5d2be4 |
/* if the op is delete and the op was not successful, remove preventryusn */
|
|
|
5d2be4 |
+/* the function is executed on TXN level */
|
|
|
5d2be4 |
static int
|
|
|
5d2be4 |
usn_bepostop_delete(Slapi_PBlock *pb)
|
|
|
5d2be4 |
{
|
|
|
5d2be4 |
int rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
Slapi_Backend *be = NULL;
|
|
|
5d2be4 |
+ int32_t tombstone_incremented = 0;
|
|
|
5d2be4 |
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"--> usn_bepostop_delete\n");
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- /* if op is not successful, don't increment the counter */
|
|
|
5d2be4 |
+ /* if op is not successful and it is a tombstone entry, decrement the counter */
|
|
|
5d2be4 |
slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
if (LDAP_SUCCESS != rc) {
|
|
|
5d2be4 |
- /* no plugin failure */
|
|
|
5d2be4 |
- rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
- goto bail;
|
|
|
5d2be4 |
- }
|
|
|
5d2be4 |
+ slapi_pblock_get(pb, SLAPI_USN_INCREMENT_FOR_TOMBSTONE, &tombstone_incremented);
|
|
|
5d2be4 |
+ if (tombstone_incremented) {
|
|
|
5d2be4 |
+ slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
5d2be4 |
+ if (NULL == be) {
|
|
|
5d2be4 |
+ rc = LDAP_PARAM_ERROR;
|
|
|
5d2be4 |
+ slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
+ rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
+ goto bail;
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- slapi_pblock_get(pb, SLAPI_BACKEND, &be);
|
|
|
5d2be4 |
- if (NULL == be) {
|
|
|
5d2be4 |
- rc = LDAP_PARAM_ERROR;
|
|
|
5d2be4 |
- slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc);
|
|
|
5d2be4 |
- rc = SLAPI_PLUGIN_FAILURE;
|
|
|
5d2be4 |
- goto bail;
|
|
|
5d2be4 |
+ if (be->be_usn_counter) {
|
|
|
5d2be4 |
+ slapi_counter_decrement(be->be_usn_counter);
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
|
|
|
5d2be4 |
- if (be->be_usn_counter) {
|
|
|
5d2be4 |
- slapi_counter_increment(be->be_usn_counter);
|
|
|
5d2be4 |
- }
|
|
|
5d2be4 |
+ /* no plugin failure */
|
|
|
5d2be4 |
+ rc = SLAPI_PLUGIN_SUCCESS;
|
|
|
5d2be4 |
bail:
|
|
|
5d2be4 |
slapi_log_err(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM,
|
|
|
5d2be4 |
"<-- usn_bepostop_delete\n");
|
|
|
5d2be4 |
diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
|
|
|
5d2be4 |
index cb562e938..454ea9cc3 100644
|
|
|
5d2be4 |
--- a/ldap/servers/slapd/pblock.c
|
|
|
5d2be4 |
+++ b/ldap/servers/slapd/pblock.c
|
|
|
5d2be4 |
@@ -2436,7 +2436,7 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
|
|
5d2be4 |
(*(char **)value) = NULL;
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
break;
|
|
|
5d2be4 |
-
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
case SLAPI_SEARCH_CTRLS:
|
|
|
5d2be4 |
if (pblock->pb_intop != NULL) {
|
|
|
5d2be4 |
(*(LDAPControl ***)value) = pblock->pb_intop->pb_search_ctrls;
|
|
|
5d2be4 |
@@ -2479,6 +2479,14 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
|
|
|
5d2be4 |
}
|
|
|
5d2be4 |
break;
|
|
|
5d2be4 |
|
|
|
5d2be4 |
+ case SLAPI_USN_INCREMENT_FOR_TOMBSTONE:
|
|
|
5d2be4 |
+ if (pblock->pb_intop != NULL) {
|
|
|
5d2be4 |
+ (*(int32_t *)value) = pblock->pb_intop->pb_usn_tombstone_incremented;
|
|
|
5d2be4 |
+ } else {
|
|
|
5d2be4 |
+ (*(int32_t *)value) = 0;
|
|
|
5d2be4 |
+ }
|
|
|
5d2be4 |
+ break;
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
/* ACI Target Check */
|
|
|
5d2be4 |
case SLAPI_ACI_TARGET_CHECK:
|
|
|
5d2be4 |
if (pblock->pb_misc != NULL) {
|
|
|
5d2be4 |
@@ -4156,6 +4164,10 @@ slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value)
|
|
|
5d2be4 |
pblock->pb_intop->pb_paged_results_cookie = *(int *)value;
|
|
|
5d2be4 |
break;
|
|
|
5d2be4 |
|
|
|
5d2be4 |
+ case SLAPI_USN_INCREMENT_FOR_TOMBSTONE:
|
|
|
5d2be4 |
+ pblock->pb_intop->pb_usn_tombstone_incremented = *((int32_t *)value);
|
|
|
5d2be4 |
+ break;
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
/* ACI Target Check */
|
|
|
5d2be4 |
case SLAPI_ACI_TARGET_CHECK:
|
|
|
5d2be4 |
_pblock_assert_pb_misc(pblock);
|
|
|
5d2be4 |
diff --git a/ldap/servers/slapd/pblock_v3.h b/ldap/servers/slapd/pblock_v3.h
|
|
|
5d2be4 |
index 7ec2f37d6..90498c0b0 100644
|
|
|
5d2be4 |
--- a/ldap/servers/slapd/pblock_v3.h
|
|
|
5d2be4 |
+++ b/ldap/servers/slapd/pblock_v3.h
|
|
|
5d2be4 |
@@ -161,6 +161,7 @@ typedef struct _slapi_pblock_intop
|
|
|
5d2be4 |
|
|
|
5d2be4 |
int pb_paged_results_index; /* stash SLAPI_PAGED_RESULTS_INDEX */
|
|
|
5d2be4 |
int pb_paged_results_cookie; /* stash SLAPI_PAGED_RESULTS_COOKIE */
|
|
|
5d2be4 |
+ int32_t pb_usn_tombstone_incremented; /* stash SLAPI_PAGED_RESULTS_COOKIE */
|
|
|
5d2be4 |
} slapi_pblock_intop;
|
|
|
5d2be4 |
|
|
|
5d2be4 |
/* Stuff that is rarely used, but still present */
|
|
|
5d2be4 |
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
|
|
|
5d2be4 |
index 04c02cf7c..589830bb4 100644
|
|
|
5d2be4 |
--- a/ldap/servers/slapd/slapi-plugin.h
|
|
|
5d2be4 |
+++ b/ldap/servers/slapd/slapi-plugin.h
|
|
|
5d2be4 |
@@ -7483,6 +7483,9 @@ typedef enum _slapi_op_note_t {
|
|
|
5d2be4 |
#define SLAPI_PAGED_RESULTS_INDEX 1945
|
|
|
5d2be4 |
#define SLAPI_PAGED_RESULTS_COOKIE 1949
|
|
|
5d2be4 |
|
|
|
5d2be4 |
+/* USN Plugin flag for tombstone entries */
|
|
|
5d2be4 |
+#define SLAPI_USN_INCREMENT_FOR_TOMBSTONE 1950
|
|
|
5d2be4 |
+
|
|
|
5d2be4 |
/* ACI Target Check */
|
|
|
5d2be4 |
#define SLAPI_ACI_TARGET_CHECK 1946
|
|
|
5d2be4 |
|
|
|
5d2be4 |
--
|
|
|
5d2be4 |
2.26.2
|
|
|
5d2be4 |
|