diff --git a/.389-ds-base.metadata b/.389-ds-base.metadata
index af43295..9c5f2b7 100644
--- a/.389-ds-base.metadata
+++ b/.389-ds-base.metadata
@@ -1,2 +1,2 @@
-7e651c99e43265c678c98ac2d8e31b8c48522be6 SOURCES/389-ds-base-1.4.3.8.tar.bz2
+90cda7aea8d8644eea5a2af28c72350dd915db34 SOURCES/389-ds-base-1.4.3.16.tar.bz2
 9e06b5cc57fd185379d007696da153893cf73e30 SOURCES/jemalloc-5.2.1.tar.bz2
diff --git a/.gitignore b/.gitignore
index 470a59e..9745926 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-SOURCES/389-ds-base-1.4.3.8.tar.bz2
+SOURCES/389-ds-base-1.4.3.16.tar.bz2
 SOURCES/jemalloc-5.2.1.tar.bz2
diff --git a/SOURCES/0001-Issue-51076-prevent-unnecessarily-duplication-of-the.patch b/SOURCES/0001-Issue-51076-prevent-unnecessarily-duplication-of-the.patch
deleted file mode 100644
index cba92a9..0000000
--- a/SOURCES/0001-Issue-51076-prevent-unnecessarily-duplication-of-the.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 97ecf0190f264a2d87750bc2d26ebf011542e3e1 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Fri, 8 May 2020 10:52:43 -0400
-Subject: [PATCH 01/12] Issue 51076 - prevent unnecessarily duplication of the
- target entry
-
-Bug Description:  For any update operation the MEP plugin was calling
-                  slapi_search_internal_get_entry() which duplicates
-                  the entry it returns.  In this case the entry is just
-                  read from and discarded, but this entry is already
-                  in the pblock (the PRE OP ENTRY).
-
-Fix Description:  Just grab the PRE OP ENTRY from the pblock and use
-                  that to read the attribute values from.  This saves
-                  two entry duplications for every update operation
-                  from MEP.
-
-fixes:  https://pagure.io/389-ds-base/issue/51076
-
-Reviewed by: tbordaz & firstyear(Thanks!!)
----
- ldap/servers/plugins/mep/mep.c | 5 ++---
- 1 file changed, 2 insertions(+), 3 deletions(-)
-
-diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c
-index ca9a64b3b..401d95e3a 100644
---- a/ldap/servers/plugins/mep/mep.c
-+++ b/ldap/servers/plugins/mep/mep.c
-@@ -2165,9 +2165,8 @@ mep_pre_op(Slapi_PBlock *pb, int modop)
-                 if (e && free_entry) {
-                     slapi_entry_free(e);
-                 }
--
--                slapi_search_internal_get_entry(sdn, 0, &e, mep_get_plugin_id());
--                free_entry = 1;
-+                slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &e);
-+                free_entry = 0;
-             }
- 
-             if (e && mep_is_managed_entry(e)) {
--- 
-2.26.2
-
diff --git a/SOURCES/0002-Ticket-51082-abort-when-a-empty-valueset-is-freed.patch b/SOURCES/0002-Ticket-51082-abort-when-a-empty-valueset-is-freed.patch
deleted file mode 100644
index 822c8d2..0000000
--- a/SOURCES/0002-Ticket-51082-abort-when-a-empty-valueset-is-freed.patch
+++ /dev/null
@@ -1,116 +0,0 @@
-From 1426f086623404ab2eacb04de7e6414177c0993a Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Mon, 11 May 2020 17:11:49 +0200
-Subject: [PATCH 02/12] Ticket 51082 - abort when a empty valueset is freed
-
-Bug Description:
-	A large valueset (more than 10 values) manages a sorted array of values.
-        replication purges old values from a valueset (valueset_array_purge). If it purges all the values
-        the valueset is freed (slapi_valueset_done).
-        A problem is that the counter of values, in the valueset, is still reflecting the initial number
-        of values (before the purge). When the valueset is freed (because empty) a safety checking
-        detects incoherent values based on the wrong counter.
-
-Fix Description:
-	When all the values have been purge reset the counter before freeing the valueset
-
-https://pagure.io/389-ds-base/issue/51082
-
-Reviewed by: Mark Reynolds
-
-Platforms tested: F30
-
-Flag Day: no
-
-Doc impact: no
----
- .../suites/replication/acceptance_test.py     | 57 +++++++++++++++++++
- ldap/servers/slapd/valueset.c                 |  4 ++
- 2 files changed, 61 insertions(+)
-
-diff --git a/dirsrvtests/tests/suites/replication/acceptance_test.py b/dirsrvtests/tests/suites/replication/acceptance_test.py
-index c8e0a4c93..5009f4e7c 100644
---- a/dirsrvtests/tests/suites/replication/acceptance_test.py
-+++ b/dirsrvtests/tests/suites/replication/acceptance_test.py
-@@ -500,6 +500,63 @@ def test_warining_for_invalid_replica(topo_m4):
-     assert topo_m4.ms["master1"].ds_error_log.match('.*nsds5ReplicaBackoffMax.*10.*invalid.*')
- 
- 
-+@pytest.mark.ds51082
-+def test_csnpurge_large_valueset(topo_m2):
-+    """Test csn generator test
-+
-+    :id: 63e2bdb2-0a8f-4660-9465-7b80a9f72a74
-+    :setup: MMR with 2 masters
-+    :steps:
-+        1. Create a test_user
-+        2. add a large set of values (more than 10)
-+        3. delete all the values (more than 10)
-+        4. configure the replica to purge those values (purgedelay=5s)
-+        5. Waiting for 6 second
-+        6. do a series of update
-+    :expectedresults:
-+        1. Should succeeds
-+        2. Should succeeds
-+        3. Should succeeds
-+        4. Should succeeds
-+        5. Should succeeds
-+        6. Should not crash
-+    """
-+    m1 = topo_m2.ms["master2"]
-+
-+    test_user = UserAccount(m1, TEST_ENTRY_DN)
-+    if test_user.exists():
-+        log.info('Deleting entry {}'.format(TEST_ENTRY_DN))
-+        test_user.delete()
-+    test_user.create(properties={
-+        'uid': TEST_ENTRY_NAME,
-+        'cn': TEST_ENTRY_NAME,
-+        'sn': TEST_ENTRY_NAME,
-+        'userPassword': TEST_ENTRY_NAME,
-+        'uidNumber' : '1000',
-+        'gidNumber' : '2000',
-+        'homeDirectory' : '/home/mmrepl_test',
-+    })
-+
-+    # create a large value set so that it is sorted
-+    for i in range(1,20):
-+        test_user.add('description', 'value {}'.format(str(i)))
-+
-+    # delete all values of the valueset
-+    for i in range(1,20):
-+        test_user.remove('description', 'value {}'.format(str(i)))
-+
-+    # set purging delay to 5 second and wait more that 5second
-+    replicas = Replicas(m1)
-+    replica = replicas.list()[0]
-+    log.info('nsds5ReplicaPurgeDelay to 5')
-+    replica.set('nsds5ReplicaPurgeDelay', '5')
-+    time.sleep(6)
-+
-+    # add some new values to the valueset containing entries that should be purged
-+    for i in range(21,25):
-+        test_user.add('description', 'value {}'.format(str(i)))
-+
-+
- if __name__ == '__main__':
-     # Run isolated
-     # -s for DEBUG mode
-diff --git a/ldap/servers/slapd/valueset.c b/ldap/servers/slapd/valueset.c
-index 2af3ee18d..12027ecb8 100644
---- a/ldap/servers/slapd/valueset.c
-+++ b/ldap/servers/slapd/valueset.c
-@@ -801,6 +801,10 @@ valueset_array_purge(const Slapi_Attr *a, Slapi_ValueSet *vs, const CSN *csn)
-             }
-         }
-     } else {
-+        /* empty valueset - reset the vs->num so that further
-+         * checking will not abort
-+         */
-+        vs->num = 0;
-         slapi_valueset_done(vs);
-     }
- 
--- 
-2.26.2
-
diff --git a/SOURCES/0003-Issue-51091-healthcheck-json-report-fails-when-mappi.patch b/SOURCES/0003-Issue-51091-healthcheck-json-report-fails-when-mappi.patch
deleted file mode 100644
index b3a1a82..0000000
--- a/SOURCES/0003-Issue-51091-healthcheck-json-report-fails-when-mappi.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-From 7a62e72b81d75ebb844835619ecc97dbf5e21058 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Thu, 14 May 2020 09:38:20 -0400
-Subject: [PATCH 03/12] Issue 51091 - healthcheck json report fails when
- mapping tree is deleted
-
-Description:  We were passing the bename in bytes and not as a utf8 string.
-              This caused the json dumping to fail.
-
-relates: https://pagure.io/389-ds-base/issue/51091
-
-Reviewed by: firstyear(Thanks!)
----
- src/lib389/lib389/backend.py | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
-index e472d3de5..4f752f414 100644
---- a/src/lib389/lib389/backend.py
-+++ b/src/lib389/lib389/backend.py
-@@ -11,7 +11,7 @@ import copy
- import ldap
- from lib389._constants import *
- from lib389.properties import *
--from lib389.utils import normalizeDN, ensure_str, ensure_bytes,  assert_c
-+from lib389.utils import normalizeDN, ensure_str, assert_c
- from lib389 import Entry
- 
- # Need to fix this ....
-@@ -488,10 +488,10 @@ class Backend(DSLdapObject):
- 
-         # Check for the missing mapping tree.
-         suffix = self.get_attr_val_utf8('nsslapd-suffix')
--        bename = self.get_attr_val_bytes('cn')
-+        bename = self.get_attr_val_utf8('cn')
-         try:
-             mt = self._mts.get(suffix)
--            if mt.get_attr_val_bytes('nsslapd-backend') != bename and mt.get_attr_val('nsslapd-state') != ensure_bytes('backend'):
-+            if mt.get_attr_val_utf8('nsslapd-backend') != bename and mt.get_attr_val_utf8('nsslapd-state') != 'backend':
-                 raise ldap.NO_SUCH_OBJECT("We have a matching suffix, but not a backend or correct database name.")
-         except ldap.NO_SUCH_OBJECT:
-             result = DSBLE0001
--- 
-2.26.2
-
diff --git a/SOURCES/0004-Issue-51076-remove-unnecessary-slapi-entry-dups.patch b/SOURCES/0004-Issue-51076-remove-unnecessary-slapi-entry-dups.patch
deleted file mode 100644
index c931a79..0000000
--- a/SOURCES/0004-Issue-51076-remove-unnecessary-slapi-entry-dups.patch
+++ /dev/null
@@ -1,943 +0,0 @@
-From f13d630ff98eb5b5505f1db3e7f207175b51b237 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 12 May 2020 13:48:30 -0400
-Subject: [PATCH 04/12] Issue 51076 - remove unnecessary slapi entry dups
-
-Description:  So the problem is that slapi_search_internal_get_entry()
-              duplicates the entry twice.  It does that as a convenience
-              where it will allocate a pblock, do the search, copy
-              the entry, free search results from the pblock, and then
-              free the pblock itself.  I basically split this function
-              into two functions.  One function allocates the pblock,
-              does the search and returns the entry.  The other function
-              frees the entries and pblock.
-
-              99% of time when we call slapi_search_internal_get_entry()
-              we are just reading it and freeing it.  It's not being
-              consumed.  In these cases we can use the two function
-              approach eliminates an extra slapi_entry_dup().  Over the
-              time of an operation/connection we can save quite a bit
-              of mallocing/freeing.  This could also help with memory
-              fragmentation.
-
-ASAN: passed
-
-relates: https://pagure.io/389-ds-base/issue/51076
-
-Reviewed by: firstyear & tbordaz(Thanks!)
----
- ldap/servers/plugins/acctpolicy/acct_config.c |  6 +--
- ldap/servers/plugins/acctpolicy/acct_plugin.c | 36 +++++++-------
- ldap/servers/plugins/acctpolicy/acct_util.c   |  6 +--
- ldap/servers/plugins/automember/automember.c  | 17 +++----
- ldap/servers/plugins/dna/dna.c                | 23 ++++-----
- ldap/servers/plugins/memberof/memberof.c      | 16 +++----
- .../plugins/pam_passthru/pam_ptconfig.c       | 10 ++--
- .../servers/plugins/pam_passthru/pam_ptimpl.c |  7 +--
- .../plugins/pam_passthru/pam_ptpreop.c        |  9 ++--
- .../plugins/replication/repl5_tot_protocol.c  |  5 +-
- ldap/servers/plugins/uiduniq/uid.c            | 23 ++++-----
- ldap/servers/slapd/daemon.c                   | 11 ++---
- ldap/servers/slapd/modify.c                   | 12 +++--
- ldap/servers/slapd/plugin_internal_op.c       | 48 +++++++++++++++++++
- ldap/servers/slapd/resourcelimit.c            | 13 ++---
- ldap/servers/slapd/schema.c                   |  7 ++-
- ldap/servers/slapd/slapi-plugin.h             | 23 ++++++++-
- 17 files changed, 161 insertions(+), 111 deletions(-)
-
-diff --git a/ldap/servers/plugins/acctpolicy/acct_config.c b/ldap/servers/plugins/acctpolicy/acct_config.c
-index fe35ba5a0..01e4f319f 100644
---- a/ldap/servers/plugins/acctpolicy/acct_config.c
-+++ b/ldap/servers/plugins/acctpolicy/acct_config.c
-@@ -37,6 +37,7 @@ static int acct_policy_entry2config(Slapi_Entry *e,
- int
- acct_policy_load_config_startup(Slapi_PBlock *pb __attribute__((unused)), void *plugin_id)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     acctPluginCfg *newcfg;
-     Slapi_Entry *config_entry = NULL;
-     Slapi_DN *config_sdn = NULL;
-@@ -44,8 +45,7 @@ acct_policy_load_config_startup(Slapi_PBlock *pb __attribute__((unused)), void *
- 
-     /* Retrieve the config entry */
-     config_sdn = slapi_sdn_new_normdn_byref(PLUGIN_CONFIG_DN);
--    rc = slapi_search_internal_get_entry(config_sdn, NULL, &config_entry,
--                                         plugin_id);
-+    rc = slapi_search_get_entry(&entry_pb, config_sdn, NULL, &config_entry, plugin_id);
-     slapi_sdn_free(&config_sdn);
- 
-     if (rc != LDAP_SUCCESS || config_entry == NULL) {
-@@ -60,7 +60,7 @@ acct_policy_load_config_startup(Slapi_PBlock *pb __attribute__((unused)), void *
-     rc = acct_policy_entry2config(config_entry, newcfg);
-     config_unlock();
- 
--    slapi_entry_free(config_entry);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     return (rc);
- }
-diff --git a/ldap/servers/plugins/acctpolicy/acct_plugin.c b/ldap/servers/plugins/acctpolicy/acct_plugin.c
-index 2a876ad72..c3c32b074 100644
---- a/ldap/servers/plugins/acctpolicy/acct_plugin.c
-+++ b/ldap/servers/plugins/acctpolicy/acct_plugin.c
-@@ -209,6 +209,7 @@ done:
- int
- acct_bind_preop(Slapi_PBlock *pb)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     const char *dn = NULL;
-     Slapi_DN *sdn = NULL;
-     Slapi_Entry *target_entry = NULL;
-@@ -236,8 +237,7 @@ acct_bind_preop(Slapi_PBlock *pb)
-         goto done;
-     }
- 
--    ldrc = slapi_search_internal_get_entry(sdn, NULL, &target_entry,
--                                           plugin_id);
-+    ldrc = slapi_search_get_entry(&entry_pb, sdn, NULL, &target_entry, plugin_id);
- 
-     /* There was a problem retrieving the entry */
-     if (ldrc != LDAP_SUCCESS) {
-@@ -275,7 +275,7 @@ done:
-         slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, NULL, 0, NULL);
-     }
- 
--    slapi_entry_free(target_entry);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     free_acctpolicy(&policy);
- 
-@@ -293,6 +293,7 @@ done:
- int
- acct_bind_postop(Slapi_PBlock *pb)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     char *dn = NULL;
-     int ldrc, tracklogin = 0;
-     int rc = 0; /* Optimistic default */
-@@ -327,8 +328,7 @@ acct_bind_postop(Slapi_PBlock *pb)
-        covered by an account policy to decide whether we should track */
-     if (tracklogin == 0) {
-         sdn = slapi_sdn_new_normdn_byref(dn);
--        ldrc = slapi_search_internal_get_entry(sdn, NULL, &target_entry,
--                                               plugin_id);
-+        ldrc = slapi_search_get_entry(&entry_pb, sdn, NULL, &target_entry, plugin_id);
- 
-         if (ldrc != LDAP_SUCCESS) {
-             slapi_log_err(SLAPI_LOG_ERR, POST_PLUGIN_NAME,
-@@ -355,7 +355,7 @@ done:
-         slapi_send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, NULL, 0, NULL);
-     }
- 
--    slapi_entry_free(target_entry);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     slapi_sdn_free(&sdn);
- 
-@@ -370,11 +370,11 @@ done:
- static int
- acct_pre_op(Slapi_PBlock *pb, int modop)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     Slapi_DN *sdn = 0;
-     Slapi_Entry *e = 0;
-     Slapi_Mods *smods = 0;
-     LDAPMod **mods;
--    int free_entry = 0;
-     char *errstr = NULL;
-     int ret = SLAPI_PLUGIN_SUCCESS;
- 
-@@ -384,28 +384,25 @@ acct_pre_op(Slapi_PBlock *pb, int modop)
- 
-     if (acct_policy_dn_is_config(sdn)) {
-         /* Validate config changes, but don't apply them.
--     * This allows us to reject invalid config changes
--     * here at the pre-op stage.  Applying the config
--     * needs to be done at the post-op stage. */
-+         * This allows us to reject invalid config changes
-+         * here at the pre-op stage.  Applying the config
-+         * needs to be done at the post-op stage. */
- 
-         if (LDAP_CHANGETYPE_ADD == modop) {
-             slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e);
- 
--            /* If the entry doesn't exist, just bail and
--     * let the server handle it. */
-+            /* If the entry doesn't exist, just bail and let the server handle it. */
-             if (e == NULL) {
-                 goto bail;
-             }
-         } else if (LDAP_CHANGETYPE_MODIFY == modop) {
-             /* Fetch the entry being modified so we can
--     * create the resulting entry for validation. */
-+             * create the resulting entry for validation. */
-             if (sdn) {
--                slapi_search_internal_get_entry(sdn, 0, &e, get_identity());
--                free_entry = 1;
-+                slapi_search_get_entry(&entry_pb, sdn, 0, &e, get_identity());
-             }
- 
--            /* If the entry doesn't exist, just bail and
--     * let the server handle it. */
-+            /* If the entry doesn't exist, just bail and let the server handle it. */
-             if (e == NULL) {
-                 goto bail;
-             }
-@@ -418,7 +415,7 @@ acct_pre_op(Slapi_PBlock *pb, int modop)
-             /* Apply the  mods to create the resulting entry. */
-             if (mods && (slapi_entry_apply_mods(e, mods) != LDAP_SUCCESS)) {
-                 /* The mods don't apply cleanly, so we just let this op go
--     * to let the main server handle it. */
-+                 * to let the main server handle it. */
-                 goto bailmod;
-             }
-         } else if (modop == LDAP_CHANGETYPE_DELETE) {
-@@ -439,8 +436,7 @@ bailmod:
-     }
- 
- bail:
--    if (free_entry && e)
--        slapi_entry_free(e);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     if (ret) {
-         slapi_log_err(SLAPI_LOG_PLUGIN, PRE_PLUGIN_NAME,
-diff --git a/ldap/servers/plugins/acctpolicy/acct_util.c b/ldap/servers/plugins/acctpolicy/acct_util.c
-index f25a3202d..f432092fe 100644
---- a/ldap/servers/plugins/acctpolicy/acct_util.c
-+++ b/ldap/servers/plugins/acctpolicy/acct_util.c
-@@ -85,6 +85,7 @@ get_attr_string_val(Slapi_Entry *target_entry, char *attr_name)
- int
- get_acctpolicy(Slapi_PBlock *pb __attribute__((unused)), Slapi_Entry *target_entry, void *plugin_id, acctPolicy **policy)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     Slapi_DN *sdn = NULL;
-     Slapi_Entry *policy_entry = NULL;
-     Slapi_Attr *attr;
-@@ -123,8 +124,7 @@ get_acctpolicy(Slapi_PBlock *pb __attribute__((unused)), Slapi_Entry *target_ent
-     }
- 
-     sdn = slapi_sdn_new_dn_byref(policy_dn);
--    ldrc = slapi_search_internal_get_entry(sdn, NULL, &policy_entry,
--                                           plugin_id);
-+    ldrc = slapi_search_get_entry(&entry_pb, sdn, NULL, &policy_entry, plugin_id);
-     slapi_sdn_free(&sdn);
- 
-     /* There should be a policy but it can't be retrieved; fatal error */
-@@ -160,7 +160,7 @@ dopolicy:
- done:
-     config_unlock();
-     slapi_ch_free_string(&policy_dn);
--    slapi_entry_free(policy_entry);
-+    slapi_search_get_entry_done(&entry_pb);
-     return (rc);
- }
- 
-diff --git a/ldap/servers/plugins/automember/automember.c b/ldap/servers/plugins/automember/automember.c
-index 7c875c852..39350ad53 100644
---- a/ldap/servers/plugins/automember/automember.c
-+++ b/ldap/servers/plugins/automember/automember.c
-@@ -1629,13 +1629,12 @@ automember_update_member_value(Slapi_Entry *member_e, const char *group_dn, char
-     char *member_value = NULL;
-     int rc = 0;
-     Slapi_DN *group_sdn;
--    Slapi_Entry *group_entry = NULL;
- 
-     /* First thing check that the group still exists */
-     group_sdn = slapi_sdn_new_dn_byval(group_dn);
--    rc = slapi_search_internal_get_entry(group_sdn, NULL, &group_entry, automember_get_plugin_id());
-+    rc = slapi_search_internal_get_entry(group_sdn, NULL, NULL, automember_get_plugin_id());
-     slapi_sdn_free(&group_sdn);
--    if (rc != LDAP_SUCCESS || group_entry == NULL) {
-+    if (rc != LDAP_SUCCESS) {
-         if (rc == LDAP_NO_SUCH_OBJECT) {
-             /* the automember group (default or target) does not exist, just skip this definition */
-             slapi_log_err(SLAPI_LOG_INFO, AUTOMEMBER_PLUGIN_SUBSYSTEM,
-@@ -1647,10 +1646,8 @@ automember_update_member_value(Slapi_Entry *member_e, const char *group_dn, char
-                       "automember_update_member_value - group (default or target) can not be retrieved (%s) err=%d\n",
-                       group_dn, rc);
-         }
--        slapi_entry_free(group_entry);
-         return rc;
-     }
--    slapi_entry_free(group_entry);
- 
-     /* If grouping_value is dn, we need to fetch the dn instead. */
-     if (slapi_attr_type_cmp(grouping_value, "dn", SLAPI_TYPE_CMP_EXACT) == 0) {
-@@ -1752,11 +1749,11 @@ out:
- static int
- automember_pre_op(Slapi_PBlock *pb, int modop)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     Slapi_DN *sdn = 0;
-     Slapi_Entry *e = 0;
-     Slapi_Mods *smods = 0;
-     LDAPMod **mods;
--    int free_entry = 0;
-     char *errstr = NULL;
-     int ret = SLAPI_PLUGIN_SUCCESS;
- 
-@@ -1784,8 +1781,7 @@ automember_pre_op(Slapi_PBlock *pb, int modop)
-             /* Fetch the entry being modified so we can
-              * create the resulting entry for validation. */
-             if (sdn) {
--                slapi_search_internal_get_entry(sdn, 0, &e, automember_get_plugin_id());
--                free_entry = 1;
-+                slapi_search_get_entry(&entry_pb, sdn, 0, &e, automember_get_plugin_id());
-             }
- 
-             /* If the entry doesn't exist, just bail and
-@@ -1799,7 +1795,7 @@ automember_pre_op(Slapi_PBlock *pb, int modop)
-             smods = slapi_mods_new();
-             slapi_mods_init_byref(smods, mods);
- 
--            /* Apply the  mods to create the resulting entry. */
-+            /* Apply the mods to create the resulting entry. */
-             if (mods && (slapi_entry_apply_mods(e, mods) != LDAP_SUCCESS)) {
-                 /* The mods don't apply cleanly, so we just let this op go
-                  * to let the main server handle it. */
-@@ -1831,8 +1827,7 @@ bailmod:
-     }
- 
- bail:
--    if (free_entry && e)
--        slapi_entry_free(e);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     if (ret) {
-         slapi_log_err(SLAPI_LOG_PLUGIN, AUTOMEMBER_PLUGIN_SUBSYSTEM,
-diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
-index 1ee271359..16c625bb0 100644
---- a/ldap/servers/plugins/dna/dna.c
-+++ b/ldap/servers/plugins/dna/dna.c
-@@ -1178,7 +1178,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply)
- 
-     value = slapi_entry_attr_get_charptr(e, DNA_SHARED_CFG_DN);
-     if (value) {
--        Slapi_Entry *shared_e = NULL;
-         Slapi_DN *sdn = NULL;
-         char *normdn = NULL;
-         char *attrs[2];
-@@ -1197,10 +1196,8 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply)
-         /* We don't need attributes */
-         attrs[0] = "cn";
-         attrs[1] = NULL;
--        slapi_search_internal_get_entry(sdn, attrs, &shared_e, getPluginID());
--
-         /* Make sure that the shared config entry exists. */
--        if (!shared_e) {
-+        if(slapi_search_internal_get_entry(sdn, attrs, NULL, getPluginID()) != LDAP_SUCCESS) {
-             /* We didn't locate the shared config container entry. Log
-              * a message and skip this config entry. */
-             slapi_log_err(SLAPI_LOG_ERR, DNA_PLUGIN_SUBSYSTEM,
-@@ -1210,9 +1207,6 @@ dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry *e, int apply)
-             ret = DNA_FAILURE;
-             slapi_sdn_free(&sdn);
-             goto bail;
--        } else {
--            slapi_entry_free(shared_e);
--            shared_e = NULL;
-         }
- 
-         normdn = (char *)slapi_sdn_get_dn(sdn);
-@@ -1539,6 +1533,7 @@ dna_delete_shared_servers(PRCList **servers)
- static int
- dna_load_host_port(void)
- {
-+    Slapi_PBlock *pb = NULL;
-     int status = DNA_SUCCESS;
-     Slapi_Entry *e = NULL;
-     Slapi_DN *config_dn = NULL;
-@@ -1554,7 +1549,7 @@ dna_load_host_port(void)
- 
-     config_dn = slapi_sdn_new_ndn_byref("cn=config");
-     if (config_dn) {
--        slapi_search_internal_get_entry(config_dn, attrs, &e, getPluginID());
-+        slapi_search_get_entry(&pb, config_dn, attrs, &e, getPluginID());
-         slapi_sdn_free(&config_dn);
-     }
- 
-@@ -1562,8 +1557,8 @@ dna_load_host_port(void)
-         hostname = slapi_entry_attr_get_charptr(e, "nsslapd-localhost");
-         portnum = slapi_entry_attr_get_charptr(e, "nsslapd-port");
-         secureportnum = slapi_entry_attr_get_charptr(e, "nsslapd-secureport");
--        slapi_entry_free(e);
-     }
-+    slapi_search_get_entry_done(&pb);
- 
-     if (!hostname || !portnum) {
-         status = DNA_FAILURE;
-@@ -2876,6 +2871,7 @@ bail:
- static int
- dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     char *replica_dn = NULL;
-     Slapi_DN *replica_sdn = NULL;
-     Slapi_DN *range_sdn = NULL;
-@@ -2912,8 +2908,7 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
-         attrs[2] = 0;
- 
-         /* Find cn=replica entry via search */
--        slapi_search_internal_get_entry(replica_sdn, attrs, &e, getPluginID());
--
-+        slapi_search_get_entry(&entry_pb, replica_sdn, attrs, &e, getPluginID());
-         if (e) {
-             /* Check if the passed in bind dn matches any of the replica bind dns. */
-             Slapi_Value *bind_dn_sv = slapi_value_new_string(bind_dn);
-@@ -2927,6 +2922,7 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
-                 attrs[0] = "member";
-                 attrs[1] = "uniquemember";
-                 attrs[2] = 0;
-+                slapi_search_get_entry_done(&entry_pb);
-                 for (i = 0; bind_group_dn != NULL && bind_group_dn[i] != NULL; i++) {
-                     if (ret) {
-                         /* already found a member, just free group */
-@@ -2934,14 +2930,14 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
-                         continue;
-                     }
-                     bind_group_sdn = slapi_sdn_new_normdn_passin(bind_group_dn[i]);
--                    slapi_search_internal_get_entry(bind_group_sdn, attrs, &bind_group_entry, getPluginID());
-+                    slapi_search_get_entry(&entry_pb, bind_group_sdn, attrs, &bind_group_entry, getPluginID());
-                     if (bind_group_entry) {
-                         ret = slapi_entry_attr_has_syntax_value(bind_group_entry, "member", bind_dn_sv);
-                         if (ret == 0) {
-                             ret = slapi_entry_attr_has_syntax_value(bind_group_entry, "uniquemember", bind_dn_sv);
-                         }
-                     }
--                    slapi_entry_free(bind_group_entry);
-+                    slapi_search_get_entry_done(&entry_pb);
-                     slapi_sdn_free(&bind_group_sdn);
-                 }
-                 slapi_ch_free((void **)&bind_group_dn);
-@@ -2956,7 +2952,6 @@ dna_is_replica_bind_dn(char *range_dn, char *bind_dn)
-     }
- 
- done:
--    slapi_entry_free(e);
-     slapi_sdn_free(&range_sdn);
-     slapi_sdn_free(&replica_sdn);
- 
-diff --git a/ldap/servers/plugins/memberof/memberof.c b/ldap/servers/plugins/memberof/memberof.c
-index 40bd4b380..e9e1ec4c7 100644
---- a/ldap/servers/plugins/memberof/memberof.c
-+++ b/ldap/servers/plugins/memberof/memberof.c
-@@ -884,7 +884,7 @@ memberof_postop_modrdn(Slapi_PBlock *pb)
-             pre_sdn = slapi_entry_get_sdn(pre_e);
-             post_sdn = slapi_entry_get_sdn(post_e);
-         }
--        
-+
-         if (pre_sdn && post_sdn && slapi_sdn_compare(pre_sdn, post_sdn) == 0) {
-             /* Regarding memberof plugin, this rename is a no-op
-              * but it can be expensive to process it. So skip it
-@@ -1466,6 +1466,7 @@ memberof_modop_one_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, Slapi
- int
- memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_op, Slapi_DN *group_sdn, Slapi_DN *op_this_sdn, Slapi_DN *replace_with_sdn, Slapi_DN *op_to_sdn, memberofstringll *stack)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     int rc = 0;
-     LDAPMod mod;
-     LDAPMod replace_mod;
-@@ -1515,8 +1516,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_o
-     }
- 
-     /* determine if this is a group op or single entry */
--    slapi_search_internal_get_entry(op_to_sdn, config->groupattrs,
--                                    &e, memberof_get_plugin_id());
-+    slapi_search_get_entry(&entry_pb, op_to_sdn, config->groupattrs, &e, memberof_get_plugin_id());
-     if (!e) {
-         /* In the case of a delete, we need to worry about the
-          * missing entry being a nested group.  There's a small
-@@ -1751,7 +1751,7 @@ memberof_modop_one_replace_r(Slapi_PBlock *pb, MemberOfConfig *config, int mod_o
- bail:
-     slapi_value_free(&to_dn_val);
-     slapi_value_free(&this_dn_val);
--    slapi_entry_free(e);
-+    slapi_search_get_entry_done(&entry_pb);
-     return rc;
- }
- 
-@@ -2368,6 +2368,7 @@ bail:
- int
- memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, Slapi_Value *memberdn)
- {
-+    Slapi_PBlock *pb = NULL;
-     int rc = 0;
-     Slapi_DN *sdn = 0;
-     Slapi_Entry *group_e = 0;
-@@ -2376,8 +2377,8 @@ memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, Slapi_Va
- 
-     sdn = slapi_sdn_new_normdn_byref(slapi_value_get_string(groupdn));
- 
--    slapi_search_internal_get_entry(sdn, config->groupattrs,
--                                    &group_e, memberof_get_plugin_id());
-+    slapi_search_get_entry(&pb, sdn, config->groupattrs,
-+                           &group_e, memberof_get_plugin_id());
- 
-     if (group_e) {
-         /* See if memberdn is referred to by any of the group attributes. */
-@@ -2388,9 +2389,8 @@ memberof_is_direct_member(MemberOfConfig *config, Slapi_Value *groupdn, Slapi_Va
-                 break;
-             }
-         }
--
--        slapi_entry_free(group_e);
-     }
-+    slapi_search_get_entry_done(&pb);
- 
-     slapi_sdn_free(&sdn);
-     return rc;
-diff --git a/ldap/servers/plugins/pam_passthru/pam_ptconfig.c b/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
-index 46a76d884..cbec2ec40 100644
---- a/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
-+++ b/ldap/servers/plugins/pam_passthru/pam_ptconfig.c
-@@ -749,22 +749,22 @@ pam_passthru_get_config(Slapi_DN *bind_sdn)
-             if (pam_passthru_check_suffix(cfg, bind_sdn) == LDAP_SUCCESS) {
-                 if (cfg->slapi_filter) {
-                     /* A filter is configured, so see if the bind entry is a match. */
-+                    Slapi_PBlock *entry_pb = NULL;
-                     Slapi_Entry *test_e = NULL;
- 
-                     /* Fetch the bind entry */
--                    slapi_search_internal_get_entry(bind_sdn, NULL, &test_e,
--                                                    pam_passthruauth_get_plugin_identity());
-+                    slapi_search_get_entry(&entry_pb, bind_sdn, NULL, &test_e,
-+                                           pam_passthruauth_get_plugin_identity());
- 
-                     /* If the entry doesn't exist, just fall through to the main server code */
-                     if (test_e) {
-                         /* Evaluate the filter. */
-                         if (LDAP_SUCCESS == slapi_filter_test_simple(test_e, cfg->slapi_filter)) {
-                             /* This is a match. */
--                            slapi_entry_free(test_e);
-+                            slapi_search_get_entry_done(&entry_pb);
-                             goto done;
-                         }
--
--                        slapi_entry_free(test_e);
-+                        slapi_search_get_entry_done(&entry_pb);
-                     }
-                 } else {
-                     /* There is no filter to check, so this is a match. */
-diff --git a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
-index 7f5fb02c4..5b43f8d1f 100644
---- a/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
-+++ b/ldap/servers/plugins/pam_passthru/pam_ptimpl.c
-@@ -81,11 +81,12 @@ derive_from_bind_dn(Slapi_PBlock *pb __attribute__((unused)), const Slapi_DN *bi
- static char *
- derive_from_bind_entry(Slapi_PBlock *pb, const Slapi_DN *bindsdn, MyStrBuf *pam_id, char *map_ident_attr, int *locked)
- {
-+	Slapi_PBlock *entry_pb = NULL;
-     Slapi_Entry *entry = NULL;
-     char *attrs[] = {NULL, NULL};
-     attrs[0] = map_ident_attr;
--    int rc = slapi_search_internal_get_entry((Slapi_DN *)bindsdn, attrs, &entry,
--                                             pam_passthruauth_get_plugin_identity());
-+    int32_t rc = slapi_search_get_entry(&entry_pb, (Slapi_DN *)bindsdn, attrs, &entry,
-+                                        pam_passthruauth_get_plugin_identity());
- 
-     if (rc != LDAP_SUCCESS) {
-         slapi_log_err(SLAPI_LOG_ERR, PAM_PASSTHRU_PLUGIN_SUBSYSTEM,
-@@ -108,7 +109,7 @@ derive_from_bind_entry(Slapi_PBlock *pb, const Slapi_DN *bindsdn, MyStrBuf *pam_
-         init_my_str_buf(pam_id, val);
-     }
- 
--    slapi_entry_free(entry);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     return pam_id->str;
- }
-diff --git a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
-index 3d0067531..5bca823ff 100644
---- a/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
-+++ b/ldap/servers/plugins/pam_passthru/pam_ptpreop.c
-@@ -526,6 +526,7 @@ done:
- static int
- pam_passthru_preop(Slapi_PBlock *pb, int modtype)
- {
-+	Slapi_PBlock *entry_pb = NULL;
-     Slapi_DN *sdn = NULL;
-     Slapi_Entry *e = NULL;
-     LDAPMod **mods;
-@@ -555,8 +556,8 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype)
-         case LDAP_CHANGETYPE_MODIFY:
-             /* Fetch the entry being modified so we can
-              * create the resulting entry for validation. */
--            slapi_search_internal_get_entry(sdn, 0, &e,
--                                            pam_passthruauth_get_plugin_identity());
-+            slapi_search_get_entry(&entry_pb, sdn, 0, &e,
-+                                   pam_passthruauth_get_plugin_identity());
- 
-             /* If the entry doesn't exist, just bail and
-              * let the server handle it. */
-@@ -576,9 +577,6 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype)
-                     /* Don't bail here, as we need to free the entry. */
-                 }
-             }
--
--            /* Free the entry. */
--            slapi_entry_free(e);
-             break;
-         case LDAP_CHANGETYPE_DELETE:
-         case LDAP_CHANGETYPE_MODDN:
-@@ -591,6 +589,7 @@ pam_passthru_preop(Slapi_PBlock *pb, int modtype)
-     }
- 
- bail:
-+    slapi_search_get_entry_done(&entry_pb);
-     /* If we are refusing the operation, return the result to the client. */
-     if (ret) {
-         slapi_send_ldap_result(pb, ret, NULL, returntext, 0, NULL);
-diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
-index 3b65d6b20..a25839f21 100644
---- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
-+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
-@@ -469,7 +469,8 @@ retry:
-          */
-         /* Get suffix */
-         Slapi_Entry *suffix = NULL;
--        rc = slapi_search_internal_get_entry(area_sdn, NULL, &suffix, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION));
-+        Slapi_PBlock *suffix_pb = NULL;
-+        rc = slapi_search_get_entry(&suffix_pb, area_sdn, NULL, &suffix, repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION));
-         if (rc) {
-             slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "repl5_tot_run -  Unable to "
-                                                            "get the suffix entry \"%s\".\n",
-@@ -517,7 +518,7 @@ retry:
-                                      LDAP_SCOPE_SUBTREE, "(parentid>=1)", NULL, 0, ctrls, NULL,
-                                      repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), OP_FLAG_BULK_IMPORT);
-         cb_data.num_entries = 0UL;
--        slapi_entry_free(suffix);
-+        slapi_search_get_entry_done(&suffix_pb);
-     } else {
-         /* Original total update */
-         /* we need to provide managedsait control so that referral entries can
-diff --git a/ldap/servers/plugins/uiduniq/uid.c b/ldap/servers/plugins/uiduniq/uid.c
-index d7ccf0e07..e69012204 100644
---- a/ldap/servers/plugins/uiduniq/uid.c
-+++ b/ldap/servers/plugins/uiduniq/uid.c
-@@ -1254,6 +1254,7 @@ preop_modify(Slapi_PBlock *pb)
- static int
- preop_modrdn(Slapi_PBlock *pb)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     int result = LDAP_SUCCESS;
-     Slapi_Entry *e = NULL;
-     Slapi_Value *sv_requiredObjectClass = NULL;
-@@ -1351,7 +1352,7 @@ preop_modrdn(Slapi_PBlock *pb)
- 
-     /* Get the entry that is being renamed so we can make a dummy copy
-      * of what it will look like after the rename. */
--    err = slapi_search_internal_get_entry(sdn, NULL, &e, plugin_identity);
-+    err = slapi_search_get_entry(&entry_pb, sdn, NULL, &e, plugin_identity);
-     if (err != LDAP_SUCCESS) {
-         result = uid_op_error(35);
-         /* We want to return a no such object error if the target doesn't exist. */
-@@ -1371,24 +1372,24 @@ preop_modrdn(Slapi_PBlock *pb)
- 
- 
-     /*
--         * Check if it has the required object class
--         */
-+     * Check if it has the required object class
-+     */
-     if (requiredObjectClass &&
-         !slapi_entry_attr_has_syntax_value(e, SLAPI_ATTR_OBJECTCLASS, sv_requiredObjectClass)) {
-         break;
-     }
- 
-     /*
--         * Find any unique attribute data in the new RDN
--         */
-+     * Find any unique attribute data in the new RDN
-+     */
-     for (i = 0; attrNames && attrNames[i]; i++) {
-         err = slapi_entry_attr_find(e, attrNames[i], &attr);
-         if (!err) {
-             /*
--                 * Passed all the requirements - this is an operation we
--                 * need to enforce uniqueness on. Now find all parent entries
--                 * with the marker object class, and do a search for each one.
--                 */
-+             * Passed all the requirements - this is an operation we
-+             * need to enforce uniqueness on. Now find all parent entries
-+             * with the marker object class, and do a search for each one.
-+             */
-             if (NULL != markerObjectClass) {
-                 /* Subtree defined by location of marker object class */
-                 result = findSubtreeAndSearch(slapi_entry_get_sdn(e), attrNames, attr, NULL,
-@@ -1407,8 +1408,8 @@ preop_modrdn(Slapi_PBlock *pb)
-     END
-         /* Clean-up */
-         slapi_value_free(&sv_requiredObjectClass);
--    if (e)
--        slapi_entry_free(e);
-+
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     if (result) {
-         slapi_log_err(SLAPI_LOG_PLUGIN, plugin_name,
-diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
-index 65f23363a..a70f40316 100644
---- a/ldap/servers/slapd/daemon.c
-+++ b/ldap/servers/slapd/daemon.c
-@@ -1916,18 +1916,13 @@ slapd_bind_local_user(Connection *conn)
-             char *root_dn = config_get_ldapi_root_dn();
- 
-             if (root_dn) {
-+                Slapi_PBlock *entry_pb = NULL;
-                 Slapi_DN *edn = slapi_sdn_new_dn_byref(
-                     slapi_dn_normalize(root_dn));
-                 Slapi_Entry *e = 0;
- 
-                 /* root might be locked too! :) */
--                ret = slapi_search_internal_get_entry(
--                    edn, 0,
--                    &e,
--                    (void *)plugin_get_default_component_id()
--
--                        );
--
-+                ret = slapi_search_get_entry(&entry_pb, edn, 0, &e, (void *)plugin_get_default_component_id());
-                 if (0 == ret && e) {
-                     ret = slapi_check_account_lock(
-                         0, /* pb not req */
-@@ -1955,7 +1950,7 @@ slapd_bind_local_user(Connection *conn)
-             root_map_free:
-                 /* root_dn consumed by bind creds set */
-                 slapi_sdn_free(&edn);
--                slapi_entry_free(e);
-+                slapi_search_get_entry_done(&entry_pb);
-                 ret = 0;
-             }
-         }
-diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
-index bbc0ab71a..259bedfff 100644
---- a/ldap/servers/slapd/modify.c
-+++ b/ldap/servers/slapd/modify.c
-@@ -592,6 +592,7 @@ modify_internal_pb(Slapi_PBlock *pb)
- static void
- op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw)
- {
-+    Slapi_PBlock *entry_pb = NULL;
-     Slapi_Backend *be = NULL;
-     Slapi_Entry *pse;
-     Slapi_Entry *referral;
-@@ -723,7 +724,7 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw)
-      * 2. If yes, then if the mods contain any passwdpolicy specific attributes.
-      * 3. If yes, then it invokes corrosponding checking function.
-      */
--    if (!repl_op && !internal_op && normdn && (e = get_entry(pb, normdn))) {
-+    if (!repl_op && !internal_op && normdn && slapi_search_get_entry(&entry_pb, sdn, NULL, &e, NULL) == LDAP_SUCCESS) {
-         Slapi_Value target;
-         slapi_value_init(&target);
-         slapi_value_set_string(&target, "passwordpolicy");
-@@ -1072,7 +1073,7 @@ free_and_return : {
-     slapi_entry_free(epre);
-     slapi_entry_free(epost);
- }
--    slapi_entry_free(e);
-+    slapi_search_get_entry_done(&entry_pb);
- 
-     if (be)
-         slapi_be_Unlock(be);
-@@ -1202,12 +1203,13 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M
-     if (!internal_op) {
-         /* slapi_acl_check_mods needs an array of LDAPMods, but
-          * we're really only interested in the one password mod. */
-+        Slapi_PBlock *entry_pb = NULL;
-         LDAPMod *mods[2];
-         mods[0] = mod;
-         mods[1] = NULL;
- 
-         /* We need to actually fetch the target here to use for ACI checking. */
--        slapi_search_internal_get_entry(&sdn, NULL, &e, (void *)plugin_get_default_component_id());
-+        slapi_search_get_entry(&entry_pb, &sdn, NULL, &e, NULL);
- 
-         /* Create a bogus entry with just the target dn if we were unable to
-          * find the actual entry.  This will only be used for checking the ACIs. */
-@@ -1238,9 +1240,12 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M
-             }
-             send_ldap_result(pb, res, NULL, errtxt, 0, NULL);
-             slapi_ch_free_string(&errtxt);
-+            slapi_search_get_entry_done(&entry_pb);
-             rc = -1;
-             goto done;
-         }
-+        /* done with slapi entry e */
-+        slapi_search_get_entry_done(&entry_pb);
- 
-         /*
-          * If this mod is being performed by a password administrator/rootDN,
-@@ -1353,7 +1358,6 @@ op_shared_allow_pw_change(Slapi_PBlock *pb, LDAPMod *mod, char **old_pw, Slapi_M
-     valuearray_free(&values);
- 
- done:
--    slapi_entry_free(e);
-     slapi_sdn_done(&sdn);
-     slapi_ch_free_string(&proxydn);
-     slapi_ch_free_string(&proxystr);
-diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c
-index 9da266b61..a140e7988 100644
---- a/ldap/servers/slapd/plugin_internal_op.c
-+++ b/ldap/servers/slapd/plugin_internal_op.c
-@@ -882,3 +882,51 @@ slapi_search_internal_get_entry(Slapi_DN *dn, char **attrs, Slapi_Entry **ret_en
-     int_search_pb = NULL;
-     return rc;
- }
-+
-+int32_t
-+slapi_search_get_entry(Slapi_PBlock **pb, Slapi_DN *dn, char **attrs, Slapi_Entry **ret_entry, void *component_identity)
-+{
-+    Slapi_Entry **entries = NULL;
-+    int32_t rc = 0;
-+    void *component = component_identity;
-+
-+    if (ret_entry) {
-+        *ret_entry = NULL;
-+    }
-+
-+    if (component == NULL) {
-+        component = (void *)plugin_get_default_component_id();
-+    }
-+
-+    if (*pb == NULL) {
-+        *pb = slapi_pblock_new();
-+    }
-+    slapi_search_internal_set_pb(*pb, slapi_sdn_get_dn(dn), LDAP_SCOPE_BASE,
-+        "(|(objectclass=*)(objectclass=ldapsubentry))",
-+        attrs, 0, NULL, NULL, component, 0 );
-+    slapi_search_internal_pb(*pb);
-+    slapi_pblock_get(*pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
-+    if (LDAP_SUCCESS == rc) {
-+        slapi_pblock_get(*pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
-+        if (NULL != entries && NULL != entries[0]) {
-+            /* Only need to dup the entry if the caller passed ret_entry in. */
-+            if (ret_entry) {
-+                *ret_entry = entries[0];
-+            }
-+        } else {
-+            rc = LDAP_NO_SUCH_OBJECT;
-+        }
-+    }
-+
-+    return rc;
-+}
-+
-+void
-+slapi_search_get_entry_done(Slapi_PBlock **pb)
-+{
-+    if (pb && *pb) {
-+        slapi_free_search_results_internal(*pb);
-+        slapi_pblock_destroy(*pb);
-+        *pb = NULL;
-+    }
-+}
-diff --git a/ldap/servers/slapd/resourcelimit.c b/ldap/servers/slapd/resourcelimit.c
-index 705344c84..9c2619716 100644
---- a/ldap/servers/slapd/resourcelimit.c
-+++ b/ldap/servers/slapd/resourcelimit.c
-@@ -305,22 +305,17 @@ reslimit_get_ext(Slapi_Connection *conn, const char *logname, SLAPIResLimitConnD
- int
- reslimit_update_from_dn(Slapi_Connection *conn, Slapi_DN *dn)
- {
--    Slapi_Entry *e;
-+    Slapi_PBlock *pb = NULL;
-+    Slapi_Entry *e = NULL;
-     int rc;
- 
--    e = NULL;
-     if (dn != NULL) {
--
-         char **attrs = reslimit_get_registered_attributes();
--        (void)slapi_search_internal_get_entry(dn, attrs, &e, reslimit_componentid);
-+        slapi_search_get_entry(&pb, dn, attrs, &e, reslimit_componentid);
-         charray_free(attrs);
-     }
--
-     rc = reslimit_update_from_entry(conn, e);
--
--    if (NULL != e) {
--        slapi_entry_free(e);
--    }
-+    slapi_search_get_entry_done(&pb);
- 
-     return (rc);
- }
-diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
-index d44b03b0e..bf7e59f75 100644
---- a/ldap/servers/slapd/schema.c
-+++ b/ldap/servers/slapd/schema.c
-@@ -341,6 +341,7 @@ schema_policy_add_action(Slapi_Entry *entry, char *attrName, schema_item_t **lis
- static void
- schema_load_repl_policy(const char *dn, repl_schema_policy_t *replica)
- {
-+    Slapi_PBlock *pb = NULL;
-     Slapi_DN sdn;
-     Slapi_Entry *entry = NULL;
-     schema_item_t *schema_item, *next;
-@@ -369,8 +370,7 @@ schema_load_repl_policy(const char *dn, repl_schema_policy_t *replica)
- 
-     /* Load the replication policy of the schema  */
-     slapi_sdn_init_dn_byref(&sdn, dn);
--    if (slapi_search_internal_get_entry(&sdn, NULL, &entry, plugin_get_default_component_id()) == LDAP_SUCCESS) {
--
-+    if (slapi_search_get_entry(&pb, &sdn, NULL, &entry, plugin_get_default_component_id()) == LDAP_SUCCESS) {
-         /* fill the policies (accept/reject) regarding objectclass */
-         schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_OBJECTCLASS_ACCEPT, &replica->objectclasses);
-         schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_OBJECTCLASS_REJECT, &replica->objectclasses);
-@@ -378,9 +378,8 @@ schema_load_repl_policy(const char *dn, repl_schema_policy_t *replica)
-         /* fill the policies (accept/reject) regarding attribute */
-         schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_ATTRIBUTE_ACCEPT, &replica->attributes);
-         schema_policy_add_action(entry, ATTR_SCHEMA_UPDATE_ATTRIBUTE_REJECT, &replica->attributes);
--
--        slapi_entry_free(entry);
-     }
-+    slapi_search_get_entry_done(&pb);
-     slapi_sdn_done(&sdn);
- }
- 
-diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
-index 0e3857068..be1e52e4d 100644
---- a/ldap/servers/slapd/slapi-plugin.h
-+++ b/ldap/servers/slapd/slapi-plugin.h
-@@ -5972,7 +5972,7 @@ void slapi_seq_internal_set_pb(Slapi_PBlock *pb, char *ibase, int type, char *at
- 
- /*
-  * slapi_search_internal_get_entry() finds an entry given a dn.  It returns
-- * an LDAP error code (LDAP_SUCCESS if all goes well).
-+ * an LDAP error code (LDAP_SUCCESS if all goes well).  Caller must free ret_entry
-  */
- int slapi_search_internal_get_entry(Slapi_DN *dn, char **attrlist, Slapi_Entry **ret_entry, void *caller_identity);
- 
-@@ -8296,6 +8296,27 @@ uint64_t slapi_atomic_decr_64(uint64_t *ptr, int memorder);
- /* helper function */
- const char * slapi_fetch_attr(Slapi_Entry *e, const char *attrname, char *default_val);
- 
-+/**
-+ * Get a Slapi_Entry via an internal search.  The caller then needs to call
-+ * slapi_get_entry_done() to free any resources allocated to get the entry
-+ *
-+ * \param pb - slapi_pblock pointer (the function will allocate if necessary)
-+ * \param dn - Slapi_DN of the entry to retrieve
-+ * \param attrs - char list of attributes to get
-+ * \param ret_entry - pointer to a Slapi_entry wer the returned entry is stored
-+ * \param component_identity - plugin component
-+ *
-+ * \return - ldap result code
-+ */
-+int32_t slapi_search_get_entry(Slapi_PBlock **pb, Slapi_DN *dn, char **attrs, Slapi_Entry **ret_entry, void *component_identity);
-+
-+/**
-+ * Free the resources allocated by slapi_search_get_entry()
-+ *
-+ * \param pb - slapi_pblock pointer
-+ */
-+void slapi_search_get_entry_done(Slapi_PBlock **pb);
-+
- #ifdef __cplusplus
- }
- #endif
--- 
-2.26.2
-
diff --git a/SOURCES/0005-Issue-51086-Improve-dscreate-instance-name-validatio.patch b/SOURCES/0005-Issue-51086-Improve-dscreate-instance-name-validatio.patch
deleted file mode 100644
index f3d3571..0000000
--- a/SOURCES/0005-Issue-51086-Improve-dscreate-instance-name-validatio.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-From 9710c327b3034d7a9d112306961c9cec98083df5 Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <simon.pichugin@gmail.com>
-Date: Mon, 18 May 2020 22:33:45 +0200
-Subject: [PATCH 05/12] Issue 51086 - Improve dscreate instance name validation
-
-Bug Description: When creating an instance using dscreate, it doesn't enforce
-max name length. The ldapi socket name contains name of the instance. If it's
-too long, we can hit limits, and the file name will be truncated. Also, it
-doesn't sanitize the instance name, it's possible to create an instance with
-non-ascii symbols in its name.
-
-Fix Description: Add more checks to 'dscreate from-file' installation.
-Add a limitation for nsslapd-ldapifilepath string lenght because it is
-limited by sizeof((*ports_info.i_listenaddr)->local.path)) it is copied to.
-
-https://pagure.io/389-ds-base/issue/51086
-
-Reviewed by: firstyear, mreynolds (Thanks!)
----
- ldap/servers/slapd/libglobs.c       | 12 ++++++++++++
- src/cockpit/389-console/src/ds.jsx  |  8 ++++++--
- src/lib389/lib389/instance/setup.py |  9 +++++++++
- 3 files changed, 27 insertions(+), 2 deletions(-)
-
-diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
-index 0d3d9a924..fbf90d92d 100644
---- a/ldap/servers/slapd/libglobs.c
-+++ b/ldap/servers/slapd/libglobs.c
-@@ -2390,11 +2390,23 @@ config_set_ldapi_filename(const char *attrname, char *value, char *errorbuf, int
- {
-     int retVal = LDAP_SUCCESS;
-     slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
-+    /*
-+     * LDAPI file path length is limited by sizeof((*ports_info.i_listenaddr)->local.path))
-+     * which is set in main.c inside of "#if defined(ENABLE_LDAPI)" block
-+     * ports_info.i_listenaddr is sizeof(PRNetAddr) and our required sizes is 8 bytes less
-+     */
-+    size_t result_size = sizeof(PRNetAddr) - 8;
- 
-     if (config_value_is_null(attrname, value, errorbuf, 0)) {
-         return LDAP_OPERATIONS_ERROR;
-     }
- 
-+    if (strlen(value) >= result_size) {
-+        slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: \"%s\" is invalid, its length must be less than %d",
-+                              attrname, value, result_size);
-+        return LDAP_OPERATIONS_ERROR;
-+    }
-+
-     if (apply) {
-         CFG_LOCK_WRITE(slapdFrontendConfig);
- 
-diff --git a/src/cockpit/389-console/src/ds.jsx b/src/cockpit/389-console/src/ds.jsx
-index 90d9e5abd..53aa5cb79 100644
---- a/src/cockpit/389-console/src/ds.jsx
-+++ b/src/cockpit/389-console/src/ds.jsx
-@@ -793,10 +793,14 @@ class CreateInstanceModal extends React.Component {
-             return;
-         }
-         newServerId = newServerId.replace(/^slapd-/i, ""); // strip "slapd-"
--        if (newServerId.length > 128) {
-+        if (newServerId === "admin") {
-+            addNotification("warning", "Instance Name 'admin' is reserved, please choose a different name");
-+            return;
-+        }
-+        if (newServerId.length > 80) {
-             addNotification(
-                 "warning",
--                "Instance name is too long, it must not exceed 128 characters"
-+                "Instance name is too long, it must not exceed 80 characters"
-             );
-             return;
-         }
-diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
-index 803992275..f5fc5495d 100644
---- a/src/lib389/lib389/instance/setup.py
-+++ b/src/lib389/lib389/instance/setup.py
-@@ -567,6 +567,15 @@ class SetupDs(object):
- 
-         # We need to know the prefix before we can do the instance checks
-         assert_c(slapd['instance_name'] is not None, "Configuration instance_name in section [slapd] not found")
-+        assert_c(len(slapd['instance_name']) <= 80, "Server identifier should not be longer than 80 symbols")
-+        assert_c(all(ord(c) < 128 for c in slapd['instance_name']), "Server identifier can not contain non ascii characters")
-+        assert_c(' ' not in slapd['instance_name'], "Server identifier can not contain a space")
-+        assert_c(slapd['instance_name'] != 'admin', "Server identifier \"admin\" is reserved, please choose a different identifier")
-+
-+        # Check that valid characters are used
-+        safe = re.compile(r'^[#%:\w@_-]+$').search
-+        assert_c(bool(safe(slapd['instance_name'])), "Server identifier has invalid characters, please choose a different value")
-+
-         # Check if the instance exists or not.
-         # Should I move this import? I think this prevents some recursion
-         from lib389 import DirSrv
--- 
-2.26.2
-
diff --git a/SOURCES/0006-Issue-51102-RFE-ds-replcheck-make-online-timeout-con.patch b/SOURCES/0006-Issue-51102-RFE-ds-replcheck-make-online-timeout-con.patch
deleted file mode 100644
index 5bb0635..0000000
--- a/SOURCES/0006-Issue-51102-RFE-ds-replcheck-make-online-timeout-con.patch
+++ /dev/null
@@ -1,254 +0,0 @@
-From c0cb15445c1434b3d317b1c06ab1a0ba8dbc6f04 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 19 May 2020 15:11:53 -0400
-Subject: [PATCH 06/12] Issue 51102 - RFE - ds-replcheck - make online timeout
- configurable
-
-Bug Description:  When doing an online check with replicas that are very
-                  far apart the connection can time out as the hardcoded
-                  timeout is 5 seconds.
-
-Fix Description:  Change the default timeout to never timeout, and add an
-                  CLI option to specify a specific timeout.
-
-                  Also caught all the possible LDAP exceptions so we can
-                  cleanly "fail".  Fixed some python syntax issues, and
-                  improved the entry inconsistency report
-
-relates: https://pagure.io/389-ds-base/issue/51102
-
-Reviewed by: firstyear & spichugi(Thanks!)
----
- ldap/admin/src/scripts/ds-replcheck | 90 ++++++++++++++++++-----------
- 1 file changed, 57 insertions(+), 33 deletions(-)
-
-diff --git a/ldap/admin/src/scripts/ds-replcheck b/ldap/admin/src/scripts/ds-replcheck
-index 30bcfd65d..5bb7dfce3 100755
---- a/ldap/admin/src/scripts/ds-replcheck
-+++ b/ldap/admin/src/scripts/ds-replcheck
-@@ -1,7 +1,7 @@
- #!/usr/bin/python3
- 
- # --- BEGIN COPYRIGHT BLOCK ---
--# Copyright (C) 2018 Red Hat, Inc.
-+# Copyright (C) 2020 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
-@@ -21,10 +21,9 @@ import getpass
- import signal
- from ldif import LDIFRecordList
- from ldap.ldapobject import SimpleLDAPObject
--from ldap.cidict import cidict
- from ldap.controls import SimplePagedResultsControl
- from lib389._entry import Entry
--from lib389.utils import ensure_str, ensure_list_str, ensure_int
-+from lib389.utils import ensure_list_str, ensure_int
- 
- VERSION = "2.0"
- RUV_FILTER = '(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))'
-@@ -185,11 +184,11 @@ def report_conflict(entry, attr, opts):
-     report = True
- 
-     if 'nscpentrywsi' in entry.data:
--        found = False
-         for val in entry.data['nscpentrywsi']:
-             if val.lower().startswith(attr + ';'):
-                 if (opts['starttime'] - extract_time(val)) <= opts['lag']:
-                     report = False
-+                    break
- 
-     return report
- 
-@@ -321,6 +320,9 @@ def ldif_search(LDIF, dn):
-     count = 0
-     ignore_list = ['conflictcsn', 'modifytimestamp', 'modifiersname']
-     val = ""
-+    attr = ""
-+    state_attr = ""
-+    part_dn = ""
-     result['entry'] = None
-     result['conflict'] = None
-     result['tombstone'] = False
-@@ -570,6 +572,7 @@ def cmp_entry(mentry, rentry, opts):
-                         if val.lower().startswith(mattr + ';'):
-                             if not found:
-                                 diff['diff'].append("      Master:")
-+                            diff['diff'].append("        - Value:      %s" % (val.split(':')[1].lstrip()))
-                             diff['diff'].append("        - State Info: %s" % (val))
-                             diff['diff'].append("        - Date:       %s\n" % (time.ctime(extract_time(val))))
-                             found = True
-@@ -588,6 +591,7 @@ def cmp_entry(mentry, rentry, opts):
-                         if val.lower().startswith(mattr + ';'):
-                             if not found:
-                                 diff['diff'].append("      Replica:")
-+                            diff['diff'].append("        - Value:      %s" % (val.split(':')[1].lstrip()))
-                             diff['diff'].append("        - State Info: %s" % (val))
-                             diff['diff'].append("        - Date:       %s\n" % (time.ctime(extract_time(val))))
-                             found = True
-@@ -654,7 +658,6 @@ def do_offline_report(opts, output_file=None):
-     rconflicts = []
-     rtombstones = 0
-     mtombstones = 0
--    idx = 0
- 
-     # Open LDIF files
-     try:
-@@ -926,7 +929,7 @@ def validate_suffix(ldapnode, suffix, hostname):
-     :return - True if suffix exists, otherwise False
-     """
-     try:
--        master_basesuffix = ldapnode.search_s(suffix, ldap.SCOPE_BASE )
-+        ldapnode.search_s(suffix, ldap.SCOPE_BASE)
-     except ldap.NO_SUCH_OBJECT:
-         print("Error: Failed to validate suffix in {}. {} does not exist.".format(hostname, suffix))
-         return False
-@@ -968,12 +971,12 @@ def connect_to_replicas(opts):
-     replica = SimpleLDAPObject(ruri)
- 
-     # Set timeouts
--    master.set_option(ldap.OPT_NETWORK_TIMEOUT,5.0)
--    master.set_option(ldap.OPT_TIMEOUT,5.0)
--    replica.set_option(ldap.OPT_NETWORK_TIMEOUT,5.0)
--    replica.set_option(ldap.OPT_TIMEOUT,5.0)
-+    master.set_option(ldap.OPT_NETWORK_TIMEOUT, opts['timeout'])
-+    master.set_option(ldap.OPT_TIMEOUT, opts['timeout'])
-+    replica.set_option(ldap.OPT_NETWORK_TIMEOUT, opts['timeout'])
-+    replica.set_option(ldap.OPT_TIMEOUT, opts['timeout'])
- 
--    # Setup Secure Conenction
-+    # Setup Secure Connection
-     if opts['certdir'] is not None:
-         # Setup Master
-         if opts['mprotocol'] != LDAPI:
-@@ -1003,7 +1006,7 @@ def connect_to_replicas(opts):
-     try:
-         master.simple_bind_s(opts['binddn'], opts['bindpw'])
-     except ldap.SERVER_DOWN as e:
--        print("Cannot connect to %r" % muri)
-+        print(f"Cannot connect to {muri} ({str(e)})")
-         sys.exit(1)
-     except ldap.LDAPError as e:
-         print("Error: Failed to authenticate to Master: ({}).  "
-@@ -1014,7 +1017,7 @@ def connect_to_replicas(opts):
-     try:
-         replica.simple_bind_s(opts['binddn'], opts['bindpw'])
-     except ldap.SERVER_DOWN as e:
--        print("Cannot connect to %r" % ruri)
-+        print(f"Cannot connect to {ruri} ({str(e)})")
-         sys.exit(1)
-     except ldap.LDAPError as e:
-         print("Error: Failed to authenticate to Replica: ({}).  "
-@@ -1218,7 +1221,6 @@ def do_online_report(opts, output_file=None):
-     """
-     m_done = False
-     r_done = False
--    done = False
-     report = {}
-     report['diff'] = []
-     report['m_missing'] = []
-@@ -1257,15 +1259,22 @@ def do_online_report(opts, output_file=None):
- 
-     # Read the results and start comparing
-     while not m_done or not r_done:
--        if not m_done:
--            m_rtype, m_rdata, m_rmsgid, m_rctrls = master.result3(master_msgid)
--        elif not r_done:
--            m_rdata = []
--
--        if not r_done:
--            r_rtype, r_rdata, r_rmsgid, r_rctrls = replica.result3(replica_msgid)
--        elif not m_done:
--            r_rdata = []
-+        try:
-+            if not m_done:
-+                m_rtype, m_rdata, m_rmsgid, m_rctrls = master.result3(master_msgid)
-+            elif not r_done:
-+                m_rdata = []
-+        except ldap.LDAPError as e:
-+            print("Error: Problem getting the results from the master: %s", str(e))
-+            sys.exit(1)
-+        try:
-+            if not r_done:
-+                r_rtype, r_rdata, r_rmsgid, r_rctrls = replica.result3(replica_msgid)
-+            elif not m_done:
-+                r_rdata = []
-+        except ldap.LDAPError as e:
-+            print("Error: Problem getting the results from the replica: %s", str(e))
-+            sys.exit(1)
- 
-         # Convert entries
-         mresult = convert_entries(m_rdata)
-@@ -1291,11 +1300,15 @@ def do_online_report(opts, output_file=None):
-                 ]
-             if m_pctrls:
-                 if m_pctrls[0].cookie:
--                    # Copy cookie from response control to request control
--                    req_pr_ctrl.cookie = m_pctrls[0].cookie
--                    master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
--                        "(|(objectclass=*)(objectclass=ldapsubentry))",
--                        ['*', 'createtimestamp', 'nscpentrywsi', 'conflictcsn', 'nsds5replconflict'], serverctrls=controls)
-+                    try:
-+                        # Copy cookie from response control to request control
-+                        req_pr_ctrl.cookie = m_pctrls[0].cookie
-+                        master_msgid = master.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
-+                            "(|(objectclass=*)(objectclass=ldapsubentry))",
-+                            ['*', 'createtimestamp', 'nscpentrywsi', 'conflictcsn', 'nsds5replconflict'], serverctrls=controls)
-+                    except ldap.LDAPError as e:
-+                        print("Error: Problem searching the master: %s", str(e))
-+                        sys.exit(1)
-                 else:
-                     m_done = True  # No more pages available
-             else:
-@@ -1311,11 +1324,15 @@ def do_online_report(opts, output_file=None):
- 
-             if r_pctrls:
-                 if r_pctrls[0].cookie:
--                    # Copy cookie from response control to request control
--                    req_pr_ctrl.cookie = r_pctrls[0].cookie
--                    replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
--                        "(|(objectclass=*)(objectclass=ldapsubentry))",
--                        ['*', 'createtimestamp', 'nscpentrywsi', 'conflictcsn', 'nsds5replconflict'], serverctrls=controls)
-+                    try:
-+                        # Copy cookie from response control to request control
-+                        req_pr_ctrl.cookie = r_pctrls[0].cookie
-+                        replica_msgid = replica.search_ext(opts['suffix'], ldap.SCOPE_SUBTREE,
-+                            "(|(objectclass=*)(objectclass=ldapsubentry))",
-+                            ['*', 'createtimestamp', 'nscpentrywsi', 'conflictcsn', 'nsds5replconflict'], serverctrls=controls)
-+                    except ldap.LDAPError as e:
-+                        print("Error: Problem searching the replica: %s", str(e))
-+                        sys.exit(1)
-                 else:
-                     r_done = True  # No more pages available
-             else:
-@@ -1426,6 +1443,9 @@ def init_online_params(args):
-         # prompt for password
-         opts['bindpw'] = getpass.getpass('Enter password: ')
- 
-+    # lastly handle the timeout
-+    opts['timeout'] = int(args.timeout)
-+
-     return opts
- 
- 
-@@ -1553,6 +1573,8 @@ def main():
-     state_parser.add_argument('-y', '--pass-file', help='A text file containing the clear text password for the bind dn', dest='pass_file', default=None)
-     state_parser.add_argument('-Z', '--cert-dir', help='The certificate database directory for secure connections',
-                               dest='certdir', default=None)
-+    state_parser.add_argument('-t', '--timeout', help='The timeout for the LDAP connections.  Default is no timeout.',
-+                              type=int, dest='timeout', default=-1)
- 
-     # Online mode
-     online_parser = subparsers.add_parser('online', help="Compare two online replicas for differences")
-@@ -1577,6 +1599,8 @@ def main():
-     online_parser.add_argument('-p', '--page-size', help='The paged-search result grouping size (default 500 entries)',
-                                dest='pagesize', default=500)
-     online_parser.add_argument('-o', '--out-file', help='The output file', dest='file', default=None)
-+    online_parser.add_argument('-t', '--timeout', help='The timeout for the LDAP connections.  Default is no timeout.',
-+                               type=int, dest='timeout', default=-1)
- 
-     # Offline LDIF mode
-     offline_parser = subparsers.add_parser('offline', help="Compare two replication LDIF files for differences (LDIF file generated by 'db2ldif -r')")
--- 
-2.26.2
-
diff --git a/SOURCES/0007-Issue-51110-Fix-ASAN-ODR-warnings.patch b/SOURCES/0007-Issue-51110-Fix-ASAN-ODR-warnings.patch
deleted file mode 100644
index df8423c..0000000
--- a/SOURCES/0007-Issue-51110-Fix-ASAN-ODR-warnings.patch
+++ /dev/null
@@ -1,428 +0,0 @@
-From a1cd3cf8e8b6b33ab21d5338921187a76dd9dcd0 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Fri, 22 May 2020 15:41:45 -0400
-Subject: [PATCH 07/12] Issue 51110 - Fix ASAN ODR warnings
-
-Description: Fixed ODR issues with glboal attributes which were duplicated from
-             the core server into the replication and retrocl plugins.
-
-relates: https://pagure.io/389-ds-base/issue/51110
-
-Reviewed by: firstyear(Thanks!)
----
- ldap/servers/plugins/replication/repl5.h      | 17 +++---
- .../plugins/replication/repl_globals.c        | 17 +++---
- ldap/servers/plugins/replication/replutil.c   | 16 +++---
- ldap/servers/plugins/retrocl/retrocl.h        | 22 ++++----
- ldap/servers/plugins/retrocl/retrocl_cn.c     | 12 ++---
- ldap/servers/plugins/retrocl/retrocl_po.c     | 52 +++++++++----------
- ldap/servers/plugins/retrocl/retrocl_trim.c   | 30 +++++------
- 7 files changed, 82 insertions(+), 84 deletions(-)
-
-diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
-index 873dd8a16..72b7089e3 100644
---- a/ldap/servers/plugins/replication/repl5.h
-+++ b/ldap/servers/plugins/replication/repl5.h
-@@ -280,15 +280,14 @@ struct berval *NSDS90StartReplicationRequest_new(const char *protocol_oid,
- int multimaster_extop_NSDS50ReplicationEntry(Slapi_PBlock *pb);
- 
- /* From repl_globals.c */
--extern char *attr_changenumber;
--extern char *attr_targetdn;
--extern char *attr_changetype;
--extern char *attr_newrdn;
--extern char *attr_deleteoldrdn;
--extern char *attr_changes;
--extern char *attr_newsuperior;
--extern char *attr_changetime;
--extern char *attr_dataversion;
-+extern char *repl_changenumber;
-+extern char *repl_targetdn;
-+extern char *repl_changetype;
-+extern char *repl_newrdn;
-+extern char *repl_deleteoldrdn;
-+extern char *repl_changes;
-+extern char *repl_newsuperior;
-+extern char *repl_changetime;
- extern char *attr_csn;
- extern char *changetype_add;
- extern char *changetype_delete;
-diff --git a/ldap/servers/plugins/replication/repl_globals.c b/ldap/servers/plugins/replication/repl_globals.c
-index 355a0ffa1..c615c77da 100644
---- a/ldap/servers/plugins/replication/repl_globals.c
-+++ b/ldap/servers/plugins/replication/repl_globals.c
-@@ -48,15 +48,14 @@ char *changetype_delete = CHANGETYPE_DELETE;
- char *changetype_modify = CHANGETYPE_MODIFY;
- char *changetype_modrdn = CHANGETYPE_MODRDN;
- char *changetype_moddn = CHANGETYPE_MODDN;
--char *attr_changenumber = ATTR_CHANGENUMBER;
--char *attr_targetdn = ATTR_TARGETDN;
--char *attr_changetype = ATTR_CHANGETYPE;
--char *attr_newrdn = ATTR_NEWRDN;
--char *attr_deleteoldrdn = ATTR_DELETEOLDRDN;
--char *attr_changes = ATTR_CHANGES;
--char *attr_newsuperior = ATTR_NEWSUPERIOR;
--char *attr_changetime = ATTR_CHANGETIME;
--char *attr_dataversion = ATTR_DATAVERSION;
-+char *repl_changenumber = ATTR_CHANGENUMBER;
-+char *repl_targetdn = ATTR_TARGETDN;
-+char *repl_changetype = ATTR_CHANGETYPE;
-+char *repl_newrdn = ATTR_NEWRDN;
-+char *repl_deleteoldrdn = ATTR_DELETEOLDRDN;
-+char *repl_changes = ATTR_CHANGES;
-+char *repl_newsuperior = ATTR_NEWSUPERIOR;
-+char *repl_changetime = ATTR_CHANGETIME;
- char *attr_csn = ATTR_CSN;
- char *type_copyingFrom = TYPE_COPYINGFROM;
- char *type_copiedFrom = TYPE_COPIEDFROM;
-diff --git a/ldap/servers/plugins/replication/replutil.c b/ldap/servers/plugins/replication/replutil.c
-index de1e77880..39f821d12 100644
---- a/ldap/servers/plugins/replication/replutil.c
-+++ b/ldap/servers/plugins/replication/replutil.c
-@@ -64,14 +64,14 @@ get_cleattrs()
- {
-     if (cleattrs[0] == NULL) {
-         cleattrs[0] = type_objectclass;
--        cleattrs[1] = attr_changenumber;
--        cleattrs[2] = attr_targetdn;
--        cleattrs[3] = attr_changetype;
--        cleattrs[4] = attr_newrdn;
--        cleattrs[5] = attr_deleteoldrdn;
--        cleattrs[6] = attr_changes;
--        cleattrs[7] = attr_newsuperior;
--        cleattrs[8] = attr_changetime;
-+        cleattrs[1] = repl_changenumber;
-+        cleattrs[2] = repl_targetdn;
-+        cleattrs[3] = repl_changetype;
-+        cleattrs[4] = repl_newrdn;
-+        cleattrs[5] = repl_deleteoldrdn;
-+        cleattrs[6] = repl_changes;
-+        cleattrs[7] = repl_newsuperior;
-+        cleattrs[8] = repl_changetime;
-         cleattrs[9] = NULL;
-     }
-     return cleattrs;
-diff --git a/ldap/servers/plugins/retrocl/retrocl.h b/ldap/servers/plugins/retrocl/retrocl.h
-index 06482a14c..2ce76fcec 100644
---- a/ldap/servers/plugins/retrocl/retrocl.h
-+++ b/ldap/servers/plugins/retrocl/retrocl.h
-@@ -94,17 +94,17 @@ extern int retrocl_nattributes;
- extern char **retrocl_attributes;
- extern char **retrocl_aliases;
- 
--extern const char *attr_changenumber;
--extern const char *attr_targetdn;
--extern const char *attr_changetype;
--extern const char *attr_newrdn;
--extern const char *attr_newsuperior;
--extern const char *attr_deleteoldrdn;
--extern const char *attr_changes;
--extern const char *attr_changetime;
--extern const char *attr_objectclass;
--extern const char *attr_nsuniqueid;
--extern const char *attr_isreplicated;
-+extern const char *retrocl_changenumber;
-+extern const char *retrocl_targetdn;
-+extern const char *retrocl_changetype;
-+extern const char *retrocl_newrdn;
-+extern const char *retrocl_newsuperior;
-+extern const char *retrocl_deleteoldrdn;
-+extern const char *retrocl_changes;
-+extern const char *retrocl_changetime;
-+extern const char *retrocl_objectclass;
-+extern const char *retrocl_nsuniqueid;
-+extern const char *retrocl_isreplicated;
- 
- extern PRLock *retrocl_internal_lock;
- extern Slapi_RWLock *retrocl_cn_lock;
-diff --git a/ldap/servers/plugins/retrocl/retrocl_cn.c b/ldap/servers/plugins/retrocl/retrocl_cn.c
-index 709d7a857..5fc5f586d 100644
---- a/ldap/servers/plugins/retrocl/retrocl_cn.c
-+++ b/ldap/servers/plugins/retrocl/retrocl_cn.c
-@@ -62,7 +62,7 @@ handle_cnum_entry(Slapi_Entry *e, void *callback_data)
-         Slapi_Attr *chattr = NULL;
-         sval = NULL;
-         value = NULL;
--        if (slapi_entry_attr_find(e, attr_changenumber, &chattr) == 0) {
-+        if (slapi_entry_attr_find(e, retrocl_changenumber, &chattr) == 0) {
-             slapi_attr_first_value(chattr, &sval);
-             if (NULL != sval) {
-                 value = slapi_value_get_berval(sval);
-@@ -79,7 +79,7 @@ handle_cnum_entry(Slapi_Entry *e, void *callback_data)
-         chattr = NULL;
-         sval = NULL;
-         value = NULL;
--        if (slapi_entry_attr_find(e, attr_changetime, &chattr) == 0) {
-+        if (slapi_entry_attr_find(e, retrocl_changetime, &chattr) == 0) {
-             slapi_attr_first_value(chattr, &sval);
-             if (NULL != sval) {
-                 value = slapi_value_get_berval(sval);
-@@ -134,7 +134,7 @@ retrocl_get_changenumbers(void)
-     cr.cr_time = 0;
- 
-     slapi_seq_callback(RETROCL_CHANGELOG_DN, SLAPI_SEQ_FIRST,
--                       (char *)attr_changenumber, /* cast away const */
-+                       (char *)retrocl_changenumber, /* cast away const */
-                        NULL, NULL, 0, &cr, NULL, handle_cnum_result,
-                        handle_cnum_entry, NULL);
- 
-@@ -144,7 +144,7 @@ retrocl_get_changenumbers(void)
-     slapi_ch_free((void **)&cr.cr_time);
- 
-     slapi_seq_callback(RETROCL_CHANGELOG_DN, SLAPI_SEQ_LAST,
--                       (char *)attr_changenumber, /* cast away const */
-+                       (char *)retrocl_changenumber, /* cast away const */
-                        NULL, NULL, 0, &cr, NULL, handle_cnum_result,
-                        handle_cnum_entry, NULL);
- 
-@@ -185,7 +185,7 @@ retrocl_getchangetime(int type, int *err)
-         return NO_TIME;
-     }
-     slapi_seq_callback(RETROCL_CHANGELOG_DN, type,
--                       (char *)attr_changenumber, /* cast away const */
-+                       (char *)retrocl_changenumber, /* cast away const */
-                        NULL,
-                        NULL, 0, &cr, NULL,
-                        handle_cnum_result, handle_cnum_entry, NULL);
-@@ -353,7 +353,7 @@ retrocl_update_lastchangenumber(void)
-     cr.cr_cnum = 0;
-     cr.cr_time = 0;
-     slapi_seq_callback(RETROCL_CHANGELOG_DN, SLAPI_SEQ_LAST,
--                       (char *)attr_changenumber, /* cast away const */
-+                       (char *)retrocl_changenumber, /* cast away const */
-                        NULL, NULL, 0, &cr, NULL, handle_cnum_result,
-                        handle_cnum_entry, NULL);
- 
-diff --git a/ldap/servers/plugins/retrocl/retrocl_po.c b/ldap/servers/plugins/retrocl/retrocl_po.c
-index d2af79b31..e1488f56b 100644
---- a/ldap/servers/plugins/retrocl/retrocl_po.c
-+++ b/ldap/servers/plugins/retrocl/retrocl_po.c
-@@ -25,17 +25,17 @@ modrdn2reple(Slapi_Entry *e, const char *newrdn, int deloldrdn, LDAPMod **ldm, c
- 
- /******************************/
- 
--const char *attr_changenumber = "changenumber";
--const char *attr_targetdn = "targetdn";
--const char *attr_changetype = "changetype";
--const char *attr_newrdn = "newrdn";
--const char *attr_deleteoldrdn = "deleteoldrdn";
--const char *attr_changes = "changes";
--const char *attr_newsuperior = "newsuperior";
--const char *attr_changetime = "changetime";
--const char *attr_objectclass = "objectclass";
--const char *attr_nsuniqueid = "nsuniqueid";
--const char *attr_isreplicated = "isreplicated";
-+const char *retrocl_changenumber = "changenumber";
-+const char *retrocl_targetdn = "targetdn";
-+const char *retrocl_changetype = "changetype";
-+const char *retrocl_newrdn = "newrdn";
-+const char *retrocl_deleteoldrdn = "deleteoldrdn";
-+const char *retrocl_changes = "changes";
-+const char *retrocl_newsuperior = "newsuperior";
-+const char *retrocl_changetime = "changetime";
-+const char *retrocl_objectclass = "objectclass";
-+const char *retrocl_nsuniqueid = "nsuniqueid";
-+const char *retrocl_isreplicated = "isreplicated";
- 
- /*
-  * Function: make_changes_string
-@@ -185,7 +185,7 @@ write_replog_db(
-                   changenum, dn);
- 
-     /* Construct the dn of this change record */
--    edn = slapi_ch_smprintf("%s=%lu,%s", attr_changenumber, changenum, RETROCL_CHANGELOG_DN);
-+    edn = slapi_ch_smprintf("%s=%lu,%s", retrocl_changenumber, changenum, RETROCL_CHANGELOG_DN);
- 
-     /*
-      * Create the entry struct, and fill in fields common to all types
-@@ -214,7 +214,7 @@ write_replog_db(
-             attributeAlias = attributeName;
-         }
- 
--        if (strcasecmp(attributeName, attr_nsuniqueid) == 0) {
-+        if (strcasecmp(attributeName, retrocl_nsuniqueid) == 0) {
-             Slapi_Entry *entry = NULL;
-             const char *uniqueId = NULL;
- 
-@@ -236,7 +236,7 @@ write_replog_db(
- 
-             extensibleObject = 1;
- 
--        } else if (strcasecmp(attributeName, attr_isreplicated) == 0) {
-+        } else if (strcasecmp(attributeName, retrocl_isreplicated) == 0) {
-             int isReplicated = 0;
-             char *attributeValue = NULL;
- 
-@@ -298,17 +298,17 @@ write_replog_db(
-     sprintf(chnobuf, "%lu", changenum);
-     val.bv_val = chnobuf;
-     val.bv_len = strlen(chnobuf);
--    slapi_entry_add_values(e, attr_changenumber, vals);
-+    slapi_entry_add_values(e, retrocl_changenumber, vals);
- 
-     /* Set the targetentrydn attribute */
-     val.bv_val = dn;
-     val.bv_len = strlen(dn);
--    slapi_entry_add_values(e, attr_targetdn, vals);
-+    slapi_entry_add_values(e, retrocl_targetdn, vals);
- 
-     /* Set the changeTime attribute */
-     val.bv_val = format_genTime(curtime);
-     val.bv_len = strlen(val.bv_val);
--    slapi_entry_add_values(e, attr_changetime, vals);
-+    slapi_entry_add_values(e, retrocl_changetime, vals);
-     slapi_ch_free((void **)&val.bv_val);
- 
-     /*
-@@ -344,7 +344,7 @@ write_replog_db(
-             /* Set the changetype attribute */
-             val.bv_val = "delete";
-             val.bv_len = 6;
--            slapi_entry_add_values(e, attr_changetype, vals);
-+            slapi_entry_add_values(e, retrocl_changetype, vals);
-         }
-         break;
- 
-@@ -422,7 +422,7 @@ entry2reple(Slapi_Entry *e, Slapi_Entry *oe, int optype)
-     } else {
-         return (1);
-     }
--    slapi_entry_add_values(e, attr_changetype, vals);
-+    slapi_entry_add_values(e, retrocl_changetype, vals);
- 
-     estr = slapi_entry2str(oe, &len);
-     p = estr;
-@@ -435,7 +435,7 @@ entry2reple(Slapi_Entry *e, Slapi_Entry *oe, int optype)
-     }
-     val.bv_val = p;
-     val.bv_len = len - (p - estr); /* length + terminating \0 */
--    slapi_entry_add_values(e, attr_changes, vals);
-+    slapi_entry_add_values(e, retrocl_changes, vals);
-     slapi_ch_free_string(&estr);
-     return 0;
- }
-@@ -471,7 +471,7 @@ mods2reple(Slapi_Entry *e, LDAPMod **ldm)
-         if (NULL != l) {
-             val.bv_val = l->ls_buf;
-             val.bv_len = l->ls_len + 1; /* string + terminating \0 */
--            slapi_entry_add_values(e, attr_changes, vals);
-+            slapi_entry_add_values(e, retrocl_changes, vals);
-             lenstr_free(&l);
-         }
-     }
-@@ -511,12 +511,12 @@ modrdn2reple(
- 
-     val.bv_val = "modrdn";
-     val.bv_len = 6;
--    slapi_entry_add_values(e, attr_changetype, vals);
-+    slapi_entry_add_values(e, retrocl_changetype, vals);
- 
-     if (newrdn) {
-         val.bv_val = (char *)newrdn; /* cast away const */
-         val.bv_len = strlen(newrdn);
--        slapi_entry_add_values(e, attr_newrdn, vals);
-+        slapi_entry_add_values(e, retrocl_newrdn, vals);
-     }
- 
-     if (deloldrdn == 0) {
-@@ -526,12 +526,12 @@ modrdn2reple(
-         val.bv_val = "TRUE";
-         val.bv_len = 4;
-     }
--    slapi_entry_add_values(e, attr_deleteoldrdn, vals);
-+    slapi_entry_add_values(e, retrocl_deleteoldrdn, vals);
- 
-     if (newsuperior) {
-         val.bv_val = (char *)newsuperior; /* cast away const */
-         val.bv_len = strlen(newsuperior);
--        slapi_entry_add_values(e, attr_newsuperior, vals);
-+        slapi_entry_add_values(e, retrocl_newsuperior, vals);
-     }
- 
-     if (NULL != ldm) {
-@@ -540,7 +540,7 @@ modrdn2reple(
-             if (l->ls_len) {
-                 val.bv_val = l->ls_buf;
-                 val.bv_len = l->ls_len;
--                slapi_entry_add_values(e, attr_changes, vals);
-+                slapi_entry_add_values(e, retrocl_changes, vals);
-             }
-             lenstr_free(&l);
-         }
-diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
-index 0378eb7f6..d031dc3f8 100644
---- a/ldap/servers/plugins/retrocl/retrocl_trim.c
-+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
-@@ -49,15 +49,15 @@ static const char **
- get_cleattrs(void)
- {
-     if (cleattrs[0] == NULL) {
--        cleattrs[0] = attr_objectclass;
--        cleattrs[1] = attr_changenumber;
--        cleattrs[2] = attr_targetdn;
--        cleattrs[3] = attr_changetype;
--        cleattrs[4] = attr_newrdn;
--        cleattrs[5] = attr_deleteoldrdn;
--        cleattrs[6] = attr_changes;
--        cleattrs[7] = attr_newsuperior;
--        cleattrs[8] = attr_changetime;
-+        cleattrs[0] = retrocl_objectclass;
-+        cleattrs[1] = retrocl_changenumber;
-+        cleattrs[2] = retrocl_targetdn;
-+        cleattrs[3] = retrocl_changetype;
-+        cleattrs[4] = retrocl_newrdn;
-+        cleattrs[5] = retrocl_deleteoldrdn;
-+        cleattrs[6] = retrocl_changes;
-+        cleattrs[7] = retrocl_newsuperior;
-+        cleattrs[8] = retrocl_changetime;
-         cleattrs[9] = NULL;
-     }
-     return cleattrs;
-@@ -81,7 +81,7 @@ delete_changerecord(changeNumber cnum)
-     char *dnbuf;
-     int delrc;
- 
--    dnbuf = slapi_ch_smprintf("%s=%ld, %s", attr_changenumber, cnum,
-+    dnbuf = slapi_ch_smprintf("%s=%ld, %s", retrocl_changenumber, cnum,
-                               RETROCL_CHANGELOG_DN);
-     pb = slapi_pblock_new();
-     slapi_delete_internal_set_pb(pb, dnbuf, NULL /*controls*/, NULL /* uniqueid */,
-@@ -154,7 +154,7 @@ handle_getchangetime_search(Slapi_Entry *e, void *callback_data)
-         if (NULL != e) {
-             Slapi_Value *sval = NULL;
-             const struct berval *val = NULL;
--            rc = slapi_entry_attr_find(e, attr_changetime, &attr);
-+            rc = slapi_entry_attr_find(e, retrocl_changetime, &attr);
-             /* Bug 624442: Logic checking for lack of timestamp was
-                reversed. */
-             if (0 != rc || slapi_attr_first_value(attr, &sval) == -1 ||
-@@ -174,14 +174,14 @@ handle_getchangetime_search(Slapi_Entry *e, void *callback_data)
- /*
-  * Function: get_changetime
-  * Arguments: cnum - number of change record to retrieve
-- * Returns: Taking the attr_changetime of the 'cnum' entry,
-+ * Returns: Taking the retrocl_changetime of the 'cnum' entry,
-  * it converts it into time_t (parse_localTime) and returns this time value.
-  * It returns 0 in the following cases:
-- *  - changerecord entry has not attr_changetime
-+ *  - changerecord entry has not retrocl_changetime
-  *  - attr_changetime attribute has no value
-  *  - attr_changetime attribute value is empty
-  *
-- * Description: Retrieve attr_changetime ("changetime") from a changerecord whose number is "cnum".
-+ * Description: Retrieve retrocl_changetime ("changetime") from a changerecord whose number is "cnum".
-  */
- static time_t
- get_changetime(changeNumber cnum, int *err)
-@@ -198,7 +198,7 @@ get_changetime(changeNumber cnum, int *err)
-     }
-     crtp->crt_nentries = crtp->crt_err = 0;
-     crtp->crt_time = 0;
--    PR_snprintf(fstr, sizeof(fstr), "%s=%ld", attr_changenumber, cnum);
-+    PR_snprintf(fstr, sizeof(fstr), "%s=%ld", retrocl_changenumber, cnum);
- 
-     pb = slapi_pblock_new();
-     slapi_search_internal_set_pb(pb, RETROCL_CHANGELOG_DN,
--- 
-2.26.2
-
diff --git a/SOURCES/0008-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch b/SOURCES/0008-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch
deleted file mode 100644
index a85a4bb..0000000
--- a/SOURCES/0008-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch
+++ /dev/null
@@ -1,466 +0,0 @@
-From 8d14ff153e9335b09739438344f9c3c78a496548 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Fri, 22 May 2020 10:42:11 -0400
-Subject: [PATCH 08/12] Issue 51095 - abort operation if CSN can not be
- generated
-
-Bug Description:  If we fail to get the system time then we were using an
-                  uninitialized timespec struct which could lead to bizarre
-                  times in CSN's.
-
-Fix description:  Check if the system time function fails, and if it does
-                  then abort the update operation.
-
-relates: https://pagure.io/389-ds-base/issue/51095
-
-Reviewed by: firstyear & tbordaz(Thanks!!)
----
- ldap/servers/plugins/replication/repl5.h      |  2 +-
- .../plugins/replication/repl5_replica.c       | 33 ++++++++------
- ldap/servers/slapd/back-ldbm/ldbm_add.c       |  8 +++-
- ldap/servers/slapd/back-ldbm/ldbm_delete.c    |  9 +++-
- ldap/servers/slapd/back-ldbm/ldbm_modify.c    | 10 ++++-
- ldap/servers/slapd/back-ldbm/ldbm_modrdn.c    |  8 +++-
- ldap/servers/slapd/csngen.c                   | 18 +++++++-
- ldap/servers/slapd/entrywsi.c                 | 15 ++++---
- ldap/servers/slapd/slap.h                     |  2 +-
- ldap/servers/slapd/slapi-plugin.h             |  8 ++++
- ldap/servers/slapd/slapi-private.h            |  5 ++-
- ldap/servers/slapd/time.c                     | 43 +++++++++++++------
- 12 files changed, 118 insertions(+), 43 deletions(-)
-
-diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
-index 72b7089e3..638471744 100644
---- a/ldap/servers/plugins/replication/repl5.h
-+++ b/ldap/servers/plugins/replication/repl5.h
-@@ -776,7 +776,7 @@ void replica_disable_replication(Replica *r);
- int replica_start_agreement(Replica *r, Repl_Agmt *ra);
- int windows_replica_start_agreement(Replica *r, Repl_Agmt *ra);
- 
--CSN *replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn);
-+int32_t replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
- int replica_get_attr(Slapi_PBlock *pb, const char *type, void *value);
- 
- /* mapping tree extensions manipulation */
-diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
-index 02caa88d9..f01782330 100644
---- a/ldap/servers/plugins/replication/repl5_replica.c
-+++ b/ldap/servers/plugins/replication/repl5_replica.c
-@@ -3931,11 +3931,9 @@ windows_replica_start_agreement(Replica *r, Repl_Agmt *ra)
-  * A callback function registered as op->o_csngen_handler and
-  * called by backend ops to generate opcsn.
-  */
--CSN *
--replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
-+int32_t
-+replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn)
- {
--    CSN *opcsn = NULL;
--
-     Replica *replica = replica_get_replica_for_op(pb);
-     if (NULL != replica) {
-         Slapi_Operation *op;
-@@ -3946,17 +3944,26 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
-                 CSNGen *gen = (CSNGen *)object_get_data(gen_obj);
-                 if (NULL != gen) {
-                     /* The new CSN should be greater than the base CSN */
--                    csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
--                    if (csn_compare(opcsn, basecsn) <= 0) {
--                        char opcsnstr[CSN_STRSIZE], basecsnstr[CSN_STRSIZE];
-+                    if (csngen_new_csn(gen, opcsn, PR_FALSE /* don't notify */) != CSN_SUCCESS) {
-+                        /* Failed to generate CSN we must abort */
-+                        object_release(gen_obj);
-+                        return -1;
-+                    }
-+                    if (csn_compare(*opcsn, basecsn) <= 0) {
-+                        char opcsnstr[CSN_STRSIZE];
-+                        char basecsnstr[CSN_STRSIZE];
-                         char opcsn2str[CSN_STRSIZE];
- 
--                        csn_as_string(opcsn, PR_FALSE, opcsnstr);
-+                        csn_as_string(*opcsn, PR_FALSE, opcsnstr);
-                         csn_as_string(basecsn, PR_FALSE, basecsnstr);
--                        csn_free(&opcsn);
-+                        csn_free(opcsn);
-                         csngen_adjust_time(gen, basecsn);
--                        csngen_new_csn(gen, &opcsn, PR_FALSE /* don't notify */);
--                        csn_as_string(opcsn, PR_FALSE, opcsn2str);
-+                        if (csngen_new_csn(gen, opcsn, PR_FALSE) != CSN_SUCCESS) {
-+                            /* Failed to generate CSN we must abort */
-+                            object_release(gen_obj);
-+                            return -1;
-+                        }
-+                        csn_as_string(*opcsn, PR_FALSE, opcsn2str);
-                         slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name,
-                                       "replica_generate_next_csn - "
-                                       "opcsn=%s <= basecsn=%s, adjusted opcsn=%s\n",
-@@ -3966,14 +3973,14 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
-                      * Insert opcsn into the csn pending list.
-                      * This is the notify effect in csngen_new_csn().
-                      */
--                    assign_csn_callback(opcsn, (void *)replica);
-+                    assign_csn_callback(*opcsn, (void *)replica);
-                 }
-                 object_release(gen_obj);
-             }
-         }
-     }
- 
--    return opcsn;
-+    return 0;
- }
- 
- /*
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c
-index d0d88bf16..ee366c74c 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
-@@ -645,7 +645,13 @@ ldbm_back_add(Slapi_PBlock *pb)
-                          * Current op is a user request. Opcsn will be assigned
-                          * if the dn is in an updatable replica.
-                          */
--                        opcsn = entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL);
-+                        if (entry_assign_operation_csn(pb, e, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
-+                            slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_add",
-+                                    "failed to generate add CSN for entry (%s), aborting operation\n",
-+                                    slapi_entry_get_dn(e));
-+                            ldap_result_code = LDAP_OPERATIONS_ERROR;
-+                            goto error_return;
-+                        }
-                     }
-                     if (opcsn != NULL) {
-                         entry_set_csn(e, opcsn);
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
-index 873b5b00e..fbcb57310 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
-@@ -464,7 +464,14 @@ replace_entry:
-                      * by entry_assign_operation_csn() if the dn is in an
-                      * updatable replica.
-                      */
--                    opcsn = entry_assign_operation_csn ( pb, e->ep_entry, NULL );
-+                    if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
-+                        slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_delete",
-+                                "failed to generate delete CSN for entry (%s), aborting operation\n",
-+                                slapi_entry_get_dn(e->ep_entry));
-+                        retval = -1;
-+                        ldap_result_code = LDAP_OPERATIONS_ERROR;
-+                        goto error_return;
-+                    }
-                 }
-                 if (opcsn != NULL) {
-                     if (!is_fixup_operation) {
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
-index b0c477e3f..e9d7e87e3 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
-@@ -598,12 +598,18 @@ ldbm_back_modify(Slapi_PBlock *pb)
-                     goto error_return;
-                 }
-                 opcsn = operation_get_csn(operation);
--                if (NULL == opcsn && operation->o_csngen_handler) {
-+                if (opcsn == NULL && operation->o_csngen_handler) {
-                     /*
-                      * Current op is a user request. Opcsn will be assigned
-                      * if the dn is in an updatable replica.
-                      */
--                    opcsn = entry_assign_operation_csn(pb, e->ep_entry, NULL);
-+                    if (entry_assign_operation_csn(pb, e->ep_entry, NULL, &opcsn) != 0) {
-+                        slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
-+                                "failed to generate modify CSN for entry (%s), aborting operation\n",
-+                                slapi_entry_get_dn(e->ep_entry));
-+                        ldap_result_code = LDAP_OPERATIONS_ERROR;
-+                        goto error_return;
-+                    }
-                 }
-                 if (opcsn) {
-                     entry_set_maxcsn(e->ep_entry, opcsn);
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-index 26698012a..fde83c99f 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-@@ -543,7 +543,13 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-                      * Current op is a user request. Opcsn will be assigned
-                      * if the dn is in an updatable replica.
-                      */
--                    opcsn = entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL);
-+                    if (entry_assign_operation_csn(pb, e->ep_entry, parententry ? parententry->ep_entry : NULL, &opcsn) != 0) {
-+                        slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
-+                                "failed to generate modrdn CSN for entry (%s), aborting operation\n",
-+                                slapi_entry_get_dn(e->ep_entry));
-+                        ldap_result_code = LDAP_OPERATIONS_ERROR;
-+                        goto error_return;
-+                    }
-                 }
-                 if (opcsn != NULL) {
-                     entry_set_maxcsn(e->ep_entry, opcsn);
-diff --git a/ldap/servers/slapd/csngen.c b/ldap/servers/slapd/csngen.c
-index 68dbbda8e..b08d8b25c 100644
---- a/ldap/servers/slapd/csngen.c
-+++ b/ldap/servers/slapd/csngen.c
-@@ -164,6 +164,7 @@ csngen_free(CSNGen **gen)
- int
- csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
- {
-+    struct timespec now = {0};
-     int rc = CSN_SUCCESS;
-     time_t cur_time;
-     int delta;
-@@ -179,12 +180,25 @@ csngen_new_csn(CSNGen *gen, CSN **csn, PRBool notify)
-         return CSN_MEMORY_ERROR;
-     }
- 
--    slapi_rwlock_wrlock(gen->lock);
-+    if ((rc = slapi_clock_gettime(&now)) != 0) {
-+        /* Failed to get system time, we must abort */
-+        slapi_log_err(SLAPI_LOG_ERR, "csngen_new_csn",
-+                "Failed to get system time (%s)\n",
-+                slapd_system_strerror(rc));
-+        return CSN_TIME_ERROR;
-+    }
-+    cur_time = now.tv_sec;
- 
--    cur_time = slapi_current_utc_time();
-+    slapi_rwlock_wrlock(gen->lock);
- 
-     /* check if the time should be adjusted */
-     delta = cur_time - gen->state.sampled_time;
-+    if (delta > _SEC_PER_DAY || delta < (-1 * _SEC_PER_DAY)) {
-+        /* We had a jump larger than a day */
-+        slapi_log_err(SLAPI_LOG_INFO, "csngen_new_csn",
-+                "Detected large jump in CSN time.  Delta: %d (current time: %ld  vs  previous time: %ld)\n",
-+                delta, cur_time, gen->state.sampled_time);
-+    }
-     if (delta > 0) {
-         rc = _csngen_adjust_local_time(gen, cur_time);
-         if (rc != CSN_SUCCESS) {
-diff --git a/ldap/servers/slapd/entrywsi.c b/ldap/servers/slapd/entrywsi.c
-index 5d1d7238a..31bf65d8e 100644
---- a/ldap/servers/slapd/entrywsi.c
-+++ b/ldap/servers/slapd/entrywsi.c
-@@ -224,13 +224,12 @@ entry_add_rdn_csn(Slapi_Entry *e, const CSN *csn)
-     slapi_rdn_free(&rdn);
- }
- 
--CSN *
--entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry)
-+int32_t
-+entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn)
- {
-     Slapi_Operation *op;
-     const CSN *basecsn = NULL;
-     const CSN *parententry_dncsn = NULL;
--    CSN *opcsn = NULL;
- 
-     slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- 
-@@ -252,14 +251,16 @@ entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parent
-                 basecsn = parententry_dncsn;
-             }
-         }
--        opcsn = op->o_csngen_handler(pb, basecsn);
-+        if(op->o_csngen_handler(pb, basecsn, opcsn) != 0) {
-+            return -1;
-+        }
- 
--        if (NULL != opcsn) {
--            operation_set_csn(op, opcsn);
-+        if (*opcsn) {
-+            operation_set_csn(op, *opcsn);
-         }
-     }
- 
--    return opcsn;
-+    return 0;
- }
- 
- /*
-diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
-index a4cae784a..cef8c789c 100644
---- a/ldap/servers/slapd/slap.h
-+++ b/ldap/servers/slapd/slap.h
-@@ -1480,7 +1480,7 @@ struct op;
- typedef void (*result_handler)(struct conn *, struct op *, int, char *, char *, int, struct berval **);
- typedef int (*search_entry_handler)(Slapi_Backend *, struct conn *, struct op *, struct slapi_entry *);
- typedef int (*search_referral_handler)(Slapi_Backend *, struct conn *, struct op *, struct berval **);
--typedef CSN *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn);
-+typedef int32_t *(*csngen_handler)(Slapi_PBlock *pb, const CSN *basecsn, CSN **opcsn);
- typedef int (*replica_attr_handler)(Slapi_PBlock *pb, const char *type, void **value);
- 
- /*
-diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
-index be1e52e4d..834a98742 100644
---- a/ldap/servers/slapd/slapi-plugin.h
-+++ b/ldap/servers/slapd/slapi-plugin.h
-@@ -6743,6 +6743,14 @@ int slapi_reslimit_get_integer_limit(Slapi_Connection *conn, int handle, int *li
-  */
- time_t slapi_current_time(void) __attribute__((deprecated));
- 
-+/**
-+ * Get the system time and check for errors.  Return
-+ *
-+ * \param tp - a timespec struct where the system time is set
-+ * \return result code, upon success tp is set to the system time
-+ */
-+int32_t slapi_clock_gettime(struct timespec *tp);
-+
- /**
-  * Returns the current system time as a hr clock relative to uptime
-  * This means the clock is not affected by timezones
-diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
-index d85ee43e5..c98c1947c 100644
---- a/ldap/servers/slapd/slapi-private.h
-+++ b/ldap/servers/slapd/slapi-private.h
-@@ -233,7 +233,8 @@ enum
-     CSN_INVALID_PARAMETER, /* invalid function argument */
-     CSN_INVALID_FORMAT,    /* invalid state format */
-     CSN_LDAP_ERROR,        /* LDAP operation failed */
--    CSN_NSPR_ERROR         /* NSPR API failure */
-+    CSN_NSPR_ERROR,        /* NSPR API failure */
-+    CSN_TIME_ERROR         /* Error generating new CSN due to clock failure */
- };
- 
- typedef struct csngen CSNGen;
-@@ -326,7 +327,7 @@ int slapi_entries_diff(Slapi_Entry **old_entries, Slapi_Entry **new_entries, int
- void set_attr_to_protected_list(char *attr, int flag);
- 
- /* entrywsi.c */
--CSN *entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry);
-+int32_t entry_assign_operation_csn(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *parententry, CSN **opcsn);
- const CSN *entry_get_maxcsn(const Slapi_Entry *entry);
- void entry_set_maxcsn(Slapi_Entry *entry, const CSN *csn);
- const CSN *entry_get_dncsn(const Slapi_Entry *entry);
-diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
-index 8048a3359..545538404 100644
---- a/ldap/servers/slapd/time.c
-+++ b/ldap/servers/slapd/time.c
-@@ -61,6 +61,25 @@ poll_current_time()
-     return 0;
- }
- 
-+/*
-+ * Check if the time function returns an error.  If so return the errno
-+ */
-+int32_t
-+slapi_clock_gettime(struct timespec *tp)
-+{
-+    int32_t rc = 0;
-+
-+    PR_ASSERT(tp && tp->tv_nsec == 0 && tp->tv_sec == 0);
-+
-+    if (clock_gettime(CLOCK_REALTIME, tp) != 0) {
-+        rc = errno;
-+    }
-+
-+    PR_ASSERT(rc == 0);
-+
-+    return rc;
-+}
-+
- time_t
- current_time(void)
- {
-@@ -69,7 +88,7 @@ current_time(void)
-      * but this should be removed in favour of the
-      * more accurately named slapi_current_utc_time
-      */
--    struct timespec now;
-+    struct timespec now = {0};
-     clock_gettime(CLOCK_REALTIME, &now);
-     return now.tv_sec;
- }
-@@ -83,7 +102,7 @@ slapi_current_time(void)
- struct timespec
- slapi_current_rel_time_hr(void)
- {
--    struct timespec now;
-+    struct timespec now = {0};
-     clock_gettime(CLOCK_MONOTONIC, &now);
-     return now;
- }
-@@ -91,7 +110,7 @@ slapi_current_rel_time_hr(void)
- struct timespec
- slapi_current_utc_time_hr(void)
- {
--    struct timespec ltnow;
-+    struct timespec ltnow = {0};
-     clock_gettime(CLOCK_REALTIME, &ltnow);
-     return ltnow;
- }
-@@ -99,7 +118,7 @@ slapi_current_utc_time_hr(void)
- time_t
- slapi_current_utc_time(void)
- {
--    struct timespec ltnow;
-+    struct timespec ltnow = {0};
-     clock_gettime(CLOCK_REALTIME, &ltnow);
-     return ltnow.tv_sec;
- }
-@@ -108,8 +127,8 @@ void
- slapi_timestamp_utc_hr(char *buf, size_t bufsize)
- {
-     PR_ASSERT(bufsize >= SLAPI_TIMESTAMP_BUFSIZE);
--    struct timespec ltnow;
--    struct tm utctm;
-+    struct timespec ltnow = {0};
-+    struct tm utctm = {0};
-     clock_gettime(CLOCK_REALTIME, &ltnow);
-     gmtime_r(&(ltnow.tv_sec), &utctm);
-     strftime(buf, bufsize, "%Y%m%d%H%M%SZ", &utctm);
-@@ -140,7 +159,7 @@ format_localTime_log(time_t t, int initsize __attribute__((unused)), char *buf,
- {
- 
-     long tz;
--    struct tm *tmsp, tms;
-+    struct tm *tmsp, tms = {0};
-     char tbuf[*bufsize];
-     char sign;
-     /* make sure our buffer will be big enough. Need at least 29 */
-@@ -191,7 +210,7 @@ format_localTime_hr_log(time_t t, long nsec, int initsize __attribute__((unused)
- {
- 
-     long tz;
--    struct tm *tmsp, tms;
-+    struct tm *tmsp, tms = {0};
-     char tbuf[*bufsize];
-     char sign;
-     /* make sure our buffer will be big enough. Need at least 39 */
-@@ -278,7 +297,7 @@ slapi_timespec_expire_check(struct timespec *expire)
-     if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
-         return TIMER_CONTINUE;
-     }
--    struct timespec now;
-+    struct timespec now = {0};
-     clock_gettime(CLOCK_MONOTONIC, &now);
-     if (now.tv_sec > expire->tv_sec ||
-         (expire->tv_sec == now.tv_sec && now.tv_sec > expire->tv_nsec)) {
-@@ -293,7 +312,7 @@ format_localTime(time_t from)
-        in the syntax of a generalizedTime, except without the time zone. */
- {
-     char *into;
--    struct tm t;
-+    struct tm t = {0};
- 
-     localtime_r(&from, &t);
- 
-@@ -362,7 +381,7 @@ format_genTime(time_t from)
-        in the syntax of a generalizedTime. */
- {
-     char *into;
--    struct tm t;
-+    struct tm t = {0};
- 
-     gmtime_r(&from, &t);
-     into = slapi_ch_malloc(SLAPI_TIMESTAMP_BUFSIZE);
-@@ -382,7 +401,7 @@ time_t
- read_genTime(struct berval *from)
- {
-     struct tm t = {0};
--    time_t retTime;
-+    time_t retTime = {0};
-     time_t diffsec = 0;
-     int i, gflag = 0, havesec = 0;
- 
--- 
-2.26.2
-
diff --git a/SOURCES/0009-Issue-51113-Allow-using-uid-for-replication-manager-.patch b/SOURCES/0009-Issue-51113-Allow-using-uid-for-replication-manager-.patch
deleted file mode 100644
index e5dbb3d..0000000
--- a/SOURCES/0009-Issue-51113-Allow-using-uid-for-replication-manager-.patch
+++ /dev/null
@@ -1,179 +0,0 @@
-From 52ce524f7672563b543e84401665765cfa72dea5 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 26 May 2020 17:03:11 -0400
-Subject: [PATCH 09/12] Issue 51113 - Allow using uid for replication manager
- entry
-
-Bug Description:  Currently it was hardcoded to only allow "cn" as
-                  the rdn attribute for the replication manager entry.
-
-Fix description:  Allow setting the rdn attribute of the replication
-                  manager DS ldap object, and include the schema that
-                  allows "uid".
-
-relates:  https://pagure.io/389-ds-base/issue/51113
-
-Reviewed by: spichugi & firstyear(Thanks!!)
----
- src/lib389/lib389/cli_conf/replication.py | 53 ++++++++++++-----------
- src/lib389/lib389/replica.py              | 11 +++--
- 2 files changed, 35 insertions(+), 29 deletions(-)
-
-diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py
-index 09cb9b435..b9bc3d291 100644
---- a/src/lib389/lib389/cli_conf/replication.py
-+++ b/src/lib389/lib389/cli_conf/replication.py
-@@ -199,19 +199,21 @@ def enable_replication(inst, basedn, log, args):
- 
-     # Create replication manager if password was provided
-     if args.bind_dn and args.bind_passwd:
--        cn_rdn = args.bind_dn.split(",", 1)[0]
--        cn_val = cn_rdn.split("=", 1)[1]
--        manager = BootstrapReplicationManager(inst, dn=args.bind_dn)
-+        rdn = args.bind_dn.split(",", 1)[0]
-+        rdn_attr, rdn_val = rdn.split("=", 1)
-+        manager = BootstrapReplicationManager(inst, dn=args.bind_dn, rdn_attr=rdn_attr)
-         try:
-             manager.create(properties={
--                'cn': cn_val,
-+                'cn': rdn_val,
-+                'uid': rdn_val,
-                 'userPassword': args.bind_passwd
-             })
-         except ldap.ALREADY_EXISTS:
-             # Already there, but could have different password.  Delete and recreate
-             manager.delete()
-             manager.create(properties={
--                'cn': cn_val,
-+                'cn': rdn_val,
-+                'uid': rdn_val,
-                 'userPassword': args.bind_passwd
-             })
-         except ldap.NO_SUCH_OBJECT:
-@@ -511,22 +513,23 @@ def get_cl(inst, basedn, log, args):
- 
- 
- def create_repl_manager(inst, basedn, log, args):
--    manager_cn = "replication manager"
-+    manager_name = "replication manager"
-     repl_manager_password = ""
-     repl_manager_password_confirm = ""
- 
-     if args.name:
--        manager_cn = args.name
--
--    if is_a_dn(manager_cn):
--        # A full DN was provided, make sure it uses "cn" for the RDN
--        if manager_cn.split("=", 1)[0].lower() != "cn":
--            raise ValueError("Replication manager DN must use \"cn\" for the rdn attribute")
--        manager_dn = manager_cn
--        manager_rdn = manager_dn.split(",", 1)[0]
--        manager_cn = manager_rdn.split("=", 1)[1]
-+        manager_name = args.name
-+
-+    if is_a_dn(manager_name):
-+        # A full DN was provided
-+        manager_dn = manager_name
-+        manager_rdn = manager_name.split(",", 1)[0]
-+        manager_attr, manager_name = manager_rdn.split("=", 1)
-+        if manager_attr.lower() not in ['cn', 'uid']:
-+            raise ValueError(f'The RDN attribute "{manager_attr}" is not allowed, you must use "cn" or "uid"')
-     else:
--        manager_dn = "cn={},cn=config".format(manager_cn)
-+        manager_dn = "cn={},cn=config".format(manager_name)
-+        manager_attr = "cn"
- 
-     if args.passwd:
-         repl_manager_password = args.passwd
-@@ -544,10 +547,11 @@ def create_repl_manager(inst, basedn, log, args):
-                 repl_manager_password = ""
-                 repl_manager_password_confirm = ""
- 
--    manager = BootstrapReplicationManager(inst, dn=manager_dn)
-+    manager = BootstrapReplicationManager(inst, dn=manager_dn, rdn_attr=manager_attr)
-     try:
-         manager.create(properties={
--            'cn': manager_cn,
-+            'cn': manager_name,
-+            'uid': manager_name,
-             'userPassword': repl_manager_password
-         })
-         if args.suffix:
-@@ -564,7 +568,8 @@ def create_repl_manager(inst, basedn, log, args):
-         # Already there, but could have different password.  Delete and recreate
-         manager.delete()
-         manager.create(properties={
--            'cn': manager_cn,
-+            'cn': manager_name,
-+            'uid': manager_name,
-             'userPassword': repl_manager_password
-         })
-         if args.suffix:
-@@ -954,6 +959,7 @@ def get_winsync_agmt_status(inst, basedn, log, args):
-     status = agmt.status(winsync=True, use_json=args.json)
-     log.info(status)
- 
-+
- #
- # Tasks
- #
-@@ -1347,8 +1353,7 @@ def create_parser(subparsers):
-     agmt_set_parser.add_argument('--wait-async-results', help="The amount of time in milliseconds the server waits if "
-                                                               "the consumer is not ready before resending data")
-     agmt_set_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
--                                                          "a consumer sends back a busy response before making another "
--                                                          "attempt to acquire access.")
-+                                 "a consumer sends back a busy response before making another attempt to acquire access.")
-     agmt_set_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
-     agmt_set_parser.add_argument('--flow-control-window', help="Sets the maximum number of entries and updates sent by a supplier, which are not acknowledged by the consumer.")
-     agmt_set_parser.add_argument('--flow-control-pause', help="The time in milliseconds to pause after reaching the number of entries and updates set in \"--flow-control-window\"")
-@@ -1438,8 +1443,7 @@ def create_parser(subparsers):
-     winsync_agmt_add_parser.add_argument('--subtree-pair', help="Set the subtree pair: <DS_SUBTREE>:<WINDOWS_SUBTREE>")
-     winsync_agmt_add_parser.add_argument('--conn-timeout', help="The timeout used for replicaton connections")
-     winsync_agmt_add_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
--                                                          "a consumer sends back a busy response before making another "
--                                                          "attempt to acquire access.")
-+                                         "a consumer sends back a busy response before making another attempt to acquire access.")
-     winsync_agmt_add_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
-     winsync_agmt_add_parser.add_argument('--init', action='store_true', default=False, help="Initialize the agreement after creating it.")
- 
-@@ -1468,8 +1472,7 @@ def create_parser(subparsers):
-     winsync_agmt_set_parser.add_argument('--subtree-pair', help="Set the subtree pair: <DS_SUBTREE>:<WINDOWS_SUBTREE>")
-     winsync_agmt_set_parser.add_argument('--conn-timeout', help="The timeout used for replicaton connections")
-     winsync_agmt_set_parser.add_argument('--busy-wait-time', help="The amount of time in seconds a supplier should wait after "
--                                                          "a consumer sends back a busy response before making another "
--                                                          "attempt to acquire access.")
-+                                         "a consumer sends back a busy response before making another attempt to acquire access.")
-     winsync_agmt_set_parser.add_argument('--session-pause-time', help="The amount of time in seconds a supplier should wait between update sessions.")
- 
-     # Get
-diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
-index e3fc7fe1f..f8adb3ce2 100644
---- a/src/lib389/lib389/replica.py
-+++ b/src/lib389/lib389/replica.py
-@@ -1779,15 +1779,18 @@ class BootstrapReplicationManager(DSLdapObject):
-     :type instance: lib389.DirSrv
-     :param dn: The dn to create
-     :type dn: str
-+    :param rdn_attr: The attribute to use for the RDN
-+    :type rdn_attr: str
-     """
--    def __init__(self, instance, dn='cn=replication manager,cn=config'):
-+    def __init__(self, instance, dn='cn=replication manager,cn=config', rdn_attr='cn'):
-         super(BootstrapReplicationManager, self).__init__(instance, dn)
--        self._rdn_attribute = 'cn'
-+        self._rdn_attribute = rdn_attr
-         self._must_attributes = ['cn', 'userPassword']
-         self._create_objectclasses = [
-             'top',
--            'netscapeServer',
--            'nsAccount'
-+            'inetUser',  # for uid
-+            'netscapeServer',  # for cn
-+            'nsAccount',  # for authentication attributes
-             ]
-         if ds_is_older('1.4.0'):
-             self._create_objectclasses.remove('nsAccount')
--- 
-2.26.2
-
diff --git a/SOURCES/0010-Issue-50931-RFE-AD-filter-rewriter-for-ObjectCategor.patch b/SOURCES/0010-Issue-50931-RFE-AD-filter-rewriter-for-ObjectCategor.patch
deleted file mode 100644
index 966627a..0000000
--- a/SOURCES/0010-Issue-50931-RFE-AD-filter-rewriter-for-ObjectCategor.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From ec85e986ec5710682de883f0f40f539b2f9945fa Mon Sep 17 00:00:00 2001
-From: Viktor Ashirov <vashirov@redhat.com>
-Date: Wed, 27 May 2020 15:22:18 +0200
-Subject: [PATCH 10/12] Issue 50931 - RFE AD filter rewriter for ObjectCategory
-
-Bug Description:
-ASAN build fails on RHEL due to linking issues
-
-Fix Description:
-Add missing libslapd.la for librewriters.la
-
-Relates: https://pagure.io/389-ds-base/issue/50931
-
-Reviewed by: tbordaz (Thanks!)
----
- Makefile.am | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/Makefile.am b/Makefile.am
-index 2309f3010..0e5f04f91 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -1159,7 +1159,7 @@ librewriters_la_SOURCES = \
- 
- librewriters_la_LDFLAGS = $(AM_LDFLAGS)
- librewriters_la_CPPFLAGS = $(AM_CPPFLAGS) $(REWRITERS_INCLUDES) $(DSPLUGIN_CPPFLAGS)
--librewriters_la_LIBADD = $(NSS_LINK) $(NSPR_LINK)
-+librewriters_la_LIBADD = libslapd.la $(NSS_LINK) $(NSPR_LINK)
- 
- #------------------------
- # libsvrcore
--- 
-2.26.2
-
diff --git a/SOURCES/0011-Issue-50746-Add-option-to-healthcheck-to-list-all-th.patch b/SOURCES/0011-Issue-50746-Add-option-to-healthcheck-to-list-all-th.patch
deleted file mode 100644
index c63a63c..0000000
--- a/SOURCES/0011-Issue-50746-Add-option-to-healthcheck-to-list-all-th.patch
+++ /dev/null
@@ -1,1218 +0,0 @@
-From 21ed5224d63e3118a39ddd5ea438367532541a8f Mon Sep 17 00:00:00 2001
-From: Matus Honek <mhonek@redhat.com>
-Date: Mon, 2 Dec 2019 14:53:31 +0100
-Subject: [PATCH 11/12] Issue 50746 - Add option to healthcheck to list all the
- lint reports
-
-Bug Description:
-Healthcheck lacks a way to find out what checks are available.
-
-Fix Description:
-Add dsctl healthcheck options to list available checks, known error
-codes, and ability to run cehcks selectively. The checks are rather
-hierarchically structured and in some cases matchable by patterns (by
-use of asterisk).
-
-Fixes https://pagure.io/389-ds-base/issue/50746
-
-Author: Matus Honek <mhonek@redhat.com>
-
-Review by: Mark, William, Simon (thanks for the patience!)
-
-(cherry picked from commit 4a55322c7bdb0b9ff57428ad0dc2e4d943572a69)
----
- src/lib389/cli/dsctl                          |   1 +
- src/lib389/lib389/_mapped_object.py           |  34 +---
- src/lib389/lib389/_mapped_object_lint.py      | 157 ++++++++++++++++++
- src/lib389/lib389/backend.py                  |  13 +-
- src/lib389/lib389/cli_ctl/health.py           | 116 +++++++++----
- src/lib389/lib389/config.py                   |  13 +-
- src/lib389/lib389/dseldif.py                  |  29 +---
- src/lib389/lib389/encrypted_attributes.py     |   1 -
- src/lib389/lib389/index.py                    |   3 -
- src/lib389/lib389/lint.py                     | 125 ++++++++------
- src/lib389/lib389/monitor.py                  |   5 +-
- src/lib389/lib389/nss_ssl.py                  |  23 ++-
- src/lib389/lib389/plugins.py                  |   5 +-
- src/lib389/lib389/replica.py                  |  10 +-
- .../lib389/tests/mapped_object_lint_test.py   |  78 +++++++++
- 15 files changed, 448 insertions(+), 165 deletions(-)
- create mode 100644 src/lib389/lib389/_mapped_object_lint.py
- create mode 100644 src/lib389/lib389/tests/mapped_object_lint_test.py
-
-diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl
-index fd9bd87c1..9deda7039 100755
---- a/src/lib389/cli/dsctl
-+++ b/src/lib389/cli/dsctl
-@@ -64,6 +64,7 @@ cli_dbgen.create_parser(subparsers)
- 
- argcomplete.autocomplete(parser)
- 
-+
- # handle a control-c gracefully
- def signal_handler(signal, frame):
-     print('\n\nExiting...')
-diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
-index ce0ebfeb8..c60837601 100644
---- a/src/lib389/lib389/_mapped_object.py
-+++ b/src/lib389/lib389/_mapped_object.py
-@@ -15,6 +15,7 @@ import json
- from functools import partial
- from lib389._entry import Entry
- from lib389._constants import DIRSRV_STATE_ONLINE
-+from lib389._mapped_object_lint import DSLint, DSLints
- from lib389.utils import (
-         ensure_bytes, ensure_str, ensure_int, ensure_list_bytes, ensure_list_str,
-         ensure_list_int, display_log_value, display_log_data
-@@ -82,7 +83,7 @@ class DSLogging(object):
-             self._log.setLevel(logging.INFO)
- 
- 
--class DSLdapObject(DSLogging):
-+class DSLdapObject(DSLogging, DSLint):
-     """A single instance of DSLdapObjects
- 
-     :param instance: An instance
-@@ -107,7 +108,6 @@ class DSLdapObject(DSLogging):
-         self._must_attributes = None
-         # attributes, we don't want to compare
-         self._compare_exclude = ['entryid', 'modifytimestamp', 'nsuniqueid']
--        self._lint_functions = None
-         self._server_controls = None
-         self._client_controls = None
-         self._object_filter = '(objectClass=*)'
-@@ -985,38 +985,10 @@ class DSLdapObject(DSLogging):
-         """
-         return self._create(rdn, properties, basedn, ensure=True)
- 
--    def lint(self):
--        """Override this to create a linter for a type. This means that we can detect
--        and report common administrative errors in the server from our cli and
--        rest tools.
--
--        The structure of a result is::
--
--          {
--            dsle: '<identifier>'. dsle == ds lint error. Will be a code unique to
--                                this module for the error, IE DSBLE0001.
--            severity: '[HIGH:MEDIUM:LOW]'. severity of the error.
--            items: '(dn,dn,dn)'. List of affected DNs or names.
--            detail: 'msg ...'. An explination of the error.
--            fix: 'msg ...'. Steps to resolve the error.
--          }
--
--        :returns: An array of these dicts, on None if there are no errors.
--        """
--
--        if not self._lint_functions:
--            return None
--        results = []
--        for fn in self._lint_functions:
--            for result in fn():
--                if result is not None:
--                    results.append(result)
--        return results
--
- 
- # A challenge of this, is how do we manage indexes? They have two naming attributes....
- 
--class DSLdapObjects(DSLogging):
-+class DSLdapObjects(DSLogging, DSLints):
-     """The object represents the next idea: "Everything is an instance of something
-     that exists in this way", i.e. we unite LDAP entries by some
-     set of parameters with the object.
-diff --git a/src/lib389/lib389/_mapped_object_lint.py b/src/lib389/lib389/_mapped_object_lint.py
-new file mode 100644
-index 000000000..2d03de98f
---- /dev/null
-+++ b/src/lib389/lib389/_mapped_object_lint.py
-@@ -0,0 +1,157 @@
-+from abc import ABC, abstractmethod
-+from functools import partial
-+from inspect import signature
-+from typing import (
-+    Callable,
-+    List,
-+    Optional,
-+    Tuple,
-+    Union,
-+    Type,
-+    Generator,
-+    Any
-+)
-+
-+
-+DSLintSpec = Tuple[str, Callable]
-+DSLintParsedSpec = Tuple[Optional[str], Optional[str]]
-+DSLintClassSpec = Generator[DSLintSpec, None, None]
-+DSLintMethodSpec = Union[str, None, Type[List]]
-+DSLintResults = Generator[Any, None, None]
-+
-+
-+class DSLint():
-+    """In a super-class, create a method with name beginning with `_lint_`
-+    which would yield results (as described below). Such a method will
-+    then be available to the `lint()` method of the class.
-+
-+    `lint_list`: takes a spec and yields available lints, recursively
-+    `lint`:      takes a spac and runs lints according to it, yielding results if any
-+
-+    `spec`: is a colon-separated string, with prefix matching a method name and suffix
-+            being passed down to the method.
-+
-+    A class inheriting from hereby class shall implement a method named `lint_uid()` which
-+    returns a pretty name of the object. This is to be used by a higher level code.
-+
-+    Each lint method has to have a name prefix with _lint_. It may accept an optional
-+    parameter `spec` in which case:
-+    - it has to accept typing.List class as a parameter, in which case it shall yield
-+      all possible lint specs for that method
-+    - it receives the suffix provided to the `spec` of hereby `lint` method (as mentioned above)
-+
-+    This means that we can detect and report common administrative errors
-+    in the server from our cli and rest tools.
-+
-+    The structure of a result shall be:
-+
-+        {
-+        dsle: '<identifier>'. dsle == ds lint error. Will be a code unique to
-+                            this module for the error, IE DSBLE0001.
-+        severity: '[HIGH:MEDIUM:LOW]'. severity of the error.
-+        items: '(dn,dn,dn)'. List of affected DNs or names.
-+        detail: 'msg ...'. An explination of the error.
-+        fix: 'msg ...'. Steps to resolve the error.
-+        }
-+    """
-+
-+    @classmethod
-+    def _dslint_fname(cls, method: Callable) -> Optional[str]:
-+        """Return a pretty name for a method."""
-+        if callable(method) and method.__name__.startswith('_lint_'):
-+            return method.__name__[len('_lint_'):]
-+        else:
-+            return None
-+
-+    @staticmethod
-+    def _dslint_parse_spec(spec: Optional[str]) -> DSLintParsedSpec:
-+        """Split `spec` to prefix and suffix."""
-+        wanted, *rest = spec.split(':', 1) if spec else (None, None)
-+        return (wanted if wanted not in [None, '*'] else None,
-+                rest[0] if rest else None)
-+
-+    @classmethod
-+    def _dslint_make_spec(cls, method: Callable, spec: Optional[str] = None) -> str:
-+        """Build a new spec from prefix (`method` name) and suffix (`spec`)."""
-+        fname = cls._dslint_fname(method)
-+        return f'{fname}:{spec}' if spec else fname
-+
-+    def lint_list(self, spec: Optional[str] = None) -> DSLintClassSpec:
-+        """Yield specs the object provides.
-+
-+        This yields from each lint method yielding all specs it can provide.
-+        """
-+
-+        assert hasattr(self, 'lint_uid')
-+
-+        # Find _lint_ methods
-+        # NOTE: There is a caveat: don't you dare try to getattr on a @property, or
-+        #       you get it executed. That's why the following line's complexity.
-+        fs = [getattr(self, f) for f in dir(self)
-+              if f.startswith('_lint_') and self._dslint_fname(getattr(self, f))]
-+
-+        # Filter acording to the `spec`
-+        wanted, rest = self._dslint_parse_spec(spec)
-+        if wanted:
-+            try:
-+                fs = [next(filter(lambda f: self._dslint_fname(f) == wanted, fs))]
-+            except StopIteration:
-+                raise ValueError('there is no such lint function')
-+
-+        # Yield known specs
-+        for f in fs:
-+            fspec_t = signature(f).parameters.get('spec', None)
-+            if fspec_t:
-+                assert fspec_t.annotation == DSLintMethodSpec
-+                for fspec in [rest] if rest else f(spec=List):
-+                    yield self._dslint_make_spec(f, fspec), partial(f, spec=fspec)
-+            else:
-+                yield self._dslint_make_spec(f, rest), f
-+
-+    def lint(self, spec: DSLintMethodSpec = None) -> DSLintResults:
-+        """Lint the object according to the `spec`."""
-+
-+        if spec == List:
-+            yield from self.lint_list()
-+        else:
-+            for fn, f in self.lint_list(spec):
-+                yield from f()
-+
-+
-+class DSLints():
-+    """This is a meta class to provide lint functionality to classes that provide
-+    method `list` which returns list of objects that inherit from DSLint.
-+
-+    Calling `lint` or `lint_list` method yields from respective object's methods.
-+
-+    The `spec` is a colon-separated string. Its prefix matches the respective object's
-+    `lint_uid` (or all when asterisk); the suffix is passed down to the respective
-+    object's method.
-+    """
-+
-+    def lint_list(self, spec: Optional[str] = None) -> DSLintClassSpec:
-+        """Yield specs the objects returned by `list` method provide."""
-+
-+        assert hasattr(self, 'list')
-+
-+        # Filter acording to the `spec`
-+        wanted, rest_spec = DSLint._dslint_parse_spec(spec)
-+        if wanted in [None, '*']:
-+            clss = self.list()
-+        else:
-+            clss = (cls for cls in self.list() if cls.lint_uid() == wanted)
-+
-+        # Yield known specs
-+        for cls in clss:
-+            for fn, f in cls.lint_list(spec=rest_spec):
-+                yield (f'{cls.lint_uid()}:{fn}',
-+                       partial(f, rest_spec) if rest_spec else f)
-+
-+    def lint(self, spec: DSLintMethodSpec = None) -> DSLintResults:
-+        """Lint the objects returned by `list` method according to the `spec`."""
-+
-+        if spec == List:
-+            yield from self.lint_list()
-+        else:
-+            for obj in self.list():
-+                yield from obj.lint()
-diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
-index 4f752f414..8863ad1a8 100644
---- a/src/lib389/lib389/backend.py
-+++ b/src/lib389/lib389/backend.py
-@@ -393,6 +393,10 @@ class BackendLegacy(object):
-         replace = [(ldap.MOD_REPLACE, 'nsslapd-require-index', 'on')]
-         self.modify_s(dn, replace)
- 
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'backends'
-+
- 
- class Backend(DSLdapObject):
-     """Backend DSLdapObject with:
-@@ -413,10 +417,12 @@ class Backend(DSLdapObject):
-         self._must_attributes = ['nsslapd-suffix', 'cn']
-         self._create_objectclasses = ['top', 'extensibleObject', BACKEND_OBJECTCLASS_VALUE]
-         self._protected = False
--        self._lint_functions = [self._lint_mappingtree, self._lint_search, self._lint_virt_attrs]
-         # Check if a mapping tree for this suffix exists.
-         self._mts = MappingTrees(self._instance)
- 
-+    def lint_uid(self):
-+        return self.get_attr_val_utf8_l('cn').lower()
-+
-     def _lint_virt_attrs(self):
-         """Check if any virtual attribute are incorrectly indexed"""
-         indexes = self.get_indexes()
-@@ -497,7 +503,6 @@ class Backend(DSLdapObject):
-             result = DSBLE0001
-             result['items'] = [bename, ]
-             yield result
--        return None
- 
-     def create_sample_entries(self, version):
-         """Creates sample entries under nsslapd-suffix value
-@@ -848,6 +853,10 @@ class Backends(DSLdapObjects):
-         self._childobject = Backend
-         self._basedn = DN_LDBM
- 
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'backends'
-+
-     def import_ldif(self, be_name, ldifs, chunk_size=None, encrypted=False, gen_uniq_id=None, only_core=False,
-                     include_suffixes=None, exclude_suffixes=None):
-         """Do an import of the suffix"""
-diff --git a/src/lib389/lib389/cli_ctl/health.py b/src/lib389/lib389/cli_ctl/health.py
-index 3d15ad85e..6333a753a 100644
---- a/src/lib389/lib389/cli_ctl/health.py
-+++ b/src/lib389/lib389/cli_ctl/health.py
-@@ -7,6 +7,9 @@
- # --- END COPYRIGHT BLOCK ---
- 
- import json
-+import re
-+from lib389._mapped_object import DSLdapObjects
-+from lib389._mapped_object_lint import DSLint
- from lib389.cli_base import connect_instance, disconnect_instance
- from lib389.cli_base.dsrc import dsrc_to_ldap, dsrc_arg_concat
- from lib389.backend import Backends
-@@ -15,17 +18,17 @@ from lib389.monitor import MonitorDiskSpace
- from lib389.replica import Replica, Changelog5
- from lib389.nss_ssl import NssSsl
- from lib389.dseldif import FSChecks, DSEldif
-+from lib389 import lint
- from lib389 import plugins
- from lib389._constants import DSRC_HOME
-+from functools import partial
-+from typing import Iterable
- 
--# These get all instances, then check them all.
--CHECK_MANY_OBJECTS = [
--    Backends,
--]
- 
- # These get single instances and check them.
- CHECK_OBJECTS = [
-     Config,
-+    Backends,
-     Encryption,
-     FSChecks,
-     plugins.ReferentialIntegrityPlugin,
-@@ -52,44 +55,51 @@ def _format_check_output(log, result, idx):
-     log.info(result['fix'])
- 
- 
--def health_check_run(inst, log, args):
--    """Connect to the local server using LDAPI, and perform various health checks
--    """
-+def _list_targets(inst):
-+    for c in CHECK_OBJECTS:
-+        o = c(inst)
-+        yield o.lint_uid(), o
-+
-+
-+def _list_errors(log):
-+    for r in map(partial(getattr, lint),
-+                 filter(partial(re.match, r'^DS'),
-+                        dir(lint))):
-+        log.info(f"{r['dsle']} :: {r['description']}")
- 
--    # update the args for connect_instance()
--    args.basedn = None
--    args.binddn = None
--    args.bindpw = None
--    args.starttls = None
--    args.pwdfile = None
--    args.prompt = False
--    dsrc_inst = dsrc_to_ldap(DSRC_HOME, args.instance, log.getChild('dsrc'))
--    dsrc_inst = dsrc_arg_concat(args, dsrc_inst)
--    try:
--        inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose, args=args)
--    except Exception as e:
--        raise ValueError('Failed to connect to Directory Server instance: ' + str(e))
- 
-+def _list_checks(inst, specs: Iterable[str]):
-+    o_uids = dict(_list_targets(inst))
-+    for s in specs:
-+        wanted, rest = DSLint._dslint_parse_spec(s)
-+        if wanted == '*':
-+            raise ValueError('Unexpected spec selector asterisk')
-+
-+        if wanted in o_uids:
-+            for l in o_uids[wanted].lint_list(rest):
-+                yield o_uids[wanted], l
-+        else:
-+            raise ValueError('No such object specifier')
-+
-+
-+def _print_checks(inst, specs: Iterable[str]) -> None:
-+    for o, s in _list_checks(inst, specs):
-+        print(f'{o.lint_uid()}:{s[0]}')
-+
-+
-+def _run(inst, log, args, checks):
-     if not args.json:
-         log.info("Beginning lint report, this could take a while ...")
-+
-     report = []
--    for lo in CHECK_MANY_OBJECTS:
-+    for o, s in checks:
-         if not args.json:
--            log.info("Checking %s ..." % lo.__name__)
--        lo_inst = lo(inst)
--        for clo in lo_inst.list():
--            result = clo.lint()
--            if result is not None:
--                report += result
--    for lo in CHECK_OBJECTS:
--        if not args.json:
--            log.info("Checking %s ..." % lo.__name__)
--        lo_inst = lo(inst)
--        result = lo_inst.lint()
--        if result is not None:
--            report += result
-+            log.info(f"Checking {o.lint_uid()}:{s[0]} ...")
-+        report += o.lint(s[0]) or []
-+
-     if not args.json:
-         log.info("Healthcheck complete.")
-+
-     count = len(report)
-     if count == 0:
-         if not args.json:
-@@ -110,6 +120,37 @@ def health_check_run(inst, log, args):
-         else:
-             log.info(json.dumps(report, indent=4))
- 
-+
-+def health_check_run(inst, log, args):
-+    """Connect to the local server using LDAPI, and perform various health checks
-+    """
-+
-+    if args.list_errors:
-+        _list_errors(log)
-+        return
-+
-+    # update the args for connect_instance()
-+    args.basedn = None
-+    args.binddn = None
-+    args.bindpw = None
-+    args.starttls = None
-+    args.pwdfile = None
-+    args.prompt = False
-+    dsrc_inst = dsrc_to_ldap(DSRC_HOME, args.instance, log.getChild('dsrc'))
-+    dsrc_inst = dsrc_arg_concat(args, dsrc_inst)
-+    try:
-+        inst = connect_instance(dsrc_inst=dsrc_inst, verbose=args.verbose, args=args)
-+    except Exception as e:
-+        raise ValueError('Failed to connect to Directory Server instance: ' + str(e))
-+
-+    checks = args.check or dict(_list_targets(inst)).keys()
-+
-+    if args.list_checks or args.dry_run:
-+        _print_checks(inst, checks)
-+        return
-+
-+    _run(inst, log, args, _list_checks(inst, checks))
-+
-     disconnect_instance(inst)
- 
- 
-@@ -120,4 +161,9 @@ def create_parser(subparsers):
-         "remote Directory Server as this tool needs access to local resources, "
-         "otherwise the report may be inaccurate.")
-     run_healthcheck_parser.set_defaults(func=health_check_run)
--
-+    run_healthcheck_parser.add_argument('--list-checks', action='store_true', help='List of known checks')
-+    run_healthcheck_parser.add_argument('--list-errors', action='store_true', help='List of known error codes')
-+    run_healthcheck_parser.add_argument('--dry-run', action='store_true', help='Do not execute the actual check, only list what would be done')
-+    run_healthcheck_parser.add_argument('--check', nargs='+', default=None,
-+                                        help='Areas to check. These can be obtained by --list-checks. Every element on the left of the colon (:)'
-+                                             ' may be replaced by an asterisk if multiple options on the right are available.')
-diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py
-index a29d0244c..aa4c92beb 100644
---- a/src/lib389/lib389/config.py
-+++ b/src/lib389/lib389/config.py
-@@ -54,7 +54,6 @@ class Config(DSLdapObject):
-         ]
-         self._compare_exclude  = self._compare_exclude + config_compare_exclude
-         self._rdn_attribute = 'cn'
--        self._lint_functions = [self._lint_hr_timestamp, self._lint_passwordscheme]
- 
-     @property
-     def dn(self):
-@@ -197,6 +196,10 @@ class Config(DSLdapObject):
-         fields = 'nsslapd-security nsslapd-ssl-check-hostname'.split()
-         return self._instance.getEntry(DN_CONFIG, attrlist=fields)
- 
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'config'
-+
-     def _lint_hr_timestamp(self):
-         hr_timestamp = self.get_attr_val('nsslapd-logging-hr-timestamps-enabled')
-         if ensure_bytes('on') != hr_timestamp:
-@@ -242,20 +245,22 @@ class Encryption(DSLdapObject):
-         self._rdn_attribute = 'cn'
-         self._must_attributes = ['cn']
-         self._protected = True
--        self._lint_functions = [self._lint_check_tls_version]
- 
-     def create(self, rdn=None, properties={'cn': 'encryption', 'nsSSLClientAuth': 'allowed'}):
-         if rdn is not None:
-             self._log.debug("dn on cn=encryption is not None. This is a mistake.")
-         super(Encryption, self).create(properties=properties)
- 
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'encryption'
-+
-     def _lint_check_tls_version(self):
-         tls_min = self.get_attr_val('sslVersionMin')
-         if tls_min is not None and tls_min < ensure_bytes('TLS1.1'):
-             report = copy.deepcopy(DSELE0001)
-             report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
-             yield report
--        yield None
- 
-     @property
-     def ciphers(self):
-@@ -487,7 +492,6 @@ class LDBMConfig(DSLdapObject):
-         self._dn = DN_CONFIG_LDBM
-         # config_compare_exclude = []
-         self._rdn_attribute = 'cn'
--        self._lint_functions = []
-         self._protected = True
- 
- 
-@@ -506,5 +510,4 @@ class BDB_LDBMConfig(DSLdapObject):
-         self._dn = DN_CONFIG_LDBM_BDB
-         self._config_compare_exclude = []
-         self._rdn_attribute = 'cn'
--        self._lint_functions = []
-         self._protected = True
-diff --git a/src/lib389/lib389/dseldif.py b/src/lib389/lib389/dseldif.py
-index 5378e6ee9..96c9af9d1 100644
---- a/src/lib389/lib389/dseldif.py
-+++ b/src/lib389/lib389/dseldif.py
-@@ -16,6 +16,7 @@ from datetime import timedelta
- from stat import ST_MODE
- # from lib389.utils import print_nice_time
- from lib389.paths import Paths
-+from lib389._mapped_object_lint import DSLint
- from lib389.lint import (
-     DSPERMLE0001,
-     DSPERMLE0002,
-@@ -25,7 +26,7 @@ from lib389.lint import (
- )
- 
- 
--class DSEldif(object):
-+class DSEldif(DSLint):
-     """A class for working with dse.ldif file
- 
-     :param instance: An instance
-@@ -58,15 +59,10 @@ class DSEldif(object):
-                         processed_line = line
-                 else:
-                     processed_line = processed_line[:-1] + line[1:]
--        self._lint_functions = [self._lint_nsstate]
- 
--    def lint(self):
--        results = []
--        for fn in self._lint_functions:
--            for result in fn():
--                if result is not None:
--                    results.append(result)
--        return results
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'dseldif'
- 
-     def _lint_nsstate(self):
-         suffixes = self.readNsState()
-@@ -320,7 +316,7 @@ class DSEldif(object):
-         return states
- 
- 
--class FSChecks(object):
-+class FSChecks(DSLint):
-     """This is for the healthcheck feature, check commonly used system config files the
-     server uses.  This is here for lack of a better place to add this class.
-     """
-@@ -344,17 +340,10 @@ class FSChecks(object):
-                 'report': DSPERMLE0002
-             },
-         ]
--        self._lint_functions = [self._lint_file_perms]
- 
--    def lint(self):
--        """Run a lint/healthcheck for this class
--        """
--        results = []
--        for fn in self._lint_functions:
--            for result in fn():
--                if result is not None:
--                    results.append(result)
--        return results
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'fschecks'
- 
-     def _lint_file_perms(self):
-         """Test file permissions are safe
-diff --git a/src/lib389/lib389/encrypted_attributes.py b/src/lib389/lib389/encrypted_attributes.py
-index 9afd2e66b..2fa26cef9 100644
---- a/src/lib389/lib389/encrypted_attributes.py
-+++ b/src/lib389/lib389/encrypted_attributes.py
-@@ -27,7 +27,6 @@ class EncryptedAttr(DSLdapObject):
-         self._must_attributes = ['cn', 'nsEncryptionAlgorithm']
-         self._create_objectclasses = ['top', 'nsAttributeEncryption']
-         self._protected = False
--        self._lint_functions = []
- 
- 
- class EncryptedAttrs(DSLdapObjects):
-diff --git a/src/lib389/lib389/index.py b/src/lib389/lib389/index.py
-index 6932883b7..a3d019d27 100644
---- a/src/lib389/lib389/index.py
-+++ b/src/lib389/lib389/index.py
-@@ -41,7 +41,6 @@ class Index(DSLdapObject):
-         self._must_attributes = ['cn', 'nsSystemIndex', 'nsIndexType']
-         self._create_objectclasses = ['top', 'nsIndex']
-         self._protected = False
--        self._lint_functions = []
- 
- 
- class Indexes(DSLdapObjects):
-@@ -77,7 +76,6 @@ class VLVSearch(DSLdapObject):
-         self._must_attributes = ['cn', 'vlvbase', 'vlvscope', 'vlvfilter']
-         self._create_objectclasses = ['top', 'vlvSearch']
-         self._protected = False
--        self._lint_functions = []
-         self._be_name = None
- 
-     def get_sorts(self):
-@@ -163,7 +161,6 @@ class VLVIndex(DSLdapObject):
-         self._must_attributes = ['cn', 'vlvsort']
-         self._create_objectclasses = ['top', 'vlvIndex']
-         self._protected = False
--        self._lint_functions = []
- 
- 
- class VLVIndexes(DSLdapObjects):
-diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
-index b5a305bc3..a103feec7 100644
---- a/src/lib389/lib389/lint.py
-+++ b/src/lib389/lib389/lint.py
-@@ -14,8 +14,9 @@
- DSBLE0001 = {
-     'dsle': 'DSBLE0001',
-     'severity': 'MEDIUM',
--    'items' : [],
--    'detail' : """This backend may be missing the correct mapping tree references. Mapping Trees allow
-+    'description': 'Possibly incorrect mapping tree.',
-+    'items': [],
-+    'detail': """This backend may be missing the correct mapping tree references. Mapping Trees allow
- the directory server to determine which backend an operation is routed to in the
- abscence of other information. This is extremely important for correct functioning
- of LDAP ADD for example.
-@@ -32,7 +33,7 @@ objectClass: extensibleObject
- objectClass: nsMappingTree
- 
- """,
--    'fix' : """Either you need to create the mapping tree, or you need to repair the related
-+    'fix': """Either you need to create the mapping tree, or you need to repair the related
- mapping tree. You will need to do this by hand by editing cn=config, or stopping
- the instance and editing dse.ldif.
- """
-@@ -41,25 +42,28 @@ the instance and editing dse.ldif.
- DSBLE0002 = {
-     'dsle': 'DSBLE0002',
-     'severity': 'HIGH',
--    'items' : [],
--    'detail' : """Unable to query the backend.  LDAP error (ERROR)""",
--    'fix' : """Check the server's error and access logs for more information."""
-+    'description': 'Unable to query backend.',
-+    'items': [],
-+    'detail': """Unable to query the backend.  LDAP error (ERROR)""",
-+    'fix': """Check the server's error and access logs for more information."""
- }
- 
- DSBLE0003 = {
-     'dsle': 'DSBLE0003',
-     'severity': 'LOW',
--    'items' : [],
--    'detail' : """The backend database has not been initialized yet""",
--    'fix' : """You need to import an LDIF file, or create the suffix entry, in order to initialize the database."""
-+    'description': 'Uninitialized backend database.',
-+    'items': [],
-+    'detail': """The backend database has not been initialized yet""",
-+    'fix': """You need to import an LDIF file, or create the suffix entry, in order to initialize the database."""
- }
- 
- # Config checks
- DSCLE0001 = {
--    'dsle' : 'DSCLE0001',
--    'severity' : 'LOW',
-+    'dsle': 'DSCLE0001',
-+    'severity': 'LOW',
-+    'description': 'Different log timestamp format.',
-     'items': ['cn=config', ],
--    'detail' : """nsslapd-logging-hr-timestamps-enabled changes the log format in directory server from
-+    'detail': """nsslapd-logging-hr-timestamps-enabled changes the log format in directory server from
- 
- [07/Jun/2017:17:15:58 +1000]
- 
-@@ -70,7 +74,7 @@ to
- This actually provides a performance improvement. Additionally, this setting will be
- removed in a future release.
- """,
--    'fix' : """Set nsslapd-logging-hr-timestamps-enabled to on.
-+    'fix': """Set nsslapd-logging-hr-timestamps-enabled to on.
- You can use 'dsconf' to set this attribute.  Here is an example:
- 
-     # dsconf slapd-YOUR_INSTANCE config replace nsslapd-logging-hr-timestamps-enabled=on"""
-@@ -79,8 +83,9 @@ You can use 'dsconf' to set this attribute.  Here is an example:
- DSCLE0002 = {
-     'dsle': 'DSCLE0002',
-     'severity': 'HIGH',
--    'items' : ['cn=config', ],
--    'detail' : """Password storage schemes in Directory Server define how passwords are hashed via a
-+    'description': 'Weak passwordStorageScheme.',
-+    'items': ['cn=config', ],
-+    'detail': """Password storage schemes in Directory Server define how passwords are hashed via a
- one-way mathematical function for storage. Knowing the hash it is difficult to gain
- the input, but knowing the input you can easily compare the hash.
- 
-@@ -112,14 +117,15 @@ You can also use 'dsconf' to replace these values.  Here is an example:
- DSELE0001 = {
-     'dsle': 'DSELE0001',
-     'severity': 'MEDIUM',
--    'items' : ['cn=encryption,cn=config', ],
-+    'description': 'Weak TLS protocol version.',
-+    'items': ['cn=encryption,cn=config', ],
-     'detail': """This Directory Server may not be using strong TLS protocol versions. TLS1.0 is known to
- have a number of issues with the protocol. Please see:
- 
- https://tools.ietf.org/html/rfc7457
- 
- It is advised you set this value to the maximum possible.""",
--    'fix' : """There are two options for setting the TLS minimum version allowed.  You,
-+    'fix': """There are two options for setting the TLS minimum version allowed.  You,
- can set "sslVersionMin" in "cn=encryption,cn=config" to a version greater than "TLS1.0"
- You can also use 'dsconf' to set this value.  Here is an example:
- 
-@@ -137,7 +143,8 @@ minimum version, but doing this affects the entire system:
- DSRILE0001 = {
-     'dsle': 'DSRILE0001',
-     'severity': 'LOW',
--    'items' : ['cn=referential integrity postoperation,cn=plugins,cn=config', ],
-+    'description': 'Referential integrity plugin may be slower.',
-+    'items': ['cn=referential integrity postoperation,cn=plugins,cn=config', ],
-     'detail': """The referential integrity plugin has an asynchronous processing mode.
- This is controlled by the update-delay flag.  When this value is 0, referential
- integrity plugin processes these changes inside of the operation that modified
-@@ -151,7 +158,7 @@ delays to your server by batching changes rather than smaller updates during syn
- 
- We advise that you set this value to 0, and enable referint on all masters as it provides a more predictable behaviour.
- """,
--    'fix' : """Set referint-update-delay to 0.
-+    'fix': """Set referint-update-delay to 0.
- 
- You can use 'dsconf' to set this value.  Here is an example:
- 
-@@ -164,12 +171,13 @@ You must restart the Directory Server for this change to take effect."""
- DSRILE0002 = {
-     'dsle': 'DSRILE0002',
-     'severity': 'HIGH',
--    'items' : ['cn=referential integrity postoperation,cn=plugins,cn=config'],
-+    'description': 'Referential integrity plugin configured with unindexed attribute.',
-+    'items': ['cn=referential integrity postoperation,cn=plugins,cn=config'],
-     'detail': """The referential integrity plugin is configured to use an attribute (ATTR)
- that does not have an "equality" index in backend (BACKEND).
- Failure to have the proper indexing will lead to unindexed searches which
- cause high CPU and can significantly slow the server down.""",
--    'fix' : """Check the attributes set in "referint-membership-attr" to make sure they have
-+    'fix': """Check the attributes set in "referint-membership-attr" to make sure they have
- an index defined that has at least the equality "eq" index type.  You will
- need to reindex the database after adding the missing index type. Here is an
- example using dsconf:
-@@ -182,12 +190,13 @@ example using dsconf:
- DSDSLE0001 = {
-     'dsle': 'DSDSLE0001',
-     'severity': 'HIGH',
--    'items' : ['Server', 'cn=config'],
-+    'description': 'Low disk space.',
-+    'items': ['Server', 'cn=config'],
-     'detail': """The disk partition used by the server (PARTITION), either for the database, the
- configuration files, or the logs is over 90% full.  If the partition becomes
- completely filled serious problems can occur with the database or the server's
- stability.""",
--    'fix' : """Attempt to free up disk space.  Also try removing old rotated logs, or disable any
-+    'fix': """Attempt to free up disk space.  Also try removing old rotated logs, or disable any
- verbose logging levels that might have been set.  You might consider enabling
- the "Disk Monitoring" feature in cn=config to help prevent a disorderly shutdown
- of the server:
-@@ -210,9 +219,10 @@ Please see the Administration guide for more information:
- DSREPLLE0001 = {
-     'dsle': 'DSREPLLE0001',
-     'severity': 'HIGH',
--    'items' : ['Replication', 'Agreement'],
-+    'description': 'Replication agreement not set to be synchronized.',
-+    'items': ['Replication', 'Agreement'],
-     'detail': """The replication agreement (AGMT) under "SUFFIX" is not in synchronization.""",
--    'fix' : """You may need to reinitialize this replication agreement.  Please check the errors
-+    'fix': """You may need to reinitialize this replication agreement.  Please check the errors
- log for more information.  If you do need to reinitialize the agreement you can do so
- using dsconf.  Here is an example:
- 
-@@ -223,9 +233,10 @@ using dsconf.  Here is an example:
- DSREPLLE0002 = {
-     'dsle': 'DSREPLLE0002',
-     'severity': 'LOW',
--    'items' : ['Replication', 'Conflict Entries'],
-+    'description': 'Replication conflict entries found.',
-+    'items': ['Replication', 'Conflict Entries'],
-     'detail': "There were COUNT conflict entries found under the replication suffix \"SUFFIX\".",
--    'fix' : """While conflict entries are expected to occur in an MMR environment, they
-+    'fix': """While conflict entries are expected to occur in an MMR environment, they
- should be resolved.  In regards to conflict entries there is always the original/counterpart
- entry that has a normal DN, and then the conflict version of that entry.  Technically both
- entries are valid, you as the administrator, needs to decide which entry you want to keep.
-@@ -253,38 +264,42 @@ can use the CLI tool "dsconf" to resolve the conflict.  Here is an example:
- DSREPLLE0003 = {
-     'dsle': 'DSREPLLE0003',
-     'severity': 'MEDIUM',
--    'items' : ['Replication', 'Agreement'],
-+    'description': 'Unsynchronized replication agreement.',
-+    'items': ['Replication', 'Agreement'],
-     'detail': """The replication agreement (AGMT) under "SUFFIX" is not in synchronization.
- Status message: MSG""",
--    'fix' : """Replication is not in synchronization but it may recover.  Continue to
-+    'fix': """Replication is not in synchronization but it may recover.  Continue to
- monitor this agreement."""
- }
- 
- DSREPLLE0004 = {
-     'dsle': 'DSREPLLE0004',
-     'severity': 'MEDIUM',
--    'items' : ['Replication', 'Agreement'],
-+    'description': 'Unable to get replication agreement status.',
-+    'items': ['Replication', 'Agreement'],
-     'detail': """Failed to get the agreement status for agreement (AGMT) under "SUFFIX".  Error (ERROR).""",
--    'fix' : """None"""
-+    'fix': """None"""
- }
- 
- DSREPLLE0005 = {
-     'dsle': 'DSREPLLE0005',
-     'severity': 'MEDIUM',
--    'items' : ['Replication', 'Agreement'],
-+    'description': 'Replication consumer not reachable.',
-+    'items': ['Replication', 'Agreement'],
-     'detail': """The replication agreement (AGMT) under "SUFFIX" is not in synchronization,
- because the consumer server is not reachable.""",
--    'fix' : """Check if the consumer is running, and also check the errors log for more information."""
-+    'fix': """Check if the consumer is running, and also check the errors log for more information."""
- }
- 
- # Replication changelog
- DSCLLE0001 = {
-     'dsle': 'DSCLLE0001',
-     'severity': 'LOW',
--    'items' : ['Replication', 'Changelog'],
-+    'description': 'Changelog trimming not configured.',
-+    'items': ['Replication', 'Changelog'],
-     'detail': """The replication changelog does have any kind of trimming configured.  This will
- lead to the changelog size growing indefinitely.""",
--    'fix' : """Configure changelog trimming, preferably by setting the maximum age of a changelog
-+    'fix': """Configure changelog trimming, preferably by setting the maximum age of a changelog
- record.  Here is an example:
- 
-     # dsconf slapd-YOUR_INSTANCE replication set-changelog --max-age 30d"""
-@@ -294,27 +309,30 @@ record.  Here is an example:
- DSCERTLE0001 = {
-     'dsle': 'DSCERTLE0001',
-     'severity': 'MEDIUM',
--    'items' : ['Expiring Certificate'],
-+    'description': 'Certificate about to expire.',
-+    'items': ['Expiring Certificate'],
-     'detail': """The certificate (CERT) will expire in less than 30 days""",
--    'fix' : """Renew the certificate before it expires to prevent disruptions with TLS connections."""
-+    'fix': """Renew the certificate before it expires to prevent disruptions with TLS connections."""
- }
- 
- DSCERTLE0002 = {
-     'dsle': 'DSCERTLE0002',
-     'severity': 'HIGH',
--    'items' : ['Expired Certificate'],
-+    'description': 'Certificate expired.',
-+    'items': ['Expired Certificate'],
-     'detail': """The certificate (CERT) has expired""",
--    'fix' : """Renew or remove the certificate."""
-+    'fix': """Renew or remove the certificate."""
- }
- 
- # Virtual Attrs & COS.  Note - ATTR and SUFFIX are replaced by the reporting function
- DSVIRTLE0001 = {
-     'dsle': 'DSVIRTLE0001',
-     'severity': 'HIGH',
--    'items' : ['Virtual Attributes'],
-+    'description': 'Virtual attribute indexed.',
-+    'items': ['Virtual Attributes'],
-     'detail': """You should not index virtual attributes, and as this will break searches that
- use the attribute in a filter.""",
--    'fix' : """Remove the index for this attribute from the backend configuration.
-+    'fix': """Remove the index for this attribute from the backend configuration.
- Here is an example using 'dsconf' to remove an index:
- 
-     # dsconf slapd-YOUR_INSTANCE backend index delete --attr ATTR SUFFIX"""
-@@ -324,10 +342,11 @@ Here is an example using 'dsconf' to remove an index:
- DSPERMLE0001 = {
-     'dsle': 'DSPERMLE0001',
-     'severity': 'MEDIUM',
--    'items' : ['File Permissions'],
-+    'description': 'Incorrect file permissions.',
-+    'items': ['File Permissions'],
-     'detail': """The file "FILE" does not have the expected permissions (PERMS).  This
- can cause issues with replication and chaining.""",
--    'fix' : """Change the file permissions:
-+    'fix': """Change the file permissions:
- 
-     # chmod PERMS FILE"""
- }
-@@ -336,10 +355,11 @@ can cause issues with replication and chaining.""",
- DSPERMLE0002 = {
-     'dsle': 'DSPERMLE0002',
-     'severity': 'HIGH',
--    'items' : ['File Permissions'],
-+    'description': 'Incorrect security database file permissions.',
-+    'items': ['File Permissions'],
-     'detail': """The file "FILE" does not have the expected permissions (PERMS).  The
- security database pin/password files should only be readable by Directory Server user.""",
--    'fix' : """Change the file permissions:
-+    'fix': """Change the file permissions:
- 
-     # chmod PERMS FILE"""
- }
-@@ -348,11 +368,12 @@ security database pin/password files should only be readable by Directory Server
- DSSKEWLE0001 = {
-     'dsle': 'DSSKEWLE0001',
-     'severity': 'Low',
--    'items' : ['Replication'],
-+    'description': 'Medium time skew.',
-+    'items': ['Replication'],
-     'detail': """The time skew is over 6 hours.  If this time skew continues to increase
- to 24 hours then replication can potentially stop working.  Please continue to
- monitor the time skew offsets for increasing values.""",
--    'fix' : """Monitor the time skew and avoid making changes to the system time.
-+    'fix': """Monitor the time skew and avoid making changes to the system time.
- Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/managing_replication-troubleshooting_replication_related_problems
- and find the paragraph "Too much time skew"."""
- }
-@@ -360,13 +381,14 @@ and find the paragraph "Too much time skew"."""
- DSSKEWLE0002 = {
-     'dsle': 'DSSKEWLE0002',
-     'severity': 'Medium',
--    'items' : ['Replication'],
-+    'description': 'Major time skew.',
-+    'items': ['Replication'],
-     'detail': """The time skew is over 12 hours.  If this time skew continues to increase
- to 24 hours then replication can potentially stop working.  Please continue to
- monitor the time skew offsets for increasing values.  Setting nsslapd-ignore-time-skew
- to "on" on each replica will allow replication to continue, but if the time skew
- continues to increase other more serious replication problems can occur.""",
--    'fix' : """Monitor the time skew and avoid making changes to the system time.
-+    'fix': """Monitor the time skew and avoid making changes to the system time.
- If you get close to 24 hours of time skew replication may stop working.
- In that case configure the server to ignore the time skew until the system
- times can be fixed/synchronized:
-@@ -380,12 +402,13 @@ and find the paragraph "Too much time skew"."""
- DSSKEWLE0003 = {
-     'dsle': 'DSSKEWLE0003',
-     'severity': 'High',
--    'items' : ['Replication'],
-+    'description': 'Extensive time skew.',
-+    'items': ['Replication'],
-     'detail': """The time skew is over 24 hours.  Setting nsslapd-ignore-time-skew
- to "on" on each replica will allow replication to continue, but if the
- time skew continues to increase other serious replication problems can
- occur.""",
--    'fix' : """Avoid making changes to the system time, and make sure the clocks
-+    'fix': """Avoid making changes to the system time, and make sure the clocks
- on all the replicas are correct.  If you haven't set the server's
- "ignore time skew" setting then do the following on all the replicas
- until the time issues have been resolved:
-diff --git a/src/lib389/lib389/monitor.py b/src/lib389/lib389/monitor.py
-index 73750c3c2..4ac7d7174 100644
---- a/src/lib389/lib389/monitor.py
-+++ b/src/lib389/lib389/monitor.py
-@@ -358,7 +358,10 @@ class MonitorDiskSpace(DSLdapObject):
-     def __init__(self, instance, dn=None):
-         super(MonitorDiskSpace, self).__init__(instance=instance, dn=dn)
-         self._dn = "cn=disk space,cn=monitor"
--        self._lint_functions = [self._lint_disk_space]
-+
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'monitor-disk-space'
- 
-     def _lint_disk_space(self):
-         partitions = self.get_attr_vals_utf8_l("dsDisk")
-diff --git a/src/lib389/lib389/nss_ssl.py b/src/lib389/lib389/nss_ssl.py
-index d14e7ce6f..e257424fd 100644
---- a/src/lib389/lib389/nss_ssl.py
-+++ b/src/lib389/lib389/nss_ssl.py
-@@ -21,6 +21,7 @@ import subprocess
- from datetime import datetime, timedelta
- from subprocess import check_output, run, PIPE
- from lib389.passwd import password_generate
-+from lib389._mapped_object_lint import DSLint
- from lib389.lint import DSCERTLE0001, DSCERTLE0002
- from lib389.utils import ensure_str, format_cmd_list
- import uuid
-@@ -42,7 +43,7 @@ VALID_MIN = 61  # Days
- log = logging.getLogger(__name__)
- 
- 
--class NssSsl(object):
-+class NssSsl(DSLint):
-     def __init__(self, dirsrv=None, dbpassword=None, dbpath=None):
-         self.dirsrv = dirsrv
-         self._certdb = dbpath
-@@ -56,18 +57,14 @@ class NssSsl(object):
-         else:
-             self.dbpassword = dbpassword
- 
--        self.db_files = {"dbm_backend": ["%s/%s" % (self._certdb, f) for f in ("key3.db", "cert8.db", "secmod.db")],
--                         "sql_backend": ["%s/%s" % (self._certdb, f) for f in ("key4.db", "cert9.db", "pkcs11.txt")],
--                         "support": ["%s/%s" % (self._certdb, f) for f in ("noise.txt", PIN_TXT, PWD_TXT)]}
--        self._lint_functions = [self._lint_certificate_expiration,]
--
--    def lint(self):
--        results = []
--        for fn in self._lint_functions:
--            for result in fn():
--                if result is not None:
--                    results.append(result)
--        return results
-+        self.db_files = {group: [f"{self._certdb}/{f}" for f in files]
-+                         for group, files in {"dbm_backend": ("key3.db", "cert8.db", "secmod.db"),
-+                                              "sql_backend": ("key4.db", "cert9.db", "pkcs11.txt"),
-+                                              "support": ("noise.txt", PIN_TXT, PWD_TXT)}.items()}
-+
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'ssl'
- 
-     def _lint_certificate_expiration(self):
-         """Check all the certificates in the db if they will expire within 30 days
-diff --git a/src/lib389/lib389/plugins.py b/src/lib389/lib389/plugins.py
-index f68a1d114..89e660287 100644
---- a/src/lib389/lib389/plugins.py
-+++ b/src/lib389/lib389/plugins.py
-@@ -431,7 +431,6 @@ class ReferentialIntegrityPlugin(Plugin):
-             'referint-logfile',
-             'referint-membership-attr',
-         ])
--        self._lint_functions = [self._lint_update_delay, self._lint_attr_indexes]
- 
-     def create(self, rdn=None, properties=None, basedn=None):
-         """Create an instance of the plugin"""
-@@ -443,6 +442,10 @@ class ReferentialIntegrityPlugin(Plugin):
-             properties['referint-logfile'] = referint_log
-         return super(ReferentialIntegrityPlugin, self).create(rdn, properties, basedn)
- 
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'refint'
-+
-     def _lint_update_delay(self):
-         if self.status():
-             delay = self.get_attr_val_int("referint-update-delay")
-diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
-index f8adb3ce2..f575e58d5 100644
---- a/src/lib389/lib389/replica.py
-+++ b/src/lib389/lib389/replica.py
-@@ -1049,7 +1049,10 @@ class Changelog5(DSLdapObject):
-                 'extensibleobject',
-             ]
-         self._protected = False
--        self._lint_functions = [self._lint_cl_trimming]
-+
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'changelog'
- 
-     def _lint_cl_trimming(self):
-         """Check that cl trimming is at least defined to prevent unbounded growth"""
-@@ -1120,7 +1123,10 @@ class Replica(DSLdapObject):
-             self._create_objectclasses.append('extensibleobject')
-         self._protected = False
-         self._suffix = None
--        self._lint_functions = [self._lint_agmts_status, self._lint_conflicts]
-+
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'replication'
- 
-     def _lint_agmts_status(self):
-         replicas = Replicas(self._instance).list()
-diff --git a/src/lib389/lib389/tests/mapped_object_lint_test.py b/src/lib389/lib389/tests/mapped_object_lint_test.py
-new file mode 100644
-index 000000000..a4ca0ea3c
---- /dev/null
-+++ b/src/lib389/lib389/tests/mapped_object_lint_test.py
-@@ -0,0 +1,78 @@
-+from typing import List
-+
-+import pytest
-+
-+from lib389._mapped_object_lint import (
-+    DSLint,
-+    DSLints,
-+    DSLintMethodSpec
-+)
-+
-+
-+def test_dslint():
-+    class DS(DSLint):
-+        def lint_uid(self) -> str:
-+            return self.param
-+
-+        def __init__(self, param):
-+            self.param = param
-+            self.suffixes = ['suffixA', 'suffixB']
-+
-+        def _lint_nsstate(self, spec: DSLintMethodSpec = None):
-+            if spec == List:
-+                yield from self.suffixes
-+            else:
-+                to_lint = [spec] if spec else self._lint_nsstate(spec=List)
-+                for tl in to_lint:
-+                    if tl == 'suffixA':
-+                        pass
-+                    elif tl == 'suffixB':
-+                        yield 'suffixB is bad'
-+                    else:
-+                        raise ValueError('There is no such suffix')
-+
-+        def _lint_second(self):
-+            yield from ()
-+
-+        def _lint_third(self):
-+            yield from ['this is a fail']
-+
-+    class DSs(DSLints):
-+        def list(self):
-+            for i in [DS("ma"), DS("mb")]:
-+                yield i
-+
-+    # single
-+    inst = DS("a")
-+    inst_lints = {'nsstate:suffixA', 'nsstate:suffixB', 'second', 'third'}
-+
-+    assert inst.param == "a"
-+
-+    assert set(dict(inst.lint_list()).keys()) == inst_lints
-+
-+    assert set(dict(inst.lint_list('nsstate')).keys()) \
-+        == {f'nsstate:suffix{s}' for s in "AB"}
-+
-+    assert list(inst._lint_nsstate(spec=List)) == ['suffixA', 'suffixB']
-+    assert list(inst.lint()) == ['suffixB is bad', 'this is a fail']
-+
-+    assert list(inst.lint('nsstate')) == ['suffixB is bad']
-+    assert list(inst.lint('nsstate:suffixA')) == []
-+    assert list(inst.lint('nsstate:suffixB')) == ['suffixB is bad']
-+    with pytest.raises(ValueError):
-+        list(inst.lint('nonexistent'))
-+
-+    # multiple
-+    insts = DSs()
-+
-+    assert insts.lint_list
-+    assert insts.lint
-+
-+    assert set(dict(insts.lint_list()).keys()) \
-+        == {f'{m}:{s}' for m in ['ma', 'mb'] for s in inst_lints}
-+    assert set(dict(insts.lint_list('*')).keys()) \
-+        == {f'{m}:{s}' for m in ['ma', 'mb'] for s in inst_lints}
-+    assert set(dict(insts.lint_list('*:nsstate')).keys()) \
-+        == {f'{m}:nsstate:suffix{s}' for m in ['ma', 'mb'] for s in "AB"}
-+    assert set(dict(insts.lint_list('mb:nsstate')).keys()) \
-+        == {f'mb:nsstate:suffix{s}' for s in "AB"}
--- 
-2.26.2
-
diff --git a/SOURCES/0012-Issue-50984-Memory-leaks-in-disk-monitoring.patch b/SOURCES/0012-Issue-50984-Memory-leaks-in-disk-monitoring.patch
deleted file mode 100644
index 3e61905..0000000
--- a/SOURCES/0012-Issue-50984-Memory-leaks-in-disk-monitoring.patch
+++ /dev/null
@@ -1,54 +0,0 @@
-From 2540354b7eb6fa03db7d36a5b755001b0852aa1b Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <spichugi@redhat.com>
-Date: Thu, 26 Mar 2020 19:33:47 +0100
-Subject: [PATCH] Issue 50984 - Memory leaks in disk monitoring
-
-Description: Memory leaks are reported by the disk monitoring test suite.
-The direct leak is related to char **dirs array which is not freed at all.
-Free the array when we clean up or go to shutdown.
-Fix disk_monitoring_test.py::test_below_half_of_the_threshold_not_starting_after_shutdown.
-It should accept different exception when the instance is not started.
-
-https://pagure.io/389-ds-base/issue/50984
-
-Reviewed by: firstyear (Thanks!)
----
- ldap/servers/slapd/daemon.c | 2 --
- ldap/servers/slapd/main.c   | 1 -
- 2 files changed, 3 deletions(-)
-
-diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
-index a70f40316..542d31037 100644
---- a/ldap/servers/slapd/daemon.c
-+++ b/ldap/servers/slapd/daemon.c
-@@ -613,7 +613,6 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
-                         }
-                     }
-                     slapi_ch_array_free(dirs);
--                    dirs = NULL;
-                     return;
-                 }
-                 /*
-@@ -713,7 +712,6 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
-             }
-         }
-         slapi_ch_array_free(dirs);
--        dirs = NULL; /* now it is not needed but the code may be changed in the future and it'd better be more robust */
-         g_set_shutdown(SLAPI_SHUTDOWN_DISKFULL);
-         return;
- }
-diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
-index e54b8e1c5..1f8b01959 100644
---- a/ldap/servers/slapd/main.c
-+++ b/ldap/servers/slapd/main.c
-@@ -958,7 +958,6 @@ main(int argc, char **argv)
-             goto cleanup;
-         }
-         slapi_ch_array_free(dirs);
--        dirs = NULL;
-     }
-     /* log the max fd limit as it is typically set in env/systemd */
-     slapi_log_err(SLAPI_LOG_INFO, "main",
--- 
-2.26.2
-
diff --git a/SOURCES/0013-Issue-50984-Memory-leaks-in-disk-monitoring.patch b/SOURCES/0013-Issue-50984-Memory-leaks-in-disk-monitoring.patch
deleted file mode 100644
index d554989..0000000
--- a/SOURCES/0013-Issue-50984-Memory-leaks-in-disk-monitoring.patch
+++ /dev/null
@@ -1,52 +0,0 @@
-From a720e002751815323a295e11e77c56d7ce38314e Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <spichugi@redhat.com>
-Date: Fri, 27 Mar 2020 11:35:55 +0100
-Subject: [PATCH] Issue 50984 - Memory leaks in disk monitoring
-
-Description: Reset dirs pointer every time we free it.
-The code may be changed in the future so we should make it
-more robust.
-
-https://pagure.io/389-ds-base/issue/50984
-
-Reviewed by: spichugi, tbordaz (one line commit rule)
----
- ldap/servers/slapd/daemon.c | 2 ++
- ldap/servers/slapd/main.c   | 1 +
- 2 files changed, 3 insertions(+)
-
-diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
-index 542d31037..a70f40316 100644
---- a/ldap/servers/slapd/daemon.c
-+++ b/ldap/servers/slapd/daemon.c
-@@ -613,6 +613,7 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
-                         }
-                     }
-                     slapi_ch_array_free(dirs);
-+                    dirs = NULL;
-                     return;
-                 }
-                 /*
-@@ -712,6 +713,7 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
-             }
-         }
-         slapi_ch_array_free(dirs);
-+        dirs = NULL; /* now it is not needed but the code may be changed in the future and it'd better be more robust */
-         g_set_shutdown(SLAPI_SHUTDOWN_DISKFULL);
-         return;
- }
-diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
-index 1f8b01959..e54b8e1c5 100644
---- a/ldap/servers/slapd/main.c
-+++ b/ldap/servers/slapd/main.c
-@@ -958,6 +958,7 @@ main(int argc, char **argv)
-             goto cleanup;
-         }
-         slapi_ch_array_free(dirs);
-+        dirs = NULL;
-     }
-     /* log the max fd limit as it is typically set in env/systemd */
-     slapi_log_err(SLAPI_LOG_INFO, "main",
--- 
-2.26.2
-
diff --git a/SOURCES/0014-Issue-50201-nsIndexIDListScanLimit-accepts-any-value.patch b/SOURCES/0014-Issue-50201-nsIndexIDListScanLimit-accepts-any-value.patch
deleted file mode 100644
index 704cff6..0000000
--- a/SOURCES/0014-Issue-50201-nsIndexIDListScanLimit-accepts-any-value.patch
+++ /dev/null
@@ -1,569 +0,0 @@
-From f60364cd9472edc61e7d327d13dca67eadf0c5b2 Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <simon.pichugin@gmail.com>
-Date: Tue, 28 Apr 2020 23:44:20 +0200
-Subject: [PATCH] Issue 50201 - nsIndexIDListScanLimit accepts any value
-
-Bug Description: Setting of nsIndexIDListScanLimit like
-'limit=2 limit=3' are detected and logged in error logs.
-But the invalid value is successfully applied in the config entry
-and the operation itself is successful.
-The impact is limited because the index will be used following
-idlistscanlimit rather than invalid definition nsIndexIDListScanLimit.
-
-Fix Description: Print the errors to the user when he tries to add
-or to modify index config entry with malformed values.
-Change tests accordingly.
-
-https://pagure.io/389-ds-base/issue/50201
-
-Reviewed by: mreynolds, tbordaz (Thanks!)
----
- .../suites/filter/filterscanlimit_test.py     | 87 ++++++++-----------
- ldap/servers/slapd/back-ldbm/instance.c       |  4 +-
- ldap/servers/slapd/back-ldbm/ldbm_attr.c      | 33 ++++++-
- .../slapd/back-ldbm/ldbm_index_config.c       | 59 +++++++++----
- ldap/servers/slapd/back-ldbm/ldif2ldbm.c      |  2 +-
- .../servers/slapd/back-ldbm/proto-back-ldbm.h |  2 +-
- 6 files changed, 114 insertions(+), 73 deletions(-)
-
-diff --git a/dirsrvtests/tests/suites/filter/filterscanlimit_test.py b/dirsrvtests/tests/suites/filter/filterscanlimit_test.py
-index dd9c6ee4e..0198f6533 100644
---- a/dirsrvtests/tests/suites/filter/filterscanlimit_test.py
-+++ b/dirsrvtests/tests/suites/filter/filterscanlimit_test.py
-@@ -11,6 +11,7 @@ This script will test different type of Filers.
- """
- 
- import os
-+import ldap
- import pytest
- 
- from lib389._constants import DEFAULT_SUFFIX, PW_DM
-@@ -19,11 +20,10 @@ from lib389.idm.user import UserAccounts
- from lib389.idm.organizationalunit import OrganizationalUnits
- from lib389.index import Index
- from lib389.idm.account import Accounts
--from lib389.idm.group import UniqueGroups, Group
-+from lib389.idm.group import UniqueGroups
- 
- pytestmark = pytest.mark.tier1
- 
--
- GIVEN_NAME = 'cn=givenname,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
- CN_NAME = 'cn=sn,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
- UNIQMEMBER = 'cn=uniquemember,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config'
-@@ -39,7 +39,6 @@ LIST_OF_USER_ACCOUNTING = [
-     "Judy Wallace",
-     "Marcus Ward",
-     "Judy McFarland",
--    "Anuj Hall",
-     "Gern Triplett",
-     "Emanuel Johnson",
-     "Brad Walker",
-@@ -57,7 +56,6 @@ LIST_OF_USER_ACCOUNTING = [
-     "Randy Ulrich",
-     "Richard Francis",
-     "Morgan White",
--    "Anuj Maddox",
-     "Jody Jensen",
-     "Mike Carter",
-     "Gern Tyler",
-@@ -77,8 +75,6 @@ LIST_OF_USER_HUMAN = [
-     "Robert Daugherty",
-     "Torrey Mason",
-     "Brad Talbot",
--    "Anuj Jablonski",
--    "Harry Miller",
-     "Jeffrey Campaigne",
-     "Stephen Triplett",
-     "John Falena",
-@@ -107,8 +103,7 @@ LIST_OF_USER_HUMAN = [
-     "Tobias Schmith",
-     "Jon Goldstein",
-     "Janet Lutz",
--    "Karl Cope",
--]
-+    "Karl Cope"]
- 
- LIST_OF_USER_TESTING = [
-     "Andy Bergin",
-@@ -122,8 +117,7 @@ LIST_OF_USER_TESTING = [
-     "Alan White",
-     "Daniel Ward",
-     "Lee Stockton",
--    "Matthew Vaughan"
--]
-+    "Matthew Vaughan"]
- 
- LIST_OF_USER_DEVELOPMENT = [
-     "Kelly Winters",
-@@ -143,7 +137,6 @@ LIST_OF_USER_DEVELOPMENT = [
-     "Timothy Kelly",
-     "Sue Mason",
-     "Chris Alexander",
--    "Anuj Jensen",
-     "Martin Talbot",
-     "Scott Farmer",
-     "Allison Jensen",
-@@ -152,9 +145,7 @@ LIST_OF_USER_DEVELOPMENT = [
-     "Dan Langdon",
-     "Ashley Knutson",
-     "Jon Bourke",
--    "Pete Hunt",
--
--]
-+    "Pete Hunt"]
- 
- LIST_OF_USER_PAYROLL = [
-     "Ashley Chassin",
-@@ -164,12 +155,17 @@ LIST_OF_USER_PAYROLL = [
-     "Patricia Shelton",
-     "Dietrich Swain",
-     "Allison Hunter",
--    "Anne-Louise Barnes"
-+    "Anne-Louise Barnes"]
- 
--]
-+LIST_OF_USER_PEOPLE = [
-+    'Sam Carter',
-+    'Tom Morris',
-+    'Kevin Vaughan',
-+    'Rich Daugherty',
-+    'Harry Miller',
-+    'Sam Schmith']
- 
- 
--@pytest.mark.skip(reason="https://pagure.io/389-ds-base/issue/50201")
- def test_invalid_configuration(topo):
-     """"
-     Error handling for invalid configuration
-@@ -190,10 +186,7 @@ def test_invalid_configuration(topo):
-               'limit=0 flags=AND flags=AND',
-               'limit=0 type=eq values=foo values=foo',
-               'limit=0 type=eq values=foo,foo',
--              'limit=0 type=sub',
--              'limit=0 type=eq values=notvalid',
-               'limit',
--              'limit=0 type=eq values=notavaliddn',
-               'limit=0 type=pres values=bogus',
-               'limit=0 type=eq,sub values=bogus',
-               'limit=',
-@@ -203,7 +196,8 @@ def test_invalid_configuration(topo):
-               'limit=-2',
-               'type=eq',
-               'limit=0 type=bogus']:
--        Index(topo.standalone, GIVEN_NAME).replace('nsIndexIDListScanLimit', i)
-+        with pytest.raises(ldap.UNWILLING_TO_PERFORM):
-+            Index(topo.standalone, GIVEN_NAME).replace('nsIndexIDListScanLimit', i)
- 
- 
- def test_idlistscanlimit(topo):
-@@ -247,28 +241,24 @@ def test_idlistscanlimit(topo):
-                  (LIST_OF_USER_HUMAN, users_human),
-                  (LIST_OF_USER_TESTING, users_testing),
-                  (LIST_OF_USER_DEVELOPMENT, users_development),
--                 (LIST_OF_USER_PAYROLL, users_payroll)]:
-+                 (LIST_OF_USER_PAYROLL, users_payroll),
-+                 (LIST_OF_USER_PEOPLE, users_people)]:
-         for demo1 in data[0]:
-+            fn = demo1.split()[0]
-+            sn = demo1.split()[1]
-+            uid = ''.join([fn[:1], sn]).lower()
-             data[1].create(properties={
--                'uid': demo1,
-+                'uid': uid,
-                 'cn': demo1,
--                'sn': demo1.split()[1],
-+                'sn': sn,
-                 'uidNumber': str(1000),
-                 'gidNumber': '2000',
--                'homeDirectory': '/home/' + demo1,
--                'givenname': demo1.split()[0],
--                'userpassword': PW_DM
-+                'homeDirectory': f'/home/{uid}',
-+                'givenname': fn,
-+                'userpassword': PW_DM,
-+                'mail': f'{uid}@test.com'
-             })
- 
--    users_people.create(properties={
--        'uid': 'scarter',
--        'cn': 'Sam Carter',
--        'sn': 'Carter',
--        'uidNumber': str(1000),
--        'gidNumber': '2000',
--        'homeDirectory': '/home/' + 'scarter',
--        'mail': 'scarter@anuj.com',
--    })
-     try:
-         # Change log levels
-         errorlog_value = topo.standalone.config.get_attr_val_utf8('nsslapd-errorlog-level')
-@@ -297,16 +287,12 @@ def test_idlistscanlimit(topo):
- 
-         Index(topo.standalone, UNIQMEMBER).\
-         replace('nsIndexIDListScanLimit',
--                'limit=0 type=eq values=uid=kvaughan,ou=People,'
--                'dc=example,dc=com,uid=rdaugherty,ou=People,dc=example,dc=com')
-+                'limit=0 type=eq values=uid=kvaughan\2Cou=People\2Cdc=example\2Cdc=com,'
-+                'uid=rdaugherty\2Cou=People\2Cdc=example\2Cdc=com')
- 
-         Index(topo.standalone, OBJECTCLASS).\
-         replace('nsIndexIDListScanLimit', 'limit=0 type=eq flags=AND values=inetOrgPerson')
- 
--        Index(topo.standalone, MAIL).\
--        replace('nsIndexIDListScanLimit',
--                'cn=mail,cn=index,cn=userRoot,cn=ldbm database,cn=plugins,cn=config')
--
-         # Search with filter
-         for i in ['(sn=Lutz)',
-                   '(sn=*ter)',
-@@ -321,22 +307,24 @@ def test_idlistscanlimit(topo):
-                   '(&(sn=*)(cn=*))',
-                   '(sn=Hunter)',
-                   '(&(givenname=Richard)(objectclass=organizationalPerson))',
--                  '(givenname=Anuj)',
-+                  '(givenname=Morgan)',
-                   '(&(givenname=*)(cn=*))',
-                   '(givenname=*)']:
-             assert Accounts(topo.standalone, DEFAULT_SUFFIX).filter(f'{i}')
- 
--        # Creating Group
--        Group(topo.standalone, 'cn=Accounting Managers,ou=groups,dc=example,dc=com').\
--        add('uniquemember',
-+        # Creating Groups and adding members
-+        groups = UniqueGroups(topo.standalone, DEFAULT_SUFFIX)
-+        accounting_managers = groups.ensure_state(properties={'cn': 'Accounting Managers'})
-+        hr_managers = groups.ensure_state(properties={'cn': 'HR Managers'})
-+
-+        accounting_managers.add('uniquemember',
-             ['uid=scarter, ou=People, dc=example,dc=com',
-              'uid=tmorris, ou=People, dc=example,dc=com',
-              'uid=kvaughan, ou=People, dc=example,dc=com',
-              'uid=rdaugherty, ou=People, dc=example,dc=com',
-              'uid=hmiller, ou=People, dc=example,dc=com'])
- 
--        Group(topo.standalone, 'cn=HR Managers,ou=groups,dc=example,dc=com').\
--        add('uniquemember',
-+        hr_managers.add('uniquemember',
-             ['uid=kvaughan, ou=People, dc=example,dc=com',
-              'uid=cschmith, ou=People, dc=example,dc=com'])
- 
-@@ -403,10 +391,9 @@ def test_idlistscanlimit(topo):
-                       '(&(sn=*)(cn=*))',
-                       '(sn=Hunter)',
-                       '(&(givenname=Richard)(objectclass=organizationalPerson))',
--                      '(givenname=Anuj)',
-+                      '(givenname=Morgan)',
-                       '(&(givenname=*)(cn=*))',
-                       '(givenname=*)']:
--
-             assert Accounts(topo.standalone, DEFAULT_SUFFIX).filter(value)
- 
-     finally:
-diff --git a/ldap/servers/slapd/back-ldbm/instance.c b/ldap/servers/slapd/back-ldbm/instance.c
-index 04c28ff39..07655a8ec 100644
---- a/ldap/servers/slapd/back-ldbm/instance.c
-+++ b/ldap/servers/slapd/back-ldbm/instance.c
-@@ -231,7 +231,7 @@ ldbm_instance_create_default_indexes(backend *be)
- 
-     /* ldbm_instance_config_add_index_entry(inst, 2, argv); */
-     e = ldbm_instance_init_config_entry(LDBM_PSEUDO_ATTR_DEFAULT, "none", 0, 0, 0);
--    attr_index_config(be, "ldbm index init", 0, e, 1, 0);
-+    attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL);
-     slapi_entry_free(e);
- 
-     if (!entryrdn_get_noancestorid()) {
-@@ -240,7 +240,7 @@ ldbm_instance_create_default_indexes(backend *be)
-          * but we still want to use the attr index file APIs.
-          */
-         e = ldbm_instance_init_config_entry(LDBM_ANCESTORID_STR, "eq", 0, 0, 0);
--        attr_index_config(be, "ldbm index init", 0, e, 1, 0);
-+        attr_index_config(be, "ldbm index init", 0, e, 1, 0, NULL);
-         slapi_entry_free(e);
-     }
- 
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
-index b9e130d77..f0d418572 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
-@@ -633,6 +633,18 @@ attr_index_idlistsize_config(Slapi_Entry *e, struct attrinfo *ai, char *returnte
-     return rc;
- }
- 
-+/*
-+ * Function that process index attributes and modifies attrinfo structure
-+ *
-+ * Called while adding default indexes, during db2index execution and
-+ * when we add/modify/delete index config entry
-+ *
-+ * If char *err_buf is not NULL, it will additionally print all error messages to STDERR
-+ * It is used when we add/modify/delete index config entry, so the user would have a better verbose
-+ *
-+ * returns -1, 1 on a failure
-+ *         0 on success
-+ */
- int
- attr_index_config(
-     backend *be,
-@@ -640,7 +652,8 @@ attr_index_config(
-     int lineno,
-     Slapi_Entry *e,
-     int init __attribute__((unused)),
--    int indextype_none)
-+    int indextype_none,
-+    char *err_buf)
- {
-     ldbm_instance *inst = (ldbm_instance *)be->be_instance_info;
-     int j = 0;
-@@ -662,6 +675,7 @@ attr_index_config(
-         slapi_attr_first_value(attr, &sval);
-         attrValue = slapi_value_get_berval(sval);
-     } else {
-+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: missing indexing arguments\n");
-         slapi_log_err(SLAPI_LOG_ERR, "attr_index_config", "Missing indexing arguments\n");
-         return -1;
-     }
-@@ -705,6 +719,10 @@ attr_index_config(
-                 }
-                 a->ai_indexmask = INDEX_OFFLINE; /* note that the index isn't available */
-             } else {
-+                slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
-+                                      "Error: %s: line %d: unknown index type \"%s\" (ignored) in entry (%s), "
-+                                      "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n",
-+                                      fname, lineno, attrValue->bv_val, slapi_entry_get_dn(e));
-                 slapi_log_err(SLAPI_LOG_ERR, "attr_index_config",
-                               "%s: line %d: unknown index type \"%s\" (ignored) in entry (%s), "
-                               "valid index types are \"pres\", \"eq\", \"approx\", or \"sub\"\n",
-@@ -715,6 +733,7 @@ attr_index_config(
-         }
-         if (hasIndexType == 0) {
-             /* indexType missing, error out */
-+            slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE, "Error: missing index type\n");
-             slapi_log_err(SLAPI_LOG_ERR, "attr_index_config", "Missing index type\n");
-             attrinfo_delete(&a);
-             return -1;
-@@ -873,16 +892,26 @@ attr_index_config(
-             slapi_ch_free((void **)&official_rules);
-         }
-     }
--
-     if ((return_value = attr_index_idlistsize_config(e, a, myreturntext))) {
-+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: %s: Failed to parse idscanlimit info: %d:%s\n",
-+                              fname, return_value, myreturntext);
-         slapi_log_err(SLAPI_LOG_ERR, "attr_index_config", "%s: Failed to parse idscanlimit info: %d:%s\n",
-                       fname, return_value, myreturntext);
-+        if (err_buf != NULL) {
-+            /* we are inside of a callback, we shouldn't allow malformed attributes in index entries */
-+            attrinfo_delete(&a);
-+            return return_value;
-+        }
-     }
- 
-     /* initialize the IDL code's private data */
-     return_value = idl_init_private(be, a);
-     if (0 != return_value) {
-         /* fatal error, exit */
-+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: %s: line %d:Fatal Error: Failed to initialize attribute structure\n",
-+                              fname, lineno);
-         slapi_log_err(SLAPI_LOG_CRIT, "attr_index_config",
-                       "%s: line %d:Fatal Error: Failed to initialize attribute structure\n",
-                       fname, lineno);
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
-index 45f0034f0..720f93036 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
-@@ -25,26 +25,34 @@ int ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry *en
- #define INDEXTYPE_NONE 1
- 
- static int
--ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name)
-+ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name, char *err_buf)
- {
-     Slapi_Attr *attr;
-     const struct berval *attrValue;
-     Slapi_Value *sval;
-+    char *edn = slapi_entry_get_dn(e);
- 
-     /* Get the name of the attribute to index which will be the value
-      * of the cn attribute. */
-     if (slapi_entry_attr_find(e, "cn", &attr) != 0) {
--        slapi_log_err(SLAPI_LOG_ERR, "ldbm_index_parse_entry", "Malformed index entry %s\n",
--                      slapi_entry_get_dn(e));
-+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: malformed index entry %s\n",
-+                              edn);
-+        slapi_log_err(SLAPI_LOG_ERR,
-+                      "ldbm_index_parse_entry", "Malformed index entry %s\n",
-+                      edn);
-         return LDAP_OPERATIONS_ERROR;
-     }
- 
-     slapi_attr_first_value(attr, &sval);
-     attrValue = slapi_value_get_berval(sval);
-     if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
-+        slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: malformed index entry %s -- empty index name\n",
-+                              edn);
-         slapi_log_err(SLAPI_LOG_ERR,
-                       "ldbm_index_parse_entry", "Malformed index entry %s -- empty index name\n",
--                      slapi_entry_get_dn(e));
-+                      edn);
-         return LDAP_OPERATIONS_ERROR;
-     }
- 
-@@ -59,16 +67,19 @@ ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_st
-         attrValue = slapi_value_get_berval(sval);
-         if (NULL == attrValue->bv_val || attrValue->bv_len == 0) {
-             /* missing the index type, error out */
--            slapi_log_err(SLAPI_LOG_ERR,
--                          "ldbm_index_parse_entry", "Malformed index entry %s -- empty nsIndexType\n",
--                          slapi_entry_get_dn(e));
-+            slapi_create_errormsg(err_buf, SLAPI_DSE_RETURNTEXT_SIZE,
-+                                  "Error: malformed index entry %s -- empty nsIndexType\n",
-+                                  edn);
-+            slapi_log_err(SLAPI_LOG_ERR, "ldbm_index_parse_entry",
-+                          "Malformed index entry %s -- empty nsIndexType\n",
-+                          edn);
-             slapi_ch_free_string(index_name);
-             return LDAP_OPERATIONS_ERROR;
-         }
-     }
- 
-     /* ok the entry is good to process, pass it to attr_index_config */
--    if (attr_index_config(inst->inst_be, (char *)trace_string, 0, e, 0, 0)) {
-+    if (attr_index_config(inst->inst_be, (char *)trace_string, 0, e, 0, 0, err_buf)) {
-         slapi_ch_free_string(index_name);
-         return LDAP_OPERATIONS_ERROR;
-     }
-@@ -92,7 +103,7 @@ ldbm_index_init_entry_callback(Slapi_PBlock *pb __attribute__((unused)),
-     ldbm_instance *inst = (ldbm_instance *)arg;
- 
-     returntext[0] = '\0';
--    *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL);
-+    *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL, NULL);
-     if (*returncode == LDAP_SUCCESS) {
-         return SLAPI_DSE_CALLBACK_OK;
-     } else {
-@@ -117,7 +128,7 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb __attribute__((unused))
-     char *index_name = NULL;
- 
-     returntext[0] = '\0';
--    *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name);
-+    *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, returntext);
-     if (*returncode == LDAP_SUCCESS) {
-         struct attrinfo *ai = NULL;
-         /* if the index is a "system" index, we assume it's being added by
-@@ -179,7 +190,7 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb,
-     slapi_attr_first_value(attr, &sval);
-     attrValue = slapi_value_get_berval(sval);
- 
--    attr_index_config(inst->inst_be, "From DSE delete", 0, e, 0, INDEXTYPE_NONE);
-+    attr_index_config(inst->inst_be, "From DSE delete", 0, e, 0, INDEXTYPE_NONE, returntext);
- 
-     ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
-     if (NULL == ainfo) {
-@@ -213,14 +224,19 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb __attribute__((unuse
-     Slapi_Value *sval;
-     const struct berval *attrValue;
-     struct attrinfo *ainfo = NULL;
-+    char *edn = slapi_entry_get_dn(e);
-+    char *edn_after = slapi_entry_get_dn(entryAfter);
- 
-     returntext[0] = '\0';
-     *returncode = LDAP_SUCCESS;
- 
-     if (slapi_entry_attr_find(entryAfter, "cn", &attr) != 0) {
-+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: malformed index entry %s - missing cn attribute\n",
-+                              edn_after);
-         slapi_log_err(SLAPI_LOG_ERR,
-                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s - missing cn attribute\n",
--                      slapi_entry_get_dn(entryAfter));
-+                      edn_after);
-         *returncode = LDAP_OBJECT_CLASS_VIOLATION;
-         return SLAPI_DSE_CALLBACK_ERROR;
-     }
-@@ -228,31 +244,40 @@ ldbm_instance_index_config_modify_callback(Slapi_PBlock *pb __attribute__((unuse
-     attrValue = slapi_value_get_berval(sval);
- 
-     if (NULL == attrValue->bv_val || 0 == attrValue->bv_len) {
-+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: malformed index entry %s - missing index name\n",
-+                              edn);
-         slapi_log_err(SLAPI_LOG_ERR,
-                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s, missing index name\n",
--                      slapi_entry_get_dn(e));
-+                      edn);
-         *returncode = LDAP_UNWILLING_TO_PERFORM;
-         return SLAPI_DSE_CALLBACK_ERROR;
-     }
- 
-     ainfo_get(inst->inst_be, attrValue->bv_val, &ainfo);
-     if (NULL == ainfo) {
-+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: malformed index entry %s - missing cn attribute info\n",
-+                              edn);
-         slapi_log_err(SLAPI_LOG_ERR,
-                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s - missing cn attribute info\n",
--                      slapi_entry_get_dn(e));
-+                      edn);
-         *returncode = LDAP_UNWILLING_TO_PERFORM;
-         return SLAPI_DSE_CALLBACK_ERROR;
-     }
- 
-     if (slapi_entry_attr_find(entryAfter, "nsIndexType", &attr) != 0) {
-+        slapi_create_errormsg(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-+                              "Error: malformed index entry %s - missing nsIndexType attribute\n",
-+                              edn_after);
-         slapi_log_err(SLAPI_LOG_ERR,
-                       "ldbm_instance_index_config_modify_callback", "Malformed index entry %s - missing nsIndexType attribute\n",
--                      slapi_entry_get_dn(entryAfter));
-+                      edn_after);
-         *returncode = LDAP_OBJECT_CLASS_VIOLATION;
-         return SLAPI_DSE_CALLBACK_ERROR;
-     }
- 
--    if (attr_index_config(inst->inst_be, "from DSE modify", 0, entryAfter, 0, 0)) {
-+    if (attr_index_config(inst->inst_be, "from DSE modify", 0, entryAfter, 0, 0, returntext)) {
-         *returncode = LDAP_UNWILLING_TO_PERFORM;
-         return SLAPI_DSE_CALLBACK_ERROR;
-     }
-@@ -364,7 +389,7 @@ ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry *e)
-         ainfo_get(inst->inst_be, index_name, &ai);
-     }
-     if (!ai) {
--        rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name);
-+        rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, NULL);
-     }
-     if (rc == LDAP_SUCCESS) {
-         /* Assume the caller knows if it is OK to go online immediately */
-diff --git a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
-index 9d82c8228..f2ef5ecd4 100644
---- a/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
-+++ b/ldap/servers/slapd/back-ldbm/ldif2ldbm.c
-@@ -291,7 +291,7 @@ db2index_add_indexed_attr(backend *be, char *attrString)
-         }
-     }
- 
--    attr_index_config(be, "from db2index()", 0, e, 0, 0);
-+    attr_index_config(be, "from db2index()", 0, e, 0, 0, NULL);
-     slapi_entry_free(e);
- 
-     return (0);
-diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-index 9a86c752b..a07acee5e 100644
---- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-@@ -24,7 +24,7 @@ void attrinfo_delete(struct attrinfo **pp);
- void ainfo_get(backend *be, char *type, struct attrinfo **at);
- void attr_masks(backend *be, char *type, int *indexmask, int *syntaxmask);
- void attr_masks_ex(backend *be, char *type, int *indexmask, int *syntaxmask, struct attrinfo **at);
--int attr_index_config(backend *be, char *fname, int lineno, Slapi_Entry *e, int init, int none);
-+int attr_index_config(backend *be, char *fname, int lineno, Slapi_Entry *e, int init, int none, char *err_buf);
- int db2index_add_indexed_attr(backend *be, char *attrString);
- int ldbm_compute_init(void);
- void attrinfo_deletetree(ldbm_instance *inst);
--- 
-2.26.2
-
diff --git a/SOURCES/0015-Issue-51157-Reindex-task-may-create-abandoned-index-.patch b/SOURCES/0015-Issue-51157-Reindex-task-may-create-abandoned-index-.patch
deleted file mode 100644
index 8da8d8f..0000000
--- a/SOURCES/0015-Issue-51157-Reindex-task-may-create-abandoned-index-.patch
+++ /dev/null
@@ -1,213 +0,0 @@
-From 3b3faee01e645577ad77ff4f38429a9e0806231b Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <simon.pichugin@gmail.com>
-Date: Tue, 16 Jun 2020 20:35:05 +0200
-Subject: [PATCH] Issue 51157 - Reindex task may create abandoned index file
-
-Bug Description: Recreating an index for the same attribute but changing
-the case of for example 1 letter, results in abandoned indexfile.
-
-Fix Decsription: Add a test case to a newly created 'indexes' test suite.
-When we remove the index config from the backend, - remove the attribute
-info from LDBM instance attributes.
-
-https://pagure.io/389-ds-base/issue/51157
-
-Reviewed by: firstyear, mreynolds (Thanks!)
----
- dirsrvtests/tests/suites/indexes/__init__.py  |   3 +
- .../tests/suites/indexes/regression_test.py   | 125 ++++++++++++++++++
- ldap/servers/slapd/back-ldbm/ldbm_attr.c      |   7 +
- .../slapd/back-ldbm/ldbm_index_config.c       |   3 +
- .../servers/slapd/back-ldbm/proto-back-ldbm.h |   1 +
- 5 files changed, 139 insertions(+)
- create mode 100644 dirsrvtests/tests/suites/indexes/__init__.py
- create mode 100644 dirsrvtests/tests/suites/indexes/regression_test.py
-
-diff --git a/dirsrvtests/tests/suites/indexes/__init__.py b/dirsrvtests/tests/suites/indexes/__init__.py
-new file mode 100644
-index 000000000..04441667e
---- /dev/null
-+++ b/dirsrvtests/tests/suites/indexes/__init__.py
-@@ -0,0 +1,3 @@
-+"""
-+   :Requirement: 389-ds-base: Indexes
-+"""
-diff --git a/dirsrvtests/tests/suites/indexes/regression_test.py b/dirsrvtests/tests/suites/indexes/regression_test.py
-new file mode 100644
-index 000000000..1a71f16e9
---- /dev/null
-+++ b/dirsrvtests/tests/suites/indexes/regression_test.py
-@@ -0,0 +1,125 @@
-+# --- BEGIN COPYRIGHT BLOCK ---
-+# Copyright (C) 2020 Red Hat, Inc.
-+# All rights reserved.
-+#
-+# License: GPL (version 3 or any later version).
-+# See LICENSE for details.
-+# --- END COPYRIGHT BLOCK ---
-+#
-+import time
-+import os
-+import pytest
-+import ldap
-+from lib389._constants import DEFAULT_BENAME, DEFAULT_SUFFIX
-+from lib389.index import Indexes
-+from lib389.backend import Backends
-+from lib389.idm.user import UserAccounts
-+from lib389.topologies import topology_st as topo
-+
-+pytestmark = pytest.mark.tier1
-+
-+
-+def test_reindex_task_creates_abandoned_index_file(topo):
-+    """
-+    Recreating an index for the same attribute but changing
-+    the case of for example 1 letter, results in abandoned indexfile
-+
-+    :id: 07ae5274-481a-4fa8-8074-e0de50d89ac6
-+    :setup: Standalone instance
-+    :steps:
-+        1. Create a user object with additional attributes:
-+           objectClass: mozillaabpersonalpha
-+           mozillaCustom1: xyz
-+        2. Add an index entry mozillacustom1
-+        3. Reindex the backend
-+        4. Check the content of the index (after it has been flushed to disk) mozillacustom1.db
-+        5. Remove the index
-+        6. Notice the mozillacustom1.db is removed
-+        7. Recreate the index but now use the exact case as mentioned in the schema
-+        8. Reindex the backend
-+        9. Check the content of the index (after it has been flushed to disk) mozillaCustom1.db
-+        10. Check that an ldapsearch does not return a result (mozillacustom1=xyz)
-+        11. Check that an ldapsearch returns the results (mozillaCustom1=xyz)
-+        12. Restart the instance
-+        13. Notice that an ldapsearch does not return a result(mozillacustom1=xyz)
-+        15. Check that an ldapsearch does not return a result (mozillacustom1=xyz)
-+        16. Check that an ldapsearch returns the results (mozillaCustom1=xyz)
-+        17. Reindex the backend
-+        18. Notice the second indexfile for this attribute
-+        19. Check the content of the index (after it has been flushed to disk) no mozillacustom1.db
-+        20. Check the content of the index (after it has been flushed to disk) mozillaCustom1.db
-+    :expectedresults:
-+        1. Should Success.
-+        2. Should Success.
-+        3. Should Success.
-+        4. Should Success.
-+        5. Should Success.
-+        6. Should Success.
-+        7. Should Success.
-+        8. Should Success.
-+        9. Should Success.
-+        10. Should Success.
-+        11. Should Success.
-+        12. Should Success.
-+        13. Should Success.
-+        14. Should Success.
-+        15. Should Success.
-+        16. Should Success.
-+        17. Should Success.
-+        18. Should Success.
-+        19. Should Success.
-+        20. Should Success.
-+    """
-+
-+    inst = topo.standalone
-+    attr_name = "mozillaCustom1"
-+    attr_value = "xyz"
-+
-+    users = UserAccounts(inst, DEFAULT_SUFFIX)
-+    user = users.create_test_user()
-+    user.add("objectClass", "mozillaabpersonalpha")
-+    user.add(attr_name, attr_value)
-+
-+    backends = Backends(inst)
-+    backend = backends.get(DEFAULT_BENAME)
-+    indexes = backend.get_indexes()
-+    index = indexes.create(properties={
-+        'cn': attr_name.lower(),
-+        'nsSystemIndex': 'false',
-+        'nsIndexType': ['eq', 'pres']
-+        })
-+
-+    backend.reindex()
-+    time.sleep(3)
-+    assert os.path.exists(f"{inst.ds_paths.db_home_dir}/{DEFAULT_BENAME}/{attr_name.lower()}.db")
-+    index.delete()
-+    assert not os.path.exists(f"{inst.ds_paths.db_home_dir}/{DEFAULT_BENAME}/{attr_name.lower()}.db")
-+
-+    index = indexes.create(properties={
-+        'cn': attr_name,
-+        'nsSystemIndex': 'false',
-+        'nsIndexType': ['eq', 'pres']
-+        })
-+
-+    backend.reindex()
-+    time.sleep(3)
-+    assert not os.path.exists(f"{inst.ds_paths.db_home_dir}/{DEFAULT_BENAME}/{attr_name.lower()}.db")
-+    assert os.path.exists(f"{inst.ds_paths.db_home_dir}/{DEFAULT_BENAME}/{attr_name}.db")
-+
-+    entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, f"{attr_name}={attr_value}")
-+    assert len(entries) > 0
-+    inst.restart()
-+    entries = inst.search_s(DEFAULT_SUFFIX, ldap.SCOPE_SUBTREE, f"{attr_name}={attr_value}")
-+    assert len(entries) > 0
-+
-+    backend.reindex()
-+    time.sleep(3)
-+    assert not os.path.exists(f"{inst.ds_paths.db_home_dir}/{DEFAULT_BENAME}/{attr_name.lower()}.db")
-+    assert os.path.exists(f"{inst.ds_paths.db_home_dir}/{DEFAULT_BENAME}/{attr_name}.db")
-+
-+
-+if __name__ == "__main__":
-+    # Run isolated
-+    # -s for DEBUG mode
-+    CURRENT_FILE = os.path.realpath(__file__)
-+    pytest.main("-s %s" % CURRENT_FILE)
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
-index f0d418572..688c4f137 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c
-@@ -98,6 +98,13 @@ ainfo_cmp(
-     return (strcasecmp(a->ai_type, b->ai_type));
- }
- 
-+void
-+attrinfo_delete_from_tree(backend *be, struct attrinfo *ai)
-+{
-+    ldbm_instance *inst = (ldbm_instance *)be->be_instance_info;
-+    avl_delete(&inst->inst_attrs, ai, ainfo_cmp);
-+}
-+
- /*
-  * Called when a duplicate "index" line is encountered.
-  *
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
-index 720f93036..9722d0ce7 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c
-@@ -201,7 +201,10 @@ ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb,
-             *returncode = LDAP_UNWILLING_TO_PERFORM;
-             rc = SLAPI_DSE_CALLBACK_ERROR;
-         }
-+        attrinfo_delete_from_tree(inst->inst_be, ainfo);
-     }
-+    /* Free attrinfo structure */
-+    attrinfo_delete(&ainfo);
- bail:
-     return rc;
- }
-diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-index a07acee5e..4d2524fd9 100644
---- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-@@ -21,6 +21,7 @@
-  */
- struct attrinfo *attrinfo_new(void);
- void attrinfo_delete(struct attrinfo **pp);
-+void attrinfo_delete_from_tree(backend *be, struct attrinfo *ai);
- void ainfo_get(backend *be, char *type, struct attrinfo **at);
- void attr_masks(backend *be, char *type, int *indexmask, int *syntaxmask);
- void attr_masks_ex(backend *be, char *type, int *indexmask, int *syntaxmask, struct attrinfo **at);
--- 
-2.26.2
-
diff --git a/SOURCES/0016-Issue-51165-add-new-access-log-keywords-for-wtime-an.patch b/SOURCES/0016-Issue-51165-add-new-access-log-keywords-for-wtime-an.patch
deleted file mode 100644
index 10c002c..0000000
--- a/SOURCES/0016-Issue-51165-add-new-access-log-keywords-for-wtime-an.patch
+++ /dev/null
@@ -1,668 +0,0 @@
-From 282edde7950ceb2515d74fdbcc0a188131769d74 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 23 Jun 2020 16:38:55 -0400
-Subject: [PATCH] Issue 51165 - add new access log keywords for wtime and
- optime
-
-Description:  In addition to the "etime" stat in the access we can also
-              add the time the operation spent in the work queue, and
-              how long the actual operation took.  We now have "wtime"
-              and "optime" to track these stats in the access log.
-
-              Also updated logconf for notes=F (related to a different
-              ticket), and stats for wtime and optime.
-
-relates: https://pagure.io/389-ds-base/issue/51165
-
-Reviewed by: ?
----
- ldap/admin/src/logconv.pl         | 187 +++++++++++++++++++++++++++---
- ldap/servers/slapd/add.c          |   3 +
- ldap/servers/slapd/bind.c         |   4 +
- ldap/servers/slapd/delete.c       |   3 +
- ldap/servers/slapd/modify.c       |   3 +
- ldap/servers/slapd/modrdn.c       |   3 +
- ldap/servers/slapd/operation.c    |  24 ++++
- ldap/servers/slapd/opshared.c     |   3 +
- ldap/servers/slapd/result.c       |  49 ++++----
- ldap/servers/slapd/slap.h         |  13 ++-
- ldap/servers/slapd/slapi-plugin.h |  26 ++++-
- 11 files changed, 269 insertions(+), 49 deletions(-)
-
-diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
-index f4808a101..1ed44a888 100755
---- a/ldap/admin/src/logconv.pl
-+++ b/ldap/admin/src/logconv.pl
-@@ -3,7 +3,7 @@
- #
- # BEGIN COPYRIGHT BLOCK
- # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
--# Copyright (C) 2013 Red Hat, Inc.
-+# Copyright (C) 2020 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
-@@ -55,7 +55,7 @@ my $reportStats = "";
- my $dataLocation = "/tmp";
- my $startTLSoid = "1.3.6.1.4.1.1466.20037";
- my @statnames=qw(last last_str results srch add mod modrdn moddn cmp del abandon
--                 conns sslconns bind anonbind unbind notesA notesU etime);
-+                 conns sslconns bind anonbind unbind notesA notesU notesF etime);
- my $s_stats;
- my $m_stats;
- my $verb = "no";
-@@ -211,6 +211,7 @@ my $sslClientBindCount = 0;
- my $sslClientFailedCount = 0;
- my $objectclassTopCount= 0;
- my $pagedSearchCount = 0;
-+my $invalidFilterCount = 0;
- my $bindCount = 0;
- my $filterCount = 0;
- my $baseCount = 0;
-@@ -258,7 +259,7 @@ map {$conn{$_} = $_} @conncodes;
- # hash db-backed hashes
- my @hashnames = qw(attr rc src rsrc excount conn_hash ip_hash conncount nentries
-                    filter base ds6xbadpwd saslmech saslconnop bindlist etime oid
--                   start_time_of_connection end_time_of_connection
-+                   start_time_of_connection end_time_of_connection notesf_conn_op
-                    notesa_conn_op notesu_conn_op etime_conn_op nentries_conn_op
-                    optype_conn_op time_conn_op srch_conn_op del_conn_op mod_conn_op
-                    mdn_conn_op cmp_conn_op bind_conn_op unbind_conn_op ext_conn_op
-@@ -926,7 +927,7 @@ if ($verb eq "yes" || $usage =~ /u/ || $usage =~ /U/){
- 			}
- 			while($op > 0){
- 				# The bind op is not the same as the search op that triggered the notes=A.
--				# We have adjust the key by decrementing the op count until we find the last bind op.
-+				# We have to adjust the key by decrementing the op count until we find the last bind op.
- 				$op--;
- 				$binddn_key = "$srvRstCnt,$conn,$op";
- 				if (exists($bind_conn_op->{$binddn_key}) && defined($bind_conn_op->{$binddn_key})) {
-@@ -1049,9 +1050,60 @@ if ($verb eq "yes" || $usage =~ /u/ || $usage =~ /U/){
- 			}
- 		}
- 	}
--} # end of unindexed search report
-+    print "\n";
-+}
-+
-+print "Invalid Attribute Filters:    $invalidFilterCount\n";
-+if ($invalidFilterCount > 0 && $verb eq "yes"){
-+    my $conn_hash = $hashes->{conn_hash};
-+    my $notesf_conn_op = $hashes->{notesf_conn_op};
-+    my $time_conn_op = $hashes->{time_conn_op};
-+    my $etime_conn_op = $hashes->{etime_conn_op};
-+    my $nentries_conn_op = $hashes->{nentries_conn_op};
-+    my $filter_conn_op = $hashes->{filter_conn_op};
-+    my $bind_conn_op = $hashes->{bind_conn_op};
-+    my $notesCount = 1;
-+    my $unindexedIp;
-+    my $binddn_key;
-+    my %uniqFilt = (); # hash of unique filters
-+    my %uniqFilter = (); # hash of unique filters bind dn
-+    my %uniqBindDNs = (); # hash of unique bind dn's
-+    my %uniqBindFilters = (); # hash of filters for a bind DN
-+
-+    while (my ($srcnt_conn_op, $count) = each %{$notesf_conn_op}) {
-+        my ($srvRstCnt, $conn, $op) = split(",", $srcnt_conn_op);
-+        my $attrIp = getIPfromConn($conn, $srvRstCnt);
-+        print "\n  Invalid Attribute Filter #".$notesCount." (notes=F)\n";
-+        print "  -  Date/Time:             $time_conn_op->{$srcnt_conn_op}\n";
-+        print "  -  Connection Number:     $conn\n";
-+        print "  -  Operation Number:      $op\n";
-+        print "  -  Etime:                 $etime_conn_op->{$srcnt_conn_op}\n";
-+        print "  -  Nentries:              $nentries_conn_op->{$srcnt_conn_op}\n";
-+        print "  -  IP Address:            $attrIp\n";
-+        if (exists($filter_conn_op->{$srcnt_conn_op}) && defined($filter_conn_op->{$srcnt_conn_op})) {
-+            print "  -  Search Filter:         $filter_conn_op->{$srcnt_conn_op}\n";
-+            $uniqFilt{$filter_conn_op->{$srcnt_conn_op}}++;
-+        }
-+        while($op > 0){
-+            # The bind op is not the same as the search op that triggered the notes=A.
-+            # We have to adjust the key by decrementing the op count until we find the last bind op.
-+            $op--;
-+            $binddn_key = "$srvRstCnt,$conn,$op";
-+            if (exists($bind_conn_op->{$binddn_key}) && defined($bind_conn_op->{$binddn_key})) {
-+                print "  -  Bind DN:               $bind_conn_op->{$binddn_key}\n";
-+                $uniqBindDNs{$bind_conn_op->{$binddn_key}}++;
-+                if( $uniqFilt{$filter_conn_op->{$srcnt_conn_op}} && defined($filter_conn_op->{$srcnt_conn_op})) {
-+                    $uniqBindFilters{$bind_conn_op->{$binddn_key}}{$filter_conn_op->{$srcnt_conn_op}}++;
-+                    $uniqFilter{$filter_conn_op->{$srcnt_conn_op}}{$bind_conn_op->{$binddn_key}}++;
-+                }
-+                last;
-+            }
-+        }
-+        $notesCount++;
-+    }
-+    print "\n";
-+}
- 
--print "\n";
- print "FDs Taken:                    $fdTaken\n";
- print "FDs Returned:                 $fdReturned\n";
- print "Highest FD Taken:             $highestFdTaken\n\n";
-@@ -1386,20 +1438,20 @@ if ($usage =~ /l/ || $verb eq "yes"){
- 	}
- }
- 
--#########################################
--#                                       #
--# Gather and Process the unique etimes  #
--#                                       #
--#########################################
-+##############################################################
-+#                                                            #
-+# Gather and Process the unique etimes, wtimes, and optimes  #
-+#                                                            #
-+##############################################################
- 
- my $first;
- if ($usage =~ /t/i || $verb eq "yes"){
-+	# Print the elapsed times (etime)
-+
- 	my $etime = $hashes->{etime};
- 	my @ekeys = keys %{$etime};
--	#
- 	# print most often etimes
--	#
--	print "\n\n----- Top $sizeCount Most Frequent etimes -----\n\n";
-+	print "\n\n----- Top $sizeCount Most Frequent etimes (elapsed times) -----\n\n";
- 	my $eloop = 0;
- 	my $retime = 0;
- 	foreach my $et (sort { $etime->{$b} <=> $etime->{$a} } @ekeys) {
-@@ -1411,16 +1463,84 @@ if ($usage =~ /t/i || $verb eq "yes"){
- 		printf "%-8s        %-12s\n", $etime->{ $et }, "etime=$et";
- 		$eloop++;
- 	}
--	#
-+	if ($eloop == 0) {
-+		print "None";
-+	}
- 	# print longest etimes
--	#
--	print "\n\n----- Top $sizeCount Longest etimes -----\n\n";
-+	print "\n\n----- Top $sizeCount Longest etimes (elapsed times) -----\n\n";
- 	$eloop = 0;
- 	foreach my $et (sort { $b <=> $a } @ekeys) {
- 		if ($eloop == $sizeCount) { last; }
- 		printf "%-12s    %-10s\n","etime=$et",$etime->{ $et };
- 		$eloop++;
- 	}
-+	if ($eloop == 0) {
-+		print "None";
-+	}
-+
-+	# Print the wait times (wtime)
-+
-+	my $wtime = $hashes->{wtime};
-+	my @wkeys = keys %{$wtime};
-+	# print most often wtimes
-+	print "\n\n----- Top $sizeCount Most Frequent wtimes (wait times) -----\n\n";
-+	$eloop = 0;
-+	$retime = 0;
-+	foreach my $et (sort { $wtime->{$b} <=> $wtime->{$a} } @wkeys) {
-+		if ($eloop == $sizeCount) { last; }
-+		if ($retime ne "2"){
-+			$first = $et;
-+			$retime = "2";
-+		}
-+		printf "%-8s        %-12s\n", $wtime->{ $et }, "wtime=$et";
-+		$eloop++;
-+	}
-+	if ($eloop == 0) {
-+		print "None";
-+	}
-+	# print longest wtimes
-+	print "\n\n----- Top $sizeCount Longest wtimes (wait times) -----\n\n";
-+	$eloop = 0;
-+	foreach my $et (sort { $b <=> $a } @wkeys) {
-+		if ($eloop == $sizeCount) { last; }
-+		printf "%-12s    %-10s\n","wtime=$et",$wtime->{ $et };
-+		$eloop++;
-+	}
-+	if ($eloop == 0) {
-+		print "None";
-+	}
-+
-+	# Print the operation times (optime)
-+
-+	my $optime = $hashes->{optime};
-+	my @opkeys = keys %{$optime};
-+	# print most often optimes
-+	print "\n\n----- Top $sizeCount Most Frequent optimes (actual operation times) -----\n\n";
-+	$eloop = 0;
-+	$retime = 0;
-+	foreach my $et (sort { $optime->{$b} <=> $optime->{$a} } @opkeys) {
-+		if ($eloop == $sizeCount) { last; }
-+		if ($retime ne "2"){
-+			$first = $et;
-+			$retime = "2";
-+		}
-+		printf "%-8s        %-12s\n", $optime->{ $et }, "optime=$et";
-+		$eloop++;
-+	}
-+	if ($eloop == 0) {
-+		print "None";
-+	}
-+	# print longest optimes
-+	print "\n\n----- Top $sizeCount Longest optimes (actual operation times) -----\n\n";
-+	$eloop = 0;
-+	foreach my $et (sort { $b <=> $a } @opkeys) {
-+		if ($eloop == $sizeCount) { last; }
-+		printf "%-12s    %-10s\n","optime=$et",$optime->{ $et };
-+		$eloop++;
-+	}
-+	if ($eloop == 0) {
-+		print "None";
-+	}
- }
- 
- #######################################
-@@ -2152,6 +2272,26 @@ sub parseLineNormal
- 	if (m/ RESULT err=/ && m/ notes=[A-Z,]*P/){
- 		$pagedSearchCount++;
- 	}
-+	if (m/ RESULT err=/ && m/ notes=[A-Z,]*F/){
-+		$invalidFilterCount++;
-+		$con = "";
-+		if ($_ =~ /conn= *([0-9A-Z]+)/i){
-+			$con = $1;
-+			if ($_ =~ /op= *([0-9\-]+)/i){ $op = $1;}
-+		}
-+
-+		if($reportStats){ inc_stats('notesF',$s_stats,$m_stats); }
-+        if ($usage =~ /u/ || $usage =~ /U/ || $verb eq "yes"){
-+            if($_ =~ /etime= *([0-9.]+)/i ){
-+                if($1 >= $minEtime){
-+                    $hashes->{etime_conn_op}->{"$serverRestartCount,$con,$op"} = $1;
-+                    $hashes->{notesf_conn_op}->{"$serverRestartCount,$con,$op"}++;
-+                    if ($_ =~ / *([0-9a-z:\/]+)/i){ $hashes->{time_conn_op}->{"$serverRestartCount,$con,$op"} = $1; }
-+                    if ($_ =~ /nentries= *([0-9]+)/i ){ $hashes->{nentries_conn_op}->{"$serverRestartCount,$con,$op"} = $1; }
-+                }
-+            }
-+        }
-+	}
- 	if (m/ notes=[A-Z,]*A/){
- 		$con = "";
- 		if ($_ =~ /conn= *([0-9A-Z]+)/i){
-@@ -2435,6 +2575,16 @@ sub parseLineNormal
- 		if ($usage =~ /t/i || $verb eq "yes"){ $hashes->{etime}->{$etime_val}++; }
- 		if ($reportStats){ inc_stats_val('etime',$etime_val,$s_stats,$m_stats); }
- 	}
-+	if ($_ =~ /wtime= *([0-9.]+)/ ) {
-+		my $wtime_val = $1;
-+		if ($usage =~ /t/i || $verb eq "yes"){ $hashes->{wtime}->{$wtime_val}++; }
-+		if ($reportStats){ inc_stats_val('wtime',$wtime_val,$s_stats,$m_stats); }
-+	}
-+	if ($_ =~ /optime= *([0-9.]+)/ ) {
-+		my $optime_val = $1;
-+		if ($usage =~ /t/i || $verb eq "yes"){ $hashes->{optime}->{$optime_val}++; }
-+		if ($reportStats){ inc_stats_val('optime',$optime_val,$s_stats,$m_stats); }
-+	}
- 	if ($_ =~ / tag=101 / || $_ =~ / tag=111 / || $_ =~ / tag=100 / || $_ =~ / tag=115 /){
- 		if ($_ =~ / nentries= *([0-9]+)/i ){ 
- 			my $nents = $1;
-@@ -2555,7 +2705,7 @@ sub parseLineNormal
- 			}
- 		}
- 	}
--	if (/ RESULT err=/ && / tag=97 nentries=0 etime=/ && $_ =~ /dn=\"(.*)\"/i){
-+	if (/ RESULT err=/ && / tag=97 nentries=0 / && $_ =~ /dn=\"(.*)\"/i){
- 		# Check if this is a sasl bind, if see we need to add the RESULT's dn as a bind dn
- 		my $binddn = $1;
- 		my ($conn, $op);
-@@ -2680,6 +2830,7 @@ print_stats_block
- 						 $stats->{'unbind'},
- 						 $stats->{'notesA'},
- 						 $stats->{'notesU'},
-+						 $stats->{'notesF'},
- 						 $stats->{'etime'}),
- 					"\n" );
- 			} else {
-diff --git a/ldap/servers/slapd/add.c b/ldap/servers/slapd/add.c
-index 06ca1ee79..52c64fa3c 100644
---- a/ldap/servers/slapd/add.c
-+++ b/ldap/servers/slapd/add.c
-@@ -441,6 +441,9 @@ op_shared_add(Slapi_PBlock *pb)
-     internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL);
-     pwpolicy = new_passwdPolicy(pb, slapi_entry_get_dn(e));
- 
-+    /* Set the time we actually started the operation */
-+    slapi_operation_set_time_started(operation);
-+
-     /* target spec is used to decide which plugins are applicable for the operation */
-     operation_set_target_spec(operation, slapi_entry_get_sdn(e));
- 
-diff --git a/ldap/servers/slapd/bind.c b/ldap/servers/slapd/bind.c
-index 310216e89..55f865077 100644
---- a/ldap/servers/slapd/bind.c
-+++ b/ldap/servers/slapd/bind.c
-@@ -87,6 +87,10 @@ do_bind(Slapi_PBlock *pb)
-         send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, NULL, 0, NULL);
-         goto free_and_return;
-     }
-+
-+    /* Set the time we actually started the operation */
-+    slapi_operation_set_time_started(pb_op);
-+
-     ber = pb_op->o_ber;
- 
-     /*
-diff --git a/ldap/servers/slapd/delete.c b/ldap/servers/slapd/delete.c
-index c0e61adf1..1a7209317 100644
---- a/ldap/servers/slapd/delete.c
-+++ b/ldap/servers/slapd/delete.c
-@@ -236,6 +236,9 @@ op_shared_delete(Slapi_PBlock *pb)
-     slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
-     internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL);
- 
-+    /* Set the time we actually started the operation */
-+    slapi_operation_set_time_started(operation);
-+
-     sdn = slapi_sdn_new_dn_byval(rawdn);
-     dn = slapi_sdn_get_dn(sdn);
-     slapi_pblock_set(pb, SLAPI_DELETE_TARGET_SDN, (void *)sdn);
-diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
-index 259bedfff..a186dbde3 100644
---- a/ldap/servers/slapd/modify.c
-+++ b/ldap/servers/slapd/modify.c
-@@ -626,6 +626,9 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw)
-     slapi_pblock_get(pb, SLAPI_SKIP_MODIFIED_ATTRS, &skip_modified_attrs);
-     slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
- 
-+    /* Set the time we actually started the operation */
-+    slapi_operation_set_time_started(operation);
-+
-     if (sdn) {
-         passin_sdn = 1;
-     } else {
-diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c
-index 3efe584a7..e04916b83 100644
---- a/ldap/servers/slapd/modrdn.c
-+++ b/ldap/servers/slapd/modrdn.c
-@@ -417,6 +417,9 @@ op_shared_rename(Slapi_PBlock *pb, int passin_args)
-     internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL);
-     slapi_pblock_get(pb, SLAPI_CONNECTION, &pb_conn);
- 
-+    /* Set the time we actually started the operation */
-+    slapi_operation_set_time_started(operation);
-+
-     /*
-      * If ownership has not been passed to this function, we replace the
-      * string input fields within the pblock with strdup'd copies.  Why?
-diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
-index ff16cd906..4dd3481c7 100644
---- a/ldap/servers/slapd/operation.c
-+++ b/ldap/servers/slapd/operation.c
-@@ -651,3 +651,27 @@ slapi_operation_time_expiry(Slapi_Operation *o, time_t timeout, struct timespec
- {
-     slapi_timespec_expire_rel(timeout, &(o->o_hr_time_rel), expiry);
- }
-+
-+/* Set the time the operation actually started */
-+void
-+slapi_operation_set_time_started(Slapi_Operation *o)
-+{
-+	clock_gettime(CLOCK_MONOTONIC, &(o->o_hr_time_started_rel));
-+}
-+
-+/* The time diff of how long the operation took once it actually started */
-+void
-+slapi_operation_op_time_elapsed(Slapi_Operation *o, struct timespec *elapsed)
-+{
-+    struct timespec o_hr_time_now;
-+    clock_gettime(CLOCK_MONOTONIC, &o_hr_time_now);
-+
-+    slapi_timespec_diff(&o_hr_time_now, &(o->o_hr_time_started_rel), elapsed);
-+}
-+
-+/* The time diff the operation waited in the work queue */
-+void
-+slapi_operation_workq_time_elapsed(Slapi_Operation *o, struct timespec *elapsed)
-+{
-+    slapi_timespec_diff(&(o->o_hr_time_started_rel), &(o->o_hr_time_rel), elapsed);
-+}
-diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
-index 9fe78655c..c0bc5dcd0 100644
---- a/ldap/servers/slapd/opshared.c
-+++ b/ldap/servers/slapd/opshared.c
-@@ -284,6 +284,9 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-     slapi_pblock_get(pb, SLAPI_SEARCH_TARGET_SDN, &sdn);
-     slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
- 
-+    /* Set the time we actually started the operation */
-+    slapi_operation_set_time_started(operation);
-+
-     if (NULL == sdn) {
-         sdn = slapi_sdn_new_dn_byval(base);
-         slapi_pblock_set(pb, SLAPI_SEARCH_TARGET_SDN, sdn);
-diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
-index 0b13c30e9..61efb6f8d 100644
---- a/ldap/servers/slapd/result.c
-+++ b/ldap/servers/slapd/result.c
-@@ -1975,6 +1975,8 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-     CSN *operationcsn = NULL;
-     char csn_str[CSN_STRSIZE + 5];
-     char etime[ETIME_BUFSIZ] = {0};
-+    char wtime[ETIME_BUFSIZ] = {0};
-+    char optime[ETIME_BUFSIZ] = {0};
-     int pr_idx = -1;
-     int pr_cookie = -1;
-     uint32_t operation_notes;
-@@ -1982,19 +1984,26 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-     int32_t op_id;
-     int32_t op_internal_id;
-     int32_t op_nested_count;
-+    struct timespec o_hr_time_end;
- 
-     get_internal_conn_op(&connid, &op_id, &op_internal_id, &op_nested_count);
--
-     slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
-     slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_COOKIE, &pr_cookie);
--
-     internal_op = operation_is_flag_set(op, OP_FLAG_INTERNAL);
- 
--    struct timespec o_hr_time_end;
-+    /* total elapsed time */
-     slapi_operation_time_elapsed(op, &o_hr_time_end);
-+    snprintf(etime, ETIME_BUFSIZ, "%" PRId64 ".%.09" PRId64 "", (int64_t)o_hr_time_end.tv_sec, (int64_t)o_hr_time_end.tv_nsec);
-+
-+    /* wait time */
-+    slapi_operation_workq_time_elapsed(op, &o_hr_time_end);
-+    snprintf(wtime, ETIME_BUFSIZ, "%" PRId64 ".%.09" PRId64 "", (int64_t)o_hr_time_end.tv_sec, (int64_t)o_hr_time_end.tv_nsec);
-+
-+    /* op time */
-+    slapi_operation_op_time_elapsed(op, &o_hr_time_end);
-+    snprintf(optime, ETIME_BUFSIZ, "%" PRId64 ".%.09" PRId64 "", (int64_t)o_hr_time_end.tv_sec, (int64_t)o_hr_time_end.tv_nsec);
- 
- 
--    snprintf(etime, ETIME_BUFSIZ, "%" PRId64 ".%.09" PRId64 "", (int64_t)o_hr_time_end.tv_sec, (int64_t)o_hr_time_end.tv_nsec);
- 
-     operation_notes = slapi_pblock_get_operation_notes(pb);
- 
-@@ -2025,16 +2034,16 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-         if (!internal_op) {
-             slapi_log_access(LDAP_DEBUG_STATS,
-                              "conn=%" PRIu64 " op=%d RESULT err=%d"
--                             " tag=%" BERTAG_T " nentries=%d etime=%s%s%s"
-+                             " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s"
-                              ", SASL bind in progress\n",
-                              op->o_connid,
-                              op->o_opid,
-                              err, tag, nentries,
--                             etime,
-+                             wtime, optime, etime,
-                              notes_str, csn_str);
-         } else {
- 
--#define LOG_SASLMSG_FMT " tag=%" BERTAG_T " nentries=%d etime=%s%s%s, SASL bind in progress\n"
-+#define LOG_SASLMSG_FMT " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s, SASL bind in progress\n"
-             slapi_log_access(LDAP_DEBUG_ARGS,
-                              connid == 0 ? LOG_CONN_OP_FMT_INT_INT LOG_SASLMSG_FMT :
-                                            LOG_CONN_OP_FMT_EXT_INT LOG_SASLMSG_FMT,
-@@ -2043,7 +2052,7 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-                              op_internal_id,
-                              op_nested_count,
-                              err, tag, nentries,
--                             etime,
-+                             wtime, optime, etime,
-                              notes_str, csn_str);
-         }
-     } else if (op->o_tag == LDAP_REQ_BIND && err == LDAP_SUCCESS) {
-@@ -2057,15 +2066,15 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-         if (!internal_op) {
-             slapi_log_access(LDAP_DEBUG_STATS,
-                              "conn=%" PRIu64 " op=%d RESULT err=%d"
--                             " tag=%" BERTAG_T " nentries=%d etime=%s%s%s"
-+                             " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s"
-                              " dn=\"%s\"\n",
-                              op->o_connid,
-                              op->o_opid,
-                              err, tag, nentries,
--                             etime,
-+                             wtime, optime, etime,
-                              notes_str, csn_str, dn ? dn : "");
-         } else {
--#define LOG_BINDMSG_FMT " tag=%" BERTAG_T " nentries=%d etime=%s%s%s dn=\"%s\"\n"
-+#define LOG_BINDMSG_FMT " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s dn=\"%s\"\n"
-             slapi_log_access(LDAP_DEBUG_ARGS,
-                              connid == 0 ? LOG_CONN_OP_FMT_INT_INT LOG_BINDMSG_FMT :
-                                            LOG_CONN_OP_FMT_EXT_INT LOG_BINDMSG_FMT,
-@@ -2074,7 +2083,7 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-                              op_internal_id,
-                              op_nested_count,
-                              err, tag, nentries,
--                             etime,
-+                             wtime, optime, etime,
-                              notes_str, csn_str, dn ? dn : "");
-         }
-         slapi_ch_free((void **)&dn);
-@@ -2083,15 +2092,15 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-             if (!internal_op) {
-                 slapi_log_access(LDAP_DEBUG_STATS,
-                                  "conn=%" PRIu64 " op=%d RESULT err=%d"
--                                 " tag=%" BERTAG_T " nentries=%d etime=%s%s%s"
-+                                 " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s"
-                                  " pr_idx=%d pr_cookie=%d\n",
-                                  op->o_connid,
-                                  op->o_opid,
-                                  err, tag, nentries,
--                                 etime,
-+                                 wtime, optime, etime,
-                                  notes_str, csn_str, pr_idx, pr_cookie);
-             } else {
--#define LOG_PRMSG_FMT " tag=%" BERTAG_T " nentries=%d etime=%s%s%s pr_idx=%d pr_cookie=%d \n"
-+#define LOG_PRMSG_FMT " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s pr_idx=%d pr_cookie=%d \n"
-                 slapi_log_access(LDAP_DEBUG_ARGS,
-                                  connid == 0 ? LOG_CONN_OP_FMT_INT_INT LOG_PRMSG_FMT :
-                                                LOG_CONN_OP_FMT_EXT_INT LOG_PRMSG_FMT,
-@@ -2100,7 +2109,7 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-                                  op_internal_id,
-                                  op_nested_count,
-                                  err, tag, nentries,
--                                 etime,
-+                                 wtime, optime, etime,
-                                  notes_str, csn_str, pr_idx, pr_cookie);
-             }
-         } else if (!internal_op) {
-@@ -2114,11 +2123,11 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-             }
-             slapi_log_access(LDAP_DEBUG_STATS,
-                              "conn=%" PRIu64 " op=%d RESULT err=%d"
--                             " tag=%" BERTAG_T " nentries=%d etime=%s%s%s%s\n",
-+                             " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s%s\n",
-                              op->o_connid,
-                              op->o_opid,
-                              err, tag, nentries,
--                             etime,
-+                             wtime, optime, etime,
-                              notes_str, csn_str, ext_str);
-             if (pbtxt) {
-                 /* if !pbtxt ==> ext_str == "".  Don't free ext_str. */
-@@ -2126,7 +2135,7 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-             }
-         } else {
-             int optype;
--#define LOG_MSG_FMT " tag=%" BERTAG_T " nentries=%d etime=%s%s%s\n"
-+#define LOG_MSG_FMT " tag=%" BERTAG_T " nentries=%d wtime=%s optime=%s etime=%s%s%s\n"
-             slapi_log_access(LDAP_DEBUG_ARGS,
-                              connid == 0 ? LOG_CONN_OP_FMT_INT_INT LOG_MSG_FMT :
-                                            LOG_CONN_OP_FMT_EXT_INT LOG_MSG_FMT,
-@@ -2135,7 +2144,7 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-                              op_internal_id,
-                              op_nested_count,
-                              err, tag, nentries,
--                             etime,
-+                             wtime, optime, etime,
-                              notes_str, csn_str);
-             /*
-              *  If this is an unindexed search we should log it in the error log if
-diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
-index cef8c789c..8e76393c3 100644
---- a/ldap/servers/slapd/slap.h
-+++ b/ldap/servers/slapd/slap.h
-@@ -1538,16 +1538,17 @@ typedef struct slapi_operation_results
-  */
- typedef struct op
- {
--    BerElement *o_ber;             /* ber of the request          */
--    ber_int_t o_msgid;             /* msgid of the request          */
--    ber_tag_t o_tag;               /* tag of the request          */
-+    BerElement *o_ber;             /* ber of the request */
-+    ber_int_t o_msgid;             /* msgid of the request */
-+    ber_tag_t o_tag;               /* tag of the request */
-     struct timespec o_hr_time_rel; /* internal system time op initiated */
-     struct timespec o_hr_time_utc; /* utc system time op initiated */
--    int o_isroot;                  /* requestor is manager          */
-+    struct timespec o_hr_time_started_rel; /* internal system time op started */
-+    int o_isroot;                  /* requestor is manager */
-     Slapi_DN o_sdn;                /* dn bound when op was initiated */
--    char *o_authtype;              /* auth method used to bind dn      */
-+    char *o_authtype;              /* auth method used to bind dn */
-     int o_ssf;                     /* ssf for this operation (highest between SASL and TLS/SSL) */
--    int o_opid;                    /* id of this operation          */
-+    int o_opid;                    /* id of this operation */
-     PRUint64 o_connid;             /* id of conn initiating this op; for logging only */
-     void *o_handler_data;
-     result_handler o_result_handler;
-diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
-index 834a98742..8d9c3fa6a 100644
---- a/ldap/servers/slapd/slapi-plugin.h
-+++ b/ldap/servers/slapd/slapi-plugin.h
-@@ -8210,13 +8210,29 @@ void slapi_operation_time_elapsed(Slapi_Operation *o, struct timespec *elapsed);
-  */
- void slapi_operation_time_initiated(Slapi_Operation *o, struct timespec *initiated);
- /**
-- * Given an operation and a timeout, return a populate struct with the expiry
-- * time of the operation suitable for checking with slapi_timespec_expire_check
-+ * Given an operation, determine the time elapsed since the op
-+ * was actually started.
-  *
-- * \param Slapi_Operation o - the operation that is in progress
-- * \param time_t timeout the seconds relative to operation initiation to expiry at.
-- * \param struct timespec *expiry the timespec to popluate with the relative expiry.
-+ * \param Slapi_Operation o - the operation which is inprogress
-+ * \param struct timespec *elapsed - location where the time difference will be
-+ * placed.
-+ */
-+void slapi_operation_op_time_elapsed(Slapi_Operation *o, struct timespec *elapsed);
-+/**
-+ * Given an operation, determine the time elapsed that the op spent
-+ * in the work queue before actually being dispatched to a worker thread
-+ *
-+ * \param Slapi_Operation o - the operation which is inprogress
-+ * \param struct timespec *elapsed - location where the time difference will be
-+ * placed.
-+ */
-+void slapi_operation_workq_time_elapsed(Slapi_Operation *o, struct timespec *elapsed);
-+/**
-+ * Set the time the operation actually started
-+ *
-+ * \param Slapi_Operation o - the operation which is inprogress
-  */
-+void slapi_operation_set_time_started(Slapi_Operation *o);
- #endif
- 
- /**
--- 
-2.26.2
-
diff --git a/SOURCES/0017-Issue-50912-pwdReset-can-be-modified-by-a-user.patch b/SOURCES/0017-Issue-50912-pwdReset-can-be-modified-by-a-user.patch
deleted file mode 100644
index 56b0db4..0000000
--- a/SOURCES/0017-Issue-50912-pwdReset-can-be-modified-by-a-user.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From ec1714c81290a03ae9aa5fd10acf3e9be71596d7 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Thu, 11 Jun 2020 15:47:43 -0400
-Subject: [PATCH] Issue 50912 - pwdReset can be modified by a user
-
-Description:  The attribute "pwdReset" should only be allowed to be set by the
-              server.  Update schema definition to include NO-USER-MODIFICATION
-
-relates: https://pagure.io/389-ds-base/issue/50912
-
-Reviewed by: mreynolds(one line commit rule)
----
- ldap/schema/02common.ldif | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ldap/schema/02common.ldif b/ldap/schema/02common.ldif
-index 966636bef..c6dc074db 100644
---- a/ldap/schema/02common.ldif
-+++ b/ldap/schema/02common.ldif
-@@ -76,7 +76,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2349 NAME ( 'passwordDictCheck' 'pwdDict
- attributeTypes: ( 2.16.840.1.113730.3.1.2350 NAME ( 'passwordDictPath' 'pwdDictPath' ) DESC '389 Directory Server password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
- attributeTypes: ( 2.16.840.1.113730.3.1.2351 NAME ( 'passwordUserAttributes' 'pwdUserAttributes' ) DESC '389 Directory Server password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
- attributeTypes: ( 2.16.840.1.113730.3.1.2352 NAME ( 'passwordBadWords' 'pwdBadWords' ) DESC '389 Directory Server password policy attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
--attributeTypes: ( 2.16.840.1.113730.3.1.2366 NAME 'pwdReset' DESC '389 Directory Server password policy attribute type' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389 Directory Server' )
-+attributeTypes: ( 2.16.840.1.113730.3.1.2366 NAME 'pwdReset' DESC '389 Directory Server password policy attribute type' EQUALITY booleanMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation X-ORIGIN '389 Directory Server' )
- attributeTypes: ( 2.16.840.1.113730.3.1.198 NAME 'memberURL' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )
- attributeTypes: ( 2.16.840.1.113730.3.1.199 NAME 'memberCertificateDescription' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server' )
- attributeTypes: ( 2.16.840.1.113730.3.1.207 NAME 'vlvBase' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )
--- 
-2.26.2
-
diff --git a/SOURCES/0018-Issue-50791-Healthcheck-should-look-for-notes-A-F-in.patch b/SOURCES/0018-Issue-50791-Healthcheck-should-look-for-notes-A-F-in.patch
deleted file mode 100644
index 5f4f6a3..0000000
--- a/SOURCES/0018-Issue-50791-Healthcheck-should-look-for-notes-A-F-in.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From a6a52365df26edd4f6b0028056395d943344d787 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Thu, 11 Jun 2020 15:30:28 -0400
-Subject: [PATCH] Issue 50791 - Healthcheck should look for notes=A/F in access
- log
-
-Description:  Add checks for notes=A (fully unindexed search) and
-              notes=F (Unknown attribute in search filter) in the
-              current access log.
-
-relates: https://pagure.io/389-ds-base/issue/50791
-
-Reviewed by: firstyear(Thanks!)
----
- src/lib389/lib389/cli_ctl/health.py |  4 +-
- src/lib389/lib389/dirsrv_log.py     | 72 +++++++++++++++++++++++++++--
- src/lib389/lib389/lint.py           | 26 ++++++++++-
- 3 files changed, 96 insertions(+), 6 deletions(-)
-
-diff --git a/src/lib389/lib389/cli_ctl/health.py b/src/lib389/lib389/cli_ctl/health.py
-index 6333a753a..89484a11b 100644
---- a/src/lib389/lib389/cli_ctl/health.py
-+++ b/src/lib389/lib389/cli_ctl/health.py
-@@ -1,5 +1,5 @@
- # --- BEGIN COPYRIGHT BLOCK ---
--# Copyright (C) 2019 Red Hat, Inc.
-+# Copyright (C) 2020 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
-@@ -18,6 +18,7 @@ from lib389.monitor import MonitorDiskSpace
- from lib389.replica import Replica, Changelog5
- from lib389.nss_ssl import NssSsl
- from lib389.dseldif import FSChecks, DSEldif
-+from lib389.dirsrv_log import DirsrvAccessLog
- from lib389 import lint
- from lib389 import plugins
- from lib389._constants import DSRC_HOME
-@@ -37,6 +38,7 @@ CHECK_OBJECTS = [
-     Changelog5,
-     DSEldif,
-     NssSsl,
-+    DirsrvAccessLog,
- ]
- 
- 
-diff --git a/src/lib389/lib389/dirsrv_log.py b/src/lib389/lib389/dirsrv_log.py
-index baac2a3c9..7bed4bb17 100644
---- a/src/lib389/lib389/dirsrv_log.py
-+++ b/src/lib389/lib389/dirsrv_log.py
-@@ -1,5 +1,5 @@
- # --- BEGIN COPYRIGHT BLOCK ---
--# Copyright (C) 2016 Red Hat, Inc.
-+# Copyright (C) 2020 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
-@@ -9,12 +9,17 @@
- """Helpers for managing the directory server internal logs.
- """
- 
-+import copy
- import re
- import gzip
- from dateutil.parser import parse as dt_parse
- from glob import glob
- from lib389.utils import ensure_bytes
--
-+from lib389._mapped_object_lint import DSLint
-+from lib389.lint import (
-+    DSLOGNOTES0001,  # Unindexed search
-+    DSLOGNOTES0002,  # Unknown attr in search filter
-+)
- 
- # Because many of these settings can change live, we need to check for certain
- # attributes all the time.
-@@ -35,7 +40,7 @@ MONTH_LOOKUP = {
- }
- 
- 
--class DirsrvLog(object):
-+class DirsrvLog(DSLint):
-     """Class of functions to working with the various DIrectory Server logs
-     """
-     def __init__(self, dirsrv):
-@@ -189,6 +194,67 @@ class DirsrvAccessLog(DirsrvLog):
-         self.full_regexs = [self.prog_m1, self.prog_con, self.prog_discon]
-         self.result_regexs = [self.prog_notes, self.prog_repl,
-                               self.prog_result]
-+    @classmethod
-+    def lint_uid(cls):
-+        return 'logs'
-+
-+    def _log_get_search_stats(self, conn, op):
-+        lines = self.match(f".* conn={conn} op={op} SRCH base=.*")
-+        if len(lines) != 1:
-+            return None
-+
-+        quoted_vals = re.findall('"([^"]*)"', lines[0])
-+        return {
-+            'base': quoted_vals[0],
-+            'filter': quoted_vals[1],
-+            'timestamp': re.findall('\[(.*)\]', lines[0])[0],
-+            'scope': lines[0].split(' scope=', 1)[1].split(' ',1)[0]
-+        }
-+
-+    def _lint_notes(self):
-+        """
-+        Check for notes=A (fully unindexed searches), and
-+        notes=F (unknown attribute in filter)
-+        """
-+        for pattern, lint_report in [(".* notes=A", DSLOGNOTES0001), (".* notes=F", DSLOGNOTES0002)]:
-+            lines = self.match(pattern)
-+            if len(lines) > 0:
-+                count = 0
-+                searches = []
-+                for line in lines:
-+                    if ' RESULT err=' in line:
-+                        # Looks like a valid notes=A/F
-+                        conn = line.split(' conn=', 1)[1].split(' ',1)[0]
-+                        op = line.split(' op=', 1)[1].split(' ',1)[0]
-+                        etime = line.split(' etime=', 1)[1].split(' ',1)[0]
-+                        stats = self._log_get_search_stats(conn, op)
-+                        if stats is not None:
-+                            timestamp = stats['timestamp']
-+                            base = stats['base']
-+                            scope = stats['scope']
-+                            srch_filter = stats['filter']
-+                            count += 1
-+                            if lint_report == DSLOGNOTES0001:
-+                                searches.append(f'\n  [{count}] Unindexed Search\n'
-+                                                f'      - date:    {timestamp}\n'
-+                                                f'      - conn/op: {conn}/{op}\n'
-+                                                f'      - base:    {base}\n'
-+                                                f'      - scope:   {scope}\n'
-+                                                f'      - filter:  {srch_filter}\n'
-+                                                f'      - etime:   {etime}\n')
-+                            else:
-+                                searches.append(f'\n  [{count}] Invalid Attribute in Filter\n'
-+                                                f'      - date:    {timestamp}\n'
-+                                                f'      - conn/op: {conn}/{op}\n'
-+                                                f'      - filter:  {srch_filter}\n')
-+                if len(searches) > 0:
-+                    report = copy.deepcopy(lint_report)
-+                    report['items'].append(self._get_log_path())
-+                    report['detail'] = report['detail'].replace('NUMBER', str(count))
-+                    for srch in searches:
-+                        report['detail'] += srch
-+                    yield report
-+
- 
-     def _get_log_path(self):
-         """Return the current log file location"""
-diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
-index a103feec7..4b1700b92 100644
---- a/src/lib389/lib389/lint.py
-+++ b/src/lib389/lib389/lint.py
-@@ -1,5 +1,5 @@
- # --- BEGIN COPYRIGHT BLOCK ---
--# Copyright (C) 2019 Red Hat, Inc.
-+# Copyright (C) 2020 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
-@@ -253,7 +253,7 @@ can use the CLI tool "dsconf" to resolve the conflict.  Here is an example:
- 
-     Remove conflict entry and keep only the original/counterpart entry:
- 
--        # dsconf slapd-YOUR_INSTANCE  repl-conflict remove <DN of conflict entry>
-+        # dsconf slapd-YOUR_INSTANCE  repl-conflict delete <DN of conflict entry>
- 
-     Replace the original/counterpart entry with the conflict entry:
- 
-@@ -418,3 +418,25 @@ until the time issues have been resolved:
- Also look at https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/managing_replication-troubleshooting_replication_related_problems
- and find the paragraph "Too much time skew"."""
- }
-+
-+DSLOGNOTES0001 = {
-+    'dsle': 'DSLOGNOTES0001',
-+    'severity': 'Medium',
-+    'description': 'Unindexed Search',
-+    'items': ['Performance'],
-+    'detail': """Found NUMBER fully unindexed searches in the current access log.
-+Unindexed searches can cause high CPU and slow down the entire server's performance.\n""",
-+    'fix': """Examine the searches that are unindexed, and either properly index the attributes
-+in the filter, increase the nsslapd-idlistscanlimit, or stop using that filter."""
-+}
-+
-+DSLOGNOTES0002 = {
-+    'dsle': 'DSLOGNOTES0002',
-+    'severity': 'Medium',
-+    'description': 'Unknown Attribute In Filter',
-+    'items': ['Possible Performance Impact'],
-+    'detail': """Found NUMBER searches in the current access log that are using an
-+unknown attribute in the search filter.\n""",
-+    'fix': """Stop using this these unknown attributes in the filter, or add the schema
-+to the server and make sure it's properly indexed."""
-+}
--- 
-2.26.2
-
diff --git a/SOURCES/0019-Issue-51144-dsctl-fails-with-instance-names-that-con.patch b/SOURCES/0019-Issue-51144-dsctl-fails-with-instance-names-that-con.patch
deleted file mode 100644
index d2663da..0000000
--- a/SOURCES/0019-Issue-51144-dsctl-fails-with-instance-names-that-con.patch
+++ /dev/null
@@ -1,51 +0,0 @@
-From 2844d4ad90cbbd23ae75309e50ae4d7145586bb7 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Wed, 10 Jun 2020 14:07:24 -0400
-Subject: [PATCH] Issue 51144 - dsctl fails with instance names that contain
- slapd-
-
-Bug Description:  If an instance name contains 'slapd-' the CLI breaks:
-
-                      slapd-test-slapd
-
-Fix Description:  Only strip off "slapd-" from the front of the instance
-                  name.
-
-relates: https://pagure.io/389-ds-base/issue/51144
-
-Reviewed by: firstyear(Thanks!)
----
- src/lib389/lib389/__init__.py | 2 +-
- src/lib389/lib389/dseldif.py  | 3 ++-
- 2 files changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py
-index 0ff1ab173..63d44b60a 100644
---- a/src/lib389/lib389/__init__.py
-+++ b/src/lib389/lib389/__init__.py
-@@ -710,7 +710,7 @@ class DirSrv(SimpleLDAPObject, object):
-         # Don't need a default value now since it's set in init.
-         if serverid is None and hasattr(self, 'serverid'):
-             serverid = self.serverid
--        elif serverid is not None:
-+        elif serverid is not None and serverid.startswith('slapd-'):
-             serverid = serverid.replace('slapd-', '', 1)
- 
-         if self.serverid is None:
-diff --git a/src/lib389/lib389/dseldif.py b/src/lib389/lib389/dseldif.py
-index 96c9af9d1..f2725add9 100644
---- a/src/lib389/lib389/dseldif.py
-+++ b/src/lib389/lib389/dseldif.py
-@@ -40,7 +40,8 @@ class DSEldif(DSLint):
-         if serverid:
-             # Get the dse.ldif from the instance name
-             prefix = os.environ.get('PREFIX', ""),
--            serverid = serverid.replace("slapd-", "")
-+            if serverid.startswith("slapd-"):
-+                serverid = serverid.replace("slapd-", "", 1)
-             self.path = "{}/etc/dirsrv/slapd-{}/dse.ldif".format(prefix[0], serverid)
-         else:
-             ds_paths = Paths(self._instance.serverid, self._instance)
--- 
-2.26.2
-
diff --git a/SOURCES/0020-Ticket-49859-A-distinguished-value-can-be-missing-in.patch b/SOURCES/0020-Ticket-49859-A-distinguished-value-can-be-missing-in.patch
deleted file mode 100644
index 8d25933..0000000
--- a/SOURCES/0020-Ticket-49859-A-distinguished-value-can-be-missing-in.patch
+++ /dev/null
@@ -1,520 +0,0 @@
-From 6cd4b1c60dbd3d7b74adb19a2434585d50553f39 Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Fri, 5 Jun 2020 12:14:51 +0200
-Subject: [PATCH] Ticket 49859 - A distinguished value can be missing in an
- entry
-
-Bug description:
-	According to RFC 4511 (see ticket), the values of the RDN attributes
-        should be present in an entry.
-	With a set of replicated operations, it is possible that those values
-        would be missing
-
-Fix description:
-        MOD and MODRDN update checks that the RDN values are presents.
-        If they are missing they are added to the resulting entry. In addition
-        the set of modifications to add those values are also indexed.
-        The specific case of single-valued attributes, where the final and unique value
-        can not be the RDN value, the attribute nsds5ReplConflict is added.
-
-https://pagure.io/389-ds-base/issue/49859
-
-Reviewed by: Mark Reynolds, William Brown
-
-Platforms tested: F31
----
- .../replication/conflict_resolve_test.py      | 174 +++++++++++++++++-
- ldap/servers/slapd/back-ldbm/ldbm_modify.c    | 136 ++++++++++++++
- ldap/servers/slapd/back-ldbm/ldbm_modrdn.c    |  37 +++-
- .../servers/slapd/back-ldbm/proto-back-ldbm.h |   1 +
- 4 files changed, 343 insertions(+), 5 deletions(-)
-
-diff --git a/dirsrvtests/tests/suites/replication/conflict_resolve_test.py b/dirsrvtests/tests/suites/replication/conflict_resolve_test.py
-index 99a072935..48d0067db 100644
---- a/dirsrvtests/tests/suites/replication/conflict_resolve_test.py
-+++ b/dirsrvtests/tests/suites/replication/conflict_resolve_test.py
-@@ -10,10 +10,11 @@ import time
- import logging
- import ldap
- import pytest
-+import re
- from itertools import permutations
- from lib389._constants import *
- from lib389.idm.nscontainer import nsContainers
--from lib389.idm.user import UserAccounts
-+from lib389.idm.user import UserAccounts, UserAccount
- from lib389.idm.group import Groups
- from lib389.idm.organizationalunit import OrganizationalUnits
- from lib389.replica import ReplicationManager
-@@ -763,6 +764,177 @@ class TestTwoMasters:
-         user_dns_m2 = [user.dn for user in test_users_m2.list()]
-         assert set(user_dns_m1) == set(user_dns_m2)
- 
-+    def test_conflict_attribute_multi_valued(self, topology_m2, base_m2):
-+        """A RDN attribute being multi-valued, checks that after several operations
-+           MODRDN and MOD_REPL its RDN values are the same on both servers
-+
-+        :id: 225b3522-8ed7-4256-96f9-5fab9b7044a5
-+        :setup: Two master replication,
-+                audit log, error log for replica and access log for internal
-+        :steps:
-+            1. Create a test entry uid=user_test_1000,...
-+            2. Pause all replication agreements
-+            3. On M1 rename it into uid=foo1,...
-+            4. On M2 rename it into uid=foo2,...
-+            5. On M1 MOD_REPL uid:foo1
-+            6. Resume all replication agreements
-+            7. Check that entry on M1 has uid=foo1, foo2
-+            8. Check that entry on M2 has uid=foo1, foo2
-+            9. Check that entry on M1 and M2 has the same uid values
-+        :expectedresults:
-+            1. It should pass
-+            2. It should pass
-+            3. It should pass
-+            4. It should pass
-+            5. It should pass
-+            6. It should pass
-+            7. It should pass
-+            8. It should pass
-+            9. It should pass
-+        """
-+
-+        M1 = topology_m2.ms["master1"]
-+        M2 = topology_m2.ms["master2"]
-+
-+        # add a test user
-+        test_users_m1 = UserAccounts(M1, base_m2.dn, rdn=None)
-+        user_1 = test_users_m1.create_test_user(uid=1000)
-+        test_users_m2 = UserAccount(M2, user_1.dn)
-+        # Waiting fo the user to be replicated
-+        for i in range(0,4):
-+            time.sleep(1)
-+            if test_users_m2.exists():
-+                break
-+        assert(test_users_m2.exists())
-+
-+        # Stop replication agreements
-+        topology_m2.pause_all_replicas()
-+
-+        # On M1 rename test entry in uid=foo1
-+        original_dn = user_1.dn
-+        user_1.rename('uid=foo1')
-+        time.sleep(1)
-+
-+        # On M2 rename test entry in uid=foo2
-+        M2.rename_s(original_dn, 'uid=foo2')
-+        time.sleep(2)
-+
-+        # on M1 MOD_REPL uid into foo1
-+        user_1.replace('uid', 'foo1')
-+
-+        # resume replication agreements
-+        topology_m2.resume_all_replicas()
-+        time.sleep(5)
-+
-+        # check that on M1, the entry 'uid' has two values 'foo1' and 'foo2'
-+        final_dn = re.sub('^.*1000,', 'uid=foo2,', original_dn)
-+        final_user_m1 = UserAccount(M1, final_dn)
-+        for val in final_user_m1.get_attr_vals_utf8('uid'):
-+            log.info("Check %s is on M1" % val)
-+            assert(val in ['foo1', 'foo2'])
-+
-+        # check that on M2, the entry 'uid' has two values 'foo1' and 'foo2'
-+        final_user_m2 = UserAccount(M2, final_dn)
-+        for val in final_user_m2.get_attr_vals_utf8('uid'):
-+            log.info("Check %s is on M1" % val)
-+            assert(val in ['foo1', 'foo2'])
-+
-+        # check that the entry have the same uid values
-+        for val in final_user_m1.get_attr_vals_utf8('uid'):
-+            log.info("Check M1.uid %s is also on M2" % val)
-+            assert(val in final_user_m2.get_attr_vals_utf8('uid'))
-+
-+        for val in final_user_m2.get_attr_vals_utf8('uid'):
-+            log.info("Check M2.uid %s is also on M1" % val)
-+            assert(val in final_user_m1.get_attr_vals_utf8('uid'))
-+
-+    def test_conflict_attribute_single_valued(self, topology_m2, base_m2):
-+        """A RDN attribute being signle-valued, checks that after several operations
-+           MODRDN and MOD_REPL its RDN values are the same on both servers
-+
-+        :id: c38ae613-5d1e-47cf-b051-c7284e64b817
-+        :setup: Two master replication, test container for entries, enable plugin logging,
-+                audit log, error log for replica and access log for internal
-+        :steps:
-+            1. Create a test entry uid=user_test_1000,...
-+            2. Pause all replication agreements
-+            3. On M1 rename it into employeenumber=foo1,...
-+            4. On M2 rename it into employeenumber=foo2,...
-+            5. On M1 MOD_REPL employeenumber:foo1
-+            6. Resume all replication agreements
-+            7. Check that entry on M1 has employeenumber=foo1
-+            8. Check that entry on M2 has employeenumber=foo1
-+            9. Check that entry on M1 and M2 has the same employeenumber values
-+        :expectedresults:
-+            1. It should pass
-+            2. It should pass
-+            3. It should pass
-+            4. It should pass
-+            5. It should pass
-+            6. It should pass
-+            7. It should pass
-+            8. It should pass
-+            9. It should pass
-+        """
-+
-+        M1 = topology_m2.ms["master1"]
-+        M2 = topology_m2.ms["master2"]
-+
-+        # add a test user with a dummy 'uid' extra value because modrdn removes
-+        # uid that conflict with 'account' objectclass
-+        test_users_m1 = UserAccounts(M1, base_m2.dn, rdn=None)
-+        user_1 = test_users_m1.create_test_user(uid=1000)
-+        user_1.add('objectclass', 'extensibleobject')
-+        user_1.add('uid', 'dummy')
-+        test_users_m2 = UserAccount(M2, user_1.dn)
-+
-+        # Waiting fo the user to be replicated
-+        for i in range(0,4):
-+            time.sleep(1)
-+            if test_users_m2.exists():
-+                break
-+        assert(test_users_m2.exists())
-+
-+        # Stop replication agreements
-+        topology_m2.pause_all_replicas()
-+
-+        # On M1 rename test entry in employeenumber=foo1
-+        original_dn = user_1.dn
-+        user_1.rename('employeenumber=foo1')
-+        time.sleep(1)
-+
-+        # On M2 rename test entry in employeenumber=foo2
-+        M2.rename_s(original_dn, 'employeenumber=foo2')
-+        time.sleep(2)
-+
-+        # on M1 MOD_REPL uid into foo1
-+        user_1.replace('employeenumber', 'foo1')
-+
-+        # resume replication agreements
-+        topology_m2.resume_all_replicas()
-+        time.sleep(5)
-+
-+        # check that on M1, the entry 'employeenumber' has value 'foo1'
-+        final_dn = re.sub('^.*1000,', 'employeenumber=foo2,', original_dn)
-+        final_user_m1 = UserAccount(M1, final_dn)
-+        for val in final_user_m1.get_attr_vals_utf8('employeenumber'):
-+            log.info("Check %s is on M1" % val)
-+            assert(val in ['foo1'])
-+
-+        # check that on M2, the entry 'employeenumber' has values 'foo1'
-+        final_user_m2 = UserAccount(M2, final_dn)
-+        for val in final_user_m2.get_attr_vals_utf8('employeenumber'):
-+            log.info("Check %s is on M2" % val)
-+            assert(val in ['foo1'])
-+
-+        # check that the entry have the same uid values
-+        for val in final_user_m1.get_attr_vals_utf8('employeenumber'):
-+            log.info("Check M1.uid %s is also on M2" % val)
-+            assert(val in final_user_m2.get_attr_vals_utf8('employeenumber'))
-+
-+        for val in final_user_m2.get_attr_vals_utf8('employeenumber'):
-+            log.info("Check M2.uid %s is also on M1" % val)
-+            assert(val in final_user_m1.get_attr_vals_utf8('employeenumber'))
- 
- class TestThreeMasters:
-     def test_nested_entries(self, topology_m3, base_m3):
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
-index e9d7e87e3..a507f3c31 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c
-@@ -213,6 +213,112 @@ error:
-     return retval;
- }
- 
-+int32_t
-+entry_get_rdn_mods(Slapi_PBlock *pb, Slapi_Entry *entry, CSN *csn, int repl_op, Slapi_Mods **smods_ret)
-+{
-+    unsigned long op_type = SLAPI_OPERATION_NONE;
-+    char *new_rdn = NULL;
-+    char **dns = NULL;
-+    char **rdns = NULL;
-+    Slapi_Mods *smods = NULL;
-+    char *type = NULL;
-+    struct berval *bvp[2] = {0};
-+    struct berval bv;
-+    Slapi_Attr *attr = NULL;
-+    const char *entry_dn = NULL;
-+
-+    *smods_ret = NULL;
-+    entry_dn = slapi_entry_get_dn_const(entry);
-+    /* Do not bother to check that RDN is present, no one rename RUV or change its nsuniqueid */
-+    if (strcasestr(entry_dn, RUV_STORAGE_ENTRY_UNIQUEID)) {
-+        return 0;
-+    }
-+
-+    /* First get the RDNs of the operation */
-+    slapi_pblock_get(pb, SLAPI_OPERATION_TYPE, &op_type);
-+    switch (op_type) {
-+        case SLAPI_OPERATION_MODIFY:
-+            dns = slapi_ldap_explode_dn(entry_dn, 0);
-+            if (dns == NULL) {
-+                slapi_log_err(SLAPI_LOG_ERR, "entry_get_rdn_mods",
-+                      "Fails to split DN \"%s\" into components\n", entry_dn);
-+                return -1;
-+            }
-+            rdns = slapi_ldap_explode_rdn(dns[0], 0);
-+            slapi_ldap_value_free(dns);
-+
-+            break;
-+        case SLAPI_OPERATION_MODRDN:
-+            slapi_pblock_get(pb, SLAPI_MODRDN_NEWRDN, &new_rdn);
-+            rdns = slapi_ldap_explode_rdn(new_rdn, 0);
-+            break;
-+        default:
-+            break;
-+    }
-+    if (rdns == NULL || rdns[0] == NULL) {
-+        slapi_log_err(SLAPI_LOG_ERR, "entry_get_rdn_mods",
-+                      "Fails to split RDN \"%s\" into components\n", slapi_entry_get_dn_const(entry));
-+        return -1;
-+    }
-+
-+    /* Update the entry to add RDNs values if they are missing */
-+    smods = slapi_mods_new();
-+
-+    bvp[0] = &bv;
-+    bvp[1] = NULL;
-+    for (size_t rdns_count = 0; rdns[rdns_count]; rdns_count++) {
-+        Slapi_Value *value;
-+        attr = NULL;
-+        slapi_rdn2typeval(rdns[rdns_count], &type, &bv);
-+
-+        /* Check if the RDN value exists */
-+        if ((slapi_entry_attr_find(entry, type, &attr) != 0) ||
-+            (slapi_attr_value_find(attr, &bv))) {
-+            const CSN *csn_rdn_add;
-+            const CSN *adcsn = attr_get_deletion_csn(attr);
-+
-+            /* It is missing => adds it */
-+            if (slapi_attr_flag_is_set(attr, SLAPI_ATTR_FLAG_SINGLE)) {
-+                if (csn_compare(adcsn, csn) >= 0) {
-+                    /* this is a single valued attribute and the current value
-+                     * (that is different from RDN value) is more recent than
-+                     * the RDN value we want to apply.
-+                     * Keep the current value and add a conflict flag
-+                     */
-+
-+                    type = ATTR_NSDS5_REPLCONFLICT;
-+                    bv.bv_val = "RDN value may be missing because it is single-valued";
-+                    bv.bv_len = strlen(bv.bv_val);
-+                    slapi_entry_add_string(entry, type, bv.bv_val);
-+                    slapi_mods_add_modbvps(smods, LDAP_MOD_ADD, type, bvp);
-+                    continue;
-+                }
-+            }
-+            /* if a RDN value needs to be forced, make sure it csn is ahead */
-+            slapi_mods_add_modbvps(smods, LDAP_MOD_ADD, type, bvp);
-+            csn_rdn_add = csn_max(adcsn, csn);
-+
-+            if (entry_apply_mods_wsi(entry, smods, csn_rdn_add, repl_op)) {
-+                slapi_log_err(SLAPI_LOG_ERR, "entry_get_rdn_mods",
-+                              "Fails to set \"%s\" in  \"%s\"\n", type, slapi_entry_get_dn_const(entry));
-+                slapi_ldap_value_free(rdns);
-+                slapi_mods_free(&smods);
-+                return -1;
-+            }
-+            /* Make the RDN value a distinguished value */
-+            attr_value_find_wsi(attr, &bv, &value);
-+            value_update_csn(value, CSN_TYPE_VALUE_DISTINGUISHED, csn_rdn_add);
-+        }
-+    }
-+    slapi_ldap_value_free(rdns);
-+    if (smods->num_mods == 0) {
-+        /* smods_ret already NULL, just free the useless smods */
-+        slapi_mods_free(&smods);
-+    } else {
-+        *smods_ret = smods;
-+    }
-+    return 0;
-+}
- /**
-    Apply the mods to the ec entry.  Check for syntax, schema problems.
-    Check for abandon.
-@@ -269,6 +375,8 @@ modify_apply_check_expand(
-         goto done;
-     }
- 
-+
-+
-     /*
-      * If the objectClass attribute type was modified in any way, expand
-      * the objectClass values to reflect the inheritance hierarchy.
-@@ -414,6 +522,7 @@ ldbm_back_modify(Slapi_PBlock *pb)
-     int result_sent = 0;
-     int32_t parent_op = 0;
-     struct timespec parent_time;
-+    Slapi_Mods *smods_add_rdn = NULL;
- 
-     slapi_pblock_get(pb, SLAPI_BACKEND, &be);
-     slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li);
-@@ -731,6 +840,15 @@ ldbm_back_modify(Slapi_PBlock *pb)
-             }
-         } /* else if new_mod_count == mod_count then betxnpremod plugin did nothing */
- 
-+        /* time to check if applying a replicated operation removed
-+         * the RDN value from the entry. Assuming that only replicated update
-+         * can lead to that bad result
-+         */
-+        if (entry_get_rdn_mods(pb, ec->ep_entry, opcsn, repl_op, &smods_add_rdn)) {
-+            goto error_return;
-+        }
-+
-+
-         /*
-          * Update the ID to Entry index.
-          * Note that id2entry_add replaces the entry, so the Entry ID
-@@ -764,6 +882,23 @@ ldbm_back_modify(Slapi_PBlock *pb)
-             MOD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
-             goto error_return;
-         }
-+
-+        if (smods_add_rdn && slapi_mods_get_num_mods(smods_add_rdn) > 0) {
-+            retval = index_add_mods(be, (LDAPMod **) slapi_mods_get_ldapmods_byref(smods_add_rdn), e, ec, &txn);
-+            if (DB_LOCK_DEADLOCK == retval) {
-+                /* Abort and re-try */
-+                slapi_mods_free(&smods_add_rdn);
-+                continue;
-+            }
-+            if (retval != 0) {
-+                slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modify",
-+                        "index_add_mods (rdn) failed, err=%d %s\n",
-+                        retval, (msg = dblayer_strerror(retval)) ? msg : "");
-+                MOD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
-+                slapi_mods_free(&smods_add_rdn);
-+                goto error_return;
-+            }
-+        }
-         /*
-          * Remove the old entry from the Virtual List View indexes.
-          * Add the new entry to the Virtual List View indexes.
-@@ -978,6 +1113,7 @@ error_return:
- 
- common_return:
-     slapi_mods_done(&smods);
-+    slapi_mods_free(&smods_add_rdn);
- 
-     if (inst) {
-         if (ec_locked || cache_is_in_cache(&inst->inst_cache, ec)) {
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-index fde83c99f..e97b7a5f6 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-@@ -21,7 +21,7 @@ static void moddn_unlock_and_return_entry(backend *be, struct backentry **target
- static int moddn_newrdn_mods(Slapi_PBlock *pb, const char *olddn, struct backentry *ec, Slapi_Mods *smods_wsi, int is_repl_op);
- static IDList *moddn_get_children(back_txn *ptxn, Slapi_PBlock *pb, backend *be, struct backentry *parententry, Slapi_DN *parentdn, struct backentry ***child_entries, struct backdn ***child_dns, int is_resurect_operation);
- static int moddn_rename_children(back_txn *ptxn, Slapi_PBlock *pb, backend *be, IDList *children, Slapi_DN *dn_parentdn, Slapi_DN *dn_newsuperiordn, struct backentry *child_entries[]);
--static int modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3);
-+static int modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li, struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3, Slapi_Mods *smods4);
- static void mods_remove_nsuniqueid(Slapi_Mods *smods);
- 
- #define MOD_SET_ERROR(rc, error, count)                                            \
-@@ -100,6 +100,7 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-     Connection *pb_conn = NULL;
-     int32_t parent_op = 0;
-     struct timespec parent_time;
-+    Slapi_Mods *smods_add_rdn = NULL;
- 
-     if (slapi_pblock_get(pb, SLAPI_CONN_ID, &conn_id) < 0) {
-         conn_id = 0; /* connection is NULL */
-@@ -842,6 +843,15 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-                     goto error_return;
-                 }
-             }
-+
-+            /* time to check if applying a replicated operation removed
-+             * the RDN value from the entry. Assuming that only replicated update
-+             * can lead to that bad result
-+             */
-+            if (entry_get_rdn_mods(pb, ec->ep_entry, opcsn, is_replicated_operation, &smods_add_rdn)) {
-+                goto error_return;
-+            }
-+
-             /* check that the entry still obeys the schema */
-             if (slapi_entry_schema_check(pb, ec->ep_entry) != 0) {
-                 ldap_result_code = LDAP_OBJECT_CLASS_VIOLATION;
-@@ -1003,7 +1013,7 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-         /*
-          * Update the indexes for the entry.
-          */
--        retval = modrdn_rename_entry_update_indexes(&txn, pb, li, e, &ec, &smods_generated, &smods_generated_wsi, &smods_operation_wsi);
-+        retval = modrdn_rename_entry_update_indexes(&txn, pb, li, e, &ec, &smods_generated, &smods_generated_wsi, &smods_operation_wsi, smods_add_rdn);
-         if (DB_LOCK_DEADLOCK == retval) {
-             /* Retry txn */
-             continue;
-@@ -1497,6 +1507,7 @@ common_return:
-     slapi_mods_done(&smods_operation_wsi);
-     slapi_mods_done(&smods_generated);
-     slapi_mods_done(&smods_generated_wsi);
-+    slapi_mods_free(&smods_add_rdn);
-     slapi_ch_free((void **)&child_entries);
-     slapi_ch_free((void **)&child_dns);
-     if (ldap_result_matcheddn && 0 != strcmp(ldap_result_matcheddn, "NULL"))
-@@ -1778,7 +1789,7 @@ mods_remove_nsuniqueid(Slapi_Mods *smods)
-  * mods contains the list of attribute change made.
-  */
- static int
--modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li __attribute__((unused)), struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3)
-+modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbminfo *li __attribute__((unused)), struct backentry *e, struct backentry **ec, Slapi_Mods *smods1, Slapi_Mods *smods2, Slapi_Mods *smods3, Slapi_Mods *smods4)
- {
-     backend *be;
-     ldbm_instance *inst;
-@@ -1874,6 +1885,24 @@ modrdn_rename_entry_update_indexes(back_txn *ptxn, Slapi_PBlock *pb, struct ldbm
-             goto error_return;
-         }
-     }
-+    if (smods4 != NULL && slapi_mods_get_num_mods(smods4) > 0) {
-+        /*
-+         * update the indexes: lastmod, rdn, etc.
-+         */
-+        retval = index_add_mods(be, slapi_mods_get_ldapmods_byref(smods4), e, *ec, ptxn);
-+        if (DB_LOCK_DEADLOCK == retval) {
-+            /* Retry txn */
-+            slapi_log_err(SLAPI_LOG_BACKLDBM, "modrdn_rename_entry_update_indexes",
-+                          "index_add_mods4 deadlock\n");
-+            goto error_return;
-+        }
-+        if (retval != 0) {
-+            slapi_log_err(SLAPI_LOG_TRACE, "modrdn_rename_entry_update_indexes",
-+                          "index_add_mods 4 failed, err=%d %s\n",
-+                          retval, (msg = dblayer_strerror(retval)) ? msg : "");
-+            goto error_return;
-+        }
-+    }
-     /*
-      * Remove the old entry from the Virtual List View indexes.
-      * Add the new entry to the Virtual List View indexes.
-@@ -1991,7 +2020,7 @@ moddn_rename_child_entry(
-          * Update all the indexes.
-          */
-         retval = modrdn_rename_entry_update_indexes(ptxn, pb, li, e, ec,
--                                                    smodsp, NULL, NULL);
-+                                                    smodsp, NULL, NULL, NULL);
-         /* JCMREPL - Should the children get updated modifiersname and lastmodifiedtime? */
-         slapi_mods_done(&smods);
-     }
-diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-index 4d2524fd9..e2f1100ed 100644
---- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-+++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h
-@@ -324,6 +324,7 @@ int get_parent_rdn(DB *db, ID parentid, Slapi_RDN *srdn);
- /*
-  * modify.c
-  */
-+int32_t entry_get_rdn_mods(Slapi_PBlock *pb, Slapi_Entry *entry, CSN *csn, int repl_op, Slapi_Mods **smods_ret);
- int modify_update_all(backend *be, Slapi_PBlock *pb, modify_context *mc, back_txn *txn);
- void modify_init(modify_context *mc, struct backentry *old_entry);
- int modify_apply_mods(modify_context *mc, Slapi_Mods *smods);
--- 
-2.26.2
-
diff --git a/SOURCES/0021-Issue-49256-log-warning-when-thread-number-is-very-d.patch b/SOURCES/0021-Issue-49256-log-warning-when-thread-number-is-very-d.patch
deleted file mode 100644
index 2e20c8c..0000000
--- a/SOURCES/0021-Issue-49256-log-warning-when-thread-number-is-very-d.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 2be9d1b4332d3b9b55a2d285e9610813100e235f Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Mon, 22 Jun 2020 17:49:10 -0400
-Subject: [PATCH] Issue 49256 - log warning when thread number is very
- different from autotuned value
-
-Description:  To help prevent customers from setting incorrect values for
-              the thread number it would be useful to warn them that the
-              configured value is either way too low or way too high.
-
-relates: https://pagure.io/389-ds-base/issue/49256
-
-Reviewed by: firstyear(Thanks!)
----
- .../tests/suites/config/autotuning_test.py    | 28 +++++++++++++++
- ldap/servers/slapd/libglobs.c                 | 34 ++++++++++++++++++-
- ldap/servers/slapd/slap.h                     |  3 ++
- 3 files changed, 64 insertions(+), 1 deletion(-)
-
-diff --git a/dirsrvtests/tests/suites/config/autotuning_test.py b/dirsrvtests/tests/suites/config/autotuning_test.py
-index d1c751444..540761250 100644
---- a/dirsrvtests/tests/suites/config/autotuning_test.py
-+++ b/dirsrvtests/tests/suites/config/autotuning_test.py
-@@ -43,6 +43,34 @@ def test_threads_basic(topo):
-     assert topo.standalone.config.get_attr_val_int("nsslapd-threadnumber") > 0
- 
- 
-+def test_threads_warning(topo):
-+    """Check that we log a warning if the thread number is too high or low
-+
-+    :id: db92412b-2812-49de-84b0-00f452cd254f
-+    :setup: Standalone Instance
-+    :steps:
-+        1. Get autotuned thread number
-+        2. Set threads way higher than hw threads, and find a warning in the log
-+        3. Set threads way lower than hw threads, and find a warning in the log
-+    :expectedresults:
-+        1. Success
-+        2. Success
-+        3. Success
-+    """
-+    topo.standalone.config.set("nsslapd-threadnumber", "-1")
-+    autotuned_value = topo.standalone.config.get_attr_val_utf8("nsslapd-threadnumber")
-+
-+    topo.standalone.config.set("nsslapd-threadnumber", str(int(autotuned_value) * 4))
-+    time.sleep(.5)
-+    assert topo.standalone.ds_error_log.match('.*higher.*hurt server performance.*')
-+
-+    if int(autotuned_value) > 1:
-+        # If autotuned is 1, there isn't anything to test here
-+        topo.standalone.config.set("nsslapd-threadnumber", "1")
-+        time.sleep(.5)
-+        assert topo.standalone.ds_error_log.match('.*lower.*hurt server performance.*')
-+
-+
- @pytest.mark.parametrize("invalid_value", ('-2', '0', 'invalid'))
- def test_threads_invalid_value(topo, invalid_value):
-     """Check nsslapd-threadnumber for an invalid values
-diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
-index fbf90d92d..88676a303 100644
---- a/ldap/servers/slapd/libglobs.c
-+++ b/ldap/servers/slapd/libglobs.c
-@@ -4374,6 +4374,7 @@ config_set_threadnumber(const char *attrname, char *value, char *errorbuf, int a
- {
-     int retVal = LDAP_SUCCESS;
-     int32_t threadnum = 0;
-+    int32_t hw_threadnum = 0;
-     char *endp = NULL;
- 
-     slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
-@@ -4386,8 +4387,39 @@ config_set_threadnumber(const char *attrname, char *value, char *errorbuf, int a
-     threadnum = strtol(value, &endp, 10);
- 
-     /* Means we want to re-run the hardware detection. */
-+    hw_threadnum = util_get_hardware_threads();
-     if (threadnum == -1) {
--        threadnum = util_get_hardware_threads();
-+        threadnum = hw_threadnum;
-+    } else {
-+        /*
-+         * Log a message if the user defined thread number is very different
-+         * from the hardware threads as this is probably not the optimal
-+         * value.
-+         */
-+        if (threadnum >= hw_threadnum) {
-+            if (threadnum > MIN_THREADS && threadnum / hw_threadnum >= 4) {
-+                /* We're over the default minimum and way higher than the hw
-+                 * threads. */
-+                slapi_log_err(SLAPI_LOG_NOTICE, "config_set_threadnumber",
-+                        "The configured thread number (%d) is significantly "
-+                        "higher than the number of hardware threads (%d).  "
-+                        "This can potentially hurt server performance.  If "
-+                        "you are unsure how to tune \"nsslapd-threadnumber\" "
-+                        "then set it to \"-1\" and the server will tune it "
-+                        "according to the system hardware\n",
-+                        threadnum, hw_threadnum);
-+            }
-+        } else if (threadnum < MIN_THREADS) {
-+            /* The thread number should never be less than the minimum and
-+             * hardware threads. */
-+            slapi_log_err(SLAPI_LOG_WARNING, "config_set_threadnumber",
-+                    "The configured thread number (%d) is lower than the number "
-+                    "of hardware threads (%d).  This will hurt server performance.  "
-+                    "If you are unsure how to tune \"nsslapd-threadnumber\" then "
-+                    "set it to \"-1\" and the server will tune it according to the "
-+                    "system hardware\n",
-+                    threadnum, hw_threadnum);
-+            }
-     }
- 
-     if (*endp != '\0' || errno == ERANGE || threadnum < 1 || threadnum > 65535) {
-diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
-index 8e76393c3..894efd29c 100644
---- a/ldap/servers/slapd/slap.h
-+++ b/ldap/servers/slapd/slap.h
-@@ -403,6 +403,9 @@ typedef void (*VFPV)(); /* takes undefined arguments */
- #define SLAPD_DEFAULT_PW_MAX_CLASS_CHARS_ATTRIBUTE 0
- #define SLAPD_DEFAULT_PW_MAX_CLASS_CHARS_ATTRIBUTE_STR "0"
- 
-+#define MIN_THREADS 16
-+#define MAX_THREADS 512
-+
- 
- /* Default password values. */
- 
--- 
-2.26.2
-
diff --git a/SOURCES/0022-Issue-51188-db2ldif-crashes-when-LDIF-file-can-t-be-.patch b/SOURCES/0022-Issue-51188-db2ldif-crashes-when-LDIF-file-can-t-be-.patch
deleted file mode 100644
index 94c3f34..0000000
--- a/SOURCES/0022-Issue-51188-db2ldif-crashes-when-LDIF-file-can-t-be-.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From d24381488a997dda0006b603fb2b452b726757c0 Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <simon.pichugin@gmail.com>
-Date: Thu, 25 Jun 2020 10:45:16 +0200
-Subject: [PATCH] Issue 51188 - db2ldif crashes when LDIF file can't be
- accessed
-
-Bug Description: db2ldif crashes when we set '-a LDIF_PATH' to a place that
-can't be accessed by the user (dirsrv by default)
-
-Fix Description: Don't attempt to close DB if we bail after a failed
-attempt to open LDIF file.
-
-https://pagure.io/389-ds-base/issue/51188
-
-Reviewed by: mreynolds (Thanks!)
----
- ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c
-index 542147c3d..9ffd877cb 100644
---- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c
-+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_ldif2db.c
-@@ -871,6 +871,7 @@ bdb_db2ldif(Slapi_PBlock *pb)
-             slapi_log_err(SLAPI_LOG_ERR, "bdb_db2ldif",
-                     "db2ldif: %s: can't open %s: %d (%s) while running as user \"%s\"\n",
-                     inst->inst_name, fname, errno, dblayer_strerror(errno), slapdFrontendConfig->localuserinfo->pw_name);
-+            we_start_the_backends = 0;
-             return_value = -1;
-             goto bye;
-         }
--- 
-2.26.2
-
diff --git a/SOURCES/0023-Issue-51086-Fix-instance-name-length-for-interactive.patch b/SOURCES/0023-Issue-51086-Fix-instance-name-length-for-interactive.patch
deleted file mode 100644
index 90c275e..0000000
--- a/SOURCES/0023-Issue-51086-Fix-instance-name-length-for-interactive.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 5e0a2d34f1c03a7d6a1c8591896a21e122d90d6b Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <spichugi@redhat.com>
-Date: Thu, 23 Jul 2020 23:45:18 +0200
-Subject: [PATCH] Issue 51086 - Fix instance name length for interactive
- install
-
-Description: Instance name lenght is not properly validated
-during interactive install. Add a check during a user input.
-
-https://pagure.io/389-ds-base/issue/51086
-
-Reviewed by: mreynolds (Thanks!)
----
- src/lib389/lib389/instance/setup.py | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
-index f5fc5495d..45c7dfdd4 100644
---- a/src/lib389/lib389/instance/setup.py
-+++ b/src/lib389/lib389/instance/setup.py
-@@ -308,6 +308,9 @@ class SetupDs(object):
- 
-             val = input('\nEnter the instance name [{}]: '.format(slapd['instance_name'])).rstrip()
-             if val != "":
-+                if len(val) > 80:
-+                    print("Server identifier should not be longer than 80 symbols")
-+                    continue
-                 if not all(ord(c) < 128 for c in val):
-                     print("Server identifier can not contain non ascii characters")
-                     continue
--- 
-2.26.2
-
diff --git a/SOURCES/0024-Issue-51129-SSL-alert-The-value-of-sslVersionMax-TLS.patch b/SOURCES/0024-Issue-51129-SSL-alert-The-value-of-sslVersionMax-TLS.patch
deleted file mode 100644
index a4c26cc..0000000
--- a/SOURCES/0024-Issue-51129-SSL-alert-The-value-of-sslVersionMax-TLS.patch
+++ /dev/null
@@ -1,360 +0,0 @@
-From 3e11020fa7a79d335a02c001435aabcf59aaa622 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Fri, 24 Jul 2020 12:14:44 -0400
-Subject: [PATCH] Issue 51129 - SSL alert: The value of sslVersionMax "TLS1.3"
- is higher than the supported version
-
-Bug Description:  If you try and set the sslVersionMax higher than the
-                  default range, but within the supported range, you
-                  would still get an error and the server would reset
-                  the max to "default" max value.
-
-Fix Description:  Keep track of both the supported and default SSL ranges,
-                  and correctly use each range for value validation.  If
-                  the value is outside the supported range, then use default
-                  value, etc, but do not check the requested range against
-                  the default range.  We only use the default range if
-                  there is no specified min or max in the config, or if
-                  a invalid min or max value is set in the config.
-
-                  Also, refactored the range variable names to be more
-                  accurate:
-
-                     enabledNSSVersions -->  defaultNSSVersions
-                     emin, emax         -->  dmin, dmax
-
-relates: https://pagure.io/389-ds-base/issue/51129
-
-Reviewed by: firstyear(Thanks!)
----
- ldap/servers/slapd/ssl.c        | 155 ++++++++++++++++----------------
- src/lib389/lib389/dirsrv_log.py |   2 +-
- 2 files changed, 81 insertions(+), 76 deletions(-)
-
-diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
-index 846106b42..7206cafd2 100644
---- a/ldap/servers/slapd/ssl.c
-+++ b/ldap/servers/slapd/ssl.c
-@@ -50,11 +50,11 @@
-  ******************************************************************************/
- 
- #define DEFVERSION "TLS1.2"
--#define CURRENT_DEFAULT_SSL_VERSION SSL_LIBRARY_VERSION_TLS_1_2
- 
- extern char *slapd_SSL3ciphers;
- extern symbol_t supported_ciphers[];
--static SSLVersionRange enabledNSSVersions;
-+static SSLVersionRange defaultNSSVersions;
-+static SSLVersionRange supportedNSSVersions;
- static SSLVersionRange slapdNSSVersions;
- 
- 
-@@ -1014,15 +1014,24 @@ slapd_nss_init(int init_ssl __attribute__((unused)), int config_available __attr
-     int create_certdb = 0;
-     PRUint32 nssFlags = 0;
-     char *certdir;
--    char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
--    /* Get the range of the supported SSL version */
--    SSL_VersionRangeGetDefault(ssl_variant_stream, &enabledNSSVersions);
-+    char dmin[VERSION_STR_LENGTH], dmax[VERSION_STR_LENGTH];
-+    char smin[VERSION_STR_LENGTH], smax[VERSION_STR_LENGTH];
- 
--    (void)slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
--    (void)slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
-+    /* Get the range of the supported SSL version */
-+    SSL_VersionRangeGetSupported(ssl_variant_stream, &supportedNSSVersions);
-+    (void)slapi_getSSLVersion_str(supportedNSSVersions.min, smin, sizeof(smin));
-+    (void)slapi_getSSLVersion_str(supportedNSSVersions.max, smax, sizeof(smax));
-+
-+    /* Get the enabled default range */
-+    SSL_VersionRangeGetDefault(ssl_variant_stream, &defaultNSSVersions);
-+    (void)slapi_getSSLVersion_str(defaultNSSVersions.min, dmin, sizeof(dmin));
-+    (void)slapi_getSSLVersion_str(defaultNSSVersions.max, dmax, sizeof(dmax));
-     slapi_log_err(SLAPI_LOG_CONFIG, "Security Initialization",
-                   "slapd_nss_init - Supported range by NSS: min: %s, max: %s\n",
--                  emin, emax);
-+                  smin, smax);
-+    slapi_log_err(SLAPI_LOG_CONFIG, "Security Initialization",
-+                  "slapd_nss_init - Enabled default range by NSS: min: %s, max: %s\n",
-+                  dmin, dmax);
- 
-     /* set in slapd_bootstrap_config,
-        thus certdir is available even if config_available is false
-@@ -1344,21 +1353,21 @@ static int
- set_NSS_version(char *val, PRUint16 *rval, int ismin)
- {
-     char *vp;
--    char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
-+    char dmin[VERSION_STR_LENGTH], dmax[VERSION_STR_LENGTH];
- 
-     if (NULL == rval) {
-         return 1;
-     }
--    (void)slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
--    (void)slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
-+    (void)slapi_getSSLVersion_str(defaultNSSVersions.min, dmin, sizeof(dmin));
-+    (void)slapi_getSSLVersion_str(defaultNSSVersions.max, dmax, sizeof(dmax));
- 
-     if (!strncasecmp(val, SSLSTR, SSLLEN)) { /* ssl# NOT SUPPORTED */
-         if (ismin) {
--            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default min value: %s\n", emin);
--            (*rval) = enabledNSSVersions.min;
-+            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default min value: %s", dmin);
-+            (*rval) = defaultNSSVersions.min;
-         } else {
--            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default max value: %s\n", emax);
--            (*rval) = enabledNSSVersions.max;
-+            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default max value: %s", dmax);
-+            (*rval) = defaultNSSVersions.max;
-         }
-     } else if (!strncasecmp(val, TLSSTR, TLSLEN)) { /* tls# */
-         float tlsv;
-@@ -1366,122 +1375,122 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin)
-         sscanf(vp, "%4f", &tlsv);
-         if (tlsv < 1.1f) { /* TLS1.0 */
-             if (ismin) {
--                if (enabledNSSVersions.min > CURRENT_DEFAULT_SSL_VERSION) {
-+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) {
-                     slapd_SSL_warn("The value of sslVersionMin "
-                                    "\"%s\" is lower than the supported version; "
-                                    "the default value \"%s\" is used.",
--                                   val, emin);
--                    (*rval) = enabledNSSVersions.min;
-+                                   val, dmin);
-+                    (*rval) = defaultNSSVersions.min;
-                 } else {
-                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
-                 }
-             } else {
--                if (enabledNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) {
-+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) {
-                     /* never happens */
-                     slapd_SSL_warn("The value of sslVersionMax "
-                                    "\"%s\" is higher than the supported version; "
-                                    "the default value \"%s\" is used.",
--                                   val, emax);
--                    (*rval) = enabledNSSVersions.max;
-+                                   val, dmax);
-+                    (*rval) = defaultNSSVersions.max;
-                 } else {
-                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
-                 }
-             }
-         } else if (tlsv < 1.2f) { /* TLS1.1 */
-             if (ismin) {
--                if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) {
-+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) {
-                     slapd_SSL_warn("The value of sslVersionMin "
-                                    "\"%s\" is lower than the supported version; "
-                                    "the default value \"%s\" is used.",
--                                   val, emin);
--                    (*rval) = enabledNSSVersions.min;
-+                                   val, dmin);
-+                    (*rval) = defaultNSSVersions.min;
-                 } else {
-                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
-                 }
-             } else {
--                if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) {
-+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) {
-                     /* never happens */
-                     slapd_SSL_warn("The value of sslVersionMax "
-                                    "\"%s\" is higher than the supported version; "
-                                    "the default value \"%s\" is used.",
--                                   val, emax);
--                    (*rval) = enabledNSSVersions.max;
-+                                   val, dmax);
-+                    (*rval) = defaultNSSVersions.max;
-                 } else {
-                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
-                 }
-             }
-         } else if (tlsv < 1.3f) { /* TLS1.2 */
-             if (ismin) {
--                if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
-+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
-                     slapd_SSL_warn("The value of sslVersionMin "
-                                    "\"%s\" is lower than the supported version; "
-                                    "the default value \"%s\" is used.",
--                                   val, emin);
--                    (*rval) = enabledNSSVersions.min;
-+                                   val, dmin);
-+                    (*rval) = defaultNSSVersions.min;
-                 } else {
-                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
-                 }
-             } else {
--                if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_2) {
-+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_2) {
-                     /* never happens */
-                     slapd_SSL_warn("The value of sslVersionMax "
-                                    "\"%s\" is higher than the supported version; "
-                                    "the default value \"%s\" is used.",
--                                   val, emax);
--                    (*rval) = enabledNSSVersions.max;
-+                                   val, dmax);
-+                    (*rval) = defaultNSSVersions.max;
-                 } else {
-                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
-                 }
-             }
-         } else if (tlsv < 1.4f) { /* TLS1.3 */
--                    if (ismin) {
--                        if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_3) {
--                            slapd_SSL_warn("The value of sslVersionMin "
--                                           "\"%s\" is lower than the supported version; "
--                                           "the default value \"%s\" is used.",
--                                           val, emin);
--                            (*rval) = enabledNSSVersions.min;
--                        } else {
--                            (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
--                        }
--                    } else {
--                        if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
--                            /* never happens */
--                            slapd_SSL_warn("The value of sslVersionMax "
--                                           "\"%s\" is higher than the supported version; "
--                                           "the default value \"%s\" is used.",
--                                           val, emax);
--                            (*rval) = enabledNSSVersions.max;
--                        } else {
--                            (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
--                        }
--                    }
-+            if (ismin) {
-+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_3) {
-+                    slapd_SSL_warn("The value of sslVersionMin "
-+                                   "\"%s\" is lower than the supported version; "
-+                                   "the default value \"%s\" is used.",
-+                                   val, dmin);
-+                    (*rval) = defaultNSSVersions.min;
-+                } else {
-+                    (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
-+                }
-+            } else {
-+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
-+                    /* never happens */
-+                    slapd_SSL_warn("The value of sslVersionMax "
-+                                   "\"%s\" is higher than the supported version; "
-+                                   "the default value \"%s\" is used.",
-+                                   val, dmax);
-+                    (*rval) = defaultNSSVersions.max;
-+                } else {
-+                    (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
-+                }
-+            }
-         } else { /* Specified TLS is newer than supported */
-             if (ismin) {
-                 slapd_SSL_warn("The value of sslVersionMin "
-                                "\"%s\" is out of the range of the supported version; "
-                                "the default value \"%s\" is used.",
--                               val, emin);
--                (*rval) = enabledNSSVersions.min;
-+                               val, dmin);
-+                (*rval) = defaultNSSVersions.min;
-             } else {
-                 slapd_SSL_warn("The value of sslVersionMax "
-                                "\"%s\" is out of the range of the supported version; "
-                                "the default value \"%s\" is used.",
--                               val, emax);
--                (*rval) = enabledNSSVersions.max;
-+                               val, dmax);
-+                (*rval) = defaultNSSVersions.max;
-             }
-         }
-     } else {
-         if (ismin) {
-             slapd_SSL_warn("The value of sslVersionMin "
-                            "\"%s\" is invalid; the default value \"%s\" is used.",
--                           val, emin);
--            (*rval) = enabledNSSVersions.min;
-+                           val, dmin);
-+            (*rval) = defaultNSSVersions.min;
-         } else {
-             slapd_SSL_warn("The value of sslVersionMax "
-                            "\"%s\" is invalid; the default value \"%s\" is used.",
--                           val, emax);
--            (*rval) = enabledNSSVersions.max;
-+                           val, dmax);
-+            (*rval) = defaultNSSVersions.max;
-         }
-     }
-     return 0;
-@@ -1511,10 +1520,9 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
-     char *tmpDir;
-     Slapi_Entry *e = NULL;
-     PRBool fipsMode = PR_FALSE;
--    PRUint16 NSSVersionMin = enabledNSSVersions.min;
--    PRUint16 NSSVersionMax = enabledNSSVersions.max;
-+    PRUint16 NSSVersionMin = defaultNSSVersions.min;
-+    PRUint16 NSSVersionMax = defaultNSSVersions.max;
-     char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
--    char newmax[VERSION_STR_LENGTH];
-     int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER;
-     int_fast16_t renegotiation = (int_fast16_t)SSL_RENEGOTIATE_REQUIRES_XTN;
- 
-@@ -1875,12 +1883,9 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
-         if (NSSVersionMin > NSSVersionMax) {
-             (void)slapi_getSSLVersion_str(NSSVersionMin, mymin, sizeof(mymin));
-             (void)slapi_getSSLVersion_str(NSSVersionMax, mymax, sizeof(mymax));
--            slapd_SSL_warn("The min value of NSS version range \"%s\" is greater than the max value \"%s\".",
-+            slapd_SSL_warn("The min value of NSS version range \"%s\" is greater than the max value \"%s\".  Adjusting the max to match the miniumum.",
-                            mymin, mymax);
--            (void)slapi_getSSLVersion_str(enabledNSSVersions.max, newmax, sizeof(newmax));
--            slapd_SSL_warn("Reset the max \"%s\" to supported max \"%s\".",
--                           mymax, newmax);
--            NSSVersionMax = enabledNSSVersions.max;
-+            NSSVersionMax = NSSVersionMin;
-         }
-     }
- 
-@@ -1896,7 +1901,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
-     if (sslStatus != SECSuccess) {
-         errorCode = PR_GetError();
-         slapd_SSL_error("Security Initialization - "
--                "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)\n",
-+                "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)",
-                 mymin, mymax, errorCode, slapd_pr_strerror(errorCode));
-     }
-     /*
-@@ -1926,13 +1931,13 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
-             (void)slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin));
-             (void)slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax));
-             slapd_SSL_error("Security Initialization - "
--                    "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)\n",
-+                    "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)",
-                     mymin, mymax, errorCode, slapd_pr_strerror(errorCode));
-         }
-     } else {
-         errorCode = PR_GetError();
-         slapd_SSL_error("Security Initialization - ",
--                "slapd_ssl_init2 - Failed to get SSL range from socket - error %d (%s)\n",
-+                "slapd_ssl_init2 - Failed to get SSL range from socket - error %d (%s)",
-                 errorCode, slapd_pr_strerror(errorCode));
-     }
- 
-@@ -2265,7 +2270,7 @@ slapd_SSL_client_auth(LDAP *ld)
-         }
-     } else {
-         if (token == NULL) {
--            slapd_SSL_warn("slapd_SSL_client_auth - certificate token was not found\n");
-+            slapd_SSL_warn("slapd_SSL_client_auth - certificate token was not found");
-         }
-         rc = -1;
-     }
-diff --git a/src/lib389/lib389/dirsrv_log.py b/src/lib389/lib389/dirsrv_log.py
-index 7bed4bb17..ab8872051 100644
---- a/src/lib389/lib389/dirsrv_log.py
-+++ b/src/lib389/lib389/dirsrv_log.py
-@@ -207,7 +207,7 @@ class DirsrvAccessLog(DirsrvLog):
-         return {
-             'base': quoted_vals[0],
-             'filter': quoted_vals[1],
--            'timestamp': re.findall('\[(.*)\]', lines[0])[0],
-+            'timestamp': re.findall('[(.*)]', lines[0])[0],
-             'scope': lines[0].split(' scope=', 1)[1].split(' ',1)[0]
-         }
- 
--- 
-2.26.2
-
diff --git a/SOURCES/0025-Issue-50984-Memory-leaks-in-disk-monitoring.patch b/SOURCES/0025-Issue-50984-Memory-leaks-in-disk-monitoring.patch
deleted file mode 100644
index 5f8d129..0000000
--- a/SOURCES/0025-Issue-50984-Memory-leaks-in-disk-monitoring.patch
+++ /dev/null
@@ -1,202 +0,0 @@
-From 68ca1de0f39c11056a57b03a544520bd6708d855 Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <simon.pichugin@gmail.com>
-Date: Thu, 11 Jun 2020 15:39:59 +0200
-Subject: [PATCH] Issue 50984 - Memory leaks in disk monitoring
-
-Description: Fix the rest of the leaks in disk monitoring
-which are present when we shutdown while being below half
-of the threshold (at the start-up in main.c).
-
-Free directories, sockets and ports before going to cleanup.
-
-https://pagure.io/389-ds-base/issue/50984
-
-Reviewed by: mhonek, tbordaz (Thanks!)
----
- ldap/servers/slapd/daemon.c | 75 ++++++++++++++++++++-----------------
- ldap/servers/slapd/fe.h     |  1 +
- ldap/servers/slapd/main.c   | 49 +++++++++++++-----------
- 3 files changed, 70 insertions(+), 55 deletions(-)
-
-diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
-index a70f40316..7091b570d 100644
---- a/ldap/servers/slapd/daemon.c
-+++ b/ldap/servers/slapd/daemon.c
-@@ -884,6 +884,46 @@ convert_pbe_des_to_aes(void)
-     charray_free(attrs);
- }
- 
-+void
-+slapd_sockets_ports_free(daemon_ports_t *ports_info)
-+{
-+    /* freeing PRFileDescs */
-+    PRFileDesc **fdesp = NULL;
-+    for (fdesp = ports_info->n_socket; fdesp && *fdesp; fdesp++) {
-+        PR_Close(*fdesp);
-+    }
-+    slapi_ch_free((void **)&ports_info->n_socket);
-+
-+    for (fdesp = ports_info->s_socket; fdesp && *fdesp; fdesp++) {
-+        PR_Close(*fdesp);
-+    }
-+    slapi_ch_free((void **)&ports_info->s_socket);
-+#if defined(ENABLE_LDAPI)
-+    for (fdesp = ports_info->i_socket; fdesp && *fdesp; fdesp++) {
-+        PR_Close(*fdesp);
-+    }
-+    slapi_ch_free((void **)&ports_info->i_socket);
-+#endif /* ENABLE_LDAPI */
-+
-+    /* freeing NetAddrs */
-+    PRNetAddr **nap;
-+    for (nap = ports_info->n_listenaddr; nap && *nap; nap++) {
-+        slapi_ch_free((void **)nap);
-+    }
-+    slapi_ch_free((void **)&ports_info->n_listenaddr);
-+
-+    for (nap = ports_info->s_listenaddr; nap && *nap; nap++) {
-+        slapi_ch_free((void **)nap);
-+    }
-+    slapi_ch_free((void **)&ports_info->s_listenaddr);
-+#if defined(ENABLE_LDAPI)
-+    for (nap = ports_info->i_listenaddr; nap && *nap; nap++) {
-+        slapi_ch_free((void **)nap);
-+    }
-+    slapi_ch_free((void **)&ports_info->i_listenaddr);
-+#endif
-+}
-+
- void
- slapd_daemon(daemon_ports_t *ports)
- {
-@@ -1099,40 +1139,7 @@ slapd_daemon(daemon_ports_t *ports)
-     /* free the listener indexes */
-     slapi_ch_free((void **)&listener_idxs);
- 
--    for (fdesp = n_tcps; fdesp && *fdesp; fdesp++) {
--        PR_Close(*fdesp);
--    }
--    slapi_ch_free((void **)&n_tcps);
--
--    for (fdesp = i_unix; fdesp && *fdesp; fdesp++) {
--        PR_Close(*fdesp);
--    }
--    slapi_ch_free((void **)&i_unix);
--
--    for (fdesp = s_tcps; fdesp && *fdesp; fdesp++) {
--        PR_Close(*fdesp);
--    }
--    slapi_ch_free((void **)&s_tcps);
--
--    /* freeing NetAddrs */
--    {
--        PRNetAddr **nap;
--        for (nap = ports->n_listenaddr; nap && *nap; nap++) {
--            slapi_ch_free((void **)nap);
--        }
--        slapi_ch_free((void **)&ports->n_listenaddr);
--
--        for (nap = ports->s_listenaddr; nap && *nap; nap++) {
--            slapi_ch_free((void **)nap);
--        }
--        slapi_ch_free((void **)&ports->s_listenaddr);
--#if defined(ENABLE_LDAPI)
--        for (nap = ports->i_listenaddr; nap && *nap; nap++) {
--            slapi_ch_free((void **)nap);
--        }
--        slapi_ch_free((void **)&ports->i_listenaddr);
--#endif
--    }
-+    slapd_sockets_ports_free(ports);
- 
-     op_thread_cleanup();
-     housekeeping_stop(); /* Run this after op_thread_cleanup() logged sth */
-diff --git a/ldap/servers/slapd/fe.h b/ldap/servers/slapd/fe.h
-index 2d9a0931b..9cd122881 100644
---- a/ldap/servers/slapd/fe.h
-+++ b/ldap/servers/slapd/fe.h
-@@ -120,6 +120,7 @@ int connection_table_iterate_active_connections(Connection_Table *ct, void *arg,
-  */
- int signal_listner(void);
- int daemon_pre_setuid_init(daemon_ports_t *ports);
-+void slapd_sockets_ports_free(daemon_ports_t *ports_info);
- void slapd_daemon(daemon_ports_t *ports);
- void daemon_register_connection(void);
- int slapd_listenhost2addr(const char *listenhost, PRNetAddr ***addr);
-diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
-index e54b8e1c5..9e5219c4a 100644
---- a/ldap/servers/slapd/main.c
-+++ b/ldap/servers/slapd/main.c
-@@ -734,7 +734,6 @@ main(int argc, char **argv)
-      * etc the backends need to start
-      */
- 
--
-     /* Important: up 'till here we could be running as root (on unix).
-      * we believe that we've not created any files before here, otherwise
-      * they'd be owned by root, which is bad. We're about to change identity
-@@ -891,6 +890,34 @@ main(int argc, char **argv)
-     }
-     }
- 
-+    if (config_get_disk_monitoring()) {
-+        char **dirs = NULL;
-+        char *dirstr = NULL;
-+        uint64_t disk_space = 0;
-+        int64_t threshold = 0;
-+        uint64_t halfway = 0;
-+        threshold = config_get_disk_threshold();
-+        halfway = threshold / 2;
-+        disk_mon_get_dirs(&dirs);
-+        dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space);
-+        if (dirstr != NULL && disk_space < halfway) {
-+            slapi_log_err(SLAPI_LOG_EMERG, "main",
-+                          "Disk Monitoring is enabled and disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). Exiting now.\n",
-+                          dirstr, threshold);
-+            slapi_ch_array_free(dirs);
-+            /*
-+             * We should free the structs we allocated for sockets and addresses
-+             * as they would be freed at the slapd_daemon but it was not initiated
-+             * at that point of start-up.
-+             */
-+            slapd_sockets_ports_free(&ports_info);
-+            return_value = 1;
-+            goto cleanup;
-+        }
-+        slapi_ch_array_free(dirs);
-+        dirs = NULL;
-+    }
-+
-     /* initialize the normalized DN cache */
-     if (ndn_cache_init() != 0) {
-         slapi_log_err(SLAPI_LOG_EMERG, "main", "Unable to create ndn cache\n");
-@@ -940,26 +967,6 @@ main(int argc, char **argv)
-         slapi_ch_free((void **)&versionstring);
-     }
- 
--    if (config_get_disk_monitoring()) {
--        char **dirs = NULL;
--        char *dirstr = NULL;
--        uint64_t disk_space = 0;
--        int64_t threshold = 0;
--        uint64_t halfway = 0;
--        threshold = config_get_disk_threshold();
--        halfway = threshold / 2;
--        disk_mon_get_dirs(&dirs);
--        dirstr = disk_mon_check_diskspace(dirs, threshold, &disk_space);
--        if (dirstr != NULL && disk_space < halfway) {
--            slapi_log_err(SLAPI_LOG_EMERG, "main",
--                          "Disk Monitoring is enabled and disk space on (%s) is too far below the threshold(%" PRIu64 " bytes). Exiting now.\n",
--                          dirstr, threshold);
--            return_value = 1;
--            goto cleanup;
--        }
--        slapi_ch_array_free(dirs);
--        dirs = NULL;
--    }
-     /* log the max fd limit as it is typically set in env/systemd */
-     slapi_log_err(SLAPI_LOG_INFO, "main",
-             "Setting the maximum file descriptor limit to: %ld\n",
--- 
-2.26.2
-
diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec
index 37554a0..3937284 100644
--- a/SPECS/389-ds-base.spec
+++ b/SPECS/389-ds-base.spec
@@ -44,8 +44,8 @@ ExcludeArch: i686
 
 Summary:          389 Directory Server (base)
 Name:             389-ds-base
-Version:          1.4.3.8
-Release:          %{?relprefix}5%{?prerel}%{?dist}
+Version:          1.4.3.16
+Release:          %{?relprefix}1%{?prerel}%{?dist}
 License:          GPLv3+
 URL:              https://www.port389.org
 Group:            System Environment/Daemons
@@ -174,31 +174,6 @@ Source2:          %{name}-devel.README
 %if %{bundle_jemalloc}
 Source3:          https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2
 %endif
-Patch01:          0001-Issue-51076-prevent-unnecessarily-duplication-of-the.patch
-Patch02:          0002-Ticket-51082-abort-when-a-empty-valueset-is-freed.patch
-Patch03:          0003-Issue-51091-healthcheck-json-report-fails-when-mappi.patch
-Patch04:          0004-Issue-51076-remove-unnecessary-slapi-entry-dups.patch
-Patch05:          0005-Issue-51086-Improve-dscreate-instance-name-validatio.patch
-Patch06:          0006-Issue-51102-RFE-ds-replcheck-make-online-timeout-con.patch
-Patch07:          0007-Issue-51110-Fix-ASAN-ODR-warnings.patch
-Patch08:          0008-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch
-Patch09:          0009-Issue-51113-Allow-using-uid-for-replication-manager-.patch
-Patch10:          0010-Issue-50931-RFE-AD-filter-rewriter-for-ObjectCategor.patch
-Patch11:          0011-Issue-50746-Add-option-to-healthcheck-to-list-all-th.patch
-Patch12:          0012-Issue-50984-Memory-leaks-in-disk-monitoring.patch
-Patch13:          0013-Issue-50984-Memory-leaks-in-disk-monitoring.patch
-Patch14:          0014-Issue-50201-nsIndexIDListScanLimit-accepts-any-value.patch
-Patch15:          0015-Issue-51157-Reindex-task-may-create-abandoned-index-.patch
-Patch16:          0016-Issue-51165-add-new-access-log-keywords-for-wtime-an.patch
-Patch17:          0017-Issue-50912-pwdReset-can-be-modified-by-a-user.patch
-Patch18:          0018-Issue-50791-Healthcheck-should-look-for-notes-A-F-in.patch
-Patch19:          0019-Issue-51144-dsctl-fails-with-instance-names-that-con.patch
-Patch20:          0020-Ticket-49859-A-distinguished-value-can-be-missing-in.patch
-Patch21:          0021-Issue-49256-log-warning-when-thread-number-is-very-d.patch
-Patch22:          0022-Issue-51188-db2ldif-crashes-when-LDIF-file-can-t-be-.patch
-Patch23:          0023-Issue-51086-Fix-instance-name-length-for-interactive.patch
-Patch24:          0024-Issue-51129-SSL-alert-The-value-of-sslVersionMax-TLS.patch
-Patch25:          0025-Issue-50984-Memory-leaks-in-disk-monitoring.patch
 
 %description
 389 Directory Server is an LDAPv3 compliant server.  The base package includes
@@ -816,6 +791,36 @@ exit 0
 %doc README.md
 
 %changelog
+* Mon Oct 26 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.16-1
+- Bump version to 1.4.3.16-1
+- Resolves: Bug 1887415 - Sync repl - if a serie of updates target the same entry then the cookie get wrong changenumber
+- Resolves: Bug 1859225 - suffix management in backends incorrect
+
+* Mon Oct 26 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.14-1
+- Bump version to 1.4.3.14-1
+- Resolves: Bug 1862529 - Rebase 389-ds-base-1.4.3 in RHEL 8.4
+- Resolves: Bug 1859301 - Misleading message in access log for idle timeout
+- Resolves: Bug 1889782 - Missing closing quote when reporting the details of unindexed/paged search results
+- Resolves: Bug 1862971 - dsidm user status fails with Error: 'nsUserAccount' object has no attribute 'is_locked' 
+- Resolves: Bug 1859878 - Managed Entries configuration not being enforced
+- Resolves: Bug 1851973 - Duplicate entryUSN numbers for different LDAP entries in the same backend
+- Resolves: Bug 1851967 - if dbhome directory is set online backup fails
+- Resolves: Bug 1887449 - Sync repl: missing update because operation are erroneously stated as nested
+- Resolves: Bug 1887415 - Sync repl - if a serie of updates target the same entry then the cookie get wrong changenumber
+- Resolves: Bug 1851978 - SyncRepl plugin provides a wrong cookie
+- Resolves: Bug 1843604 - reduce the cost of allocation/free when open/close a connection
+- Resolves: Bug 1872930 - dscreate: Not possible to bind to a unix domain socket
+- Resolves: Bug 1861504 - ds-replcheck crashes in offline mode
+- Resolves: Bug 1859282 - remove ldbm_back_entry_release 
+- Resolves: Bug 1859225 - suffix management in backends incorrect
+- Resolves: Bug 1859224 - remove unused or unnecessary database plugin functions
+- Resolves: Bug 1859219 - rfc2307 and rfc2307bis compat schema
+- Resolves: Bug 1851975 - Add option to reject internal unindexed searches
+- Resolves: Bug 1851972 - Remove code duplication from the BDB backend separation work
+- Resolves: Bug 1850275 - Add new access log keywords for time spent in work queue and actual operation time
+- Resolves: Bug 1848359 - Add failover credentials to replication agreement 
+- Resolves: Bug 1837315 - Healthcheck code DSBLE0002 not returned on disabled suffix
+
 * Wed Aug 5 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.8-5
 - Bump version to 1.4.3.8-5
 - Resolves: Bug 1841086 - SSL alert: The value of sslVersionMax "TLS1.3" is higher than the supported version
@@ -875,195 +880,3 @@ exit 0
 - Resolves: Bug 1790986 - cenotaph errors on modrdn operations
 - Resolves: Bug 1769734 - Heavy StartTLS connection load can randomly fail with err=1
 - Resolves: Bug 1758501 - LeakSanitizer: detected memory leaks in changelog5_init and perfctrs_init
-
-* Fri May 8 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.8-0
-- Bump version to 1.4.3.8-0
-- Issue 51078 - Add nsslapd-enable-upgrade-hash to the schema
-- Issue 51054 - Revise ACI target syntax checking
-- Issue 51068 - deadlock when updating the schema
-- Issue 51060 - unable to set sslVersionMin to TLS1.0
-- Issue 51064 - Unable to install server where IPv6 is disabled
-- Issue 51051 - CLI fix consistency issues with confirmations
-- Issue 49731 - undo db_home_dir under /dev/shm/dirsrv for now
-- Issue 51054 - AddressSanitizer: heap-buffer-overflow in ldap_utf8prev
-- Issue 51047 - React deprecating ComponentWillMount
-- Issue 50499 - fix npm audit issues
-- Issue 50545 - Port dbgen.pl to dsctl
-
-* Wed Apr 22 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.7-1
-- Bump version to 1.4.3.7
-- Issue 51024 - syncrepl_entry callback does not contain attributes added by postoperation plugins
-- Issue 51035 - Heavy StartTLS connection load can randomly fail with err=1
-- Issue 49731 - undo db_home_dir under /dev/shm/dirsrv for now
-- Issue 51031 - UI - transition between two instances needs improvement
-
-* Thu Apr 16 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.6-1
-- Bump version to 1.4.3.6
-- Issue 50933 - 10rfc2307compat.ldif is not ready to set used by default
-- Issue 50931 - RFE AD filter rewriter for ObjectCategory
-- Issue 51016 - Fix memory leaks in changelog5_init and perfctrs_init
-- Issue 50980 - RFE extend usability for slapi_compute_add_search_rewriter and slapi_compute_add_evaluator
-- Issue 51008 - dbhome in containers
-- Issue 50875 - Refactor passwordUserAttributes's and passwordBadWords's code
-- Issue 51014 - slapi_pal.c possible static buffer overflow
-- Issue 50545 - remove dbmon "incr" option from arg parser
-- Issue 50545 - Port dbmon.sh to dsconf
-- Issue 51005 - AttributeUniqueness plugin's DN parameter should not have a default value
-- Issue 49731 - Fix additional issues with setting db home directory by default
-- Issue 50337 - Replace exec() with setattr()
-- Issue 50905 - intermittent SSL hang with rhds
-- Issue 50952 - SSCA lacks basicConstraint:CA
-- Issue 50640 - Database links: get_monitor() takes 1 positional argument but 2 were given
-- Issue 50869 - Setting nsslapd-allowed-sasl-mechanisms truncates the value
-
-* Wed Apr 1 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.5-1
-- Bump version to 1.4.3.5
-- Issue 50994 - Fix latest UI bugs found by QE
-- Issue 50933 - rfc2307compat.ldif
-- Issue 50337 - Replace exec() with setattr()
-- Issue 50984 - Memory leaks in disk monitoring
-- Issue 50984 - Memory leaks in disk monitoring
-- Issue 49731 - dscreate fails in silent mode because of db_home_dir
-- Issue 50975 - Revise UI branding with new minimized build
-- Issue 49437 - Fix memory leak with indirect COS
-- Issue 49731 - Do not add db_home_dir to template-dse.ldif
-- Issue 49731 - set and use db_home_directory by default
-- Issue 50971 - fix BSD_SOURCE
-- Issue 50744 - -n option of dbverify does not work
-- Issue 50952 - SSCA lacks basicConstraint:CA
-- Issue 50976 - Clean up Web UI source directory from unused files
-- Issue 50955 - Fix memory leaks in chaining plugin(part 2)
-- Issue 50966 - UI - Database indexes not using typeAhead correctly
-- Issue 50974 - UI - wrong title in "Delete Suffix" popup
-- Issue 50972 - Fix cockpit plugin build
-- Issue 49761 - Fix CI test suite issues
-- Issue 50971 - Support building on FreeBSD.
-- Issue 50960 - [RFE] Advance options in RHDS Disk Monitoring Framework
-- Issue 50800 - wildcards in rootdn-allow-ip attribute are not accepted
-- Issue 50963 - We should bundle *.min.js files of Console
-- Issue 50860 - Port Password Policy test cases from TET to python3 Password grace limit section.
-- Issue 50860 - Port Password Policy test cases from TET to python3 series of bugs Port final
-- Issue 50954 - buildnum.py - fix date formatting issue
-
-* Mon Mar 16 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.4-1
-- Bump version to 1.4.3.4
-- Issue 50954 - Port buildnum.pl to python(part 2)
-- Issue 50955 - Fix memory leaks in chaining plugin
-- Issue 50954 - Port buildnum.pl to python
-- Issue 50947 - change 00core.ldif objectClasses for openldap migration
-- Issue 50755 - setting nsslapd-db-home-directory is overriding db_directory
-- Issue 50937 - Update CLI for new backend split configuration
-- Issue 50860 - Port Password Policy test cases from TET to python3 pwp.sh
-- Issue 50945 - givenname alias of gn from openldap
-- Issue 50935 - systemd override in lib389 for dscontainer
-- Issue 50499 - Fix npm audit issues
-- Issue 49761 - Fix CI test suite issues
-- Issue 50618 - clean compiler warning and log level
-- Issue 50889 - fix compiler issues
-- Issue 50884 - Health check tool DSEldif check fails
-- Issue 50926 - Remove dual spinner and other UI fixes
-- Issue 50928 - Unable to create a suffix with countryName
-- Issue 50758 - Only Recommend bash-completion, not Require
-- Issue 50923 - Fix a test regression
-- Issue 50904 - Connect All React Components And Refactor the Main Navigation Tab Code
-- Issue 50920 - cl-dump exit code is 0 even if command fails with invalid arguments
-- Issue 50923 - Add test - dsctl fails to remove instances with dashes in the name
-- Issue 50919 - Backend delete fails using dsconf
-- Issue 50872 - dsconf can't create GSSAPI replication agreements
-- Issue 50912 - RFE - add password policy attribute pwdReset
-- Issue 50914 - No error returned when adding an entry matching filters for a non existing automember group
-- Issue 50889 - Extract pem files into a private namespace
-- Issue 50909 - nsDS5ReplicaId cant be set to the old value it had before
-- Issue 50686 - Port fractional replication test cases from TET to python3 final
-- Issue 49845 - Remove pkgconfig check for libasan
-- Issue:50860 - Port Password Policy test cases from TET to python3 bug624080
-- Issue:50860 - Port Password Policy test cases from TET to python3 series of bugs
-- Issue 50786 - connection table freelist
-- Issue 50618 - support cgroupv2
-- Issue 50900 - Fix cargo offline build
-- Issue 50898 - ldclt core dumped when run with -e genldif option
-
-* Mon Feb 17 2020 Matus Honek <mhonek@redhat.com> - 1.4.3.3-3
-- Bring back the necessary c_rehash util (#1803370)
-
-* Fri Feb 14 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.3-2
-- Bump version to 1.4.3.3-2
-- Remove unneeded perl dependencies
-- Change bash-completion to "Recommends" instead of "Requires"
-
-* Thu Feb 13 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.3-1
-- Bump version to 1.4.3.3
-- Issue 50855 - remove unused file from UI
-- Issue 50855 - UI: Port Server Tab to React
-- Issue 49845 - README does not contain complete information on building
-- Issue 50686 - Port fractional replication test cases from TET to python3 part 1
-- Issue 49623 - cont cenotaph errors on modrdn operations
-- Issue 50882 - Fix healthcheck errors for instances that do not have TLS enabled
-- Issue 50886 - Typo in the replication debug message
-- Issue 50873 - Fix healthcheck and virtual attr check
-- Issue 50873 - Fix issues with healthcheck tool
-- Issue 50028 - Add a new CI test case
-- Issue 49946 - Add a new CI test case
-- Issue 50117 - Add a new CI test case
-- Issue 50787 - fix implementation of attr unique
-- Issue 50859 - support running only with ldaps socket
-- Issue 50823 - dsctl doesn't work with 'slapd-' in the instance name
-- Issue 49624 - cont - DB Deadlock on modrdn appears to corrupt database and entry cache
-- Issue 50867 - Fix minor buildsys issues
-- Issue 50737 - Allow building with rust online without vendoring
-- Issue 50831 - add cargo.lock to allow offline builds
-- Issue 50694 - import PEM certs on startup
-- Issue 50857 - Memory leak in ACI using IP subject
-- Issue 49761 - Fix CI test suite issues
-- Issue 50853 - Fix NULL pointer deref in config setting
-- Issue 50850 - Fix dsctl healthcheck for python36
-- Issue 49990 - Need to enforce a hard maximum limit for file descriptors
-- Issue 48707 - ldapssotoken for authentication
-
-* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.3.2-1.1
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
-
-* Thu Jan 23 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.2-1
-- Bump version to 1.4.3.2
-- Issue 49254 - Fix compiler failures and warnings
-- Issue 50741 - cont bdb_start - Detected Disorderly Shutdown
-- Issue 50836 - Port Schema UI tab to React
-- Issue 50842 - Decrease 389-console Cockpit component size
-- Issue 50790 - Add result text when filter is invalid
-- Issue 50627 - Add ASAN logs to HTML report
-- Issue 50834 - Incorrectly setting the NSS default SSL version max
-- Issue 50829 - Disk monitoring rotated log cleanup causes heap-use-after-free
-- Issue 50709 - (cont) Several memory leaks reported by Valgrind for 389-ds 1.3.9.1-10
-- Issue 50784 - performance testing scripts
-- Issue 50599 - Fix memory leak when removing db region files
-- Issue 49395 - Set the default TLS version min to TLS1.2
-- Issue 50818 - dsconf pwdpolicy get error
-- Issue 50824 - dsctl remove fails with "name 'ensure_str' is not defined"
-- Issue 50599 - Remove db region files prior to db recovery
-- Issue 50812 - dscontainer executable should be placed under /usr/libexec/dirsrv/
-- Issue 50816 - dsconf allows the root password to be set to nothing
-- Issue 50798 - incorrect bytes in format string(fix import issue)
-
-* Thu Jan 16 2020 Adam Williamson <awilliam@redhat.com> - 1.4.3.1-3
-- Backport two more import/missing function fixes
-
-* Wed Jan 15 2020 Adam Williamson <awilliam@redhat.com> - 1.4.3.1-2
-- Backport 828aad0 to fix missing imports from 1.4.3.1
-
-* Mon Jan 13 2020 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.1-1
-- Bump version to 1.4.3.1
-- Issue 50798 - incorrect bytes in format string
-- Issue 50545 - Add the new replication monitor functionality to UI
-- Issue 50806 - Fix minor issues in lib389 health checks
-- Issue 50690 - Port Password Storage test cases from TET to python3 part 1
-- Issue 49761 - Fix CI test suite issues
-- Issue 49761 - Fix CI test suite issues
-- Issue 50754 - Add Restore Change Log option to CLI
-- Issue 48055 - CI test - automember_plugin(part2)
-- Issue 50667 - dsctl -l did not respect PREFIX
-- Issue 50780 - More CLI fixes
-- Issue 50649 - lib389 without defaults.inf
-- Issue 50780 - Fix UI issues
-- Issue 50727 - correct mistaken options in filter validation patch
-- Issue 50779 - lib389 - conflict compare fails for DN's with spaces
-- Set branch version to 1.4.3.0