diff --git a/SOURCES/0044-Issue-4563-Failure-on-s390x-Fails-to-split-RDN-o-pki.patch b/SOURCES/0044-Issue-4563-Failure-on-s390x-Fails-to-split-RDN-o-pki.patch new file mode 100644 index 0000000..752cd19 --- /dev/null +++ b/SOURCES/0044-Issue-4563-Failure-on-s390x-Fails-to-split-RDN-o-pki.patch @@ -0,0 +1,40 @@ +From 7e042cbc74440b81f46efa73ccb36d80732c7074 Mon Sep 17 00:00:00 2001 +From: tbordaz +Date: Thu, 28 Jan 2021 10:39:31 +0100 +Subject: [PATCH] Issue 4563 - Failure on s390x: 'Fails to split RDN + "o=pki-tomcat-CA" into components' (#4573) + +Bug description: + SLAPI_OPERATION_TYPE is a stored/read as an int (slapi_pblock_get/set). + This although the storage field is an unsigned long. + Calling slapi_pblock_get with an long (8 btyes) destination creates + a problem on big-endian (s390x). + +Fix description: + Define destination op_type as an int (4 bytes) + +relates: https://github.com/389ds/389-ds-base/issues/4563 + +Reviewed by: Mark Reynolds, William Brown + +Platforms tested: F31 (little endian), Debian (big endian) +--- + ldap/servers/slapd/back-ldbm/ldbm_modify.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c +index a507f3c31..49ca01d1d 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c +@@ -216,7 +216,7 @@ error: + int32_t + entry_get_rdn_mods(Slapi_PBlock *pb, Slapi_Entry *entry, CSN *csn, int repl_op, Slapi_Mods **smods_ret) + { +- unsigned long op_type = SLAPI_OPERATION_NONE; ++ int op_type = SLAPI_OPERATION_NONE; + char *new_rdn = NULL; + char **dns = NULL; + char **rdns = NULL; +-- +2.31.1 + diff --git a/SOURCES/0045-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch b/SOURCES/0045-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch new file mode 100644 index 0000000..602d372 --- /dev/null +++ b/SOURCES/0045-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch @@ -0,0 +1,226 @@ +From 98caa0c0ddf48db791a26764aa695fa2345584ce Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 13 Jul 2021 14:18:03 -0400 +Subject: [PATCH] Issue 4443 - Internal unindexed searches in syncrepl/retro + changelog + +Bug Description: + +When a non-system index is added to a backend it is +disabled until the database is initialized or reindexed. +So in the case of the retro changelog the changenumber index +is alway disabled by default since it is never initialized. +This leads to unexpected unindexed searches of the retro +changelog. + +Fix Description: + +If an index has "nsSystemIndex" set to "true" then enable it +immediately. + +relates: https://github.com/389ds/389-ds-base/issues/4443 + +Reviewed by: spichugi & tbordaz(Thanks!!) +--- + .../suites/retrocl/retrocl_indexing_test.py | 68 +++++++++++++++++++ + ldap/servers/plugins/retrocl/retrocl_create.c | 2 +- + .../slapd/back-ldbm/ldbm_index_config.c | 25 +++++-- + src/lib389/lib389/_mapped_object.py | 13 ++++ + 4 files changed, 102 insertions(+), 6 deletions(-) + create mode 100644 dirsrvtests/tests/suites/retrocl/retrocl_indexing_test.py + +diff --git a/dirsrvtests/tests/suites/retrocl/retrocl_indexing_test.py b/dirsrvtests/tests/suites/retrocl/retrocl_indexing_test.py +new file mode 100644 +index 000000000..b1dfe962c +--- /dev/null ++++ b/dirsrvtests/tests/suites/retrocl/retrocl_indexing_test.py +@@ -0,0 +1,68 @@ ++import logging ++import pytest ++import os ++from lib389._constants import RETROCL_SUFFIX, DEFAULT_SUFFIX ++from lib389.topologies import topology_st as topo ++from lib389.plugins import RetroChangelogPlugin ++from lib389.idm.user import UserAccounts ++from lib389._mapped_object import DSLdapObjects ++log = logging.getLogger(__name__) ++ ++ ++def test_indexing_is_online(topo): ++ """Test that the changenmumber index is online right after enabling the plugin ++ ++ :id: 16f4c001-9e0c-4448-a2b3-08ac1e85d40f ++ :setup: Standalone Instance ++ :steps: ++ 1. Enable retro cl ++ 2. Perform some updates ++ 3. Search for "(changenumber>=-1)", and it is not partially unindexed ++ 4. Search for "(&(changenumber>=-1)(targetuniqueid=*))", and it is not partially unindexed ++ :expectedresults: ++ 1. Success ++ 2. Success ++ 3. Success ++ 4. Success ++ """ ++ ++ # Enable plugin ++ topo.standalone.config.set('nsslapd-accesslog-logbuffering', 'off') ++ plugin = RetroChangelogPlugin(topo.standalone) ++ plugin.enable() ++ topo.standalone.restart() ++ ++ # Do a bunch of updates ++ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX) ++ user_entry = users.create(properties={ ++ 'sn': '1', ++ 'cn': 'user 1', ++ 'uid': 'user1', ++ 'uidNumber': '11', ++ 'gidNumber': '111', ++ 'givenname': 'user1', ++ 'homePhone': '0861234567', ++ 'carLicense': '131D16674', ++ 'mail': 'user1@whereever.com', ++ 'homeDirectory': '/home' ++ }) ++ for count in range(0, 10): ++ user_entry.replace('mail', f'test{count}@test.com') ++ ++ # Search the retro cl, and check for error messages ++ filter_simple = '(changenumber>=-1)' ++ filter_compound = '(&(changenumber>=-1)(targetuniqueid=*))' ++ retro_changelog_suffix = DSLdapObjects(topo.standalone, basedn=RETROCL_SUFFIX) ++ retro_changelog_suffix.filter(filter_simple) ++ assert not topo.standalone.searchAccessLog('Partially Unindexed Filter') ++ ++ # Search the retro cl again with compound filter ++ retro_changelog_suffix.filter(filter_compound) ++ assert not topo.standalone.searchAccessLog('Partially Unindexed Filter') ++ ++ ++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/plugins/retrocl/retrocl_create.c b/ldap/servers/plugins/retrocl/retrocl_create.c +index 571e6899f..5bfde7831 100644 +--- a/ldap/servers/plugins/retrocl/retrocl_create.c ++++ b/ldap/servers/plugins/retrocl/retrocl_create.c +@@ -133,7 +133,7 @@ retrocl_create_be(const char *bedir) + val.bv_len = strlen(val.bv_val); + slapi_entry_add_values(e, "cn", vals); + +- val.bv_val = "false"; ++ val.bv_val = "true"; /* enables the index */ + val.bv_len = strlen(val.bv_val); + slapi_entry_add_values(e, "nssystemindex", vals); + +diff --git a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c +index 9722d0ce7..38e7368e1 100644 +--- a/ldap/servers/slapd/back-ldbm/ldbm_index_config.c ++++ b/ldap/servers/slapd/back-ldbm/ldbm_index_config.c +@@ -25,7 +25,7 @@ int ldbm_instance_index_config_delete_callback(Slapi_PBlock *pb, Slapi_Entry *en + #define INDEXTYPE_NONE 1 + + static int +-ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name, char *err_buf) ++ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name, PRBool *is_system_index, char *err_buf) + { + Slapi_Attr *attr; + const struct berval *attrValue; +@@ -78,6 +78,15 @@ ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_st + } + } + ++ *is_system_index = PR_FALSE; ++ if (0 == slapi_entry_attr_find(e, "nsSystemIndex", &attr)) { ++ slapi_attr_first_value(attr, &sval); ++ attrValue = slapi_value_get_berval(sval); ++ if (strcasecmp(attrValue->bv_val, "true") == 0) { ++ *is_system_index = PR_TRUE; ++ } ++ } ++ + /* ok the entry is good to process, pass it to attr_index_config */ + if (attr_index_config(inst->inst_be, (char *)trace_string, 0, e, 0, 0, err_buf)) { + slapi_ch_free_string(index_name); +@@ -101,9 +110,10 @@ ldbm_index_init_entry_callback(Slapi_PBlock *pb __attribute__((unused)), + void *arg) + { + ldbm_instance *inst = (ldbm_instance *)arg; ++ PRBool is_system_index = PR_FALSE; + + returntext[0] = '\0'; +- *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL, NULL); ++ *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL, &is_system_index /* not used */, NULL); + if (*returncode == LDAP_SUCCESS) { + return SLAPI_DSE_CALLBACK_OK; + } else { +@@ -126,17 +136,21 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb __attribute__((unused)) + { + ldbm_instance *inst = (ldbm_instance *)arg; + char *index_name = NULL; ++ PRBool is_system_index = PR_FALSE; + + returntext[0] = '\0'; +- *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, returntext); ++ *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, &is_system_index, returntext); + if (*returncode == LDAP_SUCCESS) { + struct attrinfo *ai = NULL; + /* if the index is a "system" index, we assume it's being added by + * by the server, and it's okay for the index to go online immediately. + * if not, we set the index "offline" so it won't actually be used + * until someone runs db2index on it. ++ * If caller wants to add an index that they want to be online ++ * immediately they can also set "nsSystemIndex" to "true" in the ++ * index config entry (e.g. is_system_index). + */ +- if (!ldbm_attribute_always_indexed(index_name)) { ++ if (!is_system_index && !ldbm_attribute_always_indexed(index_name)) { + ainfo_get(inst->inst_be, index_name, &ai); + PR_ASSERT(ai != NULL); + ai->ai_indexmask |= INDEX_OFFLINE; +@@ -386,13 +400,14 @@ ldbm_instance_index_config_enable_index(ldbm_instance *inst, Slapi_Entry *e) + char *index_name = NULL; + int rc = LDAP_SUCCESS; + struct attrinfo *ai = NULL; ++ PRBool is_system_index = PR_FALSE; + + index_name = slapi_entry_attr_get_charptr(e, "cn"); + if (index_name) { + ainfo_get(inst->inst_be, index_name, &ai); + } + if (!ai) { +- rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, NULL); ++ rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, &is_system_index /* not used */, NULL); + } + if (rc == LDAP_SUCCESS) { + /* Assume the caller knows if it is OK to go online immediately */ +diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py +index ca6ea6ef8..6cdcb0dc7 100644 +--- a/src/lib389/lib389/_mapped_object.py ++++ b/src/lib389/lib389/_mapped_object.py +@@ -147,6 +147,19 @@ class DSLdapObject(DSLogging, DSLint): + + return True + ++ def search(self, scope="subtree", filter='objectclass=*'): ++ search_scope = ldap.SCOPE_SUBTREE ++ if scope == 'base': ++ search_scope = ldap.SCOPE_BASE ++ elif scope == 'one': ++ search_scope = ldap.SCOPE_ONE ++ elif scope == 'subtree': ++ search_scope = ldap.SCOPE_SUBTREE ++ return self._instance.search_ext_s(self._dn, search_scope, filter, ++ serverctrls=self._server_controls, ++ clientctrls=self._client_controls, ++ escapehatch='i am sure') ++ + def display(self, attrlist=['*']): + """Get an entry but represent it as a string LDIF + +-- +2.31.1 + diff --git a/SOURCES/0046-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch b/SOURCES/0046-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch new file mode 100644 index 0000000..68a259d --- /dev/null +++ b/SOURCES/0046-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch @@ -0,0 +1,121 @@ +From 1da033b82b428bb5b90c201a59aaab24e0f14ccf Mon Sep 17 00:00:00 2001 +From: Firstyear +Date: Fri, 9 Jul 2021 11:53:35 +1000 +Subject: [PATCH] Issue 4817 - BUG - locked crypt accounts on import may allow + all passwords (#4819) + +Bug Description: Due to mishanding of short dbpwd hashes, the +crypt_r algorithm was misused and was only comparing salts +in some cases, rather than checking the actual content +of the password. + +Fix Description: Stricter checks on dbpwd lengths to ensure +that content passed to crypt_r has at least 2 salt bytes and +1 hash byte, as well as stricter checks on ct_memcmp to ensure +that compared values are the same length, rather than potentially +allowing overruns/short comparisons. + +fixes: https://github.com/389ds/389-ds-base/issues/4817 + +Author: William Brown + +Review by: @mreynolds389 +--- + .../password/pwd_crypt_asterisk_test.py | 50 +++++++++++++++++++ + ldap/servers/plugins/pwdstorage/crypt_pwd.c | 20 +++++--- + 2 files changed, 64 insertions(+), 6 deletions(-) + create mode 100644 dirsrvtests/tests/suites/password/pwd_crypt_asterisk_test.py + +diff --git a/dirsrvtests/tests/suites/password/pwd_crypt_asterisk_test.py b/dirsrvtests/tests/suites/password/pwd_crypt_asterisk_test.py +new file mode 100644 +index 000000000..d76614db1 +--- /dev/null ++++ b/dirsrvtests/tests/suites/password/pwd_crypt_asterisk_test.py +@@ -0,0 +1,50 @@ ++# --- BEGIN COPYRIGHT BLOCK --- ++# Copyright (C) 2021 William Brown ++# All rights reserved. ++# ++# License: GPL (version 3 or any later version). ++# See LICENSE for details. ++# --- END COPYRIGHT BLOCK --- ++# ++import ldap ++import pytest ++from lib389.topologies import topology_st ++from lib389.idm.user import UserAccounts ++from lib389._constants import (DEFAULT_SUFFIX, PASSWORD) ++ ++pytestmark = pytest.mark.tier1 ++ ++def test_password_crypt_asterisk_is_rejected(topology_st): ++ """It was reported that {CRYPT}* was allowing all passwords to be ++ valid in the bind process. This checks that we should be rejecting ++ these as they should represent locked accounts. Similar, {CRYPT}! ++ ++ :id: 0b8f1a6a-f3eb-4443-985e-da14d0939dc3 ++ :setup: Single instance ++ :steps: 1. Set a password hash in with CRYPT and the content * ++ 2. Test a bind ++ 3. Set a password hash in with CRYPT and the content ! ++ 4. Test a bind ++ :expectedresults: ++ 1. Successfully set the values ++ 2. The bind fails ++ 3. Successfully set the values ++ 4. The bind fails ++ """ ++ topology_st.standalone.config.set('nsslapd-allow-hashed-passwords', 'on') ++ topology_st.standalone.config.set('nsslapd-enable-upgrade-hash', 'off') ++ ++ users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX) ++ user = users.create_test_user() ++ ++ user.set('userPassword', "{CRYPT}*") ++ ++ # Attempt to bind with incorrect password. ++ with pytest.raises(ldap.INVALID_CREDENTIALS): ++ badconn = user.bind('badpassword') ++ ++ user.set('userPassword', "{CRYPT}!") ++ # Attempt to bind with incorrect password. ++ with pytest.raises(ldap.INVALID_CREDENTIALS): ++ badconn = user.bind('badpassword') ++ +diff --git a/ldap/servers/plugins/pwdstorage/crypt_pwd.c b/ldap/servers/plugins/pwdstorage/crypt_pwd.c +index 9031b2199..1b37d41ed 100644 +--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c +@@ -48,15 +48,23 @@ static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + int + crypt_pw_cmp(const char *userpwd, const char *dbpwd) + { +- int rc; +- char *cp; ++ int rc = -1; ++ char *cp = NULL; ++ size_t dbpwd_len = strlen(dbpwd); + struct crypt_data data; + data.initialized = 0; + +- /* we use salt (first 2 chars) of encoded password in call to crypt_r() */ +- cp = crypt_r(userpwd, dbpwd, &data); +- if (cp) { +- rc = slapi_ct_memcmp(dbpwd, cp, strlen(dbpwd)); ++ /* ++ * there MUST be at least 2 chars of salt and some pw bytes, else this is INVALID and will ++ * allow any password to bind as we then only compare SALTS. ++ */ ++ if (dbpwd_len >= 3) { ++ /* we use salt (first 2 chars) of encoded password in call to crypt_r() */ ++ cp = crypt_r(userpwd, dbpwd, &data); ++ } ++ /* If these are not the same length, we can not proceed safely with memcmp. */ ++ if (cp && dbpwd_len == strlen(cp)) { ++ rc = slapi_ct_memcmp(dbpwd, cp, dbpwd_len); + } else { + rc = -1; + } +-- +2.31.1 + diff --git a/SOURCES/0047-Issue-4837-persistent-search-returns-entries-even-wh.patch b/SOURCES/0047-Issue-4837-persistent-search-returns-entries-even-wh.patch new file mode 100644 index 0000000..408f0bb --- /dev/null +++ b/SOURCES/0047-Issue-4837-persistent-search-returns-entries-even-wh.patch @@ -0,0 +1,39 @@ +From 4919320a395ee13db67a4cc5f7c0b76e781b3b73 Mon Sep 17 00:00:00 2001 +From: tbordaz +Date: Wed, 21 Jul 2021 09:16:30 +0200 +Subject: [PATCH] Issue 4837 - persistent search returns entries even when an + error is returned by content-sync-plugin (#4838) + +Bug description: + When a ldap client sends a sync request control, the server response may contain a sync state control. + If the server fails to create the control the search should fail. + +Fix description: + In case the server fails to create the response control + logs the failure of the pre_search + +relates: https://github.com/389ds/389-ds-base/issues/4837 + +Reviewed by: Simon Pichugin + +Platforms tested: RH8.4 +--- + ldap/servers/plugins/sync/sync_refresh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ldap/servers/plugins/sync/sync_refresh.c b/ldap/servers/plugins/sync/sync_refresh.c +index 646ff760b..4cbb6a949 100644 +--- a/ldap/servers/plugins/sync/sync_refresh.c ++++ b/ldap/servers/plugins/sync/sync_refresh.c +@@ -213,7 +213,7 @@ sync_srch_refresh_pre_entry(Slapi_PBlock *pb) + Slapi_Entry *e; + slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e); + LDAPControl **ctrl = (LDAPControl **)slapi_ch_calloc(2, sizeof(LDAPControl *)); +- sync_create_state_control(e, &ctrl[0], LDAP_SYNC_ADD, NULL); ++ rc = sync_create_state_control(e, &ctrl[0], LDAP_SYNC_ADD, NULL); + slapi_pblock_set(pb, SLAPI_SEARCH_CTRLS, ctrl); + } + return (rc); +-- +2.31.1 + diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index 3271a91..a98b9a9 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -45,7 +45,7 @@ ExcludeArch: i686 Summary: 389 Directory Server (base) Name: 389-ds-base Version: 1.4.3.16 -Release: %{?relprefix}16%{?prerel}%{?dist}.0.2 +Release: %{?relprefix}19%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org Group: System Environment/Daemons @@ -217,6 +217,10 @@ Patch40: 0040-Issue-4764-replicated-operation-sometime-checks-ACI-.patc Patch41: 0041-Issue-4797-ACL-IP-ADDRESS-evaluation-may-corrupt-c_i.patch Patch42: 0042-Issue-4492-Changelog-cache-can-upload-updates-from-a.patch Patch43: 0043-Issue-4644-Large-updates-can-reset-the-CLcache-to-th.patch +Patch44: 0044-Issue-4563-Failure-on-s390x-Fails-to-split-RDN-o-pki.patch +Patch45: 0045-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch +Patch46: 0046-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch +Patch47: 0047-Issue-4837-persistent-search-returns-entries-even-wh.patch %description @@ -835,6 +839,19 @@ exit 0 %doc README.md %changelog +* Wed Jul 21 2021 Thierry Bordaz - 1.4.3.16-19 +- Bump version to 1.4.3.16-19 +- Resolve: Bug 1984091 - persistent search returns entries even when an error is returned by content-sync-plugin + +* Mon Jul 19 2021 Thierry Bordaz - 1.4.3.16-18 +- Bump version to 1.4.3.16-18 +- Resolve: Bug 1983121 - CRYPT password hash with asterisk allows any bind attempt to succeed + +* Fri Jul 16 2021 Thierry Bordaz - 1.4.3.16-17 +- Bump version to 1.4.3.16-17 +- Resolve: Bug 1983095 - Internal unindexed searches in syncrepl +- Resolve: Bug 1980063 - IPA installation fails on s390x with 389-ds-base-1.4.3.8-4.module+el8.3.0+7193+dfd1e8ad.s390x + * Wed Jun 16 2021 Thierry Bordaz - 1.4.3.16-16 - Bump version to 1.4.3.16-16 - Resolves: Bug 1972738 - Changelog cache can upload updates from a wrong starting point (CSN)