From de47d7ced1f337ca647716fd039c85ba92d4bec8 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 29 2020 06:58:50 +0000 Subject: import 389-ds-base-1.3.10.2-6.el7 --- 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 -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 +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 +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 -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 -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 +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 -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 +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 -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 +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 -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 +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 -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\fP and --.\" \fI\fP escape sequences to invode bold face and italics, -+.\" \fI\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 +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, <now); + 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, <now); + 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, <now); + 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 -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 +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 -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 -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 -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 -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 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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 1.3.10.1-7 - Bump version to 1.3.10.1-7