diff --git a/.389-ds-base.metadata b/.389-ds-base.metadata index 67cbf12..4f87bff 100644 --- a/.389-ds-base.metadata +++ b/.389-ds-base.metadata @@ -1,2 +1,2 @@ -09d78ce7b3e2f3d5d28c889cabd56720a573ade3 SOURCES/389-ds-base-2.3.6.tar.bz2 +e1146536caf20cdf178f8b9bca4f01be89dbcacb SOURCES/389-ds-base-2.4.5.tar.bz2 1c8f2d0dfbf39fa8cd86363bf3314351ab21f8d4 SOURCES/jemalloc-5.3.0.tar.bz2 diff --git a/.gitignore b/.gitignore index 9c09797..0bac1f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -SOURCES/389-ds-base-2.3.6.tar.bz2 +SOURCES/389-ds-base-2.4.5.tar.bz2 SOURCES/jemalloc-5.3.0.tar.bz2 diff --git a/SOURCES/0001-Issue-3527-Support-HAProxy-and-Instance-on-the-same-.patch b/SOURCES/0001-Issue-3527-Support-HAProxy-and-Instance-on-the-same-.patch new file mode 100644 index 0000000..a8232ca --- /dev/null +++ b/SOURCES/0001-Issue-3527-Support-HAProxy-and-Instance-on-the-same-.patch @@ -0,0 +1,83 @@ +From fcdeec3b876a28e06bb53a60fe502cb702403931 Mon Sep 17 00:00:00 2001 +From: Simon Pichugin +Date: Tue, 27 Feb 2024 16:30:47 -0800 +Subject: [PATCH] Issue 3527 - Support HAProxy and Instance on the same machine + configuration (#6107) + +Description: Improve how we handle HAProxy connections to work better when +the DS and HAProxy are on the same machine. +Ensure the client and header destination IPs are checked against the trusted IP list. + +Additionally, this change will also allow configuration having +HAProxy is listening on a different subnet than the one used to forward the request. + +Related: https://github.com/389ds/389-ds-base/issues/3527 + +Reviewed by: @progier389, @jchapma (Thanks!) +--- + ldap/servers/slapd/connection.c | 35 +++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c +index a30511c97..07d629475 100644 +--- a/ldap/servers/slapd/connection.c ++++ b/ldap/servers/slapd/connection.c +@@ -1187,6 +1187,8 @@ connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, int * + char str_ip[INET6_ADDRSTRLEN + 1] = {0}; + char str_haproxy_ip[INET6_ADDRSTRLEN + 1] = {0}; + char str_haproxy_destip[INET6_ADDRSTRLEN + 1] = {0}; ++ int trusted_matches_ip_found = 0; ++ int trusted_matches_destip_found = 0; + struct berval **bvals = NULL; + int proxy_connection = 0; + +@@ -1245,21 +1247,38 @@ connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, int * + normalize_IPv4(conn->cin_addr, buf_ip, sizeof(buf_ip), str_ip, sizeof(str_ip)); + normalize_IPv4(&pr_netaddr_dest, buf_haproxy_destip, sizeof(buf_haproxy_destip), + str_haproxy_destip, sizeof(str_haproxy_destip)); ++ size_t ip_len = strlen(buf_ip); ++ size_t destip_len = strlen(buf_haproxy_destip); + + /* Now, reset RC and set it to 0 only if a match is found */ + haproxy_rc = -1; + +- /* Allow only: +- * Trusted IP == Original Client IP == HAProxy Header Destination IP */ ++ /* ++ * We need to allow a configuration where DS instance and HAProxy are on the same machine. ++ * In this case, we need to check if ++ * the HAProxy client IP (which will be a loopback address) matches one of the the trusted IP addresses, ++ * while still checking that ++ * the HAProxy header destination IP address matches one of the trusted IP addresses. ++ * Additionally, this change will also allow configuration having ++ * HAProxy listening on a different subnet than one used to forward the request. ++ */ + for (size_t i = 0; bvals[i] != NULL; ++i) { +- if ((strlen(bvals[i]->bv_val) == strlen(buf_ip)) && +- (strlen(bvals[i]->bv_val) == strlen(buf_haproxy_destip)) && +- (strncasecmp(bvals[i]->bv_val, buf_ip, strlen(buf_ip)) == 0) && +- (strncasecmp(bvals[i]->bv_val, buf_haproxy_destip, strlen(buf_haproxy_destip)) == 0)) { +- haproxy_rc = 0; +- break; ++ size_t bval_len = strlen(bvals[i]->bv_val); ++ ++ /* Check if the Client IP (HAProxy's machine IP) address matches the trusted IP address */ ++ if (!trusted_matches_ip_found) { ++ trusted_matches_ip_found = (bval_len == ip_len) && (strncasecmp(bvals[i]->bv_val, buf_ip, ip_len) == 0); ++ } ++ /* Check if the HAProxy header destination IP address matches the trusted IP address */ ++ if (!trusted_matches_destip_found) { ++ trusted_matches_destip_found = (bval_len == destip_len) && (strncasecmp(bvals[i]->bv_val, buf_haproxy_destip, destip_len) == 0); + } + } ++ ++ if (trusted_matches_ip_found && trusted_matches_destip_found) { ++ haproxy_rc = 0; ++ } ++ + if (haproxy_rc == -1) { + slapi_log_err(SLAPI_LOG_CONNS, "connection_read_operation", "HAProxy header received from unknown source.\n"); + disconnect_server_nomutex(conn, conn->c_connid, -1, SLAPD_DISCONNECT_PROXY_UNKNOWN, EPROTO); +-- +2.43.0 + diff --git a/SOURCES/0001-Issue-5848-Fix-condition-and-add-a-CI-test-5916.patch b/SOURCES/0001-Issue-5848-Fix-condition-and-add-a-CI-test-5916.patch deleted file mode 100644 index 101a551..0000000 --- a/SOURCES/0001-Issue-5848-Fix-condition-and-add-a-CI-test-5916.patch +++ /dev/null @@ -1,119 +0,0 @@ -From d9784b09531b19f6541602a31cfd49c9878ef2ca Mon Sep 17 00:00:00 2001 -From: Simon Pichugin -Date: Thu, 31 Aug 2023 11:19:05 -0700 -Subject: [PATCH] Issue 5848 - Fix condition and add a CI test (#5916) - -Description: Add a "positive" test for the issue and fix the condition -to make sure that 65535 and no --replica-id are correctly accepted. - -Related: https://github.com/389ds/389-ds-base/issues/5848 - -Reviewed by: @mreynolds389 @tbordaz (Thanks!) ---- - dirsrvtests/tests/suites/clu/dsconf_test.py | 34 ++++++++++++++++++++- - src/lib389/lib389/cli_conf/replication.py | 23 ++++++++------ - 2 files changed, 47 insertions(+), 10 deletions(-) - -diff --git a/dirsrvtests/tests/suites/clu/dsconf_test.py b/dirsrvtests/tests/suites/clu/dsconf_test.py -index eb3c426c7..4f7da0b58 100644 ---- a/dirsrvtests/tests/suites/clu/dsconf_test.py -+++ b/dirsrvtests/tests/suites/clu/dsconf_test.py -@@ -99,7 +99,7 @@ def test_dsconf_with_ldaps(topology_st, enable_config, config_type): - - - @pytest.mark.parametrize('instance_role', ('consumer', 'hub')) --def test_check_replica_id_rejected (instance_role): -+def test_check_replica_id_rejected_hub_consumer(instance_role): - """Test dsconf CLI does not accept replica-id parameter for comsumer and hubs - - :id: 274b47f8-111a-11ee-8321-98fa9ba19b65 -@@ -129,3 +129,35 @@ def test_check_replica_id_rejected (instance_role): - log.info(f'output message : {msg}') - assert "Replication successfully enabled for" not in msg, f"Test Failed: --replica-id option is accepted....It shouldn't for {instance_role}" - log.info(f"Test PASSED: --replica-id option is NOT accepted for {instance_role}.") -+ -+ -+@pytest.mark.parametrize('instance_role, replica_id', -+ [('consumer', None), ('hub', None), ('consumer', "65535"), ('hub', "65535")]) -+def test_check_replica_id_accepted_hub_consumer(topology_st, instance_role, replica_id): -+ """Test dsconf CLI accepts 65535 replica-id parameter for comsumer and hubs -+ -+ :id: e0a1a1e6-11c1-40e6-92fe-cb550fb2170d -+ :parametrized: yes -+ :customerscenario: True -+ :setup: Create DS instance -+ :steps: -+ 1. Create ldap instance -+ 2. Use dsconf cli to create replica and don't specify replica id for a consumer or hub -+ 3. Use dsconf cli to create replica and specify replica id for a consumer or hub -+ :expectedresults: -+ 1. Success -+ 2. Success -+ 3. Success -+ """ -+ print("DN_DM {}".format(DN_DM)) -+ cmdline = ['/usr/sbin/dsconf', 'standalone1', '-D', DN_DM, '-w', 'password', 'replication', 'enable', '--suffix', DEFAULT_SUFFIX, '--role', instance_role] -+ if replica_id is not None: -+ cmdline.append(f'--replica-id={replica_id}') -+ log.info(f'Command used : {cmdline}') -+ proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE) -+ -+ msg = proc.communicate() -+ msg = msg[0].decode('utf-8') -+ log.info(f'output message : {msg}') -+ assert "Replication successfully enabled for" in msg -+ log.info(f"Test PASSED: --replica-id option is accepted for {instance_role}.") -diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py -index a75774ca0..2e2803ced 100644 ---- a/src/lib389/lib389/cli_conf/replication.py -+++ b/src/lib389/lib389/cli_conf/replication.py -@@ -154,6 +154,17 @@ def enable_replication(inst, basedn, log, args): - # error - unknown type - raise ValueError(f"Unknown replication role ({role}), you must use \"supplier\", \"hub\", or \"consumer\"") - -+ if args.replica_id is not None: -+ # is it a number? -+ try: -+ rid_num = int(rid) -+ except ValueError: -+ raise ValueError("--replica-id expects a number between 1 and 65535") -+ -+ # Is it in range? -+ if rid_num < 1 or rid_num > 65535: -+ raise ValueError("--replica-id expects a number between 1 and 65535") -+ - # Start the propeties and update them as needed - repl_properties = { - 'cn': 'replica', -@@ -170,15 +181,9 @@ def enable_replication(inst, basedn, log, args): - # Error, supplier needs a rid TODO - raise ValueError('You must specify the replica ID (--replica-id) when enabling a \"supplier\" replica') - -- # is it a number? -- try: -- rid_num = int(rid) -- except ValueError: -- raise ValueError("--replica-id expects a number between 1 and 65534") -- - # Is it in range? - if rid_num < 1 or rid_num > 65534: -- raise ValueError("--replica-id expects a number between 1 and 65534") -+ raise ValueError("--replica-id expects a number between 1 and 65534 for supplier role") - - # rid is good add it to the props - repl_properties['nsDS5ReplicaId'] = args.replica_id -@@ -186,9 +191,9 @@ def enable_replication(inst, basedn, log, args): - # Validate consumer and hub settings - elif role == "consumer" or role == "hub": - # Check Replica ID -- if args.replica_id is not None or args.replica_id != 65535: -+ if args.replica_id is not None and rid_num != 65535: - # Error, Replica ID cannot be specified for consumer and hub roles -- raise ValueError('Replica ID cannot be specified for consumer and hub roles') -+ raise ValueError('Replica ID other than 65535 cannot be specified for consumer and hub roles') - - # Bind DN or Bind DN Group? - if args.bind_group_dn: --- -2.41.0 - diff --git a/SOURCES/0002-Issue-5909-Multi-listener-hang-with-20k-connections.patch b/SOURCES/0002-Issue-5909-Multi-listener-hang-with-20k-connections.patch deleted file mode 100644 index a53d030..0000000 --- a/SOURCES/0002-Issue-5909-Multi-listener-hang-with-20k-connections.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b2194c95f9d02965b2ad3d0dcf333e74881347d0 Mon Sep 17 00:00:00 2001 -From: James Chapman -Date: Thu, 31 Aug 2023 14:05:31 +0000 -Subject: [PATCH] Issue 5909 - Multi listener hang with 20k connections (#5917) - -Bug Description: A fix for connection sub-table to freelist mapping results -in an uninitialised head of the sub-table linked list. - -Fix Description: During connection table creation, initialise all elements but -skip the list head during the mapping phase. - -Fixes: https//github.com/389ds/389-ds-base/issues/5909 - -Reviewed by: @progier389 @tbordaz (Thank you) ---- - ldap/servers/slapd/conntable.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/ldap/servers/slapd/conntable.c b/ldap/servers/slapd/conntable.c -index b1c66cf421..11e997432b 100644 ---- a/ldap/servers/slapd/conntable.c -+++ b/ldap/servers/slapd/conntable.c -@@ -172,9 +172,9 @@ connection_table_new(int table_size) - /* all connections start out invalid */ - ct->fd[ct_list][i].fd = SLAPD_INVALID_SOCKET; - -- /* The connection table has a double linked list running through it. -+ /* The connection sub-tables have a double linked list running through them. - * This is used to find out which connections should be looked at -- * in the poll loop. Slot 0 in the table is always the head of -+ * in the poll loop. Slot 0 in each sub-table is always the head of - * the linked list. Each slot has a c_next and c_prev which are - * pointers back into the array of connection slots. */ - ct->c[ct_list][i].c_next = NULL; -@@ -196,8 +196,10 @@ connection_table_new(int table_size) - /* Ready to rock, mark as such. */ - ct->c[ct_list][i].c_state = CONN_STATE_INIT; - -- /* Map multiple ct lists to a single freelist. */ -- ct->c_freelist[free_idx++] = &(ct->c[ct_list][i]); -+ /* Map multiple ct lists to a single freelist, but skip slot 0 of each list. */ -+ if (i != 0) { -+ ct->c_freelist[free_idx++] = &(ct->c[ct_list][i]); -+ } - } - } - diff --git a/SOURCES/0002-Issue-6112-RFE-add-new-operation-note-for-MFA-authen.patch b/SOURCES/0002-Issue-6112-RFE-add-new-operation-note-for-MFA-authen.patch new file mode 100644 index 0000000..ad60607 --- /dev/null +++ b/SOURCES/0002-Issue-6112-RFE-add-new-operation-note-for-MFA-authen.patch @@ -0,0 +1,237 @@ +From 3cd7d30628007f839436c417af6dd8a056c6a165 Mon Sep 17 00:00:00 2001 +From: Mark Reynolds +Date: Fri, 1 Mar 2024 11:28:17 -0500 +Subject: [PATCH 2/3] Issue 6112 - RFE - add new operation note for MFA + authentications + +Add a new operation note to indicate that a MFA plugin performed the +BIND. This implies that the plugin must set the note itself as there is +no other way to detect this: + + slapi_pblock_set_flag_operation_notes(pb, SLAPI_OP_NOTE_MFA_AUTH); + +The purpose for this is for auditing needs + +Fixes: https://github.com/389ds/389-ds-base/issues/6112 + +Reviewed by: spichugi(Thanks!) +--- + ldap/admin/src/logconv.pl | 37 ++++++++++++++++++------------- + ldap/servers/slapd/log.c | 6 ++++- + ldap/servers/slapd/result.c | 2 +- + ldap/servers/slapd/slapi-plugin.h | 1 + + 4 files changed, 28 insertions(+), 18 deletions(-) + +diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl +index 5ba91e99c..10bd5d2aa 100755 +--- a/ldap/admin/src/logconv.pl ++++ b/ldap/admin/src/logconv.pl +@@ -2,11 +2,11 @@ + # + # BEGIN COPYRIGHT BLOCK + # Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. +-# Copyright (C) 2022 Red Hat, Inc. ++# Copyright (C) 2010-2024 Red Hat, Inc. + # All rights reserved. + # + # License: GPL (version 3 or any later version). +-# See LICENSE for details. ++# See LICENSE for details. + # END COPYRIGHT BLOCK + # + +@@ -218,6 +218,7 @@ my $sslClientFailedCount = 0; + my $objectclassTopCount= 0; + my $pagedSearchCount = 0; + my $invalidFilterCount = 0; ++my $mfaCount = 0; + my $bindCount = 0; + my $filterCount = 0; + my $baseCount = 0; +@@ -407,7 +408,7 @@ sub statusreport { + ########################################## + # # + # Parse Access Logs # +-# # ++# # + ########################################## + + if ($files[$#files] =~ m/access.rotationinfo/) { +@@ -709,7 +710,7 @@ if($endTime){ + + # + # Get the start time in seconds +-# ++# + my $logStart = $start; + my $startTotal = convertTimeToNanoseconds($logStart); + +@@ -890,6 +891,7 @@ $etimeAvg = $totalEtime / $etimeCount; + print sprintf "Average etime (elapsed time): %.9f\n", $etimeAvg; + + print "\n"; ++print "Multi-factor Authentications: $mfaCount\n"; + print "Proxied Auth Operations: $proxiedAuthCount\n"; + print "Persistent Searches: $persistentSrchCount\n"; + print "Internal Operations: $internalOpCount\n"; +@@ -1758,7 +1760,7 @@ if ($usage =~ /j/i || $verb eq "yes"){ + $recCount++; + } + if ($objectclassTopCount > ($srchCount *.25)){ +- print "\n $recCount. You have a high number of searches that query the entire search base. Although this is not necessarily bad, it could be resource intensive if the search base contains many entries.\n"; ++ print "\n $recCount. You have a high number of searches that query the entire search base. Although this is not necessarily bad, it could be resource intensive if the search base contains many entries.\n"; + $recCount++; + } + if ($recCount == 1){ +@@ -1792,7 +1794,7 @@ sub displayUsage { + + print " -h, --help help/usage\n"; + print " -d, --rootDN default is \"cn=directory manager\"\n"; +- print " -D, --data default is \"/tmp\"\n"; ++ print " -D, --data default is \"/tmp\"\n"; + print " -s, --sizeLimit default is 20\n"; + print " -X, --excludeIP E.g. Load balancers\n"; + print " -v, --version show version of tool\n"; +@@ -1800,8 +1802,8 @@ sub displayUsage { + print " E.g. \"[28/Mar/2002:13:14:22 -0800]\"\n"; + print " -E, --endTime