diff --git a/SOURCES/0026-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch b/SOURCES/0026-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch new file mode 100644 index 0000000..7bc30a6 --- /dev/null +++ b/SOURCES/0026-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch @@ -0,0 +1,228 @@ +From c8413c93adb59db89fde84f4e8a7942246732aa5 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Tue, 13 Jul 2021 14:18:03 -0400 +Subject: [PATCH 1/4] 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 | 27 ++++++-- + src/lib389/lib389/_mapped_object.py | 13 ++++ + 4 files changed, 103 insertions(+), 7 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..9782368b4 +--- /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', 'test%d@test.com' % count) ++ ++ # 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 fb1503520..09f0a4f90 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 95e76c8dc..59bbbcd45 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) ++ldbm_index_parse_entry(ldbm_instance *inst, Slapi_Entry *e, const char *trace_string, char **index_name, PRBool *is_system_index) + { + Slapi_Attr *attr; + const struct berval *attrValue; +@@ -66,6 +66,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)) { + slapi_ch_free_string(index_name); +@@ -89,9 +98,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); ++ *returncode = ldbm_index_parse_entry(inst, e, "from ldbm instance init", NULL, &is_system_index /* not used */); + if (*returncode == LDAP_SUCCESS) { + return SLAPI_DSE_CALLBACK_OK; + } else { +@@ -113,18 +123,22 @@ ldbm_instance_index_config_add_callback(Slapi_PBlock *pb __attribute__((unused)) + void *arg) + { + ldbm_instance *inst = (ldbm_instance *)arg; +- char *index_name; ++ 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); ++ *returncode = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, &is_system_index); + 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; +@@ -357,13 +371,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); ++ rc = ldbm_index_parse_entry(inst, e, "from DSE add", &index_name, &is_system_index /* not used */); + } + 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 ada3f4976..903045c5c 100644 +--- a/src/lib389/lib389/_mapped_object.py ++++ b/src/lib389/lib389/_mapped_object.py +@@ -142,6 +142,19 @@ class DSLdapObject(DSLogging): + + 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): + """Get an entry but represent it as a string LDIF + +-- +2.31.1 + diff --git a/SOURCES/0027-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch b/SOURCES/0027-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch new file mode 100644 index 0000000..eb0e3ad --- /dev/null +++ b/SOURCES/0027-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch @@ -0,0 +1,121 @@ +From c16a4211a5f8f3a8dc1568af11116717e6a8aed7 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 a849d0075..2f2664393 100644 +--- a/ldap/servers/plugins/pwdstorage/crypt_pwd.c ++++ b/ldap/servers/plugins/pwdstorage/crypt_pwd.c +@@ -36,15 +36,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/0028-Issue-4764-replicated-operation-sometime-checks-ACI-.patch b/SOURCES/0028-Issue-4764-replicated-operation-sometime-checks-ACI-.patch new file mode 100644 index 0000000..129d620 --- /dev/null +++ b/SOURCES/0028-Issue-4764-replicated-operation-sometime-checks-ACI-.patch @@ -0,0 +1,31 @@ +From 1f227fdc2b00f344c9e6897c66d5a8f4d404cdda Mon Sep 17 00:00:00 2001 +From: progier389 +Date: Wed, 26 May 2021 16:07:43 +0200 +Subject: [PATCH] Issue 4764 - replicated operation sometime checks ACI (#4783) + +--- + ldap/servers/slapd/connection.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index b9b280e6d..d6377cb78 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -1787,6 +1787,14 @@ connection_threadmain() + } + } + ++ /* ++ * Fix bz 1931820 issue (the check to set OP_FLAG_REPLICATED may be done ++ * before replication session is properly set). ++ */ ++ if (replication_connection) { ++ operation_set_flag(op, OP_FLAG_REPLICATED); ++ } ++ + /* + * Call the do_ function to process this request. + */ +-- +2.31.1 + diff --git a/SOURCES/0029-Issue-4797-ACL-IP-ADDRESS-evaluation-may-corrupt-c_i.patch b/SOURCES/0029-Issue-4797-ACL-IP-ADDRESS-evaluation-may-corrupt-c_i.patch new file mode 100644 index 0000000..0bea4b1 --- /dev/null +++ b/SOURCES/0029-Issue-4797-ACL-IP-ADDRESS-evaluation-may-corrupt-c_i.patch @@ -0,0 +1,52 @@ +From c78a8d4159ff2620f5eeaed219287851d056d329 Mon Sep 17 00:00:00 2001 +From: tbordaz +Date: Thu, 10 Jun 2021 15:03:27 +0200 +Subject: [PATCH] Issue 4797 - ACL IP ADDRESS evaluation may corrupt + c_isreplication_session connection flags (#4799) + +Bug description: + The fix for ticket #3764 was broken with a missing break in a + switch. The consequence is that while setting the client IP + address in the pblock (SLAPI_CONN_CLIENTNETADDR_ACLIP), the + connection is erroneously set as replication connection. + This can lead to crash or failure of testcase + test_access_from_certain_network_only_ip. + This bug was quite hidden until the fix for #4764 is + showing it more frequently + +Fix description: + Add the missing break + +relates: https://github.com/389ds/389-ds-base/issues/4797 + +Reviewed by: Mark Reynolds + +Platforms tested: F33 +--- + ldap/servers/slapd/pblock.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c +index d21cf7e76..47d802219 100644 +--- a/ldap/servers/slapd/pblock.c ++++ b/ldap/servers/slapd/pblock.c +@@ -2579,7 +2579,7 @@ 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: ++ case SLAPI_CONN_CLIENTNETADDR_ACLIP: + if (pblock->pb_conn == NULL) { + break; + } +@@ -2587,6 +2587,7 @@ slapi_pblock_set(Slapi_PBlock *pblock, int arg, void *value) + slapi_ch_free((void **)&pblock->pb_conn->cin_addr_aclip); + pblock->pb_conn->cin_addr_aclip = (PRNetAddr *)value; + PR_ExitMonitor(pblock->pb_conn->c_mutex); ++ break; + case SLAPI_CONN_IS_REPLICATION_SESSION: + if (pblock->pb_conn == NULL) { + slapi_log_err(SLAPI_LOG_ERR, +-- +2.31.1 + diff --git a/SPECS/389-ds-base.spec b/SPECS/389-ds-base.spec index b55eb76..6253498 100644 --- a/SPECS/389-ds-base.spec +++ b/SPECS/389-ds-base.spec @@ -39,7 +39,7 @@ Summary: 389 Directory Server (%{variant}) Name: 389-ds-base Version: 1.3.10.2 -Release: %{?relprefix}12%{?prerel}%{?dist} +Release: %{?relprefix}13%{?prerel}%{?dist} License: GPLv3+ URL: https://www.port389.org/ Group: System Environment/Daemons @@ -171,6 +171,10 @@ Patch22: 0022-Issue-51165-Set-the-operation-start-time-for-extende.patc Patch23: 0023-Issue-4706-negative-wtime-in-access-log-for-CMP-oper.patch Patch24: 0024-Issue-4609-CVE-info-disclosure-when-authenticating.patch Patch25: 0025-Issue-4759-Fix-coverity-issue-4760.patch +Patch26: 0026-Issue-4443-Internal-unindexed-searches-in-syncrepl-r.patch +Patch27: 0027-Issue-4817-BUG-locked-crypt-accounts-on-import-may-a.patch +Patch28: 0028-Issue-4764-replicated-operation-sometime-checks-ACI-.patch +Patch29: 0029-Issue-4797-ACL-IP-ADDRESS-evaluation-may-corrupt-c_i.patch %description @@ -525,6 +529,13 @@ fi %{_sysconfdir}/%{pkgname}/dirsrvtests %changelog +* Mon Sep 20 2021 Thierry Bordaz - 1.3.10.2-13 +- Bump version to 1.3.10.2-13 +- Resolves: Bug 2005399 - Internal unindexed searches in syncrepl +- Resolves: Bug 2005432 - CVE-2021-3652 389-ds:1.4/389-ds-base: CRYPT password hash with asterisk allows any bind attempt to succeed +- Resolves: Bug 2005434 - ACIs are being evaluated against the Replication Manager account in a replication context. +- Resolves: Bug 2005435 - A connection can be erroneously flagged as replication conn during evaluation of an aci with ip bind rule + * Fri May 7 2021 Thierry Bordaz - 1.3.10.2-12 - Bump version to 1.3.10.2-12