diff --git a/.389-ds-base.metadata b/.389-ds-base.metadata
index 59b94f6..35477bb 100644
--- a/.389-ds-base.metadata
+++ b/.389-ds-base.metadata
@@ -1 +1 @@
-c995af6f5693f698c29b72ebfdbc0e60a72cc517 SOURCES/389-ds-base-1.3.10.1.tar.bz2
+5ea563775de60788f87373327d90c09ce37a574b SOURCES/389-ds-base-1.3.10.2.tar.bz2
diff --git a/.gitignore b/.gitignore
index a4a9c46..af808cb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/389-ds-base-1.3.10.1.tar.bz2
+SOURCES/389-ds-base-1.3.10.2.tar.bz2
diff --git a/SOURCES/0000-CVE-2019-14824-BZ-1748199-deref-plugin-displays-rest.patch b/SOURCES/0000-CVE-2019-14824-BZ-1748199-deref-plugin-displays-rest.patch
deleted file mode 100644
index 9fd6303..0000000
--- a/SOURCES/0000-CVE-2019-14824-BZ-1748199-deref-plugin-displays-rest.patch
+++ /dev/null
@@ -1,53 +0,0 @@
-From 63fa3ee665b66b36321489c090b24811838837c0 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 3 Sep 2019 13:15:45 -0400
-Subject: [PATCH] CVE-2019-14824 (BZ#1748199) - deref plugin displays
- restricted attributes
-
-Bug Description:  If there is an ACI that allows "search" access to an attribute,
-                  the deref plugin access control checks sees this is a "read"
-                  privilege and returns the attribute's value.
-
-Fix description:  For deref plugin we are only concerned with "read" access, not
-                  "search" access.  Removed the SLAPI_ACL_SEARCH right flag when
-                  checking access for an attribute.
-
-Reviewed by: lkrispen & tbordaz(Thanks!)
----
- ldap/servers/plugins/deref/deref.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/ldap/servers/plugins/deref/deref.c b/ldap/servers/plugins/deref/deref.c
-index cb5ebb830..ec1884ba3 100644
---- a/ldap/servers/plugins/deref/deref.c
-+++ b/ldap/servers/plugins/deref/deref.c
-@@ -573,7 +573,7 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn,
-     Slapi_Entry **entries = NULL;
-     int rc;
- 
--    /*  If the access check on the attributes is done without retrieveing the entry
-+    /*  If the access check on the attributes is done without retrieving the entry
-  *  it cannot handle acis which need teh entry, eg to apply a targetfilter rule
-  *  So the determination of attrs which can be dereferenced is delayed
-  */
-@@ -596,7 +596,7 @@ deref_do_deref_attr(Slapi_PBlock *pb, BerElement *ctrlber, const char *derefdn,
-                 int ii;
-                 int needattrvals = 1; /* need attrvals sequence? */
-                 if (deref_check_access(pb, entries[0], derefdn, attrs, &retattrs,
--                                       (SLAPI_ACL_SEARCH | SLAPI_ACL_READ))) {
-+                                       SLAPI_ACL_READ)) {
-                     slapi_log_err(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM,
-                                   "deref_do_deref_attr - The client does not have permission to read the requested "
-                                   "attributes in entry %s\n",
-@@ -714,7 +714,7 @@ deref_pre_entry(Slapi_PBlock *pb)
-         attrs[1] = NULL;
- 
-         if (deref_check_access(pb, ent, NULL, attrs, &retattrs,
--                               (SLAPI_ACL_SEARCH | SLAPI_ACL_READ))) {
-+                               SLAPI_ACL_READ)) {
-             slapi_log_err(SLAPI_LOG_PLUGIN, DEREF_PLUGIN_SUBSYSTEM,
-                           "deref_pre_entry - The client does not have permission to read attribute %s in entry %s\n",
-                           spec->derefattr, slapi_entry_get_dn_const(ent));
--- 
-2.21.0
-
diff --git a/SOURCES/0000-Issue-50800-wildcards-in-rootdn-allow-ip-attribute-a.patch b/SOURCES/0000-Issue-50800-wildcards-in-rootdn-allow-ip-attribute-a.patch
new file mode 100644
index 0000000..6ffbe56
--- /dev/null
+++ b/SOURCES/0000-Issue-50800-wildcards-in-rootdn-allow-ip-attribute-a.patch
@@ -0,0 +1,491 @@
+From 6ced3f552e4c29f588eb3a56def5a485c2e89a73 Mon Sep 17 00:00:00 2001
+From: Mark Reynolds <mreynolds@redhat.com>
+Date: Thu, 19 Mar 2020 21:24:05 -0400
+Subject: [PATCH 1/4] Issue 50800 - wildcards in rootdn-allow-ip attribute are
+ not accepted
+
+Description:  The asterick character was missing from the allowed character list.
+              Also cleaned up the source in the C file.
+
+              Thanks @yrro for contributing the original patch!
+
+relates: https://pagure.io/389-ds-base/issue/50800
+
+Reviewed by: firstyear (Thanks!)
+---
+ .../suites/plugins/rootdn_plugin_test.py      |  73 ++++++++++-
+ .../plugins/rootdn_access/rootdn_access.c     | 119 ++++++++++--------
+ 2 files changed, 137 insertions(+), 55 deletions(-)
+
+diff --git a/dirsrvtests/tests/suites/plugins/rootdn_plugin_test.py b/dirsrvtests/tests/suites/plugins/rootdn_plugin_test.py
+index af5c4c4d4..a54fd8efc 100644
+--- a/dirsrvtests/tests/suites/plugins/rootdn_plugin_test.py
++++ b/dirsrvtests/tests/suites/plugins/rootdn_plugin_test.py
+@@ -13,7 +13,6 @@ import pytest
+ from lib389.tasks import *
+ from lib389.tools import DirSrvTools
+ from lib389.topologies import topology_st
+-
+ from lib389._constants import PLUGIN_ROOTDN_ACCESS, DN_CONFIG, DEFAULT_SUFFIX, DN_DM, PASSWORD
+ 
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
+@@ -439,6 +438,7 @@ def test_rootdn_access_allowed_ip(topology_st):
+         log.fatal('test_rootdn_access_allowed_ip: Root DN was incorrectly able to bind')
+         assert False
+ 
++
+     #
+     # Allow localhost
+     #
+@@ -745,6 +745,77 @@ def test_rootdn_config_validate(topology_st):
+     log.info('test_rootdn_config_validate: PASSED')
+ 
+ 
++def test_rootdn_access_denied_ip_wildcard(topology_st, rootdn_setup, rootdn_cleanup):
++    """Test denied IP feature with a wildcard
++
++    :id: 73c74f62-9ac2-4bb6-8a63-bacc8d8bbf93
++    :setup: Standalone instance, rootdn plugin set up
++    :steps:
++        1. Set rootdn-deny-ip to '127.*'
++        2. Bind as Root DN
++        3. Change the denied IP so root DN succeeds
++        4. Bind as Root DN
++    :expectedresults:
++        1. Success
++        2. Should fail
++        3. Success
++        4. Success
++    """
++
++    log.info('Running test_rootdn_access_denied_ip_wildcard...')
++
++    plugin.add_deny_ip('127.*')
++    time.sleep(.5)
++
++    # Bind as root DN - should fail
++    uri = 'ldap://{}:{}'.format('127.0.0.1', topology_st.standalone.port)
++    with pytest.raises(ldap.UNWILLING_TO_PERFORM):
++        rootdn_bind(topology_st.standalone, uri=uri)
++
++    # Change the denied IP so root DN succeeds
++    plugin.apply_mods([(ldap.MOD_REPLACE, 'rootdn-deny-ip', '255.255.255.255')])
++    time.sleep(.5)
++
++    # Bind should succeed
++    rootdn_bind(topology_st.standalone, uri=uri)
++
++
++def test_rootdn_access_allowed_ip_wildcard(topology_st, rootdn_setup, rootdn_cleanup):
++    """Test allowed ip feature
++
++    :id: c3e22c61-9ed2-4e89-8243-6ff686ecad9b
++    :setup: Standalone instance, rootdn plugin set up
++    :steps:
++        1. Set allowed ip to 255.255.255.255 - blocks the Root DN
++        2. Bind as Root DN
++        3. Allow 127.*
++        4. Bind as Root DN
++    :expectedresults:
++        1. Success
++        2. Should fail
++        3. Success
++        4. Success
++    """
++
++    log.info('Running test_rootdn_access_allowed_ip...')
++
++    # Set allowed ip to 255.255.255.255 - blocks the Root DN
++    plugin.add_allow_ip('255.255.255.255')
++    time.sleep(.5)
++
++    # Bind as Root DN - should fail
++    uri = 'ldap://{}:{}'.format("127.0.0.1", topology_st.standalone.port)
++    with pytest.raises(ldap.UNWILLING_TO_PERFORM):
++        rootdn_bind(topology_st.standalone, uri=uri)
++
++    # Allow localhost
++    plugin.add_allow_ip('127.*')
++    time.sleep(.5)
++
++    # Bind should succeed
++    rootdn_bind(topology_st.standalone, uri=uri)
++
++
+ if __name__ == '__main__':
+     # Run isolated
+     # -s for DEBUG mode
+diff --git a/ldap/servers/plugins/rootdn_access/rootdn_access.c b/ldap/servers/plugins/rootdn_access/rootdn_access.c
+index 1cb999792..aba44ce72 100644
+--- a/ldap/servers/plugins/rootdn_access/rootdn_access.c
++++ b/ldap/servers/plugins/rootdn_access/rootdn_access.c
+@@ -48,14 +48,14 @@
+ /*
+  *  Plugin Functions
+  */
+-int rootdn_init(Slapi_PBlock *pb);
+-static int rootdn_start(Slapi_PBlock *pb);
+-static int rootdn_close(Slapi_PBlock *pb);
+-static int rootdn_load_config(Slapi_PBlock *pb);
+-static int rootdn_check_access(Slapi_PBlock *pb);
+-static int rootdn_check_host_wildcard(char *host, char *client_host);
++int32_t rootdn_init(Slapi_PBlock *pb);
++static int32_t rootdn_start(Slapi_PBlock *pb);
++static int32_t rootdn_close(Slapi_PBlock *pb);
++static int32_t rootdn_load_config(Slapi_PBlock *pb);
++static int32_t rootdn_check_access(Slapi_PBlock *pb);
++static int32_t rootdn_check_host_wildcard(char *host, char *client_host);
+ static int rootdn_check_ip_wildcard(char *ip, char *client_ip);
+-static int rootdn_preop_bind_init(Slapi_PBlock *pb);
++static int32_t rootdn_preop_bind_init(Slapi_PBlock *pb);
+ char *strToLower(char *str);
+ 
+ /*
+@@ -104,10 +104,10 @@ rootdn_get_plugin_dn(void)
+ }
+ 
+ 
+-int
++int32_t
+ rootdn_init(Slapi_PBlock *pb)
+ {
+-    int status = 0;
++    int32_t status = 0;
+     char *plugin_identity = NULL;
+ 
+     slapi_log_err(SLAPI_LOG_TRACE, ROOTDN_PLUGIN_SUBSYSTEM,
+@@ -157,7 +157,7 @@ rootdn_init(Slapi_PBlock *pb)
+     return status;
+ }
+ 
+-static int
++static int32_t
+ rootdn_preop_bind_init(Slapi_PBlock *pb)
+ {
+     if (slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_PRE_BIND_FN, (void *)rootdn_check_access) != 0) {
+@@ -169,7 +169,7 @@ rootdn_preop_bind_init(Slapi_PBlock *pb)
+     return 0;
+ }
+ 
+-static int
++static int32_t
+ rootdn_start(Slapi_PBlock *pb __attribute__((unused)))
+ {
+     slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "--> rootdn_start\n");
+@@ -196,14 +196,14 @@ rootdn_free(void)
+     ips_to_deny = NULL;
+ }
+ 
+-static int
++static int32_t
+ rootdn_close(Slapi_PBlock *pb __attribute__((unused)))
+ {
+     rootdn_free();
+     return 0;
+ }
+ 
+-static int
++static int32_t
+ rootdn_load_config(Slapi_PBlock *pb)
+ {
+     Slapi_Entry *e = NULL;
+@@ -217,9 +217,9 @@ rootdn_load_config(Slapi_PBlock *pb)
+     char *token, *iter = NULL, *copy;
+     char hour[3], min[3];
+     size_t end;
+-    int result = 0;
+-    int time;
+-    int i;
++    int32_t result = 0;
++    int32_t time;
++
+ 
+     slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "--> rootdn_load_config\n");
+ 
+@@ -346,7 +346,7 @@ rootdn_load_config(Slapi_PBlock *pb)
+             goto free_and_return;
+         }
+         if (hosts_tmp) {
+-            for (i = 0; hosts_tmp[i] != NULL; i++) {
++            for (size_t i = 0; hosts_tmp[i] != NULL; i++) {
+                 end = strspn(hosts_tmp[i], "0123456789.*-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
+                 if (!end || hosts_tmp[i][end] != '\0') {
+                     slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config - "
+@@ -359,7 +359,7 @@ rootdn_load_config(Slapi_PBlock *pb)
+             }
+         }
+         if (hosts_to_deny_tmp) {
+-            for (i = 0; hosts_to_deny_tmp[i] != NULL; i++) {
++            for (size_t i = 0; hosts_to_deny_tmp[i] != NULL; i++) {
+                 end = strspn(hosts_to_deny_tmp[i], "0123456789.*-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
+                 if (!end || hosts_to_deny_tmp[i][end] != '\0') {
+                     slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config - "
+@@ -372,8 +372,8 @@ rootdn_load_config(Slapi_PBlock *pb)
+             }
+         }
+         if (ips_tmp) {
+-            for (i = 0; ips_tmp[i] != NULL; i++) {
+-                end = strspn(ips_tmp[i], "0123456789:ABCDEFabcdef.");
++            for (size_t i = 0; ips_tmp[i] != NULL; i++) {
++                end = strspn(ips_tmp[i], "0123456789:ABCDEFabcdef.*");
+                 if (!end || ips_tmp[i][end] != '\0') {
+                     slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config - "
+                                                                           "IP address contains invalid characters (%s), skipping\n",
+@@ -399,7 +399,7 @@ rootdn_load_config(Slapi_PBlock *pb)
+             }
+         }
+         if (ips_to_deny_tmp) {
+-            for (i = 0; ips_to_deny_tmp[i] != NULL; i++) {
++            for (size_t i = 0; ips_to_deny_tmp[i] != NULL; i++) {
+                 end = strspn(ips_to_deny_tmp[i], "0123456789:ABCDEFabcdef.*");
+                 if (!end || ips_to_deny_tmp[i][end] != '\0') {
+                     slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_load_config - "
+@@ -453,7 +453,7 @@ free_and_return:
+ }
+ 
+ 
+-static int
++static int32_t
+ rootdn_check_access(Slapi_PBlock *pb)
+ {
+     PRNetAddr *client_addr = NULL;
+@@ -461,9 +461,8 @@ rootdn_check_access(Slapi_PBlock *pb)
+     time_t curr_time;
+     struct tm *timeinfo = NULL;
+     char *dnsName = NULL;
+-    int isRoot = 0;
+-    int rc = SLAPI_PLUGIN_SUCCESS;
+-    int i;
++    int32_t isRoot = 0;
++    int32_t rc = SLAPI_PLUGIN_SUCCESS;
+ 
+     /*
+      *  Verify this is a root DN
+@@ -493,8 +492,8 @@ rootdn_check_access(Slapi_PBlock *pb)
+         curr_total = (time_t)(timeinfo->tm_hour * 3600) + (timeinfo->tm_min * 60);
+ 
+         if ((curr_total < open_time) || (curr_total >= close_time)) {
+-            slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - Bind not in the "
+-                                                                     "allowed time window\n");
++            slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                    "rootdn_check_access - Bind not in the allowed time window\n");
+             return -1;
+         }
+     }
+@@ -512,8 +511,8 @@ rootdn_check_access(Slapi_PBlock *pb)
+         daysAllowed = strToLower(daysAllowed);
+ 
+         if (!strstr(daysAllowed, today)) {
+-            slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
+-                                                                     "Bind not allowed for today(%s), only allowed on days: %s\n",
++            slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
++                          "Bind not allowed for today(%s), only allowed on days: %s\n",
+                           today, daysAllowed);
+             return -1;
+         }
+@@ -522,7 +521,7 @@ rootdn_check_access(Slapi_PBlock *pb)
+      *  Check the host restrictions, deny always overrides allow
+      */
+     if (hosts || hosts_to_deny) {
+-        char buf[PR_NETDB_BUF_SIZE];
++        char buf[PR_NETDB_BUF_SIZE] = {0};
+         char *host;
+ 
+         /*
+@@ -530,8 +529,8 @@ rootdn_check_access(Slapi_PBlock *pb)
+          */
+         client_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
+         if (slapi_pblock_get(pb, SLAPI_CONN_CLIENTNETADDR, client_addr) != 0) {
+-            slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
+-                                                                  "Could not get client address for hosts.\n");
++            slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                    "rootdn_check_access - Could not get client address for hosts.\n");
+             rc = -1;
+             goto free_and_return;
+         }
+@@ -545,14 +544,14 @@ rootdn_check_access(Slapi_PBlock *pb)
+                 dnsName = slapi_ch_strdup(host_entry->h_name);
+             } else {
+                 /* no hostname */
+-                slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
+-                                                                         "Client address missing hostname\n");
++                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                        "rootdn_check_access - Client address missing hostname\n");
+                 rc = -1;
+                 goto free_and_return;
+             }
+         } else {
+-            slapi_log_err(SLAPI_LOG_PLUGIN, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
+-                                                                     "client IP address could not be resolved\n");
++            slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                    "rootdn_check_access - client IP address could not be resolved\n");
+             rc = -1;
+             goto free_and_return;
+         }
+@@ -560,18 +559,22 @@ rootdn_check_access(Slapi_PBlock *pb)
+          *  Now we have our hostname, now do our checks
+          */
+         if (hosts_to_deny) {
+-            for (i = 0; hosts_to_deny[i] != NULL; i++) {
++            for (size_t i = 0; hosts_to_deny[i] != NULL; i++) {
+                 host = hosts_to_deny[i];
+                 /* check for wild cards */
+                 if (host[0] == '*') {
+                     if (rootdn_check_host_wildcard(host, dnsName) == 0) {
+                         /* match, return failure */
++                        slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
++                             "hostname (%s) matched denied host (%s)\n", dnsName, host);
+                         rc = -1;
+                         goto free_and_return;
+                     }
+                 } else {
+                     if (strcasecmp(host, dnsName) == 0) {
+                         /* we have a match, return failure */
++                        slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
++                             "hostname (%s) matched denied host (%s)\n", dnsName, host);
+                         rc = -1;
+                         goto free_and_return;
+                     }
+@@ -580,7 +583,7 @@ rootdn_check_access(Slapi_PBlock *pb)
+             rc = 0;
+         }
+         if (hosts) {
+-            for (i = 0; hosts[i] != NULL; i++) {
++            for (size_t i = 0; hosts[i] != NULL; i++) {
+                 host = hosts[i];
+                 /* check for wild cards */
+                 if (host[0] == '*') {
+@@ -604,14 +607,15 @@ rootdn_check_access(Slapi_PBlock *pb)
+      *  Check the IP address restrictions, deny always overrides allow
+      */
+     if (ips || ips_to_deny) {
+-        char ip_str[256];
++        char ip_str[256] = {0};
+         char *ip;
+-        int ip_len, i;
++        int32_t ip_len;
+ 
+         if (client_addr == NULL) {
+             client_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
+             if (slapi_pblock_get(pb, SLAPI_CONN_CLIENTNETADDR, client_addr) != 0) {
+-                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - Could not get client address for IP.\n");
++                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                        "rootdn_check_access - Could not get client address for IP.\n");
+                 rc = -1;
+                 goto free_and_return;
+             }
+@@ -624,13 +628,15 @@ rootdn_check_access(Slapi_PBlock *pb)
+             v4addr.inet.family = PR_AF_INET;
+             v4addr.inet.ip = client_addr->ipv6.ip.pr_s6_addr32[3];
+             if (PR_NetAddrToString(&v4addr, ip_str, sizeof(ip_str)) != PR_SUCCESS) {
+-                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - Could not get IPv4 from client address.\n");
++                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                        "rootdn_check_access - Could not get IPv4 from client address.\n");
+                 rc = -1;
+                 goto free_and_return;
+             }
+         } else {
+             if (PR_NetAddrToString(client_addr, ip_str, sizeof(ip_str)) != PR_SUCCESS) {
+-                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - Could not get IPv6 from client address.\n");
++                slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM,
++                        "rootdn_check_access - Could not get IPv6 from client address.\n");
+                 rc = -1;
+                 goto free_and_return;
+             }
+@@ -639,18 +645,22 @@ rootdn_check_access(Slapi_PBlock *pb)
+          *  Now we have our IP address, do our checks
+          */
+         if (ips_to_deny) {
+-            for (i = 0; ips_to_deny[i] != NULL; i++) {
++            for (size_t i = 0; ips_to_deny[i] != NULL; i++) {
+                 ip = ips_to_deny[i];
+                 ip_len = strlen(ip);
+                 if (ip[ip_len - 1] == '*') {
+                     if (rootdn_check_ip_wildcard(ips_to_deny[i], ip_str) == 0) {
+                         /* match, return failure */
++                        slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
++                             "ip address (%s) matched denied IP address (%s)\n", ip_str, ip);
+                         rc = -1;
+                         goto free_and_return;
+                     }
+                 } else {
+                     if (strcasecmp(ip_str, ip) == 0) {
+                         /* match, return failure */
++                        slapi_log_err(SLAPI_LOG_ERR, ROOTDN_PLUGIN_SUBSYSTEM, "rootdn_check_access - "
++                             "ip address (%s) matched denied IP address (%s)\n", ip_str, ip);
+                         rc = -1;
+                         goto free_and_return;
+                     }
+@@ -659,7 +669,7 @@ rootdn_check_access(Slapi_PBlock *pb)
+             rc = 0;
+         }
+         if (ips) {
+-            for (i = 0; ips[i] != NULL; i++) {
++            for (size_t i = 0; ips[i] != NULL; i++) {
+                 ip = ips[i];
+                 ip_len = strlen(ip);
+                 if (ip[ip_len - 1] == '*') {
+@@ -668,6 +678,7 @@ rootdn_check_access(Slapi_PBlock *pb)
+                         rc = 0;
+                         goto free_and_return;
+                     }
++
+                 } else {
+                     if (strcasecmp(ip_str, ip) == 0) {
+                         /* match, return success */
+@@ -688,17 +699,19 @@ free_and_return:
+     return rc;
+ }
+ 
+-static int
++static int32_t
+ rootdn_check_host_wildcard(char *host, char *client_host)
+ {
+-    int host_len = strlen(host);
+-    int client_len = strlen(client_host);
+-    int i, j;
++    size_t host_len = strlen(host);
++    size_t client_len = strlen(client_host);
++    size_t i, j;
++
+     /*
+      *  Start at the end of the string and move backwards, and skip the first char "*"
+      */
+     if (client_len < host_len) {
+         /* this can't be a match */
++
+         return -1;
+     }
+     for (i = host_len - 1, j = client_len - 1; i > 0; i--, j--) {
+@@ -714,7 +727,7 @@ static int
+ rootdn_check_ip_wildcard(char *ip, char *client_ip)
+ {
+     size_t ip_len = strlen(ip);
+-    int i;
++
+     /*
+      *  Start at the beginning of the string and move forward, and skip the last char "*"
+      */
+@@ -722,7 +735,7 @@ rootdn_check_ip_wildcard(char *ip, char *client_ip)
+         /* this can't be a match */
+         return -1;
+     }
+-    for (i = 0; i < ip_len - 1; i++) {
++    for (size_t i = 0; i < ip_len - 1; i++) {
+         if (ip[i] != client_ip[i]) {
+             return -1;
+         }
+@@ -734,9 +747,7 @@ rootdn_check_ip_wildcard(char *ip, char *client_ip)
+ char *
+ strToLower(char *str)
+ {
+-    size_t i;
+-
+-    for (i = 0; str && i < strlen(str); i++) {
++    for (size_t i = 0; str && i < strlen(str); i++) {
+         str[i] = tolower(str[i]);
+     }
+     return str;
+-- 
+2.25.3
+
diff --git a/SOURCES/0001-Issue-49437-Fix-memory-leak-with-indirect-COS.patch b/SOURCES/0001-Issue-49437-Fix-memory-leak-with-indirect-COS.patch
new file mode 100644
index 0000000..0045b9e
--- /dev/null
+++ b/SOURCES/0001-Issue-49437-Fix-memory-leak-with-indirect-COS.patch
@@ -0,0 +1,107 @@
+From 3a8d5bc4dce01fb800c93434181060afe9287546 Mon Sep 17 00:00:00 2001
+From: Mark Reynolds <mreynolds@redhat.com>
+Date: Wed, 25 Mar 2020 16:55:34 -0400
+Subject: [PATCH 2/4] Issue 49437 - Fix memory leak with indirect COS
+
+Bug Description:  There are two leaks when dealing with indirect COS. The
+                  first leak is caused by the COS cache entry's objectclass
+                  list not being freed when the entry is removed from the
+                  hash table.
+
+                  The other leak is caused when we follow an indirect pointer
+                  COS and do not free a tmp value set that goes unused.
+
+Fix description:  Free the COS entry objectclass list when removing an entry
+                  from the hash table.  When querying a COS attribute and the
+                  returned attribute (out_attr) is NULL, then free the unused
+                  tmp_val ValueSet as it's not consumed by anything.
+
+Fixes: https://pagure.io/389-ds-base/issue/49437
+
+Reviewed by: firstyear & tbordaz(Thanks!)
+---
+ ldap/servers/plugins/cos/cos_cache.c |  3 +++
+ ldap/servers/slapd/vattr.c           | 39 +++++++++++++++-------------
+ 2 files changed, 24 insertions(+), 18 deletions(-)
+
+diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
+index 64c0441c4..eb9bd77f9 100644
+--- a/ldap/servers/plugins/cos/cos_cache.c
++++ b/ldap/servers/plugins/cos/cos_cache.c
+@@ -2372,6 +2372,9 @@ cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Slapi_Entry *
+                                             *out_attr = tmp_vals;
+                                             tmp_vals = NULL;
+                                         }
++                                    } else if (out_attr == NULL && tmp_vals) {
++                                        slapi_valueset_free(tmp_vals);
++                                        tmp_vals = NULL;
+                                     }
+                                 }
+ 
+diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
+index 852a887ce..d8b2c835a 100644
+--- a/ldap/servers/slapd/vattr.c
++++ b/ldap/servers/slapd/vattr.c
+@@ -2004,6 +2004,24 @@ vattr_map_create(void)
+     return 0;
+ }
+ 
++/*
++    vattr_delete_attrvals
++    ---------------------
++    deletes a value list
++*/
++void
++vattr_delete_attrvals(objAttrValue **attrval)
++{
++    objAttrValue *val = *attrval;
++
++    while (val) {
++        objAttrValue *next = val->pNext;
++        slapi_value_free(&val->val);
++        slapi_ch_free((void **)&val);
++        val = next;
++    }
++}
++
+ void
+ vattr_map_entry_free(vattr_map_entry *vae)
+ {
+@@ -2016,6 +2034,9 @@ vattr_map_entry_free(vattr_map_entry *vae)
+         }
+         list_entry = next_entry;
+     }
++    if (vae->objectclasses) {
++        vattr_delete_attrvals(&(vae->objectclasses));
++    }
+     slapi_ch_free_string(&(vae->type_name));
+     slapi_ch_free((void **)&vae);
+ }
+@@ -2102,24 +2123,6 @@ vattr_map_insert(vattr_map_entry *vae)
+     return 0;
+ }
+ 
+-/*
+-    vattr_delete_attrvals
+-    ---------------------
+-    deletes a value list
+-*/
+-void
+-vattr_delete_attrvals(objAttrValue **attrval)
+-{
+-    objAttrValue *val = *attrval;
+-
+-    while (val) {
+-        objAttrValue *next = val->pNext;
+-        slapi_value_free(&val->val);
+-        slapi_ch_free((void **)&val);
+-        val = next;
+-    }
+-}
+-
+ /*
+     vattr_add_attrval
+     -----------------
+-- 
+2.25.3
+
diff --git a/SOURCES/0001-Issue-50525-nsslapd-defaultnamingcontext-does-not-ch.patch b/SOURCES/0001-Issue-50525-nsslapd-defaultnamingcontext-does-not-ch.patch
deleted file mode 100644
index 7fb1a01..0000000
--- a/SOURCES/0001-Issue-50525-nsslapd-defaultnamingcontext-does-not-ch.patch
+++ /dev/null
@@ -1,250 +0,0 @@
-From d33743c8604ff4f97947dad14fddab0691e3d19e Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Thu, 1 Aug 2019 16:50:34 -0400
-Subject: [PATCH] Issue 50525 - nsslapd-defaultnamingcontext does not change
- when the assigned suffix gets deleted
-
-Bug Description:
-
-If you delete the suffix that is set as the default naming context, the attribute
-is not reset.
-
-Also using dsconf to delete a backend/suffix fails if there are vlv indexes, encrypted
-attributes, or replication is configured.
-
-Fix Description:
-
-As for the default naming context, if there is a second suffix configured, it will be
-automatically set as the new default naming context, otherwise the attribute is not
-modified.
-
-For dsconf backend delete issue, it now checks and removes replication configuration
-and agreements, and removes all the child entries under the backend entry.
-
-relates: https://pagure.io/389-ds-base/issue/50525
-
-Reviewed by: spichugi(Thanks!)
----
- .../be_del_and_default_naming_attr_test.py    | 90 +++++++++++++++++++
- ldap/servers/slapd/mapping_tree.c             | 50 ++++++-----
- src/lib389/lib389/backend.py                  | 17 ++--
- src/lib389/lib389/replica.py                  |  2 +-
- 4 files changed, 132 insertions(+), 27 deletions(-)
- create mode 100644 dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py
-
-diff --git a/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py b/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py
-new file mode 100644
-index 000000000..34a2de2ad
---- /dev/null
-+++ b/dirsrvtests/tests/suites/mapping_tree/be_del_and_default_naming_attr_test.py
-@@ -0,0 +1,90 @@
-+import logging
-+import pytest
-+import os
-+from lib389._constants import DEFAULT_SUFFIX
-+from lib389.topologies import topology_m1 as topo
-+from lib389.backend import Backends
-+from lib389.encrypted_attributes import EncryptedAttrs
-+
-+DEBUGGING = os.getenv("DEBUGGING", default=False)
-+if DEBUGGING:
-+    logging.getLogger(__name__).setLevel(logging.DEBUG)
-+else:
-+    logging.getLogger(__name__).setLevel(logging.INFO)
-+log = logging.getLogger(__name__)
-+
-+SECOND_SUFFIX = 'o=namingcontext'
-+THIRD_SUFFIX = 'o=namingcontext2'
-+
-+def test_be_delete(topo):
-+    """Test that we can delete a backend that contains replication
-+    configuration and encrypted attributes.  The default naming 
-+    context should also be updated to reflect the next available suffix
-+
-+    :id: 5208f897-7c95-4925-bad0-9ceb95fee678
-+    :setup: Master Instance
-+    :steps:
-+        1. Create second backend/suffix
-+        2. Add an encrypted attribute to the default suffix
-+        2. Delete default suffix
-+        3. Check the nsslapd-defaultnamingcontext is updated
-+        4. Delete the last backend
-+        5. Check the namingcontext has not changed
-+        6. Add new backend
-+        7. Set default naming context
-+        8. Verify the naming context is correct
-+    :expectedresults:
-+        1. Success
-+        2. Success
-+        3. Success
-+        4. Success
-+        5. Success
-+        6. Success
-+        7. Success
-+        8. Success
-+    """
-+    
-+    inst = topo.ms["master1"] 
-+    
-+    # Create second suffix      
-+    backends = Backends(inst)
-+    default_backend = backends.get(DEFAULT_SUFFIX)
-+    new_backend = backends.create(properties={'nsslapd-suffix': SECOND_SUFFIX,
-+                                              'name': 'namingRoot'})
-+  
-+    # Add encrypted attribute entry under default suffix
-+    encrypt_attrs = EncryptedAttrs(inst, basedn='cn=encrypted attributes,{}'.format(default_backend.dn))
-+    encrypt_attrs.create(properties={'cn': 'employeeNumber', 'nsEncryptionAlgorithm': 'AES'})
-+    
-+    # Delete default suffix
-+    default_backend.delete()
-+    
-+    # Check that the default naming context is set to the new/second suffix
-+    default_naming_ctx = inst.config.get_attr_val_utf8('nsslapd-defaultnamingcontext')
-+    assert default_naming_ctx == SECOND_SUFFIX
-+
-+    # delete new backend, but the naming context should not change
-+    new_backend.delete()
-+
-+    # Check that the default naming context is still set to the new/second suffix
-+    default_naming_ctx = inst.config.get_attr_val_utf8('nsslapd-defaultnamingcontext')
-+    assert default_naming_ctx == SECOND_SUFFIX
-+
-+    # Add new backend
-+    new_backend = backends.create(properties={'nsslapd-suffix': THIRD_SUFFIX,
-+                                              'name': 'namingRoot2'})
-+
-+    # manaully set naming context
-+    inst.config.set('nsslapd-defaultnamingcontext', THIRD_SUFFIX)
-+
-+    # Verify naming context is correct
-+    default_naming_ctx = inst.config.get_attr_val_utf8('nsslapd-defaultnamingcontext')
-+    assert default_naming_ctx == THIRD_SUFFIX
-+
-+
-+if __name__ == '__main__':
-+    # Run isolated
-+    # -s for DEBUG mode
-+    CURRENT_FILE = os.path.realpath(__file__)
-+    pytest.main(["-s", CURRENT_FILE])
-+
-diff --git a/ldap/servers/slapd/mapping_tree.c b/ldap/servers/slapd/mapping_tree.c
-index 834949a67..25e9fb80c 100644
---- a/ldap/servers/slapd/mapping_tree.c
-+++ b/ldap/servers/slapd/mapping_tree.c
-@@ -1521,26 +1521,36 @@ done:
-                 strcpy_unescape_value(escaped, suffix);
-             }
-             if (escaped && (0 == strcasecmp(escaped, default_naming_context))) {
--                int rc = _mtn_update_config_param(LDAP_MOD_DELETE,
--                                                  CONFIG_DEFAULT_NAMING_CONTEXT,
--                                                  NULL);
--                if (rc) {
--                    slapi_log_err(SLAPI_LOG_ERR,
--                                  "mapping_tree_entry_delete_callback",
--                                  "deleting config param %s failed: RC=%d\n",
--                                  CONFIG_DEFAULT_NAMING_CONTEXT, rc);
--                }
--                if (LDAP_SUCCESS == rc) {
--                    char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE] = {0};
--                    /* Removing defaultNamingContext from cn=config entry
--                     * was successful.  The remove does not reset the
--                     * global parameter.  We need to reset it separately. */
--                    if (config_set_default_naming_context(
--                            CONFIG_DEFAULT_NAMING_CONTEXT,
--                            NULL, errorbuf, CONFIG_APPLY)) {
--                        slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_delete_callback",
--                                      "Setting NULL to %s failed. %s\n",
--                                      CONFIG_DEFAULT_NAMING_CONTEXT, errorbuf);
-+                /*
-+                 * We can not delete the default naming attribute, so instead
-+                 * replace it only if there is another suffix available
-+                 */
-+                void *node = NULL;
-+                Slapi_DN *sdn;
-+                sdn = slapi_get_first_suffix(&node, 0);
-+                if (sdn) {
-+                    char *replacement_suffix = (char *)slapi_sdn_get_dn(sdn);
-+                    int rc = _mtn_update_config_param(LDAP_MOD_REPLACE,
-+                                                      CONFIG_DEFAULT_NAMING_CONTEXT,
-+                                                      replacement_suffix);
-+                    if (rc) {
-+                        slapi_log_err(SLAPI_LOG_ERR,
-+                                      "mapping_tree_entry_delete_callback",
-+                                      "replacing config param %s failed: RC=%d\n",
-+                                      CONFIG_DEFAULT_NAMING_CONTEXT, rc);
-+                    }
-+                    if (LDAP_SUCCESS == rc) {
-+                        char errorbuf[SLAPI_DSE_RETURNTEXT_SIZE] = {0};
-+                        /* Replacing defaultNamingContext from cn=config entry
-+                         * was successful.  The replace does not reset the
-+                         * global parameter.  We need to reset it separately. */
-+                        if (config_set_default_naming_context(
-+                                CONFIG_DEFAULT_NAMING_CONTEXT,
-+                                replacement_suffix, errorbuf, CONFIG_APPLY)) {
-+                            slapi_log_err(SLAPI_LOG_ERR, "mapping_tree_entry_delete_callback",
-+                                          "Setting %s tp %s failed. %s\n",
-+                                          CONFIG_DEFAULT_NAMING_CONTEXT, replacement_suffix, errorbuf);
-+                        }
-                     }
-                 }
-             }
-diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
-index 6f4c8694e..4d32038f6 100644
---- a/src/lib389/lib389/backend.py
-+++ b/src/lib389/lib389/backend.py
-@@ -17,6 +17,7 @@ from lib389 import Entry
- from lib389._mapped_object import DSLdapObjects, DSLdapObject
- from lib389.mappingTree import MappingTrees, MappingTree
- from lib389.exceptions import NoSuchEntryError, InvalidArgumentError
-+from lib389.replica import Replicas
- 
- # We need to be a factor to the backend monitor
- from lib389.monitor import MonitorBackend
-@@ -507,20 +508,24 @@ class Backend(DSLdapObject):
-             mt = self._mts.get(selector=bename)
-             # Assert the type is "backend"
-             # Are these the right types....?
--            if mt.get_attr_val('nsslapd-state') != ensure_bytes('backend'):
-+            if mt.get_attr_val('nsslapd-state').lower() != ensure_bytes('backend'):
-                 raise ldap.UNWILLING_TO_PERFORM('Can not delete the mapping tree, not for a backend! You may need to delete this backend via cn=config .... ;_; ')
-+
-+            # Delete replicas first
-+            try:
-+                Replicas(self._instance).get(mt.get_attr_val_utf8('cn')).delete()
-+            except ldap.NO_SUCH_OBJECT:
-+                # No replica, no problem
-+                pass
-+
-             # Delete our mapping tree if it exists.
-             mt.delete()
-         except ldap.NO_SUCH_OBJECT:
-             # Righto, it's already gone! Do nothing ...
-             pass
--        # Delete all our related indices
--        self._instance.index.delete_all(bename)
- 
-         # Now remove our children, this is all ldbm config
--        self._instance.delete_branch_s(self._dn, ldap.SCOPE_ONELEVEL)
--        # The super will actually delete ourselves.
--        super(Backend, self).delete()
-+        self._instance.delete_branch_s(self._dn, ldap.SCOPE_SUBTREE)
- 
-     def _lint_mappingtree(self):
-         """Backend lint
-diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
-index cdd0a9729..7b45683d9 100644
---- a/src/lib389/lib389/replica.py
-+++ b/src/lib389/lib389/replica.py
-@@ -458,7 +458,7 @@ class ReplicaLegacy(object):
-         try:
-             self.deleteAgreements(nsuffix)
-         except ldap.LDAPError as e:
--            self.log.fatal('Failed to delete replica agreements!')
-+            self.log.fatal('Failed to delete replica agreements!  ' + str(e))
-             raise
- 
-         # Delete the replica
--- 
-2.21.0
-
diff --git a/SOURCES/0002-Issue-50530-Directory-Server-not-RFC-4511-compliant-.patch b/SOURCES/0002-Issue-50530-Directory-Server-not-RFC-4511-compliant-.patch
deleted file mode 100644
index ccd1762..0000000
--- a/SOURCES/0002-Issue-50530-Directory-Server-not-RFC-4511-compliant-.patch
+++ /dev/null
@@ -1,146 +0,0 @@
-From 51ea1d34b861dfffb12fbe6be4e23d9342fd0fe2 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Fri, 2 Aug 2019 14:36:24 -0400
-Subject: [PATCH] Issue 50530 - Directory Server not RFC 4511 compliant with
- requested attr "1.1"
-
-Bug Description:  A regression was introduced some time back that changed the
-                  behavior of how the server handled the "1.1" requested attribute
-                  in a search request.  If "1.1" was requested along with other
-                  attributes then no attibutes were returned, but in this case "1.1"
-                  is expected to be ignroed.
-
-Fix Description:  Only comply with "1.1" if it is the only requested attribute
-
-relates: https://pagure.io/389-ds-base/issue/50530
-
-Reviewed by: firstyear(Thanks!)
----
- dirsrvtests/tests/suites/basic/basic_test.py | 57 +++++++++++++++++---
- ldap/servers/slapd/result.c                  |  7 ++-
- 2 files changed, 57 insertions(+), 7 deletions(-)
-
-diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
-index 0f7536b63..cea4f6bfe 100644
---- a/dirsrvtests/tests/suites/basic/basic_test.py
-+++ b/dirsrvtests/tests/suites/basic/basic_test.py
-@@ -28,6 +28,7 @@ log = logging.getLogger(__name__)
- USER1_DN = 'uid=user1,' + DEFAULT_SUFFIX
- USER2_DN = 'uid=user2,' + DEFAULT_SUFFIX
- USER3_DN = 'uid=user3,' + DEFAULT_SUFFIX
-+USER4_DN = 'uid=user4,' + DEFAULT_SUFFIX
- 
- ROOTDSE_DEF_ATTR_LIST = ('namingContexts',
-                          'supportedLDAPVersion',
-@@ -409,8 +410,8 @@ def test_basic_acl(topology_st, import_example_ldif):
-                                              'uid': 'user1',
-                                              'userpassword': PASSWORD})))
-     except ldap.LDAPError as e:
--        log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN
--                  + ': error ' + e.message['desc'])
-+        log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
-+                  ': error ' + e.message['desc'])
-         assert False
- 
-     try:
-@@ -421,8 +422,8 @@ def test_basic_acl(topology_st, import_example_ldif):
-                                              'uid': 'user2',
-                                              'userpassword': PASSWORD})))
-     except ldap.LDAPError as e:
--        log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN
--                  + ': error ' + e.message['desc'])
-+        log.fatal('test_basic_acl: Failed to add test user ' + USER1_DN +
-+                  ': error ' + e.message['desc'])
-         assert False
- 
-     #
-@@ -572,6 +573,50 @@ def test_basic_searches(topology_st, import_example_ldif):
-     log.info('test_basic_searches: PASSED')
- 
- 
-+@pytest.fixture(scope="module")
-+def add_test_entry(topology_st, request):
-+    # Add test entry
-+    topology_st.standalone.add_s(Entry((USER4_DN,
-+                                        {'objectclass': "top extensibleObject".split(),
-+                                         'cn': 'user1', 'uid': 'user1'})))
-+
-+
-+search_params = [(['1.1'], 'cn', False),
-+                 (['1.1', 'cn'], 'cn', True),
-+                 (['+'], 'nsUniqueId', True),
-+                 (['*'], 'cn', True),
-+                 (['cn'], 'cn', True)]
-+@pytest.mark.parametrize("attrs, attr, present", search_params)
-+def test_search_req_attrs(topology_st, add_test_entry, attrs, attr, present):
-+    """Test requested attributes in search operations.
-+    :id: 426a59ff-49b8-4a70-b377-0c0634a29b6e
-+    :setup: Standalone instance
-+    :steps:
-+         1. Test "1.1" does not return any attributes.
-+         2. Test "1.1" is ignored if there are other requested attributes
-+         3. Test "+" returns all operational attributes
-+         4. Test "*" returns all attributes
-+         5. Test requested attributes
-+
-+    :expectedresults:
-+         1. Success
-+         2. Success
-+         3. Success
-+         4. Success
-+         5. Success
-+    """
-+
-+    log.info("Testing attrs: {} attr: {} present: {}".format(attrs, attr, present))
-+    entry = topology_st.standalone.search_s(USER4_DN,
-+                                            ldap.SCOPE_BASE,
-+                                            'objectclass=top',
-+                                            attrs)
-+    if present:
-+        assert entry[0].hasAttr(attr)
-+    else:
-+        assert not entry[0].hasAttr(attr)
-+
-+
- def test_basic_referrals(topology_st, import_example_ldif):
-     """Test LDAP server in referral mode.
- 
-@@ -716,8 +761,8 @@ def test_basic_systemctl(topology_st, import_example_ldif):
-     log.info('Attempting to start the server with broken dse.ldif...')
-     try:
-         topology_st.standalone.start()
--    except:
--        log.info('Server failed to start as expected')
-+    except Exception as e:
-+        log.info('Server failed to start as expected: ' + str(e))
-     log.info('Check the status...')
-     assert (not topology_st.standalone.status())
-     log.info('Server failed to start as expected')
-diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
-index d9f431cc5..34ddd8566 100644
---- a/ldap/servers/slapd/result.c
-+++ b/ldap/servers/slapd/result.c
-@@ -1546,6 +1546,8 @@ send_ldap_search_entry_ext(
-      * "+" means all operational attributes (rfc3673)
-      * operational attributes are only retrieved if they are named
-      * specifically or when "+" is specified.
-+     * In the case of "1.1", if there are other requested attributes
-+     * then "1.1" should be ignored.
-      */
- 
-     /* figure out if we want all user attributes or no attributes at all */
-@@ -1560,7 +1562,10 @@ send_ldap_search_entry_ext(
-             if (strcmp(LDAP_ALL_USER_ATTRS, attrs[i]) == 0) {
-                 alluserattrs = 1;
-             } else if (strcmp(LDAP_NO_ATTRS, attrs[i]) == 0) {
--                noattrs = 1;
-+                /* "1.1" is only valid if it's the only requested attribute */
-+                if (i == 0 && attrs[1] == NULL) {
-+                    noattrs = 1;
-+                }
-             } else if (strcmp(LDAP_ALL_OPERATIONAL_ATTRS, attrs[i]) == 0) {
-                 alloperationalattrs = 1;
-             } else {
--- 
-2.21.0
-
diff --git a/SOURCES/0002-Ticket-50905-intermittent-SSL-hang-with-rhds.patch b/SOURCES/0002-Ticket-50905-intermittent-SSL-hang-with-rhds.patch
new file mode 100644
index 0000000..db889f6
--- /dev/null
+++ b/SOURCES/0002-Ticket-50905-intermittent-SSL-hang-with-rhds.patch
@@ -0,0 +1,60 @@
+From fe199780bd87f7a78c6d26078d0a4d0a0dbe09e9 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Fri, 3 Apr 2020 15:23:10 +0200
+Subject: [PATCH 3/4] Ticket 50905 - intermittent SSL hang with rhds
+
+Bug Description:
+	On a successfull sasl bind, a new IO layer (sasl_io_enable) is registered on top of
+	the connection. Then sasl bind sends the successful result. Registration is
+	done while sasl bind thread holds c_mutex but result is sent while the c_mutex
+	is released.
+
+	If a new operation comes in just after c_mutex was released it is
+	possible that sasl bind sends the result while the new IO layer is pushed.
+        IO layers is partially initialized at that time. It can create sigseg or
+	deadlock or...
+
+Fix Description:
+	The fix is to protect the send result from IO layer push.
+	i.e. move send_ldap_result into c_mutex
+
+https://pagure.io/389-ds-base/issue/50905
+
+Reviewed by: Mark Reynolds (Thanks !!)
+
+Platforms tested: F29
+
+Flag Day: no
+
+Doc impact: no
+---
+ ldap/servers/slapd/saslbind.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
+index 0907c623f..ef29acf71 100644
+--- a/ldap/servers/slapd/saslbind.c
++++ b/ldap/servers/slapd/saslbind.c
+@@ -1118,12 +1118,16 @@ sasl_check_result:
+             /* Enable SASL I/O on the connection */
+             PR_EnterMonitor(pb_conn->c_mutex);
+             connection_set_io_layer_cb(pb_conn, sasl_io_enable, NULL, NULL);
++
++            /* send successful result before sasl_io_enable can be pushed by another incoming op */
++            send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
++
+             PR_ExitMonitor(pb_conn->c_mutex);
++        } else {
++            /* send successful result */
++            send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
+         }
+ 
+-        /* send successful result */
+-        send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
+-
+         /* remove the sasl data from the pblock */
+         slapi_pblock_set(pb, SLAPI_BIND_RET_SASLCREDS, NULL);
+ 
+-- 
+2.25.3
+
diff --git a/SOURCES/0003-Issue-50529-LDAP-server-returning-PWP-controls-in-di.patch b/SOURCES/0003-Issue-50529-LDAP-server-returning-PWP-controls-in-di.patch
deleted file mode 100644
index a2c9297..0000000
--- a/SOURCES/0003-Issue-50529-LDAP-server-returning-PWP-controls-in-di.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 606b7b6a45f6e2014119d0716774323f30862e0c Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Fri, 2 Aug 2019 12:07:07 -0400
-Subject: [PATCH] Issue 50529 -  LDAP server returning PWP controls in
- different sequence
-
-Description:  The server returns password policy controls in different orders
-              depending on the state of grace logins.  The requested control,
-              if any, should be returned first, followed by any controls the
-              server might add.
-
-relates: https://pagure.io/389-ds-base/issue/50529
-
-Reviewed by: mreynolds (one line commit rule)
----
- ldap/servers/slapd/pw_mgmt.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ldap/servers/slapd/pw_mgmt.c b/ldap/servers/slapd/pw_mgmt.c
-index befac50cd..ca76fc12f 100644
---- a/ldap/servers/slapd/pw_mgmt.c
-+++ b/ldap/servers/slapd/pw_mgmt.c
-@@ -207,10 +207,10 @@ skip:
- 
-         /* password expired and user exceeded limit of grace attemps.
-          * Send result and also the control */
--        slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
-         if (pwresponse_req) {
-             slapi_pwpolicy_make_response_control(pb, -1, -1, LDAP_PWPOLICY_PWDEXPIRED);
-         }
-+        slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
-         slapi_send_ldap_result(pb, LDAP_INVALID_CREDENTIALS, NULL,
-                                "password expired!", 0, NULL);
- 
--- 
-2.21.0
-
diff --git a/SOURCES/0003-Issue-51029-Add-db_home_dir-defaults.inf.patch b/SOURCES/0003-Issue-51029-Add-db_home_dir-defaults.inf.patch
new file mode 100644
index 0000000..3ad2913
--- /dev/null
+++ b/SOURCES/0003-Issue-51029-Add-db_home_dir-defaults.inf.patch
@@ -0,0 +1,32 @@
+From 895f220fb3f214c7c618cde577984da3f38482b0 Mon Sep 17 00:00:00 2001
+From: Simon Pichugin <simon.pichugin@gmail.com>
+Date: Fri, 17 Apr 2020 16:07:31 +0200
+Subject: [PATCH 4/4] Issue 51029 - Add db_home_dir defaults.inf
+
+Description: Latest lib389 from master requires a new key
+'db_home_dir' in defaults.inf that is missing in the older
+builds of 389-ds-base.
+Add the key to defaults.inf so we can run the tests.
+
+https://pagure.io/389-ds-base/issue/51029
+
+Reviewed by: mreynolds (Thanks!)
+---
+ ldap/admin/src/defaults.inf.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/ldap/admin/src/defaults.inf.in b/ldap/admin/src/defaults.inf.in
+index 91486c8e3..2908c480e 100644
+--- a/ldap/admin/src/defaults.inf.in
++++ b/ldap/admin/src/defaults.inf.in
+@@ -54,6 +54,7 @@ access_log = @localstatedir@/log/dirsrv/slapd-{instance_name}/access
+ audit_log = @localstatedir@/log/dirsrv/slapd-{instance_name}/audit
+ error_log = @localstatedir@/log/dirsrv/slapd-{instance_name}/errors
+ db_dir = @localstatedir@/lib/dirsrv/slapd-{instance_name}/db
++db_home_dir = @localstatedir@/lib/dirsrv/slapd-{instance_name}
+ backup_dir = @localstatedir@/lib/dirsrv/slapd-{instance_name}/bak
+ ldif_dir = @localstatedir@/lib/dirsrv/slapd-{instance_name}/ldif
+ 
+-- 
+2.25.3
+
diff --git a/SOURCES/0004-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch b/SOURCES/0004-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch
deleted file mode 100644
index e30d326..0000000
--- a/SOURCES/0004-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch
+++ /dev/null
@@ -1,682 +0,0 @@
-From 59f03e332061b2c68bb53eed5949ddcfdc563300 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Wed, 7 Aug 2019 20:36:53 -0400
-Subject: [PATCH] Issue 50538 - cleanAllRUV task limit is not enforced for
- replicated tasks
-
-Bug Description:
-
-There is a hard limit of 64 concurrent cleanAllRUV tasks, but this limit is
-only enforced when creating "new" tasks. It was not enforced when a task was
-received via an extended operation. There were also race conditions in the
-existing logic that allowed the array of cleaned rids to get corrupted . This
-allowed for a very large number of task threads to be created.
-
-Fix Description:
-
-Maintain a new counter to keep track of the number of clean and abort threads
-to make sure it never over runs the rid array buffers.
-
-relates: https://pagure.io/389-ds-base/issue/50538
-
-Reviewed by: lkrispenz(Thanks!)
----
- .../suites/replication/cleanallruv_test.py    |  47 +++-
- ldap/servers/plugins/replication/repl5.h      |   7 +-
- .../replication/repl5_replica_config.c        | 247 ++++++++++--------
- ldap/servers/plugins/replication/repl_extop.c |  19 +-
- 4 files changed, 202 insertions(+), 118 deletions(-)
-
-diff --git a/dirsrvtests/tests/suites/replication/cleanallruv_test.py b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
-index 620a53e1a..43801dd52 100644
---- a/dirsrvtests/tests/suites/replication/cleanallruv_test.py
-+++ b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
-@@ -1,5 +1,5 @@
- # --- BEGIN COPYRIGHT BLOCK ---
--# Copyright (C) 2016 Red Hat, Inc.
-+# Copyright (C) 2019 Red Hat, Inc.
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
-@@ -7,7 +7,6 @@
- # --- END COPYRIGHT BLOCK ---
- #
- import threading
--
- import pytest
- from lib389.tasks import *
- from lib389.utils import *
-@@ -859,6 +858,50 @@ def test_multiple_tasks_with_force(topology_m4):
-     restore_master4(topology_m4)
- 
- 
-+def test_max_tasks(topology_m4):
-+    """Test we can not create more than 64 cleaning tasks
-+
-+    :id: c34d0b40-3c3e-4f53-8656-5e4c2a310a1f
-+    :setup: Replication setup with four masters
-+    :steps:
-+        1. Stop masters 3 & 4
-+        2. Create over 64 tasks between m1 and m2
-+        3. Check logs to see if (>65) tasks were rejected
-+
-+    :expectedresults:
-+        1. Success
-+        2. Success
-+        3. Success
-+    """
-+
-+    # Stop masters 3 & 4
-+    m1 = topology_m4.ms["master1"]
-+    m2 = topology_m4.ms["master2"]
-+    m3 = topology_m4.ms["master3"]
-+    m4 = topology_m4.ms["master4"]
-+    m3.stop()
-+    m4.stop()
-+
-+    # Add over 64 tasks between master1 & 2 to try to exceed the 64 task limit
-+    for i in range(1, 64):
-+        cruv_task = CleanAllRUVTask(m1)
-+        cruv_task.create(properties={
-+            'replica-id': str(i),
-+            'replica-base-dn': DEFAULT_SUFFIX,
-+            'replica-force-cleaning': 'no',  # This forces these tasks to stick around
-+        })
-+        cruv_task = CleanAllRUVTask(m2)
-+        cruv_task.create(properties={
-+            'replica-id': "10" + str(i),
-+            'replica-base-dn': DEFAULT_SUFFIX,
-+            'replica-force-cleaning': 'yes',  # This allows the tasks to propagate
-+        })
-+
-+    # Check the errors log for our error message in master 1
-+    assert m1.searchErrorsLog('Exceeded maximum number of active CLEANALLRUV tasks')
-+>>>>>>> ab24aa4cb... Issue 50538 - cleanAllRUV task limit is not enforced for replicated tasks
-+
-+
- if __name__ == '__main__':
-     # Run isolated
-     # -s for DEBUG mode
-diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
-index 3c7f06f36..b06c6fbf4 100644
---- a/ldap/servers/plugins/replication/repl5.h
-+++ b/ldap/servers/plugins/replication/repl5.h
-@@ -80,6 +80,8 @@
- #define CLEANRUV_FINISHED  "finished"
- #define CLEANRUV_CLEANING  "cleaning"
- #define CLEANRUV_NO_MAXCSN "no maxcsn"
-+#define CLEANALLRUV_ID "CleanAllRUV Task"
-+#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task"
- 
- /* DS 5.0 replication protocol error codes */
- #define NSDS50_REPL_REPLICA_READY             0x00  /* Replica ready, go ahead */
-@@ -784,6 +786,7 @@ void multimaster_mtnode_construct_replicas(void);
- void multimaster_be_state_change(void *handle, char *be_name, int old_be_state, int new_be_state);
- 
- #define CLEANRIDSIZ 64 /* maximum number for concurrent CLEANALLRUV tasks */
-+#define CLEANRID_BUFSIZ 128
- 
- typedef struct _cleanruv_data
- {
-@@ -815,6 +818,8 @@ int get_replica_type(Replica *r);
- int replica_execute_cleanruv_task_ext(Object *r, ReplicaId rid);
- void add_cleaned_rid(cleanruv_data *data, char *maxcsn);
- int is_cleaned_rid(ReplicaId rid);
-+int32_t check_and_set_cleanruv_task_count(ReplicaId rid);
-+int32_t check_and_set_abort_cleanruv_task_count(void);
- int replica_cleanall_ruv_abort(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg);
- void replica_cleanallruv_thread_ext(void *arg);
- void stop_ruv_cleaning(void);
-@@ -833,8 +838,6 @@ void set_cleaned_rid(ReplicaId rid);
- void cleanruv_log(Slapi_Task *task, int rid, char *task_type, int sev_level, char *fmt, ...);
- char *replica_cleanallruv_get_local_maxcsn(ReplicaId rid, char *base_dn);
- 
--
--
- /* replutil.c */
- LDAPControl *create_managedsait_control(void);
- LDAPControl *create_backend_control(Slapi_DN *sdn);
-diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
-index 62bfcf6ce..80a079784 100644
---- a/ldap/servers/plugins/replication/repl5_replica_config.c
-+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
-@@ -30,17 +30,18 @@
- #define CLEANALLRUV "CLEANALLRUV"
- #define CLEANALLRUVLEN 11
- #define REPLICA_RDN "cn=replica"
--#define CLEANALLRUV_ID "CleanAllRUV Task"
--#define ABORT_CLEANALLRUV_ID "Abort CleanAllRUV Task"
- 
- int slapi_log_urp = SLAPI_LOG_REPL;
--static ReplicaId cleaned_rids[CLEANRIDSIZ + 1] = {0};
--static ReplicaId pre_cleaned_rids[CLEANRIDSIZ + 1] = {0};
--static ReplicaId aborted_rids[CLEANRIDSIZ + 1] = {0};
--static Slapi_RWLock *rid_lock = NULL;
--static Slapi_RWLock *abort_rid_lock = NULL;
-+static ReplicaId cleaned_rids[CLEANRID_BUFSIZ] = {0};
-+static ReplicaId pre_cleaned_rids[CLEANRID_BUFSIZ] = {0};
-+static ReplicaId aborted_rids[CLEANRID_BUFSIZ] = {0};
-+static PRLock *rid_lock = NULL;
-+static PRLock *abort_rid_lock = NULL;
- static PRLock *notify_lock = NULL;
- static PRCondVar *notify_cvar = NULL;
-+static PRLock *task_count_lock = NULL;
-+static int32_t clean_task_count = 0;
-+static int32_t abort_task_count = 0;
- 
- /* Forward Declartions */
- static int replica_config_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *entryAfter, int *returncode, char *returntext, void *arg);
-@@ -67,8 +68,6 @@ static int replica_cleanallruv_send_abort_extop(Repl_Agmt *ra, Slapi_Task *task,
- static int replica_cleanallruv_check_maxcsn(Repl_Agmt *agmt, char *basedn, char *rid_text, char *maxcsn, Slapi_Task *task);
- static int replica_cleanallruv_replica_alive(Repl_Agmt *agmt);
- static int replica_cleanallruv_check_ruv(char *repl_root, Repl_Agmt *ra, char *rid_text, Slapi_Task *task, char *force);
--static int get_cleanruv_task_count(void);
--static int get_abort_cleanruv_task_count(void);
- static int replica_cleanup_task(Object *r, const char *task_name, char *returntext, int apply_mods);
- static int replica_task_done(Replica *replica);
- static void delete_cleaned_rid_config(cleanruv_data *data);
-@@ -114,20 +113,27 @@ replica_config_init()
-                       PR_GetError());
-         return -1;
-     }
--    rid_lock = slapi_new_rwlock();
-+    rid_lock = PR_NewLock();
-     if (rid_lock == NULL) {
-         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
-                                                        "Failed to create rid_lock; NSPR error - %d\n",
-                       PR_GetError());
-         return -1;
-     }
--    abort_rid_lock = slapi_new_rwlock();
-+    abort_rid_lock = PR_NewLock();
-     if (abort_rid_lock == NULL) {
-         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
-                                                        "Failed to create abort_rid_lock; NSPR error - %d\n",
-                       PR_GetError());
-         return -1;
-     }
-+    task_count_lock = PR_NewLock();
-+    if (task_count_lock == NULL) {
-+        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
-+                                                       "Failed to create task_count_lock; NSPR error - %d\n",
-+                      PR_GetError());
-+        return -1;
-+    }
-     if ((notify_lock = PR_NewLock()) == NULL) {
-         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
-                                                        "Failed to create notify lock; NSPR error - %d\n",
-@@ -1483,12 +1489,6 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
- 
-     cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Initiating CleanAllRUV Task...");
- 
--    if (get_cleanruv_task_count() >= CLEANRIDSIZ) {
--        /* we are already running the maximum number of tasks */
--        cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
--                     "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
--        return LDAP_UNWILLING_TO_PERFORM;
--    }
-     /*
-      *  Grab the replica
-      */
-@@ -1540,6 +1540,13 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
-         goto fail;
-     }
- 
-+    if (check_and_set_cleanruv_task_count(rid) != LDAP_SUCCESS) {
-+        cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
-+                     "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
-+        rc = LDAP_UNWILLING_TO_PERFORM;
-+        goto fail;
-+    }
-+
-     /*
-      *  Launch the cleanallruv thread.  Once all the replicas are cleaned it will release the rid
-      */
-@@ -1547,6 +1554,9 @@ replica_execute_cleanall_ruv_task(Object *r, ReplicaId rid, Slapi_Task *task, co
-     if (data == NULL) {
-         cleanruv_log(pre_task, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Failed to allocate cleanruv_data.  Aborting task.");
-         rc = -1;
-+        PR_Lock(task_count_lock);
-+        clean_task_count--;
-+        PR_Unlock(task_count_lock);
-         goto fail;
-     }
-     data->repl_obj = r;
-@@ -1629,13 +1639,13 @@ replica_cleanallruv_thread(void *arg)
-     int aborted = 0;
-     int rc = 0;
- 
--    if (!data || slapi_is_shutting_down()) {
--        return; /* no data */
--    }
--
-     /* Increase active thread count to prevent a race condition at server shutdown */
-     g_incr_active_threadcnt();
- 
-+    if (!data || slapi_is_shutting_down()) {
-+        goto done;
-+    }
-+
-     if (data->task) {
-         slapi_task_inc_refcount(data->task);
-         slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name,
-@@ -1682,16 +1692,13 @@ replica_cleanallruv_thread(void *arg)
-         slapi_task_begin(data->task, 1);
-     }
-     /*
--     *  Presetting the rid prevents duplicate thread creation, but allows the db and changelog to still
--     *  process updates from the rid.
--     *  set_cleaned_rid() blocks updates, so we don't want to do that... yet unless we are in force mode.
--     *  If we are forcing a clean independent of state of other servers for this RID we can set_cleaned_rid()
-+     *  We have already preset this rid, but if we are forcing a clean independent of state
-+     *  of other servers for this RID we can set_cleaned_rid()
-      */
-     if (data->force) {
-         set_cleaned_rid(data->rid);
--    } else {
--        preset_cleaned_rid(data->rid);
-     }
-+
-     rid_text = slapi_ch_smprintf("%d", data->rid);
-     csn_as_string(data->maxcsn, PR_FALSE, csnstr);
-     /*
-@@ -1861,6 +1868,9 @@ done:
-     /*
-      *  If the replicas are cleaned, release the rid
-      */
-+    if (slapi_is_shutting_down()) {
-+        stop_ruv_cleaning();
-+    }
-     if (!aborted && !slapi_is_shutting_down()) {
-         /*
-          * Success - the rid has been cleaned!
-@@ -1879,10 +1889,9 @@ done:
-         } else {
-             cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Propagated task does not delete Keep alive entry (%d).", data->rid);
-         }
--
-         clean_agmts(data);
-         remove_cleaned_rid(data->rid);
--        cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d).", data->rid);
-+        cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_INFO, "Successfully cleaned rid(%d)", data->rid);
-     } else {
-         /*
-          *  Shutdown or abort
-@@ -1915,6 +1924,10 @@ done:
-     slapi_ch_free_string(&data->force);
-     slapi_ch_free_string(&rid_text);
-     slapi_ch_free((void **)&data);
-+    /* decrement task count */
-+    PR_Lock(task_count_lock);
-+    clean_task_count--;
-+    PR_Unlock(task_count_lock);
-     g_decr_active_threadcnt();
- }
- 
-@@ -2414,16 +2427,14 @@ replica_send_cleanruv_task(Repl_Agmt *agmt, cleanruv_data *clean_data)
- int
- is_cleaned_rid(ReplicaId rid)
- {
--    int i;
--
--    slapi_rwlock_rdlock(rid_lock);
--    for (i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != 0; i++) {
-+    PR_Lock(rid_lock);
-+    for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
-         if (rid == cleaned_rids[i]) {
--            slapi_rwlock_unlock(rid_lock);
-+            PR_Unlock(rid_lock);
-             return 1;
-         }
-     }
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(rid_lock);
- 
-     return 0;
- }
-@@ -2431,16 +2442,14 @@ is_cleaned_rid(ReplicaId rid)
- int
- is_pre_cleaned_rid(ReplicaId rid)
- {
--    int i;
--
--    slapi_rwlock_rdlock(rid_lock);
--    for (i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != 0; i++) {
-+    PR_Lock(rid_lock);
-+    for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
-         if (rid == pre_cleaned_rids[i]) {
--            slapi_rwlock_unlock(rid_lock);
-+            PR_Unlock(rid_lock);
-             return 1;
-         }
-     }
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(rid_lock);
- 
-     return 0;
- }
-@@ -2453,14 +2462,14 @@ is_task_aborted(ReplicaId rid)
-     if (rid == 0) {
-         return 0;
-     }
--    slapi_rwlock_rdlock(abort_rid_lock);
--    for (i = 0; i < CLEANRIDSIZ && aborted_rids[i] != 0; i++) {
-+    PR_Lock(abort_rid_lock);
-+    for (i = 0; i < CLEANRID_BUFSIZ && aborted_rids[i] != 0; i++) {
-         if (rid == aborted_rids[i]) {
--            slapi_rwlock_unlock(abort_rid_lock);
-+            PR_Unlock(abort_rid_lock);
-             return 1;
-         }
-     }
--    slapi_rwlock_unlock(abort_rid_lock);
-+    PR_Unlock(abort_rid_lock);
-     return 0;
- }
- 
-@@ -2469,15 +2478,14 @@ preset_cleaned_rid(ReplicaId rid)
- {
-     int i;
- 
--    slapi_rwlock_wrlock(rid_lock);
--    for (i = 0; i < CLEANRIDSIZ; i++) {
-+    PR_Lock(rid_lock);
-+    for (i = 0; i < CLEANRID_BUFSIZ && pre_cleaned_rids[i] != rid; i++) {
-         if (pre_cleaned_rids[i] == 0) {
-             pre_cleaned_rids[i] = rid;
--            pre_cleaned_rids[i + 1] = 0;
-             break;
-         }
-     }
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(rid_lock);
- }
- 
- /*
-@@ -2490,14 +2498,13 @@ set_cleaned_rid(ReplicaId rid)
- {
-     int i;
- 
--    slapi_rwlock_wrlock(rid_lock);
--    for (i = 0; i < CLEANRIDSIZ; i++) {
-+    PR_Lock(rid_lock);
-+    for (i = 0; i < CLEANRID_BUFSIZ && cleaned_rids[i] != rid; i++) {
-         if (cleaned_rids[i] == 0) {
-             cleaned_rids[i] = rid;
--            cleaned_rids[i + 1] = 0;
-         }
-     }
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(rid_lock);
- }
- 
- /*
-@@ -2569,15 +2576,14 @@ add_aborted_rid(ReplicaId rid, Replica *r, char *repl_root)
-     int rc;
-     int i;
- 
--    slapi_rwlock_wrlock(abort_rid_lock);
--    for (i = 0; i < CLEANRIDSIZ; i++) {
-+    PR_Lock(abort_rid_lock);
-+    for (i = 0; i < CLEANRID_BUFSIZ; i++) {
-         if (aborted_rids[i] == 0) {
-             aborted_rids[i] = rid;
--            aborted_rids[i + 1] = 0;
-             break;
-         }
-     }
--    slapi_rwlock_unlock(abort_rid_lock);
-+    PR_Unlock(abort_rid_lock);
-     /*
-      *  Write the rid to the config entry
-      */
-@@ -2620,21 +2626,24 @@ delete_aborted_rid(Replica *r, ReplicaId rid, char *repl_root, int skip)
-     char *data;
-     char *dn;
-     int rc;
--    int i;
- 
-     if (r == NULL)
-         return;
- 
-     if (skip) {
-         /* skip the deleting of the config, and just remove the in memory rid */
--        slapi_rwlock_wrlock(abort_rid_lock);
--        for (i = 0; i < CLEANRIDSIZ && aborted_rids[i] != rid; i++)
--            ; /* found rid, stop */
--        for (; i < CLEANRIDSIZ; i++) {
--            /* rewrite entire array */
--            aborted_rids[i] = aborted_rids[i + 1];
--        }
--        slapi_rwlock_unlock(abort_rid_lock);
-+        ReplicaId new_abort_rids[CLEANRID_BUFSIZ] = {0};
-+        int32_t idx = 0;
-+
-+        PR_Lock(abort_rid_lock);
-+        for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
-+            if (aborted_rids[i] != rid) {
-+                new_abort_rids[idx] = aborted_rids[i];
-+                idx++;
-+            }
-+        }
-+        memcpy(aborted_rids, new_abort_rids, sizeof(new_abort_rids));
-+        PR_Unlock(abort_rid_lock);
-     } else {
-         /* only remove the config, leave the in-memory rid */
-         dn = replica_get_dn(r);
-@@ -2792,27 +2801,31 @@ bail:
- void
- remove_cleaned_rid(ReplicaId rid)
- {
--    int i;
--    /*
--     *  Remove this rid, and optimize the array
--     */
--    slapi_rwlock_wrlock(rid_lock);
-+    ReplicaId new_cleaned_rids[CLEANRID_BUFSIZ] = {0};
-+    ReplicaId new_pre_cleaned_rids[CLEANRID_BUFSIZ] = {0};
-+    size_t idx = 0;
-+
-+    PR_Lock(rid_lock);
- 
--    for (i = 0; i < CLEANRIDSIZ && cleaned_rids[i] != rid; i++)
--        ; /* found rid, stop */
--    for (; i < CLEANRIDSIZ; i++) {
--        /* rewrite entire array */
--        cleaned_rids[i] = cleaned_rids[i + 1];
-+    for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
-+        if (cleaned_rids[i] != rid) {
-+            new_cleaned_rids[idx] = cleaned_rids[i];
-+            idx++;
-+        }
-     }
-+    memcpy(cleaned_rids, new_cleaned_rids, sizeof(new_cleaned_rids));
-+
-     /* now do the preset cleaned rids */
--    for (i = 0; i < CLEANRIDSIZ && pre_cleaned_rids[i] != rid; i++)
--        ; /* found rid, stop */
--    for (; i < CLEANRIDSIZ; i++) {
--        /* rewrite entire array */
--        pre_cleaned_rids[i] = pre_cleaned_rids[i + 1];
-+    idx = 0;
-+    for (size_t i = 0; i < CLEANRID_BUFSIZ; i++) {
-+        if (pre_cleaned_rids[i] != rid) {
-+            new_pre_cleaned_rids[idx] = pre_cleaned_rids[i];
-+            idx++;
-+        }
-     }
-+    memcpy(pre_cleaned_rids, new_pre_cleaned_rids, sizeof(new_pre_cleaned_rids));
- 
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(rid_lock);
- }
- 
- /*
-@@ -2840,16 +2853,6 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)),
-     char *ridstr = NULL;
-     int rc = SLAPI_DSE_CALLBACK_OK;
- 
--    if (get_abort_cleanruv_task_count() >= CLEANRIDSIZ) {
--        /* we are already running the maximum number of tasks */
--        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
--                    "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",
--                    CLEANRIDSIZ);
--        cleanruv_log(task, -1, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext);
--        *returncode = LDAP_OPERATIONS_ERROR;
--        return SLAPI_DSE_CALLBACK_ERROR;
--    }
--
-     /* allocate new task now */
-     task = slapi_new_task(slapi_entry_get_ndn(e));
- 
-@@ -2934,6 +2937,16 @@ replica_cleanall_ruv_abort(Slapi_PBlock *pb __attribute__((unused)),
-          */
-         certify_all = "no";
-     }
-+
-+    if (check_and_set_abort_cleanruv_task_count() != LDAP_SUCCESS) {
-+        /* we are already running the maximum number of tasks */
-+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
-+                    "Exceeded maximum number of active ABORT CLEANALLRUV tasks(%d)",
-+                    CLEANRIDSIZ);
-+        cleanruv_log(task, -1, ABORT_CLEANALLRUV_ID, SLAPI_LOG_ERR, "%s", returntext);
-+        *returncode = LDAP_UNWILLING_TO_PERFORM;
-+        goto out;
-+    }
-     /*
-      *  Create payload
-      */
-@@ -3142,6 +3155,9 @@ done:
-     slapi_ch_free_string(&data->certify);
-     slapi_sdn_free(&data->sdn);
-     slapi_ch_free((void **)&data);
-+    PR_Lock(task_count_lock);
-+    abort_task_count--;
-+    PR_Unlock(task_count_lock);
-     g_decr_active_threadcnt();
- }
- 
-@@ -3493,36 +3509,43 @@ replica_cleanallruv_check_ruv(char *repl_root, Repl_Agmt *agmt, char *rid_text,
-     return rc;
- }
- 
--static int
--get_cleanruv_task_count(void)
-+/*
-+ * Before starting a cleanAllRUV task make sure there are not
-+ * too many task threads already running.  If everything is okay
-+ * also pre-set the RID now so rebounding extended ops do not
-+ * try to clean it over and over.
-+ */
-+int32_t
-+check_and_set_cleanruv_task_count(ReplicaId rid)
- {
--    int i, count = 0;
-+    int32_t rc = 0;
- 
--    slapi_rwlock_wrlock(rid_lock);
--    for (i = 0; i < CLEANRIDSIZ; i++) {
--        if (pre_cleaned_rids[i] != 0) {
--            count++;
--        }
-+    PR_Lock(task_count_lock);
-+    if (clean_task_count >= CLEANRIDSIZ) {
-+        rc = -1;
-+    } else {
-+        clean_task_count++;
-+        preset_cleaned_rid(rid);
-     }
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(task_count_lock);
- 
--    return count;
-+    return rc;
- }
- 
--static int
--get_abort_cleanruv_task_count(void)
-+int32_t
-+check_and_set_abort_cleanruv_task_count(void)
- {
--    int i, count = 0;
-+    int32_t rc = 0;
- 
--    slapi_rwlock_wrlock(rid_lock);
--    for (i = 0; i < CLEANRIDSIZ; i++) {
--        if (aborted_rids[i] != 0) {
--            count++;
-+    PR_Lock(task_count_lock);
-+    if (abort_task_count > CLEANRIDSIZ) {
-+            rc = -1;
-+        } else {
-+            abort_task_count++;
-         }
--    }
--    slapi_rwlock_unlock(rid_lock);
-+    PR_Unlock(task_count_lock);
- 
--    return count;
-+    return rc;
- }
- 
- /*
-diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
-index 68e2544b4..0c2abb6d5 100644
---- a/ldap/servers/plugins/replication/repl_extop.c
-+++ b/ldap/servers/plugins/replication/repl_extop.c
-@@ -1393,6 +1393,12 @@ multimaster_extop_abort_cleanruv(Slapi_PBlock *pb)
-         rc = LDAP_OPERATIONS_ERROR;
-         goto out;
-     }
-+    if (check_and_set_abort_cleanruv_task_count() != LDAP_SUCCESS) {
-+        cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
-+                     "Exceeded maximum number of active abort CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
-+        rc = LDAP_UNWILLING_TO_PERFORM;
-+        goto out;
-+    }
-     /*
-      *  Prepare the abort data
-      */
-@@ -1499,6 +1505,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
-     if (force == NULL) {
-         force = "no";
-     }
-+
-     maxcsn = csn_new();
-     csn_init_by_string(maxcsn, csnstr);
-     /*
-@@ -1535,13 +1542,21 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
-         goto free_and_return;
-     }
- 
-+    if (check_and_set_cleanruv_task_count((ReplicaId)rid) != LDAP_SUCCESS) {
-+        cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR,
-+                     "Exceeded maximum number of active CLEANALLRUV tasks(%d)", CLEANRIDSIZ);
-+        rc = LDAP_UNWILLING_TO_PERFORM;
-+        goto free_and_return;
-+    }
-+
-     if (replica_get_type(r) != REPLICA_TYPE_READONLY) {
-         /*
-          *  Launch the cleanruv monitoring thread.  Once all the replicas are cleaned it will release the rid
-          *
-          *  This will also release mtnode_ext->replica
-          */
--        slapi_log_err(SLAPI_LOG_INFO, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Launching cleanAllRUV thread...\n");
-+
-+        cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Launching cleanAllRUV thread...\n");
-         data = (cleanruv_data *)slapi_ch_calloc(1, sizeof(cleanruv_data));
-         if (data == NULL) {
-             slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Failed to allocate "
-@@ -1635,7 +1650,7 @@ free_and_return:
-         ber_printf(resp_bere, "{s}", CLEANRUV_ACCEPTED);
-         ber_flatten(resp_bere, &resp_bval);
-         slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, resp_bval);
--        slapi_send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
-+        slapi_send_ldap_result(pb, rc, NULL, NULL, 0, NULL);
-         /* resp_bere */
-         if (NULL != resp_bere) {
-             ber_free(resp_bere, 1);
--- 
-2.21.0
-
diff --git a/SOURCES/0004-Ticket-51068-deadlock-when-updating-the-schema.patch b/SOURCES/0004-Ticket-51068-deadlock-when-updating-the-schema.patch
new file mode 100644
index 0000000..f79d04f
--- /dev/null
+++ b/SOURCES/0004-Ticket-51068-deadlock-when-updating-the-schema.patch
@@ -0,0 +1,224 @@
+From 28e3a979dbe3aa1d08ae32056b772a6a59fae581 Mon Sep 17 00:00:00 2001
+From: Thierry Bordaz <tbordaz@redhat.com>
+Date: Tue, 5 May 2020 17:44:01 +0200
+Subject: [PATCH 1/2] Ticket 51068 - deadlock when updating the schema
+
+Bug Description:
+        It exists a 3 threads deadlock scenario. It involves state change plugins when it
+        calls schema_changed_callback. So the trigger is a change of schema (direct or via
+        replication). The scenario is
+      MOD(cn=schema)    hold StateChange lock   wait for vattr lock
+      SRCH              hold vattr lock         wait for DB page
+      MOD               hold DB page            wait for StateChange lock
+
+Fix Description:
+        Statechange lock protects the list of registered callbacks.
+        lock is a mutex where actually registration of callback is only done
+        at startup. Later the list is only lookup.
+        Making statechange lock a rwlock suppresses the deadlock scenario
+        as MODs will only acquire in read StateChange lock.
+        It should also improve performance as at the moment all MODs are serialized
+        on that lock
+	In order to prevent writer starvation a new slapi_new_rwlock_prio
+        create rwlock with priority to writers.
+
+https://pagure.io/389-ds-base/issue/51068
+
+Reviewed by: Mark Reynolds, William Brown
+
+Platforms tested: 30
+
+Flag Day: no
+
+Doc impact: no
+---
+ .../servers/plugins/statechange/statechange.c | 24 ++++++++++--------
+ ldap/servers/slapd/slapi-plugin.h             | 16 ++++++++++++
+ ldap/servers/slapd/slapi2nspr.c               | 25 +++++++++++++++++++
+ ldap/servers/slapd/vattr.c                    |  2 +-
+ 4 files changed, 55 insertions(+), 12 deletions(-)
+
+diff --git a/ldap/servers/plugins/statechange/statechange.c b/ldap/servers/plugins/statechange/statechange.c
+index f89b394c6..0a3838b5e 100644
+--- a/ldap/servers/plugins/statechange/statechange.c
++++ b/ldap/servers/plugins/statechange/statechange.c
+@@ -40,7 +40,7 @@ static SCNotify *head; /* a place to start in the list */
+ #define SCN_PLUGIN_SUBSYSTEM "statechange-plugin" /* used for logging */
+ 
+ static void *api[5];
+-static Slapi_Mutex *buffer_lock = 0;
++static Slapi_RWLock *buffer_lock = 0;
+ static PRUint64 g_plugin_started = 0;
+ 
+ /*
+@@ -140,7 +140,7 @@ statechange_start(Slapi_PBlock *pb __attribute__((unused)))
+     api[3] = (void *)_statechange_unregister_all;
+     api[4] = (void *)_statechange_vattr_cache_invalidator_callback;
+ 
+-    if (0 == (buffer_lock = slapi_new_mutex())) /* we never free this mutex */
++    if (0 == (buffer_lock = slapi_new_rwlock()))
+     {
+         /* badness */
+         slapi_log_err(SLAPI_LOG_ERR, SCN_PLUGIN_SUBSYSTEM, "statechange_start - Failed to create lock\n");
+@@ -180,7 +180,9 @@ statechange_close(Slapi_PBlock *pb __attribute__((unused)))
+     slapi_counter_destroy(&op_counter);
+ 
+     slapi_apib_unregister(StateChange_v1_0_GUID);
+-    slapi_destroy_mutex(buffer_lock);
++    if (buffer_lock) {
++        slapi_destroy_rwlock(buffer_lock);
++    }
+     buffer_lock = NULL;
+ 
+     slapi_log_err(SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<-- statechange_close\n");
+@@ -240,7 +242,7 @@ statechange_post_op(Slapi_PBlock *pb, int modtype)
+     slapi_log_err(SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "--> statechange_post_op\n");
+ 
+     /* evaluate this operation against the notification entries */
+-    slapi_lock_mutex(buffer_lock);
++    slapi_rwlock_rdlock(buffer_lock);
+     if (head) {
+         slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
+         if (NULL == sdn) {
+@@ -290,7 +292,7 @@ statechange_post_op(Slapi_PBlock *pb, int modtype)
+         } while (notify && notify != head);
+     }
+ bail:
+-    slapi_unlock_mutex(buffer_lock);
++    slapi_rwlock_unlock(buffer_lock);
+     slapi_log_err(SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<-- statechange_post_op\n");
+ 
+     return SLAPI_PLUGIN_SUCCESS; /* always succeed */
+@@ -338,7 +340,7 @@ _statechange_register(char *caller_id, char *dn, char *filter, void *caller_data
+         }
+         item->func = func;
+ 
+-        slapi_lock_mutex(buffer_lock);
++        slapi_rwlock_wrlock(buffer_lock);
+         if (head == NULL) {
+             head = item;
+             head->next = head;
+@@ -349,7 +351,7 @@ _statechange_register(char *caller_id, char *dn, char *filter, void *caller_data
+             head->prev = item;
+             item->prev->next = item;
+         }
+-        slapi_unlock_mutex(buffer_lock);
++        slapi_rwlock_unlock(buffer_lock);
+         slapi_ch_free_string(&writable_filter);
+ 
+         ret = SLAPI_PLUGIN_SUCCESS;
+@@ -371,7 +373,7 @@ _statechange_unregister(char *dn, char *filter, notify_callback thefunc)
+         return ret;
+     }
+ 
+-    slapi_lock_mutex(buffer_lock);
++    slapi_rwlock_wrlock(buffer_lock);
+ 
+     if ((func = statechange_find_notify(dn, filter, thefunc))) {
+         func->prev->next = func->next;
+@@ -392,7 +394,7 @@ _statechange_unregister(char *dn, char *filter, notify_callback thefunc)
+         slapi_ch_free((void **)&func);
+     }
+ 
+-    slapi_unlock_mutex(buffer_lock);
++    slapi_rwlock_unlock(buffer_lock);
+     slapi_counter_decrement(op_counter);
+ 
+     return ret;
+@@ -410,7 +412,7 @@ _statechange_unregister_all(char *caller_id, caller_data_free_callback callback)
+         return;
+     }
+ 
+-    slapi_lock_mutex(buffer_lock);
++    slapi_rwlock_wrlock(buffer_lock);
+ 
+     if (notify) {
+         do {
+@@ -441,7 +443,7 @@ _statechange_unregister_all(char *caller_id, caller_data_free_callback callback)
+         } while (notify != start_notify && notify != NULL);
+     }
+ 
+-    slapi_unlock_mutex(buffer_lock);
++    slapi_rwlock_unlock(buffer_lock);
+     slapi_counter_decrement(op_counter);
+ }
+ 
+diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
+index 679bdbb5c..865d83b9b 100644
+--- a/ldap/servers/slapd/slapi-plugin.h
++++ b/ldap/servers/slapd/slapi-plugin.h
+@@ -6126,6 +6126,22 @@ void slapi_destroy_condvar(Slapi_CondVar *cvar);
+ int slapi_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout);
+ int slapi_notify_condvar(Slapi_CondVar *cvar, int notify_all);
+ 
++/**
++ * Creates a new read/write lock
++ * If prio_writer the rwlock gives priority on writers
++ * else it give priority on readers (default)
++ *
++ * \return A pointer to a \c Slapi_RWLock
++ *
++ * \note Free the returned lock by calling slapi_destroy_rwlock() when finished
++ *
++ * \see slapi_destroy_rwlock()
++ * \see slapi_rwlock_rdlock()
++ * \see slapi_rwlock_wrlock()
++ * \see slapi_rwlock_unlock()
++ */
++Slapi_RWLock *slapi_new_rwlock_prio(int32_t prio_writer);
++
+ /**
+  * Creates a new read/write lock.
+  *
+diff --git a/ldap/servers/slapd/slapi2nspr.c b/ldap/servers/slapd/slapi2nspr.c
+index b3e6d94c2..232d1599e 100644
+--- a/ldap/servers/slapd/slapi2nspr.c
++++ b/ldap/servers/slapd/slapi2nspr.c
+@@ -181,6 +181,31 @@ slapi_notify_condvar(Slapi_CondVar *cvar, int notify_all)
+     return (prrc == PR_SUCCESS ? 1 : 0);
+ }
+ 
++Slapi_RWLock *
++slapi_new_rwlock_prio(int32_t prio_writer)
++{
++#ifdef USE_POSIX_RWLOCKS
++    pthread_rwlock_t *rwlock = NULL;
++    pthread_rwlockattr_t attr;
++
++    pthread_rwlockattr_init(&attr);
++    if (prio_writer) {
++        pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
++    } else {
++        pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_READER_NP);
++    }
++
++    rwlock = (pthread_rwlock_t *)slapi_ch_malloc(sizeof(pthread_rwlock_t));
++    if (rwlock) {
++        pthread_rwlock_init(rwlock, &attr);
++    }
++
++    return ((Slapi_RWLock *)rwlock);
++#else
++    return ((Slapi_RWLock *)PR_NewRWLock(PR_RWLOCK_RANK_NONE, "slapi_rwlock"));
++#endif
++}
++
+ Slapi_RWLock *
+ slapi_new_rwlock(void)
+ {
+diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
+index 852a887ce..eef444270 100644
+--- a/ldap/servers/slapd/vattr.c
++++ b/ldap/servers/slapd/vattr.c
+@@ -1996,7 +1996,7 @@ vattr_map_create(void)
+         return ENOMEM;
+     }
+ 
+-    the_map->lock = slapi_new_rwlock();
++    the_map->lock = slapi_new_rwlock_prio(1 /* priority on writers */);
+     if (NULL == the_map) {
+         slapd_nasty(sourcefile, 3, 0);
+         return ENOMEM;
+-- 
+2.25.4
+
diff --git a/SOURCES/0005-Issue-49624-modrdn-silently-fails-if-DB-deadlock-occ.patch b/SOURCES/0005-Issue-49624-modrdn-silently-fails-if-DB-deadlock-occ.patch
deleted file mode 100644
index 3323340..0000000
--- a/SOURCES/0005-Issue-49624-modrdn-silently-fails-if-DB-deadlock-occ.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From f50dfbb61224e6a9516b93cd3d3957c1fde4798e Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Thu, 22 Aug 2019 10:26:24 -0400
-Subject: [PATCH] Issue 49624 - modrdn silently fails if DB deadlock occurs
-
-Bug Description:
-
-If a DB Deadlock error occurs during a modrdn operation the entry
-cache gets updated (corrupted), but the update is not applied to
-the database.
-
-Fix Description:
-
-Looks like there was a copy & paste error, and the wrong attribute
-was updated during the retry of the modrdn operation.
-
-relates: https://pagure.io/389-ds-base/issue/49624
-
-Reviewed by: lkrispenz (Thanks!)
----
- ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-index 65610d613..433ed88fb 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-@@ -251,7 +251,7 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-             slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &dn_newsuperiordn);
-             slapi_sdn_free(&dn_newsuperiordn);
-             slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, orig_dn_newsuperiordn);
--            orig_dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
-+            dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
-             /* must duplicate ec before returning it to cache,
-              * which could free the entry. */
-             if ((tmpentry = backentry_dup(original_entry ? original_entry : ec)) == NULL) {
--- 
-2.21.0
-
diff --git a/SOURCES/0005-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch b/SOURCES/0005-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch
new file mode 100644
index 0000000..e0fb1d1
--- /dev/null
+++ b/SOURCES/0005-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch
@@ -0,0 +1,70 @@
+From 2e88d7ecfdd096ec3cd0b2fe7be0dacef74fe0c5 Mon Sep 17 00:00:00 2001
+From: Mark Reynolds <mreynolds@redhat.com>
+Date: Tue, 19 May 2020 11:25:13 -0400
+Subject: [PATCH 2/2] Issue 50745: ns-slapd hangs during CleanAllRUV tests
+
+Bug Description:
+	The hang condition:
+		- is not systematic
+		- occurs in rare case, for example here during the deletion of a replica.
+		- a thread is waiting for a dblock that an other thread "forgot" to
+		  release.
+		- have always existed, at least since 1.4.0 but likely since 1.2.x
+
+	When deleting a replica, the replica is retrieved from
+	mapping tree structure (mtnode).
+	The replica is also retrieved through the mapping tree
+	when writing updates to the changelog.
+
+	When deleting the replica, mapping tree structure is cleared
+	after the changelog is deleted (that can take some cycles).
+	There is a window where an update can retrieve the replica,
+	from the not yet cleared MT, while the changelog being removed.
+
+	At the end, the update will update the changelog that is
+	currently removed and keeps an unfree lock in the DB.
+
+Fix description:
+	Ideally mapping tree should be protected by a lock but it
+	is not done systematically (e.g.  slapi_get_mapping_tree_node).
+	Using a lock looks an overkill and can probably introduce
+	deadlock and performance hit.
+	The idea of the fix is to reduce the window, moving the
+	mapping tree clear before the changelog removal.
+
+https://pagure.io/389-ds-base/issue/50745
+
+Reviewed by: Mark Reynolds, Ludwig Krispenz
+---
+ ldap/servers/plugins/replication/repl5_replica_config.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
+index 80a079784..95b7fa50e 100644
+--- a/ldap/servers/plugins/replication/repl5_replica_config.c
++++ b/ldap/servers/plugins/replication/repl5_replica_config.c
+@@ -735,18 +735,18 @@ replica_config_delete(Slapi_PBlock *pb __attribute__((unused)),
+     PR_ASSERT(mtnode_ext);
+ 
+     if (mtnode_ext->replica) {
++        Object *repl_obj = mtnode_ext->replica;
+         /* remove object from the hash */
+         r = (Replica *)object_get_data(mtnode_ext->replica);
++        mtnode_ext->replica = NULL;
+         PR_ASSERT(r);
+         /* The changelog for this replica is no longer valid, so we should remove it. */
+         slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "replica_config_delete - "
+                                                            "The changelog for replica %s is no longer valid since "
+                                                            "the replica config is being deleted.  Removing the changelog.\n",
+                       slapi_sdn_get_dn(replica_get_root(r)));
+-        cl5DeleteDBSync(mtnode_ext->replica);
++        cl5DeleteDBSync(repl_obj);
+         replica_delete_by_name(replica_get_name(r));
+-        object_release(mtnode_ext->replica);
+-        mtnode_ext->replica = NULL;
+     }
+ 
+     PR_Unlock(s_configLock);
+-- 
+2.25.4
+
diff --git a/SOURCES/0006-Issue-50572-After-running-cl-dump-dbdir-cldb-ldif.do.patch b/SOURCES/0006-Issue-50572-After-running-cl-dump-dbdir-cldb-ldif.do.patch
deleted file mode 100644
index 2e93871..0000000
--- a/SOURCES/0006-Issue-50572-After-running-cl-dump-dbdir-cldb-ldif.do.patch
+++ /dev/null
@@ -1,153 +0,0 @@
-From d8935139d377ad75be4242db7d3194f3706dc44a Mon Sep 17 00:00:00 2001
-From: Simon Pichugin <spichugi@redhat.com>
-Date: Thu, 29 Aug 2019 15:51:56 +0200
-Subject: [PATCH] Issue 50572 - After running cl-dump dbdir/cldb/*ldif.done are
- not deleted
-
-Description: By default, remove ldif.done files after running cl-dump.
-Add an option '-l' which allows keep the files.
-Update man files.
-
-https://pagure.io/389-ds-base/issue/50572
-
-Reviewed by: firstyear, mreynolds (Thanks!)
----
- ldap/admin/src/scripts/cl-dump.pl | 23 +++++++++++++++--------
- man/man1/cl-dump.1                | 11 +++++++----
- 2 files changed, 22 insertions(+), 12 deletions(-)
-
-diff --git a/ldap/admin/src/scripts/cl-dump.pl b/ldap/admin/src/scripts/cl-dump.pl
-index f4ad5dd33..2e7f20413 100755
---- a/ldap/admin/src/scripts/cl-dump.pl
-+++ b/ldap/admin/src/scripts/cl-dump.pl
-@@ -5,7 +5,7 @@
- # All rights reserved.
- #
- # License: GPL (version 3 or any later version).
--# See LICENSE for details. 
-+# See LICENSE for details.
- # END COPYRIGHT BLOCK
- ###################################################################################
- #
-@@ -13,7 +13,7 @@
- #
- # SYNOPSIS:
- #  cl-dump.pl [-h host] [-p port] [-D bind-dn] -w bind-password | -P bind-cert
--#       [-r replica-roots] [-o output-file] [-c] [-v]
-+#       [-r replica-roots] [-o output-file] [-c] [-l] [-v]
- #
- #  cl-dump.pl -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]
- #
-@@ -22,7 +22,7 @@
- #
- # OPTIONS:
- #    -c Dump and interpret CSN only. This option can be used with or
--#       without -i option. 
-+#       without -i option.
- #
- #    -D bind-dn
- #       Directory server's bind DN. Default to "cn=Directory Manager" if
-@@ -32,6 +32,8 @@
- #       Directory server's host. Default to the server where the script
- #       is running.
- #
-+#    -l Preserve generated ldif.done files from changelogdir
-+#
- #    -i changelog-ldif-file-with-base64encoding
- #       If you already have a ldif-like changelog, but the changes
- #       in that file are encoded, you may use this option to
-@@ -68,7 +70,7 @@
- # all of this nonsense can be omitted if the mozldapsdk and perldap are
- # installed in the operating system locations (e.g. /usr/lib /usr/lib/perl5)
- 
--$usage="Usage: $0 [-h host] [-p port] [-D bind-dn] [-w bind-password | -P bind-cert] [-r replica-roots] [-o output-file] [-c] [-v]\n\n       $0 -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]\n";
-+$usage="Usage: $0 [-h host] [-p port] [-D bind-dn] [-w bind-password | -P bind-cert] [-r replica-roots] [-o output-file] [-c] [-l] [-v]\n\n       $0 -i changelog-ldif-file-with-base64encoding [-o output-file] [-c]\n";
- 
- use Getopt::Std;			# Parse command line arguments
- use Mozilla::LDAP::Conn;		# LDAP module for Perl
-@@ -86,7 +88,7 @@ $version = "Directory Server Changelog Dump - Version 1.0";
- 	$| = 1;
- 
- 	# Check for legal options
--	if (!getopts('h:p:D:w:P:r:o:cvi:')) {
-+	if (!getopts('h:p:D:w:P:r:o:clvi:')) {
- 		print $usage;
- 		exit -1;
- 	}
-@@ -123,7 +125,7 @@ sub validateArgs
- 	if ($opt_o && ! open (OUTPUT, ">$opt_o")) {
- 		print "Can't create output file $opt_o\n";
- 		$rc = -1;
--	} 
-+	}
- 	# Open STDOUT if option -o is missing
- 	open (OUTPUT, ">-") if !$opt_o;
- 
-@@ -194,10 +196,15 @@ sub cl_dump_and_decode
- 			else {
- 				&cl_decode ($_);
- 			}
--			# Test op -M doesn't work well so we use rename
-+			# Test op -M doesn't work well so we use rename/remove
- 			# here to avoid reading the same ldif file more
- 			# than once.
--			rename ($ldif, "$ldif.done");
-+			if ($opt_l) {
-+				rename ($ldif, "$ldif.done");
-+			} else {
-+				# Remove the file - default behaviou when '-l' is not specified
-+				unlink ($ldif)
-+			}
- 		}
- 		&print_header ($replica, "Not Found") if !$gotldif;
- 	}
-diff --git a/man/man1/cl-dump.1 b/man/man1/cl-dump.1
-index db736aca9..fbb836a72 100644
---- a/man/man1/cl-dump.1
-+++ b/man/man1/cl-dump.1
-@@ -20,7 +20,7 @@ cl-dump \- Dump and decode Directory Server replication change log
- .SH SYNOPSIS
- .B cl\-dump
- [\fI\-h host\fR] [\fI\-p port\fR] [\fI\-D bind\(hydn\fR] \-w bind\(hypassword | \-P bind\(hycert
--       [\fI\-r replica\(hyroots\fR] [\fI\-o output\(hyfile\fR] [\fI\-c\fR] [\fI\-v\fR]
-+       [\fI\-r replica\(hyroots\fR] [\fI\-o output\(hyfile\fR] [\fI\-c\fR] [\fI\-l\fR] [\fI\-v\fR]
- 
- .PP
- .B cl\-dump
-@@ -30,12 +30,12 @@ cl-dump \- Dump and decode Directory Server replication change log
- Dump and decode Directory Server replication change log
- .PP
- .\" TeX users may be more comfortable with the \fB<whatever>\fP and
--.\" \fI<whatever>\fP escape sequences to invode bold face and italics, 
-+.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
- .\" respectively.
- .SH OPTIONS
- A summary of options is included below.
- .TP
--.B \-c 
-+.B \-c
- Dump and interpret CSN only. This option can be used with or
- without \-i option.
- .TP
-@@ -47,6 +47,9 @@ the option is omitted.
- Directory server's host. Default to the server where the script
- is running.
- .TP
-+.B \-l
-+Preserve generated ldif.done files from changelogdir
-+.TP
- .B \-i changelog\(hyldif\(hyfile\(hywith\(hybase64encoding
- If you already have a ldif-like changelog, but the changes
- in that file are encoded, you may use this option to
-@@ -66,7 +69,7 @@ Specify replica roots whose changelog you want to dump. The replica
- roots may be separated by comma. All the replica roots would be
- dumped if the option is omitted.
- .TP
--.B \-v 
-+.B \-v
- Print the version of this script.
- .TP
- .B \-w bind\(hypassword
--- 
-2.21.0
-
diff --git a/SOURCES/0006-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch b/SOURCES/0006-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch
new file mode 100644
index 0000000..7a452fe
--- /dev/null
+++ b/SOURCES/0006-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch
@@ -0,0 +1,463 @@
+From d9f1be15663f673588e2746e5a97f8ee2c92769f Mon Sep 17 00:00:00 2001
+From: Mark Reynolds <mreynolds@redhat.com>
+Date: Fri, 22 May 2020 10:42:11 -0400
+Subject: [PATCH] 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       | 29 ++++++++-----
+ 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, 116 insertions(+), 41 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
+index b06c6fbf4..bdc59422a 100644
+--- a/ldap/servers/plugins/replication/repl5.h
++++ b/ldap/servers/plugins/replication/repl5.h
+@@ -775,7 +775,7 @@ void replica_disable_replication(Replica *r, Object *r_obj);
+ 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 cdbcde39a..c1b3ed73c 100644
+--- a/ldap/servers/plugins/replication/repl5_replica.c
++++ b/ldap/servers/plugins/replication/repl5_replica.c
+@@ -3976,10 +3976,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;
+     Object *replica_obj;
+ 
+     replica_obj = replica_get_replica_for_op(pb);
+@@ -3994,17 +3993,25 @@ 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) {
++                        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], 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 /* don't notify */) != 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",
+@@ -4014,7 +4021,7 @@ 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);
+                 }
+@@ -4023,7 +4030,7 @@ replica_generate_next_csn(Slapi_PBlock *pb, const CSN *basecsn)
+         object_release(replica_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 264f0ceea..09bfb8468 100644
+--- a/ldap/servers/slapd/back-ldbm/ldbm_add.c
++++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c
+@@ -644,7 +644,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 1ad846447..6c4229049 100644
+--- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c
++++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c
+@@ -463,7 +463,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 080eb15aa..12ac5678a 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 4c53d43dc..1d0a9cbeb 100644
+--- a/ldap/servers/slapd/slap.h
++++ b/ldap/servers/slapd/slap.h
+@@ -1464,7 +1464,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 865d83b9b..ea9bcf87b 100644
+--- a/ldap/servers/slapd/slapi-plugin.h
++++ b/ldap/servers/slapd/slapi-plugin.h
+@@ -6772,6 +6772,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 d676486a8..f37cfcd41 100644
+--- a/ldap/servers/slapd/slapi-private.h
++++ b/ldap/servers/slapd/slapi-private.h
+@@ -227,7 +227,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;
+@@ -320,7 +321,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/0007-Issue-50538-Fix-cherry-pick-error.patch b/SOURCES/0007-Issue-50538-Fix-cherry-pick-error.patch
deleted file mode 100644
index 7260efe..0000000
--- a/SOURCES/0007-Issue-50538-Fix-cherry-pick-error.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-From 5fee4d79db94684d8093501fde3422ad34ac2716 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 3 Sep 2019 13:40:27 -0400
-Subject: [PATCH] Issue 50538 - Fix cherry-pick error
-
-Description:  Remove cherry-=pick error formating
-
-relates: https://pagure.io/389-ds-base/issue/50538
----
- dirsrvtests/tests/suites/replication/cleanallruv_test.py | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/dirsrvtests/tests/suites/replication/cleanallruv_test.py b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
-index 43801dd52..caf214b19 100644
---- a/dirsrvtests/tests/suites/replication/cleanallruv_test.py
-+++ b/dirsrvtests/tests/suites/replication/cleanallruv_test.py
-@@ -899,7 +899,6 @@ def test_max_tasks(topology_m4):
- 
-     # Check the errors log for our error message in master 1
-     assert m1.searchErrorsLog('Exceeded maximum number of active CLEANALLRUV tasks')
-->>>>>>> ab24aa4cb... Issue 50538 - cleanAllRUV task limit is not enforced for replicated tasks
- 
- 
- if __name__ == '__main__':
--- 
-2.21.0
-
diff --git a/SOURCES/0007-Issue-51132-Winsync-setting-winSyncWindowsFilter-not.patch b/SOURCES/0007-Issue-51132-Winsync-setting-winSyncWindowsFilter-not.patch
new file mode 100644
index 0000000..501d9ac
--- /dev/null
+++ b/SOURCES/0007-Issue-51132-Winsync-setting-winSyncWindowsFilter-not.patch
@@ -0,0 +1,100 @@
+From fe51cdabe75917e82195fcad47563fc169026625 Mon Sep 17 00:00:00 2001
+From: Mark Reynolds <mreynolds@redhat.com>
+Date: Wed, 3 Jun 2020 15:58:21 -0400
+Subject: [PATCH] Issue 51132 - Winsync setting winSyncWindowsFilter not
+ working as expected
+
+Bug Description:  When processing updates from AD we search AD using a filter,
+                  and this filter can be customized via the attribute setting:
+                  winSyncWindowsFilter.  However, after setting a custom filter
+                  replication appears to stop working as expected.  New entries
+                  that match the filter are replicated to DS, but not updates
+                  to these entries.  The problem is that when dirsync sends
+                  updates, it is just a partial entry - only containing the
+                  attributes that changed.  Then the server checks the filter
+                  again on the returned entry, but if it's just a mod update then
+                  the entry is missing most of its attributes, and the filter
+                  check fails and the entry is not updated on DS.
+
+Fix Description:  Do not check the filter on the returned entries when processing
+                  incremental updates as the fitler test was already done when
+                  gathering the candidates.
+
+relates: https://pagure.io/389-ds-base/issue/51132
+
+Reviewed by: tbordaz & firstyear (Thanks!)
+---
+ .../plugins/replication/windows_protocol_util.c   | 15 +++++++++------
+ 1 file changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
+index e35437221..c394f82ce 100644
+--- a/ldap/servers/plugins/replication/windows_protocol_util.c
++++ b/ldap/servers/plugins/replication/windows_protocol_util.c
+@@ -48,7 +48,7 @@ static int windows_get_remote_entry(Private_Repl_Protocol *prp, const Slapi_DN *
+ static int windows_get_remote_tombstone(Private_Repl_Protocol *prp, const Slapi_DN *remote_dn, Slapi_Entry **remote_entry);
+ static int windows_reanimate_tombstone(Private_Repl_Protocol *prp, const Slapi_DN *tombstone_dn, const char *new_dn);
+ static const char *op2string(int op);
+-static int is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra);
++static int is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra, int test_filter);
+ static int map_entry_dn_inbound(Slapi_Entry *e, Slapi_DN **dn, const Repl_Agmt *ra);
+ static int map_entry_dn_inbound_ext(Slapi_Entry *e, Slapi_DN **dn, const Repl_Agmt *ra, int use_guid, int user_username);
+ static int windows_update_remote_entry(Private_Repl_Protocol *prp, Slapi_Entry *remote_entry, Slapi_Entry *local_entry, int is_user);
+@@ -57,6 +57,9 @@ static int map_windows_tombstone_dn(Slapi_Entry *e, Slapi_DN **dn, Private_Repl_
+ static int windows_check_mods_for_rdn_change(Private_Repl_Protocol *prp, LDAPMod **original_mods, Slapi_Entry *local_entry, Slapi_DN *remote_dn, char **newrdn);
+ static int windows_get_superior_change(Private_Repl_Protocol *prp, Slapi_DN *local_dn, Slapi_DN *remote_dn, char **newsuperior, int to_windows);
+ 
++#define SKIP_FILTER 0
++#define TEST_FILTER 1
++
+ /* Controls the direction of flow for mapped attributes */
+ typedef enum mapping_types {
+     bidirectional,
+@@ -442,7 +445,7 @@ map_dn_values(Private_Repl_Protocol *prp, Slapi_ValueSet *original_values, Slapi
+             /* Try to get the remote entry */
+             retval = windows_get_remote_entry(prp, original_dn, &remote_entry);
+             if (remote_entry && 0 == retval) {
+-                is_ours = is_subject_of_agreement_remote(remote_entry, prp->agmt);
++                is_ours = is_subject_of_agreement_remote(remote_entry, prp->agmt, TEST_FILTER);
+                 if (is_ours) {
+                     retval = map_entry_dn_inbound(remote_entry, &local_dn, prp->agmt);
+                     if (0 == retval && local_dn) {
+@@ -3708,7 +3711,7 @@ map_entry_dn_outbound(Slapi_Entry *e,
+                       slapi_sdn_get_dn(new_dn),
+                       remote_entry ? slapi_entry_get_dn_const(remote_entry) : "(null)");
+         if (0 == rc && remote_entry) {
+-            if (!is_subject_of_agreement_remote(remote_entry, prp->agmt)) {
++            if (!is_subject_of_agreement_remote(remote_entry, prp->agmt, TEST_FILTER)) {
+                 /* The remote entry is out of scope of the agreement.
+                  * Thus, we don't map the entry_dn.
+                  * This occurs when the remote entry is moved out. */
+@@ -4198,7 +4201,7 @@ is_dn_subject_of_agreement_local(const Slapi_DN *sdn, const Repl_Agmt *ra)
+  *               0 -- out of scope
+  */
+ static int
+-is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra)
++is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra, int test_filter)
+ {
+     int retval = 0;
+     int is_in_subtree = 0;
+@@ -4232,7 +4235,7 @@ is_subject_of_agreement_remote(Slapi_Entry *e, const Repl_Agmt *ra)
+         Slapi_DN psdn = {0};
+         Slapi_Entry *pentry = NULL;
+ 
+-        if (windows_private_get_windows_filter(ra) &&
++        if (test_filter && windows_private_get_windows_filter(ra) &&
+             slapi_filter_test_simple(e, windows_private_get_windows_filter(ra))) {
+             /* type_winSyncWindowsFilter is set and the remote entry does not match the filter */
+             goto error;
+@@ -5627,7 +5630,7 @@ windows_process_dirsync_entry(Private_Repl_Protocol *prp, Slapi_Entry *e, int is
+         }
+     } else {
+         /* Is this entry one we should be interested in ? */
+-        if (is_subject_of_agreement_remote(e, prp->agmt)) {
++        if (is_subject_of_agreement_remote(e, prp->agmt, SKIP_FILTER)) {
+             ConnResult cres = 0;
+             const char *searchbase = slapi_entry_get_dn_const(e);
+             char *filter = "(objectclass=*)";
+-- 
+2.26.2
+
diff --git a/SOURCES/0008-Issue-50646-Improve-task-handling-during-shutdowns.patch b/SOURCES/0008-Issue-50646-Improve-task-handling-during-shutdowns.patch
deleted file mode 100644
index 30eabd6..0000000
--- a/SOURCES/0008-Issue-50646-Improve-task-handling-during-shutdowns.patch
+++ /dev/null
@@ -1,172 +0,0 @@
-From 81587cabb358bb24d0ae2623076e09676a4a0620 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 15 Oct 2019 11:02:24 -0400
-Subject: [PATCH] Issue 50646 - Improve task handling during shutdowns
-
-Bug Description:  There is a race condition when stopping the server and
-                  a running import task that can cause a heap-use-after-free.
-
-Fix Description:  For an import task, encapsulate the import thread with
-                  a global thread increment/decrement (just like the export
-                  task).  Also improved how tasks are notified to abort by
-                  notifiying them before we wait for active threads to finish.
-                  Then the tasks get destroyed after all threads are complete.
-
-relates: https://pagure.io/389-ds-base/issue/50646
-
-Reviewed by: lkrispen & tbordaz (Thanks!!)
----
- ldap/servers/slapd/back-ldbm/import.c |  3 ++
- ldap/servers/slapd/daemon.c           |  5 ++++
- ldap/servers/slapd/main.c             |  2 +-
- ldap/servers/slapd/slapi-private.h    |  1 +
- ldap/servers/slapd/task.c             | 40 +++++++++++++++++----------
- 5 files changed, 35 insertions(+), 16 deletions(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c
-index 42e2696d3..1c21f6e55 100644
---- a/ldap/servers/slapd/back-ldbm/import.c
-+++ b/ldap/servers/slapd/back-ldbm/import.c
-@@ -1626,7 +1626,10 @@ error:
- void
- import_main(void *arg)
- {
-+    /* For online import tasks increment/decrement the global thread count */
-+    g_incr_active_threadcnt();
-     import_main_offline(arg);
-+    g_decr_active_threadcnt();
- }
- 
- int
-diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
-index afe0fb737..5d8767df6 100644
---- a/ldap/servers/slapd/daemon.c
-+++ b/ldap/servers/slapd/daemon.c
-@@ -1218,6 +1218,11 @@ slapd_daemon(daemon_ports_t *ports, ns_thrpool_t *tp)
-         ns_thrpool_wait(tp);
-     }
- 
-+    if (!in_referral_mode) {
-+        /* signal tasks to start shutting down */
-+        task_cancel_all();
-+    }
-+
-     threads = g_get_active_threadcnt();
-     if (threads > 0) {
-         slapi_log_err(SLAPI_LOG_INFO, "slapd_daemon",
-diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
-index 5e24b3b5f..5ca52ce74 100644
---- a/ldap/servers/slapd/main.c
-+++ b/ldap/servers/slapd/main.c
-@@ -1989,7 +1989,7 @@ lookup_plugin_by_instance_name(const char *name)
- {
-     Slapi_Entry **entries = NULL;
-     Slapi_PBlock *pb = slapi_pblock_new();
--    struct slapdplugin *plugin;
-+    struct slapdplugin *plugin = NULL;
-     char *query, *dn, *cn;
-     int ret = 0;
- 
-diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
-index b347b6162..d676486a8 100644
---- a/ldap/servers/slapd/slapi-private.h
-+++ b/ldap/servers/slapd/slapi-private.h
-@@ -794,6 +794,7 @@ int slapi_lookup_instance_name_by_suffix(char *suffix,
- 
- /* begin and end the task subsystem */
- void task_init(void);
-+void task_cancel_all(void);
- void task_shutdown(void);
- void task_cleanup(void);
- 
-diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
-index 80a238392..7e7094750 100644
---- a/ldap/servers/slapd/task.c
-+++ b/ldap/servers/slapd/task.c
-@@ -26,7 +26,7 @@
-  */
- static Slapi_Task *global_task_list = NULL;
- static PRLock *global_task_lock = NULL;
--static int shutting_down = 0;
-+static uint64_t shutting_down = 0;
- 
- /***********************************
-  * Private Defines
-@@ -588,7 +588,7 @@ new_task(const char *rawdn, void *plugin)
-     Slapi_Task *task = NULL;
-     char *dn = NULL;
- 
--    if (rawdn == NULL) {
-+    if (rawdn == NULL || shutting_down) {
-         return NULL;
-     }
- 
-@@ -600,9 +600,20 @@ new_task(const char *rawdn, void *plugin)
-     }
-     task = (Slapi_Task *)slapi_ch_calloc(1, sizeof(Slapi_Task));
-     PR_Lock(global_task_lock);
-+    if (shutting_down) {
-+        /* Abort!  Free everything and return NULL */
-+        PR_Unlock(task->task_log_lock);
-+        PR_Unlock(global_task_lock);
-+        PR_DestroyLock(task->task_log_lock);
-+        slapi_ch_free((void **)&task);
-+        slapi_ch_free_string(&dn);
-+        slapi_log_err(SLAPI_LOG_ERR, "new_task", "Server is shutting down, aborting task: %s\n", rawdn);
-+        return NULL;
-+    }
-     task->next = global_task_list;
-     global_task_list = task;
-     PR_Unlock(global_task_lock);
-+
-     task->task_dn = dn;
-     task->task_state = SLAPI_TASK_SETUP;
-     task->task_flags = SLAPI_TASK_RUNNING_AS_TASK;
-@@ -2990,32 +3001,31 @@ task_init(void)
- 
- /* called when the server is shutting down -- abort all existing tasks */
- void
--task_shutdown(void)
--{
-+task_cancel_all(void) {
-     Slapi_Task *task;
--    int found_any = 0;
- 
--    /* first, cancel all tasks */
-     PR_Lock(global_task_lock);
-     shutting_down = 1;
-     for (task = global_task_list; task; task = task->next) {
--        if ((task->task_state != SLAPI_TASK_CANCELLED) &&
--            (task->task_state != SLAPI_TASK_FINISHED)) {
-+        if (task->task_state != SLAPI_TASK_CANCELLED &&
-+            task->task_state != SLAPI_TASK_FINISHED)
-+        {
-             task->task_state = SLAPI_TASK_CANCELLED;
-             if (task->cancel) {
--                slapi_log_err(SLAPI_LOG_INFO, "task_shutdown", "Cancelling task '%s'\n",
-+                slapi_log_err(SLAPI_LOG_INFO, "task_cancel_all", "Canceling task '%s'\n",
-                               task->task_dn);
-                 (*task->cancel)(task);
--                found_any = 1;
-             }
-         }
-     }
-+    PR_Unlock(global_task_lock);
-+}
- 
--    if (found_any) {
--        /* give any tasks 1 second to say their last rites */
--        DS_Sleep(PR_SecondsToInterval(1));
--    }
--
-+void
-+task_shutdown(void)
-+{
-+    /* Now we can destroy the tasks... */
-+    PR_Lock(global_task_lock);
-     while (global_task_list) {
-         destroy_task(0, global_task_list);
-     }
--- 
-2.21.0
-
diff --git a/SOURCES/0009-Issue-50653-objectclass-parsing-fails-to-log-error-m.patch b/SOURCES/0009-Issue-50653-objectclass-parsing-fails-to-log-error-m.patch
deleted file mode 100644
index 7ad32f8..0000000
--- a/SOURCES/0009-Issue-50653-objectclass-parsing-fails-to-log-error-m.patch
+++ /dev/null
@@ -1,69 +0,0 @@
-From df8ad0467a6c5e69b8bd5f48e23582734d78b356 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Wed, 16 Oct 2019 14:16:55 -0400
-Subject: [PATCH] Issue 50653 -  objectclass parsing fails to log error message
- text
-
-Description:  When replacing an objectclass, if it already exists we
-              log an error but we do not log what objectclass it is.
-              This commit adds the error message text.
-
-relates: https://pagure.io/389-ds-base/issue/50653
-
-Reviewed by: abbra(Thanks!)
----
- ldap/servers/slapd/schema.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
-diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
-index 68c98341a..e4f0d663e 100644
---- a/ldap/servers/slapd/schema.c
-+++ b/ldap/servers/slapd/schema.c
-@@ -126,7 +126,7 @@ static struct dse *pschemadse = NULL;
- 
- static void oc_add_nolock(struct objclass *newoc);
- static int oc_delete_nolock(char *ocname);
--static int oc_replace_nolock(const char *ocname, struct objclass *newoc);
-+static int oc_replace_nolock(const char *ocname, struct objclass *newoc, char *errorbuf, size_t errorbufsize);
- static int oc_check_required(Slapi_PBlock *, Slapi_Entry *, struct objclass *);
- static int oc_check_allowed_sv(Slapi_PBlock *, Slapi_Entry *e, const char *type, struct objclass **oclist);
- static int schema_delete_objectclasses(Slapi_Entry *entryBefore,
-@@ -1110,7 +1110,7 @@ oc_find_oid_nolock(const char *ocoid)
- */
- 
- static int
--oc_replace_nolock(const char *ocname, struct objclass *newoc)
-+oc_replace_nolock(const char *ocname, struct objclass *newoc, char *errorbuf, size_t errorbufsize)
- {
-     struct objclass *oc, *pnext;
-     int rc = LDAP_SUCCESS;
-@@ -1130,6 +1130,8 @@ oc_replace_nolock(const char *ocname, struct objclass *newoc)
-         for (pnext = oc; pnext != NULL;
-              oc = pnext, pnext = pnext->oc_next) {
-             if (pnext->oc_name == NULL) {
-+                schema_create_errormsg(errorbuf, errorbufsize, schema_errprefix_oc,
-+                                       ocname, "Failed to replace objectclass");
-                 rc = LDAP_OPERATIONS_ERROR;
-                 break;
-             }
-@@ -1146,6 +1148,8 @@ oc_replace_nolock(const char *ocname, struct objclass *newoc)
-                     break;
- 
-                 } else {
-+                    schema_create_errormsg(errorbuf, errorbufsize, schema_errprefix_oc,
-+                                           ocname, "Can not replace objectclass that already exists");
-                     rc = LDAP_TYPE_OR_VALUE_EXISTS;
-                     break;
-                 }
-@@ -2817,7 +2821,7 @@ add_oc_internal(struct objclass *pnew_oc, char *errorbuf, size_t errorbufsize, i
-     /* insert new objectclass exactly where the old one one in the linked list*/
-     if (!rc && redefined_oc) {
-         pnew_oc->oc_flags |= OC_FLAG_REDEFINED_OC;
--        rc = oc_replace_nolock(pnew_oc->oc_name, pnew_oc);
-+        rc = oc_replace_nolock(pnew_oc->oc_name, pnew_oc, errorbuf, errorbufsize);
-     }
- 
-     if (!rc && !redefined_oc) {
--- 
-2.21.0
-
diff --git a/SOURCES/0010-Issue-50655-access-log-etime-is-not-properly-formatt.patch b/SOURCES/0010-Issue-50655-access-log-etime-is-not-properly-formatt.patch
deleted file mode 100644
index 7e90d4b..0000000
--- a/SOURCES/0010-Issue-50655-access-log-etime-is-not-properly-formatt.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-From f4a5a7f3074e15c3439fd906bef78568bd6ab13c Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Wed, 16 Oct 2019 16:52:59 -0400
-Subject: [PATCH] Issue 50655 - access log etime is not properly formatted
-
-Description:  The wrong printf format was used for displaying the nanosecond etime
-              in the access log.
-
-relates: https://pagure.io/389-ds-base/issue/50655
-
-Reviewed by: firstyear(Thanks!)
----
- ldap/servers/slapd/result.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/ldap/servers/slapd/result.c b/ldap/servers/slapd/result.c
-index 34ddd8566..61e7a70f9 100644
---- a/ldap/servers/slapd/result.c
-+++ b/ldap/servers/slapd/result.c
-@@ -1925,7 +1925,8 @@ log_result(Slapi_PBlock *pb, Operation *op, int err, ber_tag_t tag, int nentries
-     struct timespec o_hr_time_end;
-     slapi_operation_time_elapsed(op, &o_hr_time_end);
- 
--    snprintf(etime, ETIME_BUFSIZ, "%" PRId64 ".%010" 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);
- 
-     slapi_pblock_get(pb, SLAPI_OPERATION_NOTES, &operation_notes);
- 
--- 
-2.21.0
-
diff --git a/SOURCES/0011-Issue-49850-ldbm_get_nonleaf_ids-slow-for-databases-.patch b/SOURCES/0011-Issue-49850-ldbm_get_nonleaf_ids-slow-for-databases-.patch
deleted file mode 100644
index 4ab1ce5..0000000
--- a/SOURCES/0011-Issue-49850-ldbm_get_nonleaf_ids-slow-for-databases-.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From d8875611eefff661ad3f92b6f75b0c90c22918a6 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Wed, 16 Oct 2019 20:27:30 -0400
-Subject: [PATCH] Issue 49850 -  ldbm_get_nonleaf_ids() slow for databases with
- many non-leaf entries
-
-Bug Description:  The logs from an LDIF import indicated that gathering non-leaf IDs
-                  for creating the ancestorid index took an enormous amount of time,
-                  over 10hrs.  The root cause is that the parentid index btree ordering
-                  is lexical, but the IDList being built up from it is sorted numerically.
-                  In the existing code, the IDList is maintained in constantly sorted
-                  order by idl_insert().
-
-Fix Description:  ldbm_get_nonleaf_ids() switches to idl_append_extend() instead idl_insert()
-                  for building up the IDList and then sorts the result only once, using
-                  qsort with idl_sort_cmp, after the entire list has been gathered.
-
-                  The improvement on identical hardware is for the operation to take 10
-                  seconds rather than 10 hours
-
-Patch Author:  Thomas Lackey <telackey@bozemanpass.com>  Thanks for the great contribution!!!
-
-relates: https://pagure.io/389-ds-base/issue/49850
-
-Reviewed by: mreynolds, tbordaz, and firstyear
----
- ldap/servers/slapd/back-ldbm/ancestorid.c | 20 +++++++++++++++++++-
- 1 file changed, 19 insertions(+), 1 deletion(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/ancestorid.c b/ldap/servers/slapd/back-ldbm/ancestorid.c
-index 24642923d..254a3aa3b 100644
---- a/ldap/servers/slapd/back-ldbm/ancestorid.c
-+++ b/ldap/servers/slapd/back-ldbm/ancestorid.c
-@@ -82,7 +82,14 @@ ldbm_get_nonleaf_ids(backend *be, DB_TXN *txn, IDList **idl, ImportJob *job)
-         ret = dbc->c_get(dbc, &key, &data, DB_NEXT_NODUP);
-         if ((ret == 0) && (*(char *)key.data == EQ_PREFIX)) {
-             id = (ID)strtoul((char *)key.data + 1, NULL, 10);
--            idl_insert(&nodes, id);
-+            /*
-+             * TEL 20180711 - switch to idl_append instead of idl_insert because there is no
-+             * no need to keep the list constantly sorted, which can be very expensive with
-+             * large databases (exacerbated by the fact that the parentid btree ordering is
-+             * lexical, but the idl_insert ordering is numeric).  It is enough to gather them
-+             * all together and sort them once at the end.
-+             */
-+            idl_append_extend(&nodes, id);
-         }
-         key_count++;
-         if (!(key_count % PROGRESS_INTERVAL)) {
-@@ -107,6 +114,17 @@ ldbm_get_nonleaf_ids(backend *be, DB_TXN *txn, IDList **idl, ImportJob *job)
-     if (ret != 0)
-         ldbm_nasty("ldbm_get_nonleaf_ids", sourcefile, 13030, ret);
- 
-+    if (ret == 0) {
-+        /* now sort it */
-+        import_log_notice(job, SLAPI_LOG_INFO, "ldbm_get_nonleaf_ids",
-+            "Starting sort of ancestorid non-leaf IDs...");
-+
-+        qsort((void *)&nodes->b_ids[0], nodes->b_nids, (size_t)sizeof(ID), idl_sort_cmp);
-+
-+        import_log_notice(job, SLAPI_LOG_INFO, "ldbm_get_nonleaf_ids",
-+            "Finished sort of ancestorid non-leaf IDs.");
-+    }
-+
- out:
-     /* Close the cursor */
-     if (dbc != NULL) {
--- 
-2.21.0
-
diff --git a/SOURCES/0012-Issue-50536-Audit-log-heading-written-to-log-after-e.patch b/SOURCES/0012-Issue-50536-Audit-log-heading-written-to-log-after-e.patch
deleted file mode 100644
index 3baf2cb..0000000
--- a/SOURCES/0012-Issue-50536-Audit-log-heading-written-to-log-after-e.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 177faf2c7080d3476798d305451e8ee19ea47f8d Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Wed, 7 Aug 2019 16:57:17 -0400
-Subject: [PATCH] Issue 50536 - Audit log heading written to log after every
- update
-
-Bug Description:  Once the audit log is rotated the log "title" is incorrectly
-                  written to the log after every single update.  This happened
-                  becuase when we udpated the state of the log it was applied
-                  to a local variable, and not the log info structure itself.
-
-Fix Description:  After writting the "title", update the state of the log using
-                  a pointer to the log info structure.
-
-relates: https://pagure.io/389-ds-base/issue/50536
-
-Reviewed by: lkrispenz(Thanks!)
----
- ldap/servers/slapd/log.c        | 14 +++++++-------
- ldap/servers/slapd/proto-slap.h |  2 +-
- 2 files changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
-index 2456abf1e..f308a4813 100644
---- a/ldap/servers/slapd/log.c
-+++ b/ldap/servers/slapd/log.c
-@@ -2073,11 +2073,11 @@ slapd_log_audit(
-     int retval = LDAP_SUCCESS;
-     int lbackend = loginfo.log_backend; /* We copy this to make these next checks atomic */
- 
--    int state = 0;
-+    int *state;
-     if (sourcelog == SLAPD_AUDIT_LOG) {
--        state = loginfo.log_audit_state;
-+        state = &loginfo.log_audit_state;
-     } else if (sourcelog == SLAPD_AUDITFAIL_LOG) {
--        state = loginfo.log_auditfail_state;
-+        state = &loginfo.log_auditfail_state;
-     } else {
-         /* How did we even get here! */
-         return 1;
-@@ -2106,9 +2106,9 @@ int
- slapd_log_audit_internal(
-     char *buffer,
-     int buf_len,
--    int state)
-+    int *state)
- {
--    if ((state & LOGGING_ENABLED) && (loginfo.log_audit_file != NULL)) {
-+    if ((*state & LOGGING_ENABLED) && (loginfo.log_audit_file != NULL)) {
-         LOG_AUDIT_LOCK_WRITE();
-         if (log__needrotation(loginfo.log_audit_fdes,
-                               SLAPD_AUDIT_LOG) == LOG_ROTATE) {
-@@ -2122,9 +2122,9 @@ slapd_log_audit_internal(
-                 loginfo.log_audit_rotationsyncclock += PR_ABS(loginfo.log_audit_rotationtime_secs);
-             }
-         }
--        if (state & LOGGING_NEED_TITLE) {
-+        if (*state & LOGGING_NEED_TITLE) {
-             log_write_title(loginfo.log_audit_fdes);
--            state &= ~LOGGING_NEED_TITLE;
-+            *state &= ~LOGGING_NEED_TITLE;
-         }
-         LOG_WRITE_NOW_NO_ERR(loginfo.log_audit_fdes, buffer, buf_len, 0);
-         LOG_AUDIT_UNLOCK_WRITE();
-diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
-index a0648ca3c..e37f702ea 100644
---- a/ldap/servers/slapd/proto-slap.h
-+++ b/ldap/servers/slapd/proto-slap.h
-@@ -777,7 +777,7 @@ int slapi_log_access(int level, char *fmt, ...)
-     ;
- #endif
- int slapd_log_audit(char *buffer, int buf_len, int sourcelog);
--int slapd_log_audit_internal(char *buffer, int buf_len, int state);
-+int slapd_log_audit_internal(char *buffer, int buf_len, int *state);
- int slapd_log_auditfail(char *buffer, int buf_len);
- int slapd_log_auditfail_internal(char *buffer, int buf_len);
- void log_access_flush(void);
--- 
-2.21.0
-
diff --git a/SOURCES/0013-Issue-50636-Crash-during-sasl-bind.patch b/SOURCES/0013-Issue-50636-Crash-during-sasl-bind.patch
deleted file mode 100644
index aa71560..0000000
--- a/SOURCES/0013-Issue-50636-Crash-during-sasl-bind.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-From fbbbcda083034031e564e8772affe815f2058047 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Thu, 17 Oct 2019 09:42:02 -0400
-Subject: [PATCH] Issue 50636 - Crash during sasl bind
-
-Bug Description:
-	Sasl bind registers IO layers (sasl_IoMethods) that will be
-	pushed (and called) by the next incoming operation.
-	So the next incoming operation should synchronize itself
-	with the sasl bind.
-
-Fix Description:
-	The call to connection_call_io_layer_callbacks, that pushes
-	registered methods, must hold c_mutex so that it let
-	a pending sasl bind to fully register the methods.
-
-https://pagure.io/389-ds-base/issue/50636
-
-Reviewed by: Ludwig Krispenz, Mark Reynolds
----
- ldap/servers/slapd/connection.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
-index 845a67091..9abd546f9 100644
---- a/ldap/servers/slapd/connection.c
-+++ b/ldap/servers/slapd/connection.c
-@@ -1585,12 +1585,14 @@ connection_threadmain()
-                      */
-                     pb_conn->c_anonlimits_set = 1;
-                 }
--                PR_ExitMonitor(pb_conn->c_mutex);
--
-+                /* must hold c_mutex so that it synchronizes the IO layer push
-+                 * with a potential pending sasl bind that is registering the IO layer
-+                 */
-                 if (connection_call_io_layer_callbacks(pb_conn)) {
-                     slapi_log_err(SLAPI_LOG_ERR, "connection_threadmain",
-                                   "Could not add/remove IO layers from connection\n");
-                 }
-+		PR_ExitMonitor(pb_conn->c_mutex);
-                 break;
-             default:
-                 break;
--- 
-2.21.0
-
diff --git a/SOURCES/0014-Ticket-49850-cont-fix-crash-in-ldbm_non_leaf.patch b/SOURCES/0014-Ticket-49850-cont-fix-crash-in-ldbm_non_leaf.patch
deleted file mode 100644
index d6afcf3..0000000
--- a/SOURCES/0014-Ticket-49850-cont-fix-crash-in-ldbm_non_leaf.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 87b7e568cd1f31ef107a0880dd21198b2b401612 Mon Sep 17 00:00:00 2001
-From: Ludwig Krispenz <lkrispen@redhat.com>
-Date: Thu, 24 Oct 2019 14:26:20 +0200
-Subject: [PATCH] Ticket 49850 cont -fix crash in ldbm_non_leaf
-
-        Bug: if the ldif to be imported contains only one entry there are no leaf nodes
-                and the call to qsort crashes
-
-        Fix: check that nodes is not NULL
----
- ldap/servers/slapd/back-ldbm/ancestorid.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/ancestorid.c b/ldap/servers/slapd/back-ldbm/ancestorid.c
-index 254a3aa3b..f26ac1364 100644
---- a/ldap/servers/slapd/back-ldbm/ancestorid.c
-+++ b/ldap/servers/slapd/back-ldbm/ancestorid.c
-@@ -114,7 +114,7 @@ ldbm_get_nonleaf_ids(backend *be, DB_TXN *txn, IDList **idl, ImportJob *job)
-     if (ret != 0)
-         ldbm_nasty("ldbm_get_nonleaf_ids", sourcefile, 13030, ret);
- 
--    if (ret == 0) {
-+    if (ret == 0 && nodes) {
-         /* now sort it */
-         import_log_notice(job, SLAPI_LOG_INFO, "ldbm_get_nonleaf_ids",
-             "Starting sort of ancestorid non-leaf IDs...");
--- 
-2.21.0
-
diff --git a/SOURCES/0015-Ticket-49624-cont-DB-Deadlock-on-modrdn-appears-to-c.patch b/SOURCES/0015-Ticket-49624-cont-DB-Deadlock-on-modrdn-appears-to-c.patch
deleted file mode 100644
index 9e469a4..0000000
--- a/SOURCES/0015-Ticket-49624-cont-DB-Deadlock-on-modrdn-appears-to-c.patch
+++ /dev/null
@@ -1,162 +0,0 @@
-From 1e050b8bee725bfdc4bb6e12bf062227437935a7 Mon Sep 17 00:00:00 2001
-From: Ludwig Krispenz <lkrispen@redhat.com>
-Date: Thu, 30 Jan 2020 17:26:35 +0100
-Subject: [PATCH]     Ticket 49624 cont - DB Deadlock on modrdn appears to
- corrupt database and entry cache
-
-    Bug: If there are deadlocks a transaction will be retried. In the case
-            of modrdn operation there is an error in handling the newsuperior
-            dn, which has to be reset when the txn is repeated.
-         There is also an error in freeing the entry stored in the pblock which can
-            lead to a double free
-         There is also a memory leak for ec entries
-
-    Fix: check if the newsuperior in the pblock was changed before the retry and
-            only then free and reset it.
-         check and protect pblock entry from double free
-         remove ec entry from cache
-
-         There is also a message at shutdown that entries remain in the entry cache
-            although no leaks are reported and a hash dump didn't show entries.
-            Change log level to avoid confusion
-
-    Reviewed by: Thierry, William, Viktor - Thanks
----
- ldap/servers/slapd/back-ldbm/cache.c       |  2 +-
- ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 60 ++++++++++++++++------
- 2 files changed, 44 insertions(+), 18 deletions(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/cache.c b/ldap/servers/slapd/back-ldbm/cache.c
-index 02453abac..c8d9f606b 100644
---- a/ldap/servers/slapd/back-ldbm/cache.c
-+++ b/ldap/servers/slapd/back-ldbm/cache.c
-@@ -723,7 +723,7 @@ entrycache_clear_int(struct cache *cache)
-     }
-     cache->c_maxsize = size;
-     if (cache->c_curentries > 0) {
--        slapi_log_err(SLAPI_LOG_WARNING,
-+        slapi_log_err(SLAPI_LOG_CACHE,
-                       "entrycache_clear_int", "There are still %" PRIu64 " entries "
-                                               "in the entry cache.\n",
-                       cache->c_curentries);
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-index 433ed88fb..26698012a 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
-@@ -67,6 +67,7 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-     Slapi_DN *dn_newsuperiordn = NULL;
-     Slapi_DN dn_parentdn;
-     Slapi_DN *orig_dn_newsuperiordn = NULL;
-+    Slapi_DN *pb_dn_newsuperiordn = NULL; /* used to check what is currently in the pblock */
-     Slapi_Entry *target_entry = NULL;
-     Slapi_Entry *original_targetentry = NULL;
-     int rc;
-@@ -248,30 +249,45 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-             slapi_sdn_set_dn_byref(&dn_newrdn, original_newrdn);
-             original_newrdn = slapi_ch_strdup(original_newrdn);
- 
--            slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &dn_newsuperiordn);
--            slapi_sdn_free(&dn_newsuperiordn);
--            slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, orig_dn_newsuperiordn);
--            dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
-+            /* we need to restart with the original newsuperiordn which could have
-+             * been modified. So check what is in the pblock, if it was changed
-+             * free it, reset orig dn in th epblock and recreate a working superior
-+             */
-+            slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &pb_dn_newsuperiordn);
-+            if (pb_dn_newsuperiordn != orig_dn_newsuperiordn) {
-+                slapi_sdn_free(&pb_dn_newsuperiordn);
-+                slapi_pblock_set(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, orig_dn_newsuperiordn);
-+                dn_newsuperiordn = slapi_sdn_dup(orig_dn_newsuperiordn);
-+            }
-             /* must duplicate ec before returning it to cache,
-              * which could free the entry. */
--            if ((tmpentry = backentry_dup(original_entry ? original_entry : ec)) == NULL) {
-+            if (!original_entry) {
-+                slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_modrdn",
-+                    "retrying transaction, but no original entry found\n");
-+                ldap_result_code = LDAP_OPERATIONS_ERROR;
-+                goto error_return;
-+            }
-+            if ((tmpentry = backentry_dup(original_entry)) == NULL) {
-                 ldap_result_code = LDAP_OPERATIONS_ERROR;
-                 goto error_return;
-             }
-             slapi_pblock_get(pb, SLAPI_MODRDN_EXISTING_ENTRY, &ent);
-             if (cache_is_in_cache(&inst->inst_cache, ec)) {
-                 CACHE_REMOVE(&inst->inst_cache, ec);
--                if (ent && (ent == ec->ep_entry)) {
--                    /*
--                     * On a retry, it's possible that ec is now stored in the
--                     * pblock as SLAPI_MODRDN_EXISTING_ENTRY.  "ec" will be freed
--                     * by CACHE_RETURN below, so set ent to NULL so don't free
--                     * it again.
--                     */
--                    ent = NULL;
--                }
-+            }
-+            if (ent && (ent == ec->ep_entry)) {
-+                /*
-+                 * On a retry, it's possible that ec is now stored in the
-+                 * pblock as SLAPI_MODRDN_EXISTING_ENTRY.  "ec" will be freed
-+                 * by CACHE_RETURN below, so set ent to NULL so don't free
-+                 * it again.
-+                 * And it needs to be checked always.
-+                 */
-+                ent = NULL;
-             }
-             CACHE_RETURN(&inst->inst_cache, &ec);
-+
-+            /* LK why do we need this ????? */
-             if (!cache_is_in_cache(&inst->inst_cache, e)) {
-                 if (CACHE_ADD(&inst->inst_cache, e, NULL) < 0) {
-                     slapi_log_err(SLAPI_LOG_CACHE,
-@@ -1087,8 +1103,9 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-         if (slapi_sdn_get_dn(dn_newsuperiordn) != NULL) {
-             retval = ldbm_ancestorid_move_subtree(be, sdn, &dn_newdn, e->ep_id, children, &txn);
-             if (retval != 0) {
--                if (retval == DB_LOCK_DEADLOCK)
-+                if (retval == DB_LOCK_DEADLOCK) {
-                     continue;
-+                }
-                 if (retval == DB_RUNRECOVERY || LDBM_OS_ERR_IS_DISKFULL(retval))
-                     disk_full = 1;
-                 MOD_SET_ERROR(ldap_result_code,
-@@ -1108,8 +1125,9 @@ ldbm_back_modrdn(Slapi_PBlock *pb)
-                                              e->ep_id, &txn, is_tombstone);
-             slapi_rdn_done(&newsrdn);
-             if (retval != 0) {
--                if (retval == DB_LOCK_DEADLOCK)
-+                if (retval == DB_LOCK_DEADLOCK) {
-                     continue;
-+                }
-                 if (retval == DB_RUNRECOVERY || LDBM_OS_ERR_IS_DISKFULL(retval))
-                     disk_full = 1;
-                 MOD_SET_ERROR(ldap_result_code, LDAP_OPERATIONS_ERROR, retry_count);
-@@ -1500,7 +1518,12 @@ common_return:
-     done_with_pblock_entry(pb, SLAPI_MODRDN_NEWPARENT_ENTRY);
-     done_with_pblock_entry(pb, SLAPI_MODRDN_TARGET_ENTRY);
-     slapi_ch_free_string(&original_newrdn);
--    slapi_sdn_free(&orig_dn_newsuperiordn);
-+    slapi_pblock_get(pb, SLAPI_MODRDN_NEWSUPERIOR_SDN, &pb_dn_newsuperiordn);
-+    if (pb_dn_newsuperiordn != orig_dn_newsuperiordn) {
-+        slapi_sdn_free(&orig_dn_newsuperiordn);
-+    } else {
-+        slapi_sdn_free(&dn_newsuperiordn);
-+    }
-     backentry_free(&original_entry);
-     backentry_free(&tmpentry);
-     slapi_entry_free(original_targetentry);
-@@ -1561,6 +1584,9 @@ moddn_unlock_and_return_entry(
-     /* Something bad happened so we should give back all the entries */
-     if (*targetentry != NULL) {
-         cache_unlock_entry(&inst->inst_cache, *targetentry);
-+        if (cache_is_in_cache(&inst->inst_cache, *targetentry)) {
-+            CACHE_REMOVE(&inst->inst_cache, *targetentry);
-+        }
-         CACHE_RETURN(&inst->inst_cache, targetentry);
-         *targetentry = NULL;
-     }
--- 
-2.21.1
-
diff --git a/SOURCES/0016-Ticket-50542-Entry-cache-contention-during-base-sear.patch b/SOURCES/0016-Ticket-50542-Entry-cache-contention-during-base-sear.patch
deleted file mode 100644
index 4aa0dce..0000000
--- a/SOURCES/0016-Ticket-50542-Entry-cache-contention-during-base-sear.patch
+++ /dev/null
@@ -1,327 +0,0 @@
-From 03453b7cb4d03691d47ccf5d82d92fe0572ec244 Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Thu, 8 Aug 2019 12:05:00 +0200
-Subject: [PATCH] Ticket 50542 - Entry cache contention during base search
-
-Bug Description:
-	During a base search the entry cache lock is acquired to retrieve the target entry.
-	Later when the candidate list is built, the entry cache lock is also acquired
-	to retrieve the candidate that is actually the target entry itself
-
-	So for a base search the entry cache lock is accessed 4 times (2 acquires + 2 releases)
-
-	It is very easy to create a huge contention (e.g. dereferencing large group) increasing
-	etime
-
-Fix Description:
-	The idea is to acquire the entry, from the entry cache (with refcnt++) when searching the base
-	search. Then instead of returning the entry (refcnt--) the entry is kept in the operation until
-	the operation completes. If later we need the entry (to send it back to the client), the entry is
-	picked up from the operation not from the entry cache lookup
-
-https://pagure.io/389-ds-base/issue/50542
-
-Reviewed by: Ludwig Krispenz, William Brown
-
-Platforms tested: F29
-
-Flag Day: no
-
-Doc impact: no
----
- ldap/servers/slapd/back-ldbm/ldbm_search.c | 45 +++++++++++++++++++---
- ldap/servers/slapd/operation.c             | 32 +++++++++++++++
- ldap/servers/slapd/opshared.c              | 36 ++++++++++++++++-
- ldap/servers/slapd/proto-slap.h            |  4 ++
- ldap/servers/slapd/slap.h                  |  9 +++++
- 5 files changed, 118 insertions(+), 8 deletions(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
-index 8f3111813..c8f5719e1 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
-@@ -551,6 +551,13 @@ ldbm_back_search(Slapi_PBlock *pb)
-                                             LDBM_SRCH_DEFAULT_RESULT, NULL, 1, &vlv_request_control, NULL, candidates);
-         }
-     }
-+    /* We have the base search entry and a callback to "cache_return" it.
-+     * Keep it into the operation to avoid additional cache fetch/return
-+     */
-+    if (e && be->be_entry_release) {
-+        operation_set_target_entry(operation, (void *) e);
-+        operation_set_target_entry_id(operation, e->ep_id);
-+    }
- 
-     /*
-      * If this is a persistent search then the client is only
-@@ -807,7 +814,6 @@ ldbm_back_search(Slapi_PBlock *pb)
-         }
-     }
- 
--    CACHE_RETURN(&inst->inst_cache, &e);
- 
-     /*
-      * if the candidate list is an allids list, arrange for access log
-@@ -1345,6 +1351,27 @@ ldbm_back_next_search_entry(Slapi_PBlock *pb)
-     return ldbm_back_next_search_entry_ext(pb, 0);
- }
- 
-+/* The reference on the target_entry (base search) is stored in the operation
-+ * This is to prevent additional cache find/return that require cache lock.
-+ *
-+ * The target entry is acquired during be->be_search (when building the candidate list).
-+ * and is returned once the operation completes (or fail).
-+ *
-+ * The others entries sent back to the client have been acquired/returned during send_results_ext.
-+ * If the target entry is sent back to the client it is not returned (refcnt--) during the send_results_ext.
-+ *
-+ * This function returns(refcnt-- in the entry cache) the entry unless it is
-+ * the target_entry (base search). target_entry will be return once the operation
-+ * completes
-+ */
-+static void
-+non_target_cache_return(Slapi_Operation *op, struct cache *cache, struct backentry **e)
-+{
-+    if (e && (*e != operation_get_target_entry(op))) {
-+        CACHE_RETURN(cache, e);
-+    }
-+}
-+
- int
- ldbm_back_next_search_entry_ext(Slapi_PBlock *pb, int use_extension)
- {
-@@ -1447,7 +1474,7 @@ ldbm_back_next_search_entry_ext(Slapi_PBlock *pb, int use_extension)
-     /* If we are using the extension, the front end will tell
-      * us when to do this so we don't do it now */
-     if (sr->sr_entry && !use_extension) {
--        CACHE_RETURN(&inst->inst_cache, &(sr->sr_entry));
-+        non_target_cache_return(op, &inst->inst_cache, &(sr->sr_entry));
-         sr->sr_entry = NULL;
-     }
- 
-@@ -1559,7 +1586,13 @@ ldbm_back_next_search_entry_ext(Slapi_PBlock *pb, int use_extension)
-         }
- 
-         /* get the entry */
--        e = id2entry(be, id, &txn, &err);
-+        e = operation_get_target_entry(op);
-+        if ((e == NULL) || (id != operation_get_target_entry_id(op))) {
-+            /* if the entry is not the target_entry (base search)
-+             * we need to fetch it from the entry cache (it was not
-+             * referenced in the operation) */
-+            e = id2entry(be, id, &txn, &err);
-+        }
-         if (e == NULL) {
-             if (err != 0 && err != DB_NOTFOUND) {
-                 slapi_log_err(SLAPI_LOG_ERR, "ldbm_back_next_search_entry_ext", "next_search_entry db err %d\n",
-@@ -1679,7 +1712,7 @@ ldbm_back_next_search_entry_ext(Slapi_PBlock *pb, int use_extension)
-                     /* check size limit */
-                     if (slimit >= 0) {
-                         if (--slimit < 0) {
--                            CACHE_RETURN(&inst->inst_cache, &e);
-+                            non_target_cache_return(op, &inst->inst_cache, &e);
-                             slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET_SIZE_ESTIMATE, &estimate);
-                             delete_search_result_set(pb, &sr);
-                             slapi_send_ldap_result(pb, LDAP_SIZELIMIT_EXCEEDED, NULL, NULL, nentries, urls);
-@@ -1717,12 +1750,12 @@ ldbm_back_next_search_entry_ext(Slapi_PBlock *pb, int use_extension)
-                     rc = 0;
-                     goto bail;
-                 } else {
--                    CACHE_RETURN(&inst->inst_cache, &(sr->sr_entry));
-+                    non_target_cache_return(op, &inst->inst_cache, &(sr->sr_entry));
-                     sr->sr_entry = NULL;
-                 }
-             } else {
-                 /* Failed the filter test, and this isn't a VLV Search */
--                CACHE_RETURN(&inst->inst_cache, &(sr->sr_entry));
-+                non_target_cache_return(op, &inst->inst_cache, &(sr->sr_entry));
-                 sr->sr_entry = NULL;
-                 if (LDAP_UNWILLING_TO_PERFORM == filter_test) {
-                     /* Need to catch this error to detect the vattr loop */
-diff --git a/ldap/servers/slapd/operation.c b/ldap/servers/slapd/operation.c
-index 4a05e0a49..8186fd33b 100644
---- a/ldap/servers/slapd/operation.c
-+++ b/ldap/servers/slapd/operation.c
-@@ -354,6 +354,38 @@ operation_is_flag_set(Slapi_Operation *op, int flag)
-     return op->o_flags & flag;
- }
- 
-+void *
-+operation_get_target_entry(Slapi_Operation *op)
-+{
-+    PR_ASSERT(op);
-+
-+    return op->o_target_entry;
-+}
-+
-+void
-+operation_set_target_entry(Slapi_Operation *op, void *target_entry)
-+{
-+    PR_ASSERT(op);
-+
-+    op->o_target_entry = target_entry;
-+}
-+
-+u_int32_t
-+operation_get_target_entry_id(Slapi_Operation *op)
-+{
-+    PR_ASSERT(op);
-+
-+    return op->o_target_entry_id;
-+}
-+
-+void
-+operation_set_target_entry_id(Slapi_Operation *op, u_int32_t target_entry_id)
-+{
-+    PR_ASSERT(op);
-+
-+    op->o_target_entry_id = target_entry_id;
-+}
-+
- Slapi_DN *
- operation_get_target_spec(Slapi_Operation *op)
- {
-diff --git a/ldap/servers/slapd/opshared.c b/ldap/servers/slapd/opshared.c
-index cf6cdff01..b9fc83516 100644
---- a/ldap/servers/slapd/opshared.c
-+++ b/ldap/servers/slapd/opshared.c
-@@ -193,6 +193,28 @@ slapi_attr_is_last_mod(char *attr)
-     return 0;
- }
- 
-+/* The reference on the target_entry (base search) is stored in the operation
-+ * This is to prevent additional cache find/return that require cache lock.
-+ *
-+ * The target entry is acquired during be->be_search (when building the candidate list).
-+ * and is returned once the operation completes (or fail).
-+ *
-+ * The others entries sent back to the client have been acquired/returned during send_results_ext.
-+ * If the target entry is sent back to the client it is not returned (refcnt--) during the send_results_ext.
-+ *
-+ * This function only returns (refcnt-- in the entry cache) the target_entry (base search).
-+ * It is called at the operation level (op_shared_search)
-+ *
-+ */
-+static void
-+cache_return_target_entry(Slapi_PBlock *pb, Slapi_Backend *be, Slapi_Operation *operation)
-+{
-+    if (operation_get_target_entry(operation) && be->be_entry_release) {
-+        (*be->be_entry_release)(pb, operation_get_target_entry(operation));
-+        operation_set_target_entry(operation, NULL);
-+        operation_set_target_entry_id(operation, 0);
-+    }
-+}
- /*
-  * Returns: 0    - if the operation is successful
-  *        < 0    - if operation fails.
-@@ -252,6 +274,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-     /* get search parameters */
-     slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &base);
-     slapi_pblock_get(pb, SLAPI_SEARCH_TARGET_SDN, &sdn);
-+    slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
- 
-     if (NULL == sdn) {
-         sdn = slapi_sdn_new_dn_byval(base);
-@@ -276,7 +299,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-     slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &scope);
-     slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &fstr);
-     slapi_pblock_get(pb, SLAPI_SEARCH_ATTRS, &attrs);
--    slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
-+
-     if (operation == NULL) {
-         op_shared_log_error_access(pb, "SRCH", base, "NULL operation");
-         send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "NULL operation", 0, NULL);
-@@ -808,6 +831,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-              * the error has already been sent
-              * stop the search here
-              */
-+                    cache_return_target_entry(pb, be, operation);
-                     goto free_and_return;
-                 }
- 
-@@ -815,6 +839,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
- 
-             case SLAPI_FAIL_DISKFULL:
-                 operation_out_of_disk_space();
-+                cache_return_target_entry(pb, be, operation);
-                 goto free_and_return;
- 
-             case 0: /* search was successful and we need to send the result */
-@@ -840,6 +865,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-                             /* no more entries && no more backends */
-                             curr_search_count = -1;
-                         } else if (rc < 0) {
-+                            cache_return_target_entry(pb, be, operation);
-                             goto free_and_return;
-                         }
-                     } else {
-@@ -852,6 +878,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-                             (pagedresults_set_search_result_set_size_estimate(pb_conn, operation, estimate, pr_idx) < 0) ||
-                             (pagedresults_set_with_sort(pb_conn, operation, with_sort, pr_idx) < 0)) {
-                             pagedresults_unlock(pb_conn, pr_idx);
-+                            cache_return_target_entry(pb, be, operation);
-                             goto free_and_return;
-                         }
-                         pagedresults_unlock(pb_conn, pr_idx);
-@@ -867,6 +894,7 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-                         pagedresults_set_response_control(pb, 0, estimate, -1, pr_idx);
-                         send_ldap_result(pb, 0, NULL, "Simple Paged Results Search abandoned", 0, NULL);
-                         rc = LDAP_SUCCESS;
-+                        cache_return_target_entry(pb, be, operation);
-                         goto free_and_return;
-                     }
-                     pagedresults_set_response_control(pb, 0, estimate, curr_search_count, pr_idx);
-@@ -880,10 +908,14 @@ op_shared_search(Slapi_PBlock *pb, int send_result)
-          * LDAP error should already have been sent to the client
-          * stop the search, free and return
-          */
--                if (rc != 0)
-+                if (rc != 0) {
-+                    cache_return_target_entry(pb, be, operation);
-                     goto free_and_return;
-+                }
-                 break;
-             }
-+            /* cache return the target_entry */
-+            cache_return_target_entry(pb, be, operation);
-         }
- 
-         nentries += pnentries;
-diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
-index e37f702ea..d9fb8fd08 100644
---- a/ldap/servers/slapd/proto-slap.h
-+++ b/ldap/servers/slapd/proto-slap.h
-@@ -873,6 +873,10 @@ void operation_free(Slapi_Operation **op, Connection *conn);
- int slapi_op_abandoned(Slapi_PBlock *pb);
- void operation_out_of_disk_space(void);
- int get_operation_object_type(void);
-+void *operation_get_target_entry(Slapi_Operation *op);
-+void operation_set_target_entry(Slapi_Operation *op, void *target_void);
-+u_int32_t operation_get_target_entry_id(Slapi_Operation *op);
-+void operation_set_target_entry_id(Slapi_Operation *op, u_int32_t target_entry_id);
- Slapi_DN *operation_get_target_spec(Slapi_Operation *op);
- void operation_set_target_spec(Slapi_Operation *op, const Slapi_DN *target_spec);
- void operation_set_target_spec_str(Slapi_Operation *op, const char *target_spec);
-diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
-index bce720974..a8908d94c 100644
---- a/ldap/servers/slapd/slap.h
-+++ b/ldap/servers/slapd/slap.h
-@@ -1545,6 +1545,15 @@ typedef struct op
-     unsigned long o_flags;                                     /* flags for this operation      */
-     void *o_extension;                                         /* plugins are able to extend the Operation object */
-     Slapi_DN *o_target_spec;                                   /* used to decide which plugins should be called for the operation */
-+    void *o_target_entry;                                      /* Only used for SEARCH operation
-+                                                                * reference of search target entry (base search) in the entry cache
-+                                                                * When it is set the refcnt (of the entry in the entry cache) as been increased
-+                                                                */
-+    u_int32_t o_target_entry_id;                               /* Only used for SEARCH operation
-+                                                                * contains the ID of the o_target_entry. In send_result we have ID of the candidates, this
-+                                                                * accelerates the tests as we have not to retrieve for each candidate the
-+                                                                * ep_id inside the o_target_entry.
-+                                                                */
-     unsigned long o_abandoned_op;                              /* operation abandoned by this operation - used to decide which plugins to invoke */
-     struct slapi_operation_parameters o_params;
-     struct slapi_operation_results o_results;
--- 
-2.24.1
-
diff --git a/SOURCES/0017-Issue-50834-Incorrectly-setting-the-NSS-default-SSL-.patch b/SOURCES/0017-Issue-50834-Incorrectly-setting-the-NSS-default-SSL-.patch
deleted file mode 100644
index aa439a6..0000000
--- a/SOURCES/0017-Issue-50834-Incorrectly-setting-the-NSS-default-SSL-.patch
+++ /dev/null
@@ -1,35 +0,0 @@
-From a1c4b869645eca6bf81e1b7bc116bbb0de389197 Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Mon, 20 Jan 2020 13:16:36 -0500
-Subject: [PATCH] Issue 50834 - Incorrectly setting the NSS default SSL version
- max
-
-Description:  We've been using the wrong function to get the NSS max
-              version We were calling SSL_VersionRangeGetSupported()
-              which gets the versions NSS "can" handle, but
-              SSL_VersionRangeGetDefault() gets the versions that
-              are actually "enabled".
-
-relates: https://pagure.io/389-ds-base/issue/50834
-
-Reviewed by: mreynolds(one line commit rule)
----
- ldap/servers/slapd/ssl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
-index ed054db44..c71e3019b 100644
---- a/ldap/servers/slapd/ssl.c
-+++ b/ldap/servers/slapd/ssl.c
-@@ -1164,7 +1164,7 @@ slapd_nss_init(int init_ssl __attribute__((unused)), int config_available __attr
-     char *certdir;
-     char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
-     /* Get the range of the supported SSL version */
--    SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
-+    SSL_VersionRangeGetDefault(ssl_variant_stream, &enabledNSSVersions);
- 
-     (void)slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
-     (void)slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
--- 
-2.24.1
-
diff --git a/SOURCES/0018-Ticket-50736-RetroCL-trimming-may-crash-at-shutdown-.patch b/SOURCES/0018-Ticket-50736-RetroCL-trimming-may-crash-at-shutdown-.patch
deleted file mode 100644
index 38ec626..0000000
--- a/SOURCES/0018-Ticket-50736-RetroCL-trimming-may-crash-at-shutdown-.patch
+++ /dev/null
@@ -1,263 +0,0 @@
-From 5497023c6857ae0fcf046e57744a91107d362c41 Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Mon, 25 Nov 2019 10:59:44 +0100
-Subject: [PATCH] Ticket 50736 - RetroCL trimming may crash at shutdown if
- trimming configuration is invalid
-
-Bug Description:
-	If config of retroCL trimming contains invalid value for trim-interval
-        and/or maxage, then the trimming initialization is skipped.
-        In such case the trimming structures are not allocated and if they
-        are freed at shutdown it triggers a crash
-
-Fix Description:
-        When trimming mechanism is stopped (at shutdown) check that
-        it was successfully initialized before freeing the structs
-
-https://pagure.io/389-ds-base/issue/50736
-
-Reviewed by: Mark Reynolds
-
-Platforms tested: F30
-
-Flag Day: no
-
-Doc impact: no
----
- .../suites/replication/changelog_test.py      | 185 ++++++++++++++++++
- ldap/servers/plugins/retrocl/retrocl_trim.c   |  17 +-
- 2 files changed, 196 insertions(+), 6 deletions(-)
-
-diff --git a/dirsrvtests/tests/suites/replication/changelog_test.py b/dirsrvtests/tests/suites/replication/changelog_test.py
-index 0b6b886f3..0d3e85bb2 100755
---- a/dirsrvtests/tests/suites/replication/changelog_test.py
-+++ b/dirsrvtests/tests/suites/replication/changelog_test.py
-@@ -16,6 +16,12 @@ from lib389.replica import Replicas
- from lib389.idm.user import UserAccounts
- from lib389.topologies import topology_m2 as topo
- from lib389._constants import *
-+from lib389.plugins import RetroChangelogPlugin
-+from lib389.dseldif import DSEldif
-+from lib389.tasks import *
-+from lib389.utils import *
-+
-+pytestmark = pytest.mark.tier1
- 
- TEST_ENTRY_NAME = 'replusr'
- NEW_RDN_NAME = 'cl5usr'
-@@ -235,6 +241,185 @@ def test_verify_changelog_offline_backup(topo):
-     _check_changelog_ldif(topo, changelog_ldif)
- 
- 
-+@pytest.mark.ds47669
-+def test_changelog_maxage(topo, changelog_init):
-+    """Check nsslapd-changelog max age values
-+
-+    :id: d284ff27-03b2-412c-ac74-ac4f2d2fae3b
-+    :setup: Replication with two master, change nsslapd-changelogdir to
-+    '/var/lib/dirsrv/slapd-master1/changelog' and
-+    set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
-+    :steps:
-+        1. Set nsslapd-changelogmaxage in cn=changelog5,cn=config to values - '12345','10s','30M','12h','2D','4w'
-+        2. Set nsslapd-changelogmaxage in cn=changelog5,cn=config to values - '-123','xyz'
-+
-+    :expectedresults:
-+        1. Operation should be successful
-+        2. Operation should be unsuccessful
-+     """
-+    log.info('1. Test nsslapd-changelogmaxage in cn=changelog5,cn=config')
-+
-+    # bind as directory manager
-+    topo.ms["master1"].log.info("Bind as %s" % DN_DM)
-+    topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
-+
-+    add_and_check(topo, CHANGELOG, MAXAGE, '12345', True)
-+    add_and_check(topo, CHANGELOG, MAXAGE, '10s', True)
-+    add_and_check(topo, CHANGELOG, MAXAGE, '30M', True)
-+    add_and_check(topo, CHANGELOG, MAXAGE, '12h', True)
-+    add_and_check(topo, CHANGELOG, MAXAGE, '2D', True)
-+    add_and_check(topo, CHANGELOG, MAXAGE, '4w', True)
-+    add_and_check(topo, CHANGELOG, MAXAGE, '-123', False)
-+    add_and_check(topo, CHANGELOG, MAXAGE, 'xyz', False)
-+
-+
-+@pytest.mark.ds47669
-+def test_ticket47669_changelog_triminterval(topo, changelog_init):
-+    """Check nsslapd-changelog triminterval values
-+
-+    :id: 8f850c37-7e7c-49dd-a4e0-9344638616d6
-+    :setup: Replication with two master, change nsslapd-changelogdir to
-+    '/var/lib/dirsrv/slapd-master1/changelog' and
-+    set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
-+    :steps:
-+        1. Set nsslapd-changelogtrim-interval in cn=changelog5,cn=config to values -
-+           '12345','10s','30M','12h','2D','4w'
-+        2. Set nsslapd-changelogtrim-interval in cn=changelog5,cn=config to values - '-123','xyz'
-+
-+    :expectedresults:
-+        1. Operation should be successful
-+        2. Operation should be unsuccessful
-+     """
-+    log.info('2. Test nsslapd-changelogtrim-interval in cn=changelog5,cn=config')
-+
-+    # bind as directory manager
-+    topo.ms["master1"].log.info("Bind as %s" % DN_DM)
-+    topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
-+
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '12345', True)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '10s', True)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '30M', True)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '12h', True)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '2D', True)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '4w', True)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, '-123', False)
-+    add_and_check(topo, CHANGELOG, TRIMINTERVAL, 'xyz', False)
-+
-+
-+@pytest.mark.ds47669
-+def test_changelog_compactdbinterval(topo, changelog_init):
-+    """Check nsslapd-changelog compactdbinterval values
-+
-+    :id: 0f4b3118-9dfa-4c2a-945c-72847b42a48c
-+    :setup: Replication with two master, change nsslapd-changelogdir to
-+    '/var/lib/dirsrv/slapd-master1/changelog' and
-+    set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
-+    :steps:
-+        1. Set nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config to values -
-+           '12345','10s','30M','12h','2D','4w'
-+        2. Set nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config to values -
-+           '-123','xyz'
-+
-+    :expectedresults:
-+        1. Operation should be successful
-+        2. Operation should be unsuccessful
-+     """
-+    log.info('3. Test nsslapd-changelogcompactdb-interval in cn=changelog5,cn=config')
-+
-+    # bind as directory manager
-+    topo.ms["master1"].log.info("Bind as %s" % DN_DM)
-+    topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
-+
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '12345', True)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '10s', True)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '30M', True)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '12h', True)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '2D', True)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '4w', True)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, '-123', False)
-+    add_and_check(topo, CHANGELOG, COMPACTDBINTERVAL, 'xyz', False)
-+
-+
-+@pytest.mark.ds47669
-+def test_retrochangelog_maxage(topo, changelog_init):
-+    """Check nsslapd-retrochangelog max age values
-+
-+    :id: 0cb84d81-3e86-4dbf-84a2-66aefd8281db
-+    :setup: Replication with two master, change nsslapd-changelogdir to
-+    '/var/lib/dirsrv/slapd-master1/changelog' and
-+    set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
-+    :steps:
-+        1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to values -
-+           '12345','10s','30M','12h','2D','4w'
-+        2. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to values -
-+           '-123','xyz'
-+
-+    :expectedresults:
-+        1. Operation should be successful
-+        2. Operation should be unsuccessful
-+     """
-+    log.info('4. Test nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config')
-+
-+    # bind as directory manager
-+    topo.ms["master1"].log.info("Bind as %s" % DN_DM)
-+    topo.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
-+
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '12345', True)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '10s', True)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '30M', True)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '12h', True)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '2D', True)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '4w', True)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, '-123', False)
-+    add_and_check(topo, RETROCHANGELOG, MAXAGE, 'xyz', False)
-+
-+    topo.ms["master1"].log.info("ticket47669 was successfully verified.")
-+
-+@pytest.mark.ds50736
-+def test_retrochangelog_trimming_crash(topo, changelog_init):
-+    """Check that when retroCL nsslapd-retrocthangelog contains invalid
-+    value, then the instance does not crash at shutdown
-+
-+    :id: 5d9bd7ca-e9bf-4be9-8fc8-902aa5513052
-+    :setup: Replication with two master, change nsslapd-changelogdir to
-+    '/var/lib/dirsrv/slapd-master1/changelog' and
-+    set cn=Retro Changelog Plugin,cn=plugins,cn=config to 'on'
-+    :steps:
-+        1. Set nsslapd-changelogmaxage in cn=Retro Changelog Plugin,cn=plugins,cn=config to value '-1'
-+           This value is invalid. To disable retroCL trimming it should be set to 0
-+        2. Do several restart
-+        3. check there is no 'Detected Disorderly Shutdown' message (crash)
-+        4. restore valid value for nsslapd-changelogmaxage '1w'
-+
-+    :expectedresults:
-+        1. Operation should be successful
-+        2. Operation should be successful
-+        3. Operation should be successful
-+        4. Operation should be successful
-+     """
-+    log.info('1. Test retroCL trimming crash in cn=Retro Changelog Plugin,cn=plugins,cn=config')
-+
-+    # set the nsslapd-changelogmaxage directly on dse.ldif
-+    # because the set value is invalid
-+    topo.ms["master1"].log.info("ticket50736 start verification")
-+    topo.ms["master1"].stop()
-+    retroPlugin = RetroChangelogPlugin(topo.ms["master1"])
-+    dse_ldif = DSEldif(topo.ms["master1"])
-+    dse_ldif.replace(retroPlugin.dn, 'nsslapd-changelogmaxage', '-1')
-+    topo.ms["master1"].start()
-+
-+    # The crash should be systematic, but just in case do several restart
-+    # with a delay to let all plugin init
-+    for i in range(5):
-+        time.sleep(1)
-+        topo.ms["master1"].stop()
-+        topo.ms["master1"].start()
-+
-+    assert not topo.ms["master1"].detectDisorderlyShutdown()
-+
-+    topo.ms["master1"].log.info("ticket 50736 was successfully verified.")
-+
-+
- if __name__ == '__main__':
-     # Run isolated
-     # -s for DEBUG mode
-diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
-index a46534984..0378eb7f6 100644
---- a/ldap/servers/plugins/retrocl/retrocl_trim.c
-+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
-@@ -481,11 +481,16 @@ retrocl_init_trimming(void)
- void
- retrocl_stop_trimming(void)
- {
--    retrocl_trimming = 0;
--    if (retrocl_trim_ctx) {
--        slapi_eq_cancel(retrocl_trim_ctx);
--        retrocl_trim_ctx = NULL;
-+    if (retrocl_trimming) {
-+        /* RetroCL trimming config was valid and trimming struct allocated
-+         * Let's free them
-+         */
-+        retrocl_trimming = 0;
-+        if (retrocl_trim_ctx) {
-+            slapi_eq_cancel(retrocl_trim_ctx);
-+            retrocl_trim_ctx = NULL;
-+        }
-+        PR_DestroyLock(ts.ts_s_trim_mutex);
-+        ts.ts_s_trim_mutex = NULL;
-     }
--    PR_DestroyLock(ts.ts_s_trim_mutex);
--    ts.ts_s_trim_mutex = NULL;
- }
--- 
-2.24.1
-
diff --git a/SOURCES/0019-Ticket-50709-Several-memory-leaks-reported-by-Valgri.patch b/SOURCES/0019-Ticket-50709-Several-memory-leaks-reported-by-Valgri.patch
deleted file mode 100644
index dedd8a9..0000000
--- a/SOURCES/0019-Ticket-50709-Several-memory-leaks-reported-by-Valgri.patch
+++ /dev/null
@@ -1,189 +0,0 @@
-From ceef0b6ae9edbb60bc6324c3dc045f3a4e5fd725 Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Fri, 8 Nov 2019 18:16:06 +0100
-Subject: [PATCH] Ticket 50709: Several memory leaks reported by Valgrind for
- 389-ds 1.3.9.1-10
-
-Description of the problem:
-
-	When evaluating an ACI with 'ip' subject, it adds a PRNetAddr to the subject
-	property list. When the list is free (acl__done_aclpb) the property is not freed.
-
-Description of the fix:
-
-	Add the property to the pblock (SLAPI_CONN_CLIENTNETADDR_ACLIP) so that it
-	the property is freed with acl pblock.
-
-https://pagure.io/389-ds-base/issue/50709
-
-Reviewed by: Mark Reynolds, William Brown, Ludwig Krispenz
----
- ldap/servers/plugins/acl/acllas.c | 54 ++++++++++++++++++++-----------
- ldap/servers/slapd/connection.c   |  2 ++
- ldap/servers/slapd/pblock.c       | 16 +++++++++
- ldap/servers/slapd/slap.h         |  1 +
- ldap/servers/slapd/slapi-plugin.h |  1 +
- 5 files changed, 56 insertions(+), 18 deletions(-)
-
-diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
-index 3950fd405..a5602e198 100644
---- a/ldap/servers/plugins/acl/acllas.c
-+++ b/ldap/servers/plugins/acl/acllas.c
-@@ -251,6 +251,7 @@ DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t auth_in
- {
-     struct acl_pblock *aclpb = NULL;
-     PRNetAddr *client_praddr = NULL;
-+    PRNetAddr *pb_client_praddr = NULL;
-     char ip_str[256];
-     int rv = LAS_EVAL_TRUE;
- 
-@@ -262,25 +263,39 @@ DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t auth_in
-         return LAS_EVAL_FAIL;
-     }
- 
--    client_praddr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
--    if (client_praddr == NULL) {
--        slapi_log_err(SLAPI_LOG_ERR, plugin_name, "DS_LASIpGetter - Failed to allocate client_praddr\n");
--        return (LAS_EVAL_FAIL);
--    }
-+    slapi_pblock_get(aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR_ACLIP, &pb_client_praddr);
-+    if (pb_client_praddr == NULL) {
- 
--    if (slapi_pblock_get(aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR, client_praddr) != 0) {
--        slapi_log_err(SLAPI_LOG_ERR, plugin_name, "DS_LASIpGetter - Could not get client IP.\n");
--        slapi_ch_free((void **)&client_praddr);
--        return (LAS_EVAL_FAIL);
--    }
-+        client_praddr = (PRNetAddr *) slapi_ch_malloc(sizeof (PRNetAddr));
-+        if (client_praddr == NULL) {
-+            slapi_log_err(SLAPI_LOG_ERR, plugin_name, "DS_LASIpGetter - Failed to allocate client_praddr\n");
-+            return (LAS_EVAL_FAIL);
-+        }
- 
--    rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *)client_praddr, NULL);
--    if (rv < 0) {
--        slapi_log_err(SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter - "
--                                                  "Couldn't set the client addr property(%d)\n",
--                      rv);
--        slapi_ch_free((void **)&client_praddr);
--        return LAS_EVAL_FAIL;
-+        if (slapi_pblock_get(aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR, client_praddr) != 0) {
-+            slapi_log_err(SLAPI_LOG_ERR, plugin_name, "DS_LASIpGetter - Could not get client IP.\n");
-+            slapi_ch_free((void **) &client_praddr);
-+            return (LAS_EVAL_FAIL);
-+        }
-+
-+        rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *) client_praddr, NULL);
-+        if (rv < 0) {
-+            slapi_log_err(SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter - "
-+                    "Couldn't set the client addr property(%d)\n",
-+                    rv);
-+            slapi_ch_free((void **) &client_praddr);
-+            return LAS_EVAL_FAIL;
-+        }
-+
-+    } else {
-+        client_praddr = pb_client_praddr;
-+        rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *) client_praddr, NULL);
-+        if (rv < 0) {
-+            slapi_log_err(SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter - "
-+                    "Couldn't set the client addr property(%d)\n",
-+                    rv);
-+            return LAS_EVAL_FAIL;
-+        }
-     }
-     if (PR_NetAddrToString(client_praddr, ip_str, sizeof(ip_str)) == PR_SUCCESS) {
-         slapi_log_err(SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter - "
-@@ -290,7 +305,10 @@ DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t auth_in
-         slapi_log_err(SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter - "
-                                                   "Returning client ip address 'unknown'\n");
-     }
--
-+    if (client_praddr != pb_client_praddr) {
-+        /* Set it in pblock only if it is newly allocated */
-+        slapi_pblock_set(aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR_ACLIP, client_praddr);
-+    }
-     return LAS_EVAL_TRUE;
- }
- 
-diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
-index 9abd546f9..b9b280e6d 100644
---- a/ldap/servers/slapd/connection.c
-+++ b/ldap/servers/slapd/connection.c
-@@ -205,6 +205,7 @@ connection_cleanup(Connection *conn)
-     conn->c_isreplication_session = 0;
-     slapi_ch_free((void **)&conn->cin_addr);
-     slapi_ch_free((void **)&conn->cin_destaddr);
-+    slapi_ch_free((void **)&conn->cin_addr_aclip);
-     slapi_ch_free_string(&conn->c_ipaddr);
-     if (conn->c_domain != NULL) {
-         ber_bvecfree(conn->c_domain);
-@@ -397,6 +398,7 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib
-             str_destip = str_unknown;
-         }
-     }
-+    slapi_ch_free((void **)&conn->cin_addr_aclip);
- 
- 
-     if (!in_referral_mode) {
-diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
-index bc18a7b18..d2ad6147a 100644
---- a/ldap/servers/slapd/pblock.c
-+++ b/ldap/servers/slapd/pblock.c
-@@ -482,6 +482,14 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
-         }
-         PR_ExitMonitor(pblock->pb_conn->c_mutex);
-         break;
-+	case SLAPI_CONN_CLIENTNETADDR_ACLIP:
-+        if (pblock->pb_conn == NULL) {
-+            break;
-+        }
-+        pthread_mutex_lock(&(pblock->pb_conn->c_mutex));
-+        (*(PRNetAddr **) value) = pblock->pb_conn->cin_addr_aclip;
-+        pthread_mutex_unlock(&(pblock->pb_conn->c_mutex));
-+        break;
-     case SLAPI_CONN_SERVERNETADDR:
-         if (pblock->pb_conn == NULL) {
-             memset(value, 0, sizeof(PRNetAddr));
-@@ -2571,6 +2579,14 @@ slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value)
-         pblock->pb_conn->c_authtype = slapi_ch_strdup((char *)value);
-         PR_ExitMonitor(pblock->pb_conn->c_mutex);
-         break;
-+	case SLAPI_CONN_CLIENTNETADDR_ACLIP:
-+        if (pblock->pb_conn == NULL) {
-+            break;
-+        }
-+        pthread_mutex_lock(&(pblock->pb_conn->c_mutex));
-+        slapi_ch_free((void **)&pblock->pb_conn->cin_addr_aclip);
-+        pblock->pb_conn->cin_addr_aclip = (PRNetAddr *)value;
-+        pthread_mutex_unlock(&(pblock->pb_conn->c_mutex));
-     case SLAPI_CONN_IS_REPLICATION_SESSION:
-         if (pblock->pb_conn == NULL) {
-             slapi_log_err(SLAPI_LOG_ERR,
-diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
-index a8908d94c..4c53d43dc 100644
---- a/ldap/servers/slapd/slap.h
-+++ b/ldap/servers/slapd/slap.h
-@@ -1617,6 +1617,7 @@ typedef struct conn
-     char *c_external_dn;             /* client DN of this SSL session  */
-     char *c_external_authtype;       /* used for c_external_dn   */
-     PRNetAddr *cin_addr;             /* address of client on this conn */
-+    PRNetAddr *cin_addr_aclip;       /* address of client allocated by acl with 'ip' subject */
-     PRNetAddr *cin_destaddr;         /* address client connected to    */
-     struct berval **c_domain;        /* DNS names of client            */
-     Operation *c_ops;                /* list of pending operations      */
-diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
-index 0bc3a6fab..679bdbb5c 100644
---- a/ldap/servers/slapd/slapi-plugin.h
-+++ b/ldap/servers/slapd/slapi-plugin.h
-@@ -6971,6 +6971,7 @@ slapi_timer_result slapi_timespec_expire_check(struct timespec *expire);
- #define SLAPI_CONN_DN                     143
- #define SLAPI_CONN_CLIENTNETADDR          850
- #define SLAPI_CONN_SERVERNETADDR          851
-+#define SLAPI_CONN_CLIENTNETADDR_ACLIP    853
- #define SLAPI_CONN_IS_REPLICATION_SESSION 149
- #define SLAPI_CONN_IS_SSL_SESSION         747
- #define SLAPI_CONN_CERT                   743
--- 
-2.24.1
-
diff --git a/SOURCES/0020-Ticket-50857-Memory-leak-in-ACI-using-IP-subject.patch b/SOURCES/0020-Ticket-50857-Memory-leak-in-ACI-using-IP-subject.patch
deleted file mode 100644
index c6c8c9d..0000000
--- a/SOURCES/0020-Ticket-50857-Memory-leak-in-ACI-using-IP-subject.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From db358c127ff26c280bef5d85e62e3a08153438d5 Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Mon, 27 Jan 2020 13:49:37 +0100
-Subject: [PATCH] Ticket 50857 - Memory leak in ACI using IP subject
-
-Bug Description:
-	When a ACI is evaluated (LASIpEval) a context (cookie) is allocated.
-	At the end of the connection, the context is freed
-	via a callback (LASIpFlush).
-	The context contains two LASIpTree_t tree (ipv4 and ipv6)
-	In free callback, only ipv4 tree is freed
-
-Fix Description:
-	Free ipv6 tree in LASIpTree
-
-https://pagure.io/389-ds-base/issue/50857
-
-Reviewed by: Mark Reynolds
-
-Platforms tested: F31
-
-Flag Day: no
-
-Doc impact: no
----
- lib/libaccess/lasip.cpp | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/lib/libaccess/lasip.cpp b/lib/libaccess/lasip.cpp
-index 30c546df7..cdb88eec5 100644
---- a/lib/libaccess/lasip.cpp
-+++ b/lib/libaccess/lasip.cpp
-@@ -436,6 +436,7 @@ LASIpFlush(void **las_cookie)
-         return;
- 
-     LASIpTreeDealloc(((LASIpContext_t *)*las_cookie)->treetop);
-+    LASIpTreeDealloc(((LASIpContext_t *)*las_cookie)->treetop_ipv6);
-     PERM_FREE(*las_cookie);
-     *las_cookie = NULL;
-     return;
--- 
-2.24.1
-
diff --git a/SOURCES/0021-Ticket-50709-cont-Several-memory-leaks-reported-by-V.patch b/SOURCES/0021-Ticket-50709-cont-Several-memory-leaks-reported-by-V.patch
deleted file mode 100644
index 2cee9d2..0000000
--- a/SOURCES/0021-Ticket-50709-cont-Several-memory-leaks-reported-by-V.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-From cbe93b4bd4569181db85aeac501798985d7d1acd Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Fri, 24 Jan 2020 10:56:23 +0100
-Subject: [PATCH] Ticket 50709: (cont) Several memory leaks reported by
- Valgrind for 389-ds 1.3.9.1-10
-
-Bug Description:
-	Cherry pick from master was broken because connection locking
-	uses pthread lock in master while it remains Monitor in 1.3.10
-
-Fix Description:
-	Change the locking function to use Monitor in that branch
-
-https://pagure.io/389-ds-base/issue/50709
-
-Reviewed by: thierry bordaz
-
-Platforms tested: 7.8
-
-Flag Day: no
-
-Doc impact: no
----
- ldap/servers/slapd/pblock.c | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c
-index d2ad6147a..d21cf7e76 100644
---- a/ldap/servers/slapd/pblock.c
-+++ b/ldap/servers/slapd/pblock.c
-@@ -486,9 +486,9 @@ slapi_pblock_get(Slapi_PBlock *pblock, int arg, void *value)
-         if (pblock->pb_conn == NULL) {
-             break;
-         }
--        pthread_mutex_lock(&(pblock->pb_conn->c_mutex));
-+        PR_EnterMonitor(pblock->pb_conn->c_mutex);
-         (*(PRNetAddr **) value) = pblock->pb_conn->cin_addr_aclip;
--        pthread_mutex_unlock(&(pblock->pb_conn->c_mutex));
-+        PR_ExitMonitor(pblock->pb_conn->c_mutex);
-         break;
-     case SLAPI_CONN_SERVERNETADDR:
-         if (pblock->pb_conn == NULL) {
-@@ -2583,10 +2583,10 @@ slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value)
-         if (pblock->pb_conn == NULL) {
-             break;
-         }
--        pthread_mutex_lock(&(pblock->pb_conn->c_mutex));
-+        PR_EnterMonitor(pblock->pb_conn->c_mutex);
-         slapi_ch_free((void **)&pblock->pb_conn->cin_addr_aclip);
-         pblock->pb_conn->cin_addr_aclip = (PRNetAddr *)value;
--        pthread_mutex_unlock(&(pblock->pb_conn->c_mutex));
-+        PR_ExitMonitor(pblock->pb_conn->c_mutex);
-     case SLAPI_CONN_IS_REPLICATION_SESSION:
-         if (pblock->pb_conn == NULL) {
-             slapi_log_err(SLAPI_LOG_ERR,
--- 
-2.24.1
-
diff --git a/SOURCES/0022-fix-for-50542-crashes-in-filter-tests.patch b/SOURCES/0022-fix-for-50542-crashes-in-filter-tests.patch
deleted file mode 100644
index e0f1fac..0000000
--- a/SOURCES/0022-fix-for-50542-crashes-in-filter-tests.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From 391130c60ccedb0f7650d4454141686d293dc39e Mon Sep 17 00:00:00 2001
-From: Ludwig Krispenz <lkrispen@redhat.com>
-Date: Tue, 20 Aug 2019 10:18:22 +0200
-Subject: [PATCH] fix for 50542 crashes in filter tests
-
-The crash is when a backentry is released, there is a call to CACHE_RETURN
-and then check and free of a vlv entry.
-But CACHE_RETURN, under some conditions, can free the backentry - the following check will
-dereference a NULL entry and crashes
-
-Fix: Reverse the order of freeing vlv entry and returning entry to cache
-
-Note: Viktor did successfully runthe tests, thanks
-
-Reviewed by: ?
----
- ldap/servers/slapd/back-ldbm/ldbm_search.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
-index c8f5719e1..2ad8f743a 100644
---- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
-+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
-@@ -1896,13 +1896,13 @@ ldbm_back_entry_release(Slapi_PBlock *pb, void *backend_info_ptr)
-     slapi_pblock_get(pb, SLAPI_BACKEND, &be);
-     inst = (ldbm_instance *)be->be_instance_info;
- 
--    CACHE_RETURN(&inst->inst_cache, (struct backentry **)&backend_info_ptr);
--
-     if (((struct backentry *)backend_info_ptr)->ep_vlventry != NULL) {
-         /* This entry was created during a vlv search whose acl check failed.  It needs to be
-          * freed here */
-         slapi_entry_free(((struct backentry *)backend_info_ptr)->ep_vlventry);
-         ((struct backentry *)backend_info_ptr)->ep_vlventry = NULL;
-     }
-+    CACHE_RETURN(&inst->inst_cache, (struct backentry **)&backend_info_ptr);
-+
-     return 0;
- }
--- 
-2.24.1
-
diff --git a/SOURCES/0023-Ticket-49623-cont-cenotaph-errors-on-modrdn-operatio.patch b/SOURCES/0023-Ticket-49623-cont-cenotaph-errors-on-modrdn-operatio.patch
deleted file mode 100644
index 54f76b2..0000000
--- a/SOURCES/0023-Ticket-49623-cont-cenotaph-errors-on-modrdn-operatio.patch
+++ /dev/null
@@ -1,168 +0,0 @@
-From 819eaedc4bd51d0ec34928c5443a7cd7f094c60a Mon Sep 17 00:00:00 2001
-From: Ludwig Krispenz <lkrispen@redhat.com>
-Date: Tue, 11 Feb 2020 09:47:45 +0100
-Subject: [PATCH 1/2] Ticket - 49623-cont cenotaph errors on modrdn operations
-
-Bug: In modrdn operations a cenotaph entries are created to track the time when
-	an entry had existed. But in cases where rentries were renamed in cycles
-	reusing the dns again and again this failed with an error: "faild to add cenotaph"
-
-Fix: Previous versions of cenotaphs with the same dn are not used (or maybe in very unlikely
-	scenarios) so there is no need to change the dn construction to be able to keep all
-	versions of the same cenotaph. Instead, if the creation of the cenotaph fails because
-	it already exists, the existin cenotaph is moodified with the lifespan data of the
-	cenotaph that was tried to add.
-
-Reviewed by: Thierry, thanks
----
- .../tests/tickets/ticket49623_2_test.py       | 66 +++++++++++++++++++
- ldap/servers/plugins/replication/urp.c        | 42 ++++++++++--
- 2 files changed, 104 insertions(+), 4 deletions(-)
- create mode 100644 dirsrvtests/tests/tickets/ticket49623_2_test.py
-
-diff --git a/dirsrvtests/tests/tickets/ticket49623_2_test.py b/dirsrvtests/tests/tickets/ticket49623_2_test.py
-new file mode 100644
-index 000000000..1d3167d49
---- /dev/null
-+++ b/dirsrvtests/tests/tickets/ticket49623_2_test.py
-@@ -0,0 +1,66 @@
-+# --- 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 os
-+import ldap
-+import pytest
-+import subprocess
-+from lib389.tasks import *
-+from lib389.utils import *
-+from lib389.topologies import topology_m1
-+from lib389.idm.user import UserAccounts
-+from lib389._constants import DEFAULT_SUFFIX
-+from contextlib import contextmanager
-+
-+pytestmark = pytest.mark.tier1
-+
-+logging.getLogger(__name__).setLevel(logging.DEBUG)
-+log = logging.getLogger(__name__)
-+
-+
-+@pytest.mark.ds49623
-+@pytest.mark.bz1790986
-+def test_modrdn_loop(topology_m1):
-+    """Test that renaming the same entry multiple times reusing the same
-+       RDN multiple times does not result in cenotaph error messages
-+
-+    :id: 631b2be9-5c03-44c7-9853-a87c923d5b30
-+
-+    :setup: Single master instance
-+
-+    :steps: 1. Add an entry with RDN start rdn
-+            2. Rename the entry to rdn change
-+            3. Rename the entry to start again
-+            4. Rename the entry to rdn change
-+            5. check for cenotaph error messages
-+    :expectedresults:
-+            1. No error messages
-+    """
-+
-+    topo = topology_m1.ms['master1']
-+    TEST_ENTRY_RDN_START = 'start'
-+    TEST_ENTRY_RDN_CHANGE = 'change'
-+    TEST_ENTRY_NAME = 'tuser'
-+    users = UserAccounts(topo, DEFAULT_SUFFIX)
-+    user_properties = {
-+        'uid': TEST_ENTRY_RDN_START,
-+        'cn': TEST_ENTRY_NAME,
-+        'sn': TEST_ENTRY_NAME,
-+        'uidNumber': '1001',
-+        'gidNumber': '2001',
-+        'homeDirectory': '/home/{}'.format(TEST_ENTRY_NAME)
-+    }
-+
-+    tuser = users.create(properties=user_properties)
-+    tuser.rename('uid={}'.format(TEST_ENTRY_RDN_CHANGE), newsuperior=None, deloldrdn=True)
-+    tuser.rename('uid={}'.format(TEST_ENTRY_RDN_START), newsuperior=None, deloldrdn=True)
-+    tuser.rename('uid={}'.format(TEST_ENTRY_RDN_CHANGE), newsuperior=None, deloldrdn=True)
-+
-+    log.info("Check the log messages for cenotaph error")
-+    error_msg = ".*urp_fixup_add_cenotaph - failed to add cenotaph, err= 68"
-+    assert not topo.ds_error_log.match(error_msg)
-diff --git a/ldap/servers/plugins/replication/urp.c b/ldap/servers/plugins/replication/urp.c
-index 37fe77379..d71e1fa63 100644
---- a/ldap/servers/plugins/replication/urp.c
-+++ b/ldap/servers/plugins/replication/urp.c
-@@ -854,7 +854,7 @@ urp_post_delete_operation(Slapi_PBlock *pb)
- }
- 
- static int
--urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
-+urp_fixup_add_cenotaph(Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
- {
-     Slapi_PBlock *add_pb;
-     Slapi_Entry *cenotaph = NULL;
-@@ -892,7 +892,7 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
-     /* slapi_sdn_free(&pre_sdn); */
- 
-     cenotaph = slapi_entry_alloc();
--    slapi_entry_init(cenotaph, newdn, NULL);
-+    slapi_entry_init(cenotaph, slapi_ch_strdup(newdn), NULL);
- 
-     dncsn = (CSN *)entry_get_dncsn (pre_entry);
-     slapi_entry_add_string(cenotaph, SLAPI_ATTR_OBJECTCLASS, "extensibleobject");
-@@ -914,12 +914,46 @@ urp_fixup_add_cenotaph (Slapi_PBlock *pb, char *sessionid, CSN *opcsn)
-                                     OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP|OP_FLAG_CENOTAPH_ENTRY|SLAPI_OP_FLAG_BYPASS_REFERRALS);
-     slapi_add_internal_pb(add_pb);
-     slapi_pblock_get(add_pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
-+    slapi_pblock_destroy(add_pb);
-+
-+    if (ret == LDAP_ALREADY_EXISTS) {
-+        /* the cenotaph already exists, probably because of a loop
-+         * in renaming entries. Update it with new csns
-+         */
-+        slapi_log_err(SLAPI_LOG_REPL, sessionid,
-+                       "urp_fixup_add_cenotaph - cenotaph (%s) already exists, updating\n", newdn);
-+        Slapi_PBlock *mod_pb = slapi_pblock_new();
-+        Slapi_Mods smods;
-+        Slapi_DN *sdn = slapi_sdn_new_dn_byval(newdn);
-+        slapi_mods_init(&smods, 4);
-+        slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "cenotaphfrom", csn_as_string(dncsn, PR_FALSE, csnstr));
-+        slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "cenotaphto", csn_as_string(opcsn, PR_FALSE, csnstr));
-+        slapi_mods_add_string(&smods, LDAP_MOD_REPLACE, "nstombstonecsn", csn_as_string(opcsn, PR_FALSE, csnstr));
-+
-+        slapi_modify_internal_set_pb_ext(
-+            mod_pb,
-+            sdn,
-+            slapi_mods_get_ldapmods_byref(&smods),
-+            NULL, /* Controls */
-+            NULL,
-+            repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION),
-+            OP_FLAG_REPL_FIXUP|OP_FLAG_NOOP|OP_FLAG_CENOTAPH_ENTRY|SLAPI_OP_FLAG_BYPASS_REFERRALS);
-+
-+        slapi_modify_internal_pb(mod_pb);
-+        slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
-+        if (ret != LDAP_SUCCESS) {
-+            slapi_log_err(SLAPI_LOG_ERR, sessionid,
-+                       "urp_fixup_add_cenotaph - failed to modify cenotaph, err= %d\n", ret);
-+        }
-+        slapi_mods_done(&smods);
-+        slapi_sdn_free(&sdn);
-+        slapi_pblock_destroy(mod_pb);
- 
--    if (ret != LDAP_SUCCESS) {
-+    } else if (ret != LDAP_SUCCESS) {
-         slapi_log_err(SLAPI_LOG_ERR, sessionid,
-                        "urp_fixup_add_cenotaph - failed to add cenotaph, err= %d\n", ret);
-     }
--    slapi_pblock_destroy(add_pb);
-+    slapi_ch_free_string(&newdn);
- 
-     return ret;
- }
--- 
-2.25.1
-
diff --git a/SOURCES/0024-Ticket-50905-intermittent-SSL-hang-with-rhds.patch b/SOURCES/0024-Ticket-50905-intermittent-SSL-hang-with-rhds.patch
deleted file mode 100644
index 3af4844..0000000
--- a/SOURCES/0024-Ticket-50905-intermittent-SSL-hang-with-rhds.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From 14e3bea927c33a97ca8aed937b6edd9ce4557d24 Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Fri, 3 Apr 2020 15:23:10 +0200
-Subject: [PATCH] Ticket 50905 - intermittent SSL hang with rhds
-
-Bug Description:
-	On a successfull sasl bind, a new IO layer (sasl_io_enable) is registered on top of
-	the connection. Then sasl bind sends the successful result. Registration is
-	done while sasl bind thread holds c_mutex but result is sent while the c_mutex
-	is released.
-
-	If a new operation comes in just after c_mutex was released it is
-	possible that sasl bind sends the result while the new IO layer is pushed.
-        IO layers is partially initialized at that time. It can create sigseg or
-	deadlock or...
-
-Fix Description:
-	The fix is to protect the send result from IO layer push.
-	i.e. move send_ldap_result into c_mutex
-
-https://pagure.io/389-ds-base/issue/50905
-
-Reviewed by: Mark Reynolds (Thanks !!)
-
-Platforms tested: F29
-
-Flag Day: no
-
-Doc impact: no
----
- ldap/servers/slapd/saslbind.c | 10 +++++++---
- 1 file changed, 7 insertions(+), 3 deletions(-)
-
-diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
-index 0907c623f..ef29acf71 100644
---- a/ldap/servers/slapd/saslbind.c
-+++ b/ldap/servers/slapd/saslbind.c
-@@ -1118,12 +1118,16 @@ sasl_check_result:
-             /* Enable SASL I/O on the connection */
-             PR_EnterMonitor(pb_conn->c_mutex);
-             connection_set_io_layer_cb(pb_conn, sasl_io_enable, NULL, NULL);
-+
-+            /* send successful result before sasl_io_enable can be pushed by another incoming op */
-+            send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
-+
-             PR_ExitMonitor(pb_conn->c_mutex);
-+        } else {
-+            /* send successful result */
-+            send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
-         }
- 
--        /* send successful result */
--        send_ldap_result(pb, LDAP_SUCCESS, NULL, NULL, 0, NULL);
--
-         /* remove the sasl data from the pblock */
-         slapi_pblock_set(pb, SLAPI_BIND_RET_SASLCREDS, NULL);
- 
--- 
-2.25.4
-
diff --git a/SOURCES/0026-Ticket-51068-deadlock-when-updating-the-schema.patch b/SOURCES/0026-Ticket-51068-deadlock-when-updating-the-schema.patch
deleted file mode 100644
index 2f48907..0000000
--- a/SOURCES/0026-Ticket-51068-deadlock-when-updating-the-schema.patch
+++ /dev/null
@@ -1,224 +0,0 @@
-From 3b589a2bfc33f407cf2c23dc6896566bb8e2acdf Mon Sep 17 00:00:00 2001
-From: Thierry Bordaz <tbordaz@redhat.com>
-Date: Tue, 5 May 2020 17:44:01 +0200
-Subject: [PATCH] Ticket 51068 - deadlock when updating the schema
-
-Bug Description:
-        It exists a 3 threads deadlock scenario. It involves state change plugins when it
-        calls schema_changed_callback. So the trigger is a change of schema (direct or via
-        replication). The scenario is
-      MOD(cn=schema)    hold StateChange lock   wait for vattr lock
-      SRCH              hold vattr lock         wait for DB page
-      MOD               hold DB page            wait for StateChange lock
-
-Fix Description:
-        Statechange lock protects the list of registered callbacks.
-        lock is a mutex where actually registration of callback is only done
-        at startup. Later the list is only lookup.
-        Making statechange lock a rwlock suppresses the deadlock scenario
-        as MODs will only acquire in read StateChange lock.
-        It should also improve performance as at the moment all MODs are serialized
-        on that lock
-	In order to prevent writer starvation a new slapi_new_rwlock_prio
-        create rwlock with priority to writers.
-
-https://pagure.io/389-ds-base/issue/51068
-
-Reviewed by: Mark Reynolds, William Brown
-
-Platforms tested: 30
-
-Flag Day: no
-
-Doc impact: no
----
- .../servers/plugins/statechange/statechange.c | 24 ++++++++++--------
- ldap/servers/slapd/slapi-plugin.h             | 16 ++++++++++++
- ldap/servers/slapd/slapi2nspr.c               | 25 +++++++++++++++++++
- ldap/servers/slapd/vattr.c                    |  2 +-
- 4 files changed, 55 insertions(+), 12 deletions(-)
-
-diff --git a/ldap/servers/plugins/statechange/statechange.c b/ldap/servers/plugins/statechange/statechange.c
-index f89b394c6..0a3838b5e 100644
---- a/ldap/servers/plugins/statechange/statechange.c
-+++ b/ldap/servers/plugins/statechange/statechange.c
-@@ -40,7 +40,7 @@ static SCNotify *head; /* a place to start in the list */
- #define SCN_PLUGIN_SUBSYSTEM "statechange-plugin" /* used for logging */
- 
- static void *api[5];
--static Slapi_Mutex *buffer_lock = 0;
-+static Slapi_RWLock *buffer_lock = 0;
- static PRUint64 g_plugin_started = 0;
- 
- /*
-@@ -140,7 +140,7 @@ statechange_start(Slapi_PBlock *pb __attribute__((unused)))
-     api[3] = (void *)_statechange_unregister_all;
-     api[4] = (void *)_statechange_vattr_cache_invalidator_callback;
- 
--    if (0 == (buffer_lock = slapi_new_mutex())) /* we never free this mutex */
-+    if (0 == (buffer_lock = slapi_new_rwlock()))
-     {
-         /* badness */
-         slapi_log_err(SLAPI_LOG_ERR, SCN_PLUGIN_SUBSYSTEM, "statechange_start - Failed to create lock\n");
-@@ -180,7 +180,9 @@ statechange_close(Slapi_PBlock *pb __attribute__((unused)))
-     slapi_counter_destroy(&op_counter);
- 
-     slapi_apib_unregister(StateChange_v1_0_GUID);
--    slapi_destroy_mutex(buffer_lock);
-+    if (buffer_lock) {
-+        slapi_destroy_rwlock(buffer_lock);
-+    }
-     buffer_lock = NULL;
- 
-     slapi_log_err(SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<-- statechange_close\n");
-@@ -240,7 +242,7 @@ statechange_post_op(Slapi_PBlock *pb, int modtype)
-     slapi_log_err(SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "--> statechange_post_op\n");
- 
-     /* evaluate this operation against the notification entries */
--    slapi_lock_mutex(buffer_lock);
-+    slapi_rwlock_rdlock(buffer_lock);
-     if (head) {
-         slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
-         if (NULL == sdn) {
-@@ -290,7 +292,7 @@ statechange_post_op(Slapi_PBlock *pb, int modtype)
-         } while (notify && notify != head);
-     }
- bail:
--    slapi_unlock_mutex(buffer_lock);
-+    slapi_rwlock_unlock(buffer_lock);
-     slapi_log_err(SLAPI_LOG_TRACE, SCN_PLUGIN_SUBSYSTEM, "<-- statechange_post_op\n");
- 
-     return SLAPI_PLUGIN_SUCCESS; /* always succeed */
-@@ -338,7 +340,7 @@ _statechange_register(char *caller_id, char *dn, char *filter, void *caller_data
-         }
-         item->func = func;
- 
--        slapi_lock_mutex(buffer_lock);
-+        slapi_rwlock_wrlock(buffer_lock);
-         if (head == NULL) {
-             head = item;
-             head->next = head;
-@@ -349,7 +351,7 @@ _statechange_register(char *caller_id, char *dn, char *filter, void *caller_data
-             head->prev = item;
-             item->prev->next = item;
-         }
--        slapi_unlock_mutex(buffer_lock);
-+        slapi_rwlock_unlock(buffer_lock);
-         slapi_ch_free_string(&writable_filter);
- 
-         ret = SLAPI_PLUGIN_SUCCESS;
-@@ -371,7 +373,7 @@ _statechange_unregister(char *dn, char *filter, notify_callback thefunc)
-         return ret;
-     }
- 
--    slapi_lock_mutex(buffer_lock);
-+    slapi_rwlock_wrlock(buffer_lock);
- 
-     if ((func = statechange_find_notify(dn, filter, thefunc))) {
-         func->prev->next = func->next;
-@@ -392,7 +394,7 @@ _statechange_unregister(char *dn, char *filter, notify_callback thefunc)
-         slapi_ch_free((void **)&func);
-     }
- 
--    slapi_unlock_mutex(buffer_lock);
-+    slapi_rwlock_unlock(buffer_lock);
-     slapi_counter_decrement(op_counter);
- 
-     return ret;
-@@ -410,7 +412,7 @@ _statechange_unregister_all(char *caller_id, caller_data_free_callback callback)
-         return;
-     }
- 
--    slapi_lock_mutex(buffer_lock);
-+    slapi_rwlock_wrlock(buffer_lock);
- 
-     if (notify) {
-         do {
-@@ -441,7 +443,7 @@ _statechange_unregister_all(char *caller_id, caller_data_free_callback callback)
-         } while (notify != start_notify && notify != NULL);
-     }
- 
--    slapi_unlock_mutex(buffer_lock);
-+    slapi_rwlock_unlock(buffer_lock);
-     slapi_counter_decrement(op_counter);
- }
- 
-diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
-index 679bdbb5c..865d83b9b 100644
---- a/ldap/servers/slapd/slapi-plugin.h
-+++ b/ldap/servers/slapd/slapi-plugin.h
-@@ -6126,6 +6126,22 @@ void slapi_destroy_condvar(Slapi_CondVar *cvar);
- int slapi_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout);
- int slapi_notify_condvar(Slapi_CondVar *cvar, int notify_all);
- 
-+/**
-+ * Creates a new read/write lock
-+ * If prio_writer the rwlock gives priority on writers
-+ * else it give priority on readers (default)
-+ *
-+ * \return A pointer to a \c Slapi_RWLock
-+ *
-+ * \note Free the returned lock by calling slapi_destroy_rwlock() when finished
-+ *
-+ * \see slapi_destroy_rwlock()
-+ * \see slapi_rwlock_rdlock()
-+ * \see slapi_rwlock_wrlock()
-+ * \see slapi_rwlock_unlock()
-+ */
-+Slapi_RWLock *slapi_new_rwlock_prio(int32_t prio_writer);
-+
- /**
-  * Creates a new read/write lock.
-  *
-diff --git a/ldap/servers/slapd/slapi2nspr.c b/ldap/servers/slapd/slapi2nspr.c
-index b3e6d94c2..232d1599e 100644
---- a/ldap/servers/slapd/slapi2nspr.c
-+++ b/ldap/servers/slapd/slapi2nspr.c
-@@ -181,6 +181,31 @@ slapi_notify_condvar(Slapi_CondVar *cvar, int notify_all)
-     return (prrc == PR_SUCCESS ? 1 : 0);
- }
- 
-+Slapi_RWLock *
-+slapi_new_rwlock_prio(int32_t prio_writer)
-+{
-+#ifdef USE_POSIX_RWLOCKS
-+    pthread_rwlock_t *rwlock = NULL;
-+    pthread_rwlockattr_t attr;
-+
-+    pthread_rwlockattr_init(&attr);
-+    if (prio_writer) {
-+        pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
-+    } else {
-+        pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_READER_NP);
-+    }
-+
-+    rwlock = (pthread_rwlock_t *)slapi_ch_malloc(sizeof(pthread_rwlock_t));
-+    if (rwlock) {
-+        pthread_rwlock_init(rwlock, &attr);
-+    }
-+
-+    return ((Slapi_RWLock *)rwlock);
-+#else
-+    return ((Slapi_RWLock *)PR_NewRWLock(PR_RWLOCK_RANK_NONE, "slapi_rwlock"));
-+#endif
-+}
-+
- Slapi_RWLock *
- slapi_new_rwlock(void)
- {
-diff --git a/ldap/servers/slapd/vattr.c b/ldap/servers/slapd/vattr.c
-index 852a887ce..eef444270 100644
---- a/ldap/servers/slapd/vattr.c
-+++ b/ldap/servers/slapd/vattr.c
-@@ -1996,7 +1996,7 @@ vattr_map_create(void)
-         return ENOMEM;
-     }
- 
--    the_map->lock = slapi_new_rwlock();
-+    the_map->lock = slapi_new_rwlock_prio(1 /* priority on writers */);
-     if (NULL == the_map) {
-         slapd_nasty(sourcefile, 3, 0);
-         return ENOMEM;
--- 
-2.26.2
-
diff --git a/SOURCES/0027-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch b/SOURCES/0027-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch
deleted file mode 100644
index e9ce0d3..0000000
--- a/SOURCES/0027-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From b69687377d6afd973a8bc27d8d34bf8069943a9d Mon Sep 17 00:00:00 2001
-From: Mark Reynolds <mreynolds@redhat.com>
-Date: Tue, 19 May 2020 11:25:13 -0400
-Subject: [PATCH] Issue 50745: ns-slapd hangs during CleanAllRUV tests
-
-Bug Description:
-	The hang condition:
-		- is not systematic
-		- occurs in rare case, for example here during the deletion of a replica.
-		- a thread is waiting for a dblock that an other thread "forgot" to
-		  release.
-		- have always existed, at least since 1.4.0 but likely since 1.2.x
-
-	When deleting a replica, the replica is retrieved from
-	mapping tree structure (mtnode).
-	The replica is also retrieved through the mapping tree
-	when writing updates to the changelog.
-
-	When deleting the replica, mapping tree structure is cleared
-	after the changelog is deleted (that can take some cycles).
-	There is a window where an update can retrieve the replica,
-	from the not yet cleared MT, while the changelog being removed.
-
-	At the end, the update will update the changelog that is
-	currently removed and keeps an unfree lock in the DB.
-
-Fix description:
-	Ideally mapping tree should be protected by a lock but it
-	is not done systematically (e.g.  slapi_get_mapping_tree_node).
-	Using a lock looks an overkill and can probably introduce
-	deadlock and performance hit.
-	The idea of the fix is to reduce the window, moving the
-	mapping tree clear before the changelog removal.
-
-https://pagure.io/389-ds-base/issue/50745
-
-Reviewed by: Mark Reynolds, Ludwig Krispenz
----
- ldap/servers/plugins/replication/repl5_replica_config.c | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
-index 80a079784..95b7fa50e 100644
---- a/ldap/servers/plugins/replication/repl5_replica_config.c
-+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
-@@ -735,18 +735,18 @@ replica_config_delete(Slapi_PBlock *pb __attribute__((unused)),
-     PR_ASSERT(mtnode_ext);
- 
-     if (mtnode_ext->replica) {
-+        Object *repl_obj = mtnode_ext->replica;
-         /* remove object from the hash */
-         r = (Replica *)object_get_data(mtnode_ext->replica);
-+        mtnode_ext->replica = NULL;
-         PR_ASSERT(r);
-         /* The changelog for this replica is no longer valid, so we should remove it. */
-         slapi_log_err(SLAPI_LOG_WARNING, repl_plugin_name, "replica_config_delete - "
-                                                            "The changelog for replica %s is no longer valid since "
-                                                            "the replica config is being deleted.  Removing the changelog.\n",
-                       slapi_sdn_get_dn(replica_get_root(r)));
--        cl5DeleteDBSync(mtnode_ext->replica);
-+        cl5DeleteDBSync(repl_obj);
-         replica_delete_by_name(replica_get_name(r));
--        object_release(mtnode_ext->replica);
--        mtnode_ext->replica = NULL;
-     }
- 
-     PR_Unlock(s_configLock);
--- 
-2.26.2
-
diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec
index 40aa433..425833b 100644
--- a/SPECS/389-ds-base.spec
+++ b/SPECS/389-ds-base.spec
@@ -38,8 +38,8 @@
 
 Summary:          389 Directory Server (%{variant})
 Name:             389-ds-base
-Version:          1.3.10.1
-Release:          %{?relprefix}14%{?prerel}%{?dist}
+Version:          1.3.10.2
+Release:          %{?relprefix}6%{?prerel}%{?dist}
 License:          GPLv3+
 URL:              https://www.port389.org/
 Group:            System Environment/Daemons
@@ -145,35 +145,14 @@ Requires:         gperftools-libs
 Source0:          https://releases.pagure.org/389-ds-base/%{name}-%{version}%{?prerel}.tar.bz2
 Source1:          %{name}-git.sh
 Source2:          %{name}-devel.README
-Patch00:          0000-CVE-2019-14824-BZ-1748199-deref-plugin-displays-rest.patch
-Patch01:          0001-Issue-50525-nsslapd-defaultnamingcontext-does-not-ch.patch
-Patch02:          0002-Issue-50530-Directory-Server-not-RFC-4511-compliant-.patch
-Patch03:          0003-Issue-50529-LDAP-server-returning-PWP-controls-in-di.patch
-Patch04:          0004-Issue-50538-cleanAllRUV-task-limit-is-not-enforced-f.patch
-Patch05:          0005-Issue-49624-modrdn-silently-fails-if-DB-deadlock-occ.patch
-Patch06:          0006-Issue-50572-After-running-cl-dump-dbdir-cldb-ldif.do.patch
-Patch07:          0007-Issue-50538-Fix-cherry-pick-error.patch
-Patch08:          0008-Issue-50646-Improve-task-handling-during-shutdowns.patch
-Patch09:          0009-Issue-50653-objectclass-parsing-fails-to-log-error-m.patch
-Patch10:          0010-Issue-50655-access-log-etime-is-not-properly-formatt.patch
-Patch11:          0011-Issue-49850-ldbm_get_nonleaf_ids-slow-for-databases-.patch
-Patch12:          0012-Issue-50536-Audit-log-heading-written-to-log-after-e.patch
-Patch13:          0013-Issue-50636-Crash-during-sasl-bind.patch
-Patch14:          0014-Ticket-49850-cont-fix-crash-in-ldbm_non_leaf.patch
-Patch15:          0015-Ticket-49624-cont-DB-Deadlock-on-modrdn-appears-to-c.patch
-Patch16:          0016-Ticket-50542-Entry-cache-contention-during-base-sear.patch
-Patch17:          0017-Issue-50834-Incorrectly-setting-the-NSS-default-SSL-.patch
-Patch18:          0018-Ticket-50736-RetroCL-trimming-may-crash-at-shutdown-.patch
-Patch19:          0019-Ticket-50709-Several-memory-leaks-reported-by-Valgri.patch
-Patch20:          0020-Ticket-50857-Memory-leak-in-ACI-using-IP-subject.patch
-Patch21:          0021-Ticket-50709-cont-Several-memory-leaks-reported-by-V.patch
-Patch22:          0022-fix-for-50542-crashes-in-filter-tests.patch
-Patch23:          0023-Ticket-49623-cont-cenotaph-errors-on-modrdn-operatio.patch
-Patch24:          0024-Ticket-50905-intermittent-SSL-hang-with-rhds.patch
-# Patch25:          0025-Issue-50940-Permissions-of-some-shipped-directories-.patch
-Patch26:          0026-Ticket-51068-deadlock-when-updating-the-schema.patch
-Patch27:          0027-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch
-
+Patch00:          0000-Issue-50800-wildcards-in-rootdn-allow-ip-attribute-a.patch
+Patch01:          0001-Issue-49437-Fix-memory-leak-with-indirect-COS.patch
+Patch02:          0002-Ticket-50905-intermittent-SSL-hang-with-rhds.patch
+Patch03:          0003-Issue-51029-Add-db_home_dir-defaults.inf.patch
+Patch04:          0004-Ticket-51068-deadlock-when-updating-the-schema.patch
+Patch05:          0005-Issue-50745-ns-slapd-hangs-during-CleanAllRUV-tests.patch
+Patch06:          0006-Issue-51095-abort-operation-if-CSN-can-not-be-genera.patch
+Patch07:          0007-Issue-51132-Winsync-setting-winSyncWindowsFilter-not.patch 
 %description
 389 Directory Server is an LDAPv3 compliant server.  The base package includes
 the LDAP server and command line utilities for server administration.
@@ -287,7 +266,8 @@ cp -r %{_builddir}/%{name}-%{version}%{?prerel}/man/man3 $RPM_BUILD_ROOT/%{_mand
 
 mkdir -p $RPM_BUILD_ROOT/var/log/%{pkgname}
 mkdir -p $RPM_BUILD_ROOT/var/lib/%{pkgname}
-mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname}
+mkdir -p $RPM_BUILD_ROOT/var/lock/%{pkgname} \
+    && chmod 770 $RPM_BUILD_ROOT/var/lock/%{pkgname}
 
 # for systemd
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/systemd/system/%{groupname}.wants
@@ -525,34 +505,45 @@ fi
 %{_sysconfdir}/%{pkgname}/dirsrvtests
 
 %changelog
-* Mon Jun 15 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-14
-- Bump version to 1.3.10.1-14
-- Resolves: Bug 1814603 - revert patch as it conflicts with 389-admin package
-
-* Thu Jun 4 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-13
-- Bump version to 1.3.10.1-13
-- Resolves: Bug 1842469 - ns-slapd hangs during CleanAllRUV tests
- 
-* Fri May 29 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-12
-- Bump version to 1.3.10.1-12
-- Resolves: Bug 1814603 - 389-base-ds expected file permissions
-
-* Fri May 29 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-11
-- Bump version to 1.3.10.1-11
-- Resolves: Bug 1839173 - ipa ns-slapd 3 threads deadlock, db pages, state_change lock, write vattr lock
-
-* Tue May 19 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-10
-- Bump version to 1.3.10.1-10
-- Resolves: Bug 1814603 - 389-base-ds expected file permissions in package don't match final runtime permissions
-- Resolves: Bug 1836171 - intermittent SSL hang with rhds
-
-* Mon Apr 6 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-9
-- Bump version to 1.3.10.1-9
-- Resolves: Bug 1817933 - cenotaph errors on modrdn operations
-
-* Fri Mar 6 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-8
-- Bump version to 1.3.10.1-8
-- Resolves: Bug 1809160 - Entry cache contention during base search (Fix crash - part 2)
+* Thu Jun 4 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10-2-6
+- Bump version to 1.3.10.2-6
+- Resolves: Bug 1839085 - IPA: Winsync not honoring parameters winSyncDirectoryFilter and winSyncWindowsFilter
+
+* Tue Jun 2 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.2-5
+- Bump version to 1.3.10.2-5
+- Resolves: Bug 1700987 - 389-base-ds expected file permissions in package don't match final runtime permissions
+
+* Fri May 29 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.2-4
+- Bump version to 1.3.10.2-4
+- Resolves: Bug 1837105 - Check for clock errors and time skew
+
+* Tue May 19 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.2-3
+- Bump version to 1.3.10.2-3
+- Resolves: Bug 1824930 - ipa ns-slapd 3 threads deadlock, db pages, state_change lock, write vattr lock
+- Resolves: Bug 1837477 - ns-slapd hangs during CleanAllRUV tests
+
+* Thu Apr 23 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.2-2
+- Bump version to  1.3.10.2-2
+- Resolves: Bug 1820433 - Invalid defaults.inf, missing key db_home_dir
+- Resolves: Bug 1801327 - intermittent SSL hang with rhds
+- Resolves: Bug 1807537 - wildcards in rootdn-allow-ip attribute are not accepted
+- Resolves: Bug 1827284 - Memory leak in indirect COS
+
+* Mon Mar 16 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.2-1
+- Bump version to  1.3.10.2-1
+- Resolves: Bug 1724761 - Entry cache contention during base search
+- Resolves: Bug 1515319 - nsDS5ReplicaId cant be set to the old value it had before
+- Resolves: Bug 1700987 - 389-base-ds expected file permissions in package don't match final runtime permissions
+- Resolves: Bug 1762901 - cenotaph errors on modrdn operations
+- Resolves: Bug 1772616 - Typo in the replication debug message "error 0 for oparation 561" 
+- Resolves: Bug 1781276 - Regression: NSS has interop problems as server when using limited cipher list
+- Resolves: Bug 1787921 - Crash on startup: Bus error in __env_faultmem.isra.1.part.2
+- Resolves: Bug 1759142 - No error returned when adding an entry matching filters for a non existing automember group
+- Resolves: Bug 1763365 - ns-slapd is crashing while restarting ipactl
+- Resolves: Bug 1769418 - Several memory leaks reported by Valgrind for 389-ds 1.3.9.1-10
+- Resolves: Bug 1775165 - ldclt core dumped when run with -e genldif option
+- Resolves: Bug 1796558 - Memory leak in ACI using IP subject
+- Resolves: Bug 1769296 - cl-dump exit code is 0 even if command fails with invalid arguments
 
 * Mon Mar 2 2020 Mark Reynolds <mreynolds@redhat.com> - 1.3.10.1-7
 - Bump version to 1.3.10.1-7