Bump version to 2.5.1-2

Resolves: RHEL-44324 - unauthenticated user can trigger a DoS by sending a specific extended search request
Resolves: RHEL-40946 - Malformed userPassword hash may cause Denial of Service
Resolves: RHEL-33087 - dsconf schema does not show inChain matching rule
Resolves: RHEL-28177 - Malformed userPassword may cause crash at do_modify in slapd/modify.c
Resolves: RHEL-25070 - nsslapd-haproxy-trusted-ip is not in schema
This commit is contained in:
James Chapman 2024-07-09 22:35:04 +01:00
parent 760f896ee9
commit c7dc9357ac
6 changed files with 411 additions and 1 deletions

108
0002-CVE-2024-2199.patch Normal file
View File

@ -0,0 +1,108 @@
From 23956cfb86a312318667fb9376322574fa8ec7f4 Mon Sep 17 00:00:00 2001
From: James Chapman <jachapma@redhat.com>
Date: Wed, 1 May 2024 15:01:33 +0100
Subject: [PATCH] CVE-2024-2199
---
.../tests/suites/password/password_test.py | 56 +++++++++++++++++++
ldap/servers/slapd/modify.c | 8 ++-
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/dirsrvtests/tests/suites/password/password_test.py b/dirsrvtests/tests/suites/password/password_test.py
index 1245feb31..e4abd9907 100644
--- a/dirsrvtests/tests/suites/password/password_test.py
+++ b/dirsrvtests/tests/suites/password/password_test.py
@@ -63,6 +63,62 @@ def test_password_delete_specific_password(topology_st):
log.info('test_password_delete_specific_password: PASSED')
+def test_password_modify_non_utf8(topology_st):
+ """Attempt a modify of the userPassword attribute with
+ an invalid non utf8 value
+
+ :id: a31af9d5-d665-42b9-8d6e-fea3d0837d36
+ :setup: Standalone instance
+ :steps:
+ 1. Add a user if it doesnt exist and set its password
+ 2. Verify password with a bind
+ 3. Modify userPassword attr with invalid value
+ 4. Attempt a bind with invalid password value
+ 5. Verify original password with a bind
+ :expectedresults:
+ 1. The user with userPassword should be added successfully
+ 2. Operation should be successful
+ 3. Server returns ldap.UNWILLING_TO_PERFORM
+ 4. Server returns ldap.INVALID_CREDENTIALS
+ 5. Operation should be successful
+ """
+
+ log.info('Running test_password_modify_non_utf8...')
+
+ # Create user and set password
+ standalone = topology_st.standalone
+ users = UserAccounts(standalone, DEFAULT_SUFFIX)
+ if not users.exists(TEST_USER_PROPERTIES['uid'][0]):
+ user = users.create(properties=TEST_USER_PROPERTIES)
+ else:
+ user = users.get(TEST_USER_PROPERTIES['uid'][0])
+ user.set('userpassword', PASSWORD)
+
+ # Verify password
+ try:
+ user.bind(PASSWORD)
+ except ldap.LDAPError as e:
+ log.fatal('Failed to bind as {}, error: '.format(user.dn) + e.args[0]['desc'])
+ assert False
+
+ # Modify userPassword with an invalid value
+ password = b'tes\x82t-password' # A non UTF-8 encoded password
+ with pytest.raises(ldap.UNWILLING_TO_PERFORM):
+ user.replace('userpassword', password)
+
+ # Verify a bind fails with invalid pasword
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
+ user.bind(password)
+
+ # Verify we can still bind with original password
+ try:
+ user.bind(PASSWORD)
+ except ldap.LDAPError as e:
+ log.fatal('Failed to bind as {}, error: '.format(user.dn) + e.args[0]['desc'])
+ assert False
+
+ log.info('test_password_modify_non_utf8: PASSED')
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/slapd/modify.c b/ldap/servers/slapd/modify.c
index a20984e0b..fb65d58b3 100644
--- a/ldap/servers/slapd/modify.c
+++ b/ldap/servers/slapd/modify.c
@@ -762,8 +762,10 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw)
* flagged - leave mod attributes alone */
if (!repl_op && !skip_modified_attrs && lastmod) {
modify_update_last_modified_attr(pb, &smods);
+ slapi_pblock_set(pb, SLAPI_MODIFY_MODS, slapi_mods_get_ldapmods_byref(&smods));
}
+
if (0 == slapi_mods_get_num_mods(&smods)) {
/* nothing to do - no mods - this is not an error - just
send back LDAP_SUCCESS */
@@ -930,8 +932,10 @@ op_shared_modify(Slapi_PBlock *pb, int pw_change, char *old_pw)
/* encode password */
if (pw_encodevals_ext(pb, sdn, va)) {
- slapi_log_err(SLAPI_LOG_CRIT, "op_shared_modify", "Unable to hash userPassword attribute for %s.\n", slapi_entry_get_dn_const(e));
- send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Unable to store attribute \"userPassword\" correctly\n", 0, NULL);
+ slapi_log_err(SLAPI_LOG_CRIT, "op_shared_modify", "Unable to hash userPassword attribute for %s, "
+ "check value is utf8 string.\n", slapi_entry_get_dn_const(e));
+ send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Unable to hash \"userPassword\" attribute, "
+ "check value is utf8 string.\n", 0, NULL);
valuearray_free(&va);
goto free_and_return;
}
--
2.41.0

View File

@ -0,0 +1,31 @@
From 6c7047ad75016a7b767d70813a86b9a7b03ea49b Mon Sep 17 00:00:00 2001
From: Simon Pichugin <spichugi@redhat.com>
Date: Wed, 5 Jun 2024 17:24:00 -0700
Subject: [PATCH] Issue 6188 - Add nsslapd-haproxy-trusted-ip to cn=schema
(#6201)
Description: Add HAProxy trusted IP address multi-valued attribute
to cn=schema in 01core389.ldif
Related: https://github.com/389ds/389-ds-base/issues/6188
Reviewed by: @progier389 (Thanks!)
---
ldap/schema/01core389.ldif | 1 +
1 file changed, 1 insertion(+)
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index fad8bc2f9..c98e5b34b 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -331,6 +331,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2390 NAME 'nsds5ReplicaKeepAliveUpdateIn
attributeTypes: ( 2.16.840.1.113730.3.1.2391 NAME 'dsEntryDN' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 NO-USER-MODIFICATION SINGLE-VALUE USAGE directoryOperation X-ORIGIN '389 Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2392 NAME 'nsslapd-return-original-entrydn' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2393 NAME 'nsslapd-auditlog-display-attrs' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2398 NAME 'nsslapd-haproxy-trusted-ip' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server' )
#
# objectclasses
#
--
2.45.2

145
0004-CVE-2024-5953.patch Normal file
View File

@ -0,0 +1,145 @@
From 52a9ee6556a0467f5134fb6392ff1681a38f3252 Mon Sep 17 00:00:00 2001
From: Pierre Rogier <progier@redhat.com>
Date: Fri, 14 Jun 2024 13:27:10 +0200
Subject: [PATCH] CVE-2024-5953
---
.../tests/suites/password/regression_test.py | 51 ++++++++++++++++++-
ldap/servers/plugins/pwdstorage/md5_pwd.c | 9 +++-
ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c | 6 +++
3 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/dirsrvtests/tests/suites/password/regression_test.py b/dirsrvtests/tests/suites/password/regression_test.py
index 4876ff435..160d6f01d 100644
--- a/dirsrvtests/tests/suites/password/regression_test.py
+++ b/dirsrvtests/tests/suites/password/regression_test.py
@@ -8,11 +8,12 @@
import pytest
import time
import glob
+import base64
from lib389._constants import PASSWORD, DN_DM, DEFAULT_SUFFIX
from lib389._constants import SUFFIX, PASSWORD, DN_DM, DN_CONFIG, PLUGIN_RETRO_CHANGELOG, DEFAULT_SUFFIX, DEFAULT_CHANGELOG_DB, DEFAULT_BENAME
from lib389 import Entry
from lib389.topologies import topology_m1 as topo_supplier
-from lib389.idm.user import UserAccounts
+from lib389.idm.user import UserAccounts, UserAccount
from lib389.utils import ldap, os, logging, ensure_bytes, ds_is_newer, ds_supports_new_changelog
from lib389.topologies import topology_st as topo
from lib389.idm.organizationalunit import OrganizationalUnits
@@ -40,6 +41,13 @@ TEST_PASSWORDS += ['CNpwtest1ZZZZ', 'ZZZZZCNpwtest1',
TEST_PASSWORDS2 = (
'CN12pwtest31', 'SN3pwtest231', 'UID1pwtest123', 'MAIL2pwtest12@redhat.com', '2GN1pwtest123', 'People123')
+SUPPORTED_SCHEMES = (
+ "{SHA}", "{SSHA}", "{SHA256}", "{SSHA256}",
+ "{SHA384}", "{SSHA384}", "{SHA512}", "{SSHA512}",
+ "{crypt}", "{NS-MTA-MD5}", "{clear}", "{MD5}",
+ "{SMD5}", "{PBKDF2_SHA256}", "{PBKDF2_SHA512}",
+ "{GOST_YESCRYPT}", "{PBKDF2-SHA256}", "{PBKDF2-SHA512}" )
+
def _check_unhashed_userpw(inst, user_dn, is_present=False):
"""Check if unhashed#user#password attribute is present or not in the changelog"""
unhashed_pwd_attribute = 'unhashed#user#password'
@@ -319,6 +327,47 @@ def test_unhashed_pw_switch(topo_supplier):
# Add debugging steps(if any)...
pass
+@pytest.mark.parametrize("scheme", SUPPORTED_SCHEMES )
+def test_long_hashed_password(topo, create_user, scheme):
+ """Check that hashed password with very long value does not cause trouble
+
+ :id: 252a1f76-114b-11ef-8a7a-482ae39447e5
+ :setup: standalone Instance
+ :parametrized: yes
+ :steps:
+ 1. Add a test user user
+ 2. Set a long password with requested scheme
+ 3. Bind on that user using a wrong password
+ 4. Check that instance is still alive
+ 5. Remove the added user
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 3. Should get ldap.INVALID_CREDENTIALS exception
+ 4. Success
+ 5. Success
+ """
+ inst = topo.standalone
+ inst.simple_bind_s(DN_DM, PASSWORD)
+ users = UserAccounts(inst, DEFAULT_SUFFIX)
+ # Make sure that server is started as this test may crash it
+ inst.start()
+ # Adding Test user (It may already exists if previous test failed)
+ user2 = UserAccount(inst, dn='uid=test_user_1002,ou=People,dc=example,dc=com')
+ if not user2.exists():
+ user2 = users.create_test_user(uid=1002, gid=2002)
+ # Setting hashed password
+ passwd = 'A'*4000
+ hashed_passwd = scheme.encode('utf-8') + base64.b64encode(passwd.encode('utf-8'))
+ user2.replace('userpassword', hashed_passwd)
+ # Bind on that user using a wrong password
+ with pytest.raises(ldap.INVALID_CREDENTIALS):
+ conn = user2.bind(PASSWORD)
+ # Check that instance is still alive
+ assert inst.status()
+ # Remove the added user
+ user2.delete()
+
if __name__ == '__main__':
# Run isolated
diff --git a/ldap/servers/plugins/pwdstorage/md5_pwd.c b/ldap/servers/plugins/pwdstorage/md5_pwd.c
index 1e2cf58e7..b9a48d5ca 100644
--- a/ldap/servers/plugins/pwdstorage/md5_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/md5_pwd.c
@@ -37,6 +37,7 @@ md5_pw_cmp(const char *userpwd, const char *dbpwd)
unsigned char hash_out[MD5_HASH_LEN];
unsigned char b2a_out[MD5_HASH_LEN * 2]; /* conservative */
SECItem binary_item;
+ size_t dbpwd_len = strlen(dbpwd);
ctx = PK11_CreateDigestContext(SEC_OID_MD5);
if (ctx == NULL) {
@@ -45,6 +46,12 @@ md5_pw_cmp(const char *userpwd, const char *dbpwd)
goto loser;
}
+ if (dbpwd_len >= sizeof b2a_out) {
+ slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME,
+ "The hashed password stored in the user entry is longer than any valid md5 hash");
+ goto loser;
+ }
+
/* create the hash */
PK11_DigestBegin(ctx);
PK11_DigestOp(ctx, (const unsigned char *)userpwd, strlen(userpwd));
@@ -57,7 +64,7 @@ md5_pw_cmp(const char *userpwd, const char *dbpwd)
bver = NSSBase64_EncodeItem(NULL, (char *)b2a_out, sizeof b2a_out, &binary_item);
/* bver points to b2a_out upon success */
if (bver) {
- rc = slapi_ct_memcmp(bver, dbpwd, strlen(dbpwd));
+ rc = slapi_ct_memcmp(bver, dbpwd, dbpwd_len);
} else {
slapi_log_err(SLAPI_LOG_PLUGIN, MD5_SUBSYSTEM_NAME,
"Could not base64 encode hashed value for password compare");
diff --git a/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c b/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c
index dcac4fcdd..82b8c9501 100644
--- a/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c
+++ b/ldap/servers/plugins/pwdstorage/pbkdf2_pwd.c
@@ -255,6 +255,12 @@ pbkdf2_sha256_pw_cmp(const char *userpwd, const char *dbpwd)
passItem.data = (unsigned char *)userpwd;
passItem.len = strlen(userpwd);
+ if (pwdstorage_base64_decode_len(dbpwd, dbpwd_len) > sizeof dbhash) {
+ /* Hashed value is too long and cannot match any value generated by pbkdf2_sha256_hash */
+ slapi_log_err(SLAPI_LOG_ERR, (char *)schemeName, "Unable to base64 decode dbpwd value. (hashed value is too long)\n");
+ return result;
+ }
+
/* Decode the DBpwd to bytes from b64 */
if (PL_Base64Decode(dbpwd, dbpwd_len, dbhash) == NULL) {
slapi_log_err(SLAPI_LOG_ERR, (char *)schemeName, "Unable to base64 decode dbpwd value\n");
--
2.44.0

25
0005-CVE-2024-6237.patch Normal file
View File

@ -0,0 +1,25 @@
From 323f74c69f84a8482413ecd73cf61d09cfc4a0a1 Mon Sep 17 00:00:00 2001
From: Thierry Bordaz <tbordaz@redhat.com>
Date: Mon, 24 Jun 2024 15:51:28 +0200
Subject: [PATCH] CVE-2024-6237
---
ldap/servers/plugins/syntaxes/inchain.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/plugins/syntaxes/inchain.c b/ldap/servers/plugins/syntaxes/inchain.c
index df19c973b..0a6a04e9f 100644
--- a/ldap/servers/plugins/syntaxes/inchain.c
+++ b/ldap/servers/plugins/syntaxes/inchain.c
@@ -277,7 +277,7 @@ inchain_values2keys(Slapi_PBlock *pb, Slapi_Value **vals, Slapi_Value ***ivals,
slapi_pblock_get(pb, SLAPI_SEARCH_TARGET_SDN, &base_sdn);
if (! slapi_attr_is_dn_syntax_type(mrTYPE)) {
- slapi_log_err(SLAPI_LOG_ERR, "inchain", "Requires distinguishedName syntax. AttributeDescription %s is not distinguishedName\n");
+ slapi_log_err(SLAPI_LOG_ERR, "inchain", "Requires distinguishedName syntax. AttributeDescription %s is not distinguishedName\n", mrTYPE);
result = (Slapi_Value **)slapi_ch_calloc(1, sizeof(Slapi_Value *));
*ivals = result;
return(0);
--
2.44.0

View File

@ -0,0 +1,88 @@
From cf6cdd05b7ddab36a0196d614b7a28b4372cf801 Mon Sep 17 00:00:00 2001
From: tbordaz <tbordaz@redhat.com>
Date: Mon, 24 Jun 2024 13:41:35 +0200
Subject: [PATCH] Issue 6227 - dsconf schema does not show inChain matching
rule (#6228)
Bug description:
The registered inChain MR does defined any matching rule
syntax (mr_syntax).
When dsconf reads the matching rules (read_schema_dse)
it only reports those which have OID and SYNTAX.
As a consequence InChain was not reported.
Fix description:
The syntax defines that assersion syntax that is
distinguished name. Add this syntax to the register
struct
relates: #6227
Reviewed by: Pierre Rogier (Thanks !)
---
.../tests/suites/filter/inchain_test.py | 19 +++++++++++++++++++
ldap/servers/plugins/syntaxes/inchain.c | 4 ++--
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/dirsrvtests/tests/suites/filter/inchain_test.py b/dirsrvtests/tests/suites/filter/inchain_test.py
index c650b9374..d1d276edf 100644
--- a/dirsrvtests/tests/suites/filter/inchain_test.py
+++ b/dirsrvtests/tests/suites/filter/inchain_test.py
@@ -15,6 +15,7 @@ from lib389._constants import DEFAULT_SUFFIX, PW_DM, PLUGIN_MEMBER_OF
from lib389.topologies import topology_st as topo
from lib389.plugins import MemberOfPlugin
+from lib389.schema import Schema
from lib389.idm.user import UserAccount, UserAccounts
from lib389.idm.account import Accounts
from lib389.idm.account import Anonymous
@@ -812,6 +813,24 @@ def test_invalid_assertion(topo):
memberof = topo.standalone.search_s(DEFAULT_SUFFIX, SCOPE_SUBTREE, "(member:%s:=%s)" % (INCHAIN_OID, user))
assert len(memberof) == 0
+def test_check_dsconf_matchingrule(topo):
+ """Test that the matching rule 'inchain' is listed by dsconf
+
+ :id: b8dd4049-ccec-4316-bc9c-5aa5c5afcfbd
+ :setup: Standalone Instance
+ :steps:
+ 1. fetch matching rules from the schema
+ 2. Checks that matching rules contains inchaineMatch matching rule
+ :expectedresults:
+ 1. Success
+ 2. Success
+ """
+ schema = Schema(topo.standalone)
+ mrs = [ f"{mr.oid} {mr.names[0]}" for mr in schema.get_matchingrules() if len(mr.names) > 0 ]
+ for mr in mrs:
+ log.info("retrieved matching rules are: %s", mr)
+ assert '1.2.840.113556.1.4.1941 inchainMatch' in mrs
+
if __name__ == "__main__":
CURRENT_FILE = os.path.realpath(__file__)
pytest.main("-s -v %s" % CURRENT_FILE)
diff --git a/ldap/servers/plugins/syntaxes/inchain.c b/ldap/servers/plugins/syntaxes/inchain.c
index 52d0c4994..df19c973b 100644
--- a/ldap/servers/plugins/syntaxes/inchain.c
+++ b/ldap/servers/plugins/syntaxes/inchain.c
@@ -38,7 +38,7 @@ static char *names[] = {"inchain", "inchain", LDAP_MATCHING_RULE_IN_CHAIN_OID, 0
static Slapi_PluginDesc pdesc = {"inchain-matching-rule", VENDOR, DS_PACKAGE_VERSION,
"inchain matching rule plugin"};
-static const char *inchainMatch_names[] = {"inchainMatch", "1.2.840.113556.1.4.1941", NULL};
+static const char *inchainMatch_names[] = {"inchainMatch", LDAP_MATCHING_RULE_IN_CHAIN_OID, NULL};
static struct mr_plugin_def mr_plugin_table[] = {
{
@@ -64,7 +64,7 @@ static struct mr_plugin_def mr_plugin_table[] = {
"the AVA comparisons evaluate to Undefined and the remaining AVA "
"comparisons return TRUE then the distinguishedNameMatch rule "
"evaluates to Undefined.",
- NULL,
+ DN_SYNTAX_OID,
0,
NULL /* dn only for now */
}, /* matching rule desc */
--
2.45.2

View File

@ -47,7 +47,7 @@ ExcludeArch: i686
Summary: 389 Directory Server (base)
Name: 389-ds-base
Version: 2.5.1
Release: 1%{?dist}
Release: 2%{?dist}
License: GPL-3.0-or-later AND (0BSD OR Apache-2.0 OR MIT) AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT OR Zlib) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-DFS-2016 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0
URL: https://www.port389.org
Conflicts: selinux-policy-base < 3.9.8
@ -467,6 +467,11 @@ Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download
%endif
Source4: 389-ds-base.sysusers
Patch01: 0001-CVE-2024-3657.patch
Patch02: 0002-CVE-2024-2199.patch
Patch03: 0003-Issue-6188-Add-nsslapd-haproxy-trusted-ip-to-cn-sche.patch
Patch04: 0004-CVE-2024-5953.patch
Patch05: 0005-CVE-2024-6237.patch
Patch06: 0006-Issue-6227-dsconf-schema-does-not-show-inChain-match.patch
%description
@ -910,6 +915,14 @@ exit 0
%endif
%changelog
* Tue Jul 09 2024 James Chapman <jachapma@redhat.com> - 2.5.1-2
- Bump version to 2.5.1-2
- Resolves: RHEL-44324 - unauthenticated user can trigger a DoS by sending a specific extended search request
- Resolves: RHEL-40946 - Malformed userPassword hash may cause Denial of Service
- Resolves: RHEL-33087 - dsconf schema does not show inChain matching rule
- Resolves: RHEL-28177 - Malformed userPassword may cause crash at do_modify in slapd/modify.c
- Resolves: RHEL-25070 - nsslapd-haproxy-trusted-ip is not in schema
* Tue May 07 2024 James Chapman <jachapma@redhat.com> - 2.5.1-1
- Bump version to 2.5.1-1
- Resolves: RHEL-31777 - Rebase 389-ds-base.2.5.1 in RHEL 9.5