import 389-ds-base-1.4.3.34-1.module+el8.7.0+18367+58a49cb0

This commit is contained in:
CentOS Sources 2023-04-04 08:52:34 +00:00 committed by Stepan Oksanichenko
parent 69d0b88d75
commit a7a184d43c
20 changed files with 539 additions and 5515 deletions

View File

@ -1,3 +1,3 @@
672f63948af9d242034f689340f772b8e148ee3c SOURCES/389-ds-base-1.4.3.30.tar.bz2
204dc26c2d598b837aa4350ddc3df4449c6852ea SOURCES/389-ds-base-1.4.3.34.tar.bz2
1c8f2d0dfbf39fa8cd86363bf3314351ab21f8d4 SOURCES/jemalloc-5.3.0.tar.bz2
dc0d2e81e54cc7e4098a829b8202d59ec471b34f SOURCES/vendor-1.4.3.30-1.tar.gz
c24a7ec12257842852fd13c939c777fa4f0a03e4 SOURCES/vendor-1.4.3.34-2.tar.gz

4
.gitignore vendored
View File

@ -1,3 +1,3 @@
SOURCES/389-ds-base-1.4.3.30.tar.bz2
SOURCES/389-ds-base-1.4.3.34.tar.bz2
SOURCES/jemalloc-5.3.0.tar.bz2
SOURCES/vendor-1.4.3.30-1.tar.gz
SOURCES/vendor-1.4.3.34-2.tar.gz

View File

@ -1,86 +0,0 @@
From 36da9be6b82c96a656fa6dd1f99e5a7c41c7652a Mon Sep 17 00:00:00 2001
From: Thierry Bordaz <tbordaz@redhat.com>
Date: Mon, 23 May 2022 16:53:41 +0200
Subject: [PATCH] Revert 4866 - cl trimming not applicable in 1.4.3
---
.../suites/healthcheck/health_repl_test.py | 2 +-
.../tests/suites/replication/acceptance_test.py | 17 +----------------
src/lib389/lib389/replica.py | 13 -------------
3 files changed, 2 insertions(+), 30 deletions(-)
diff --git a/dirsrvtests/tests/suites/healthcheck/health_repl_test.py b/dirsrvtests/tests/suites/healthcheck/health_repl_test.py
index 9e1af2ff8..238d25290 100644
--- a/dirsrvtests/tests/suites/healthcheck/health_repl_test.py
+++ b/dirsrvtests/tests/suites/healthcheck/health_repl_test.py
@@ -74,7 +74,7 @@ def set_changelog_trimming(instance):
inst_changelog = Changelog5(instance)
log.info('Set nsslapd-changelogmaxage to 30d')
- inst_changelog.set_max_age('30d')
+ inst_changelog.add('nsslapd-changelogmaxage', '30')
@pytest.mark.ds50873
diff --git a/dirsrvtests/tests/suites/replication/acceptance_test.py b/dirsrvtests/tests/suites/replication/acceptance_test.py
index 8b96df7a4..a5f0c4c6b 100644
--- a/dirsrvtests/tests/suites/replication/acceptance_test.py
+++ b/dirsrvtests/tests/suites/replication/acceptance_test.py
@@ -15,7 +15,7 @@ from lib389.topologies import topology_m4 as topo_m4
from lib389.topologies import topology_m2 as topo_m2
from . import get_repl_entries
from lib389.idm.user import UserAccount
-from lib389.replica import ReplicationManager, Changelog
+from lib389.replica import ReplicationManager
from lib389._constants import *
pytestmark = pytest.mark.tier0
@@ -645,21 +645,6 @@ def test_csngen_task(topo_m2):
assert m1.searchErrorsLog("_csngen_gen_tester_main")
-def test_default_cl_trimming_enabled(topo_m2):
- """Check that changelog trimming was enabled by default
-
- :id: c37b9a28-f961-4867-b8a1-e81edd7f9bf3
- :setup: Supplier Instance
- :steps:
- 1. Check changelog has trimming set up by default
- :expectedresults:
- 1. Success
- """
-
- # Set up changelog trimming by default
- cl = Changelog(topo_m2.ms["supplier1"], DEFAULT_SUFFIX)
- assert cl.get_attr_val_utf8("nsslapd-changelogmaxage") == "7d"
-
if __name__ == '__main__':
# Run isolated
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
index c7328605b..90905dbf1 100644
--- a/src/lib389/lib389/replica.py
+++ b/src/lib389/lib389/replica.py
@@ -1667,19 +1667,6 @@ class Replicas(DSLdapObjects):
self._childobject = Replica
self._basedn = DN_MAPPING_TREE
- def create(self, rdn=None, properties=None):
- replica = super(Replicas, self).create(rdn, properties)
-
- # Set up changelog trimming by default
- if properties is not None:
- for attr, val in properties.items():
- if attr.lower() == 'nsds5replicaroot':
- cl = Changelog(self._instance, val[0])
- cl.set_max_age("7d")
- break
-
- return replica
-
def get(self, selector=[], dn=None):
"""Get a child entry (DSLdapObject, Replica, etc.) with dn or selector
using a base DN and objectClasses of our object (DSLdapObjects, Replicas, etc.)
--
2.31.1

View File

@ -1,77 +0,0 @@
From 6c8906559cd049b14b08e4d3158338f6611f04e4 Mon Sep 17 00:00:00 2001
From: Firstyear <william@blackhats.net.au>
Date: Fri, 20 Aug 2021 09:18:50 +1000
Subject: [PATCH] Issue 4877 - RFE - EntryUUID to validate UUIDs on fixup
(#4878)
Bug Description: Due to changing the syntax of EntryUUID's
to string, we may have invalid EntryUUID's imported into
the database.
Fix Description: To resolve this during a fixup we validate
that Uuid's have a valid syntax. If they do not, we regenerate
them.
fixes: https://github.com/389ds/389-ds-base/issues/4877
Author: William Brown <william@blackhats.net.au>
Review by: @mreynolds389
---
src/plugins/entryuuid/src/lib.rs | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/src/plugins/entryuuid/src/lib.rs b/src/plugins/entryuuid/src/lib.rs
index 29a9f1258..ad3faef4b 100644
--- a/src/plugins/entryuuid/src/lib.rs
+++ b/src/plugins/entryuuid/src/lib.rs
@@ -144,11 +144,17 @@ impl SlapiPlugin3 for EntryUuid {
// Error if the first filter is empty?
// Now, to make things faster, we wrap the filter in a exclude term.
+
+ // 2021 - #4877 because we allow entryuuid to be strings, on import these may
+ // be invalid. As a result, we DO need to allow the fixup to check the entryuuid
+ // value is correct, so we can not exclude these during the search.
+ /*
let raw_filter = if !raw_filter.starts_with('(') && !raw_filter.ends_with('(') {
format!("(&({})(!(entryuuid=*)))", raw_filter)
} else {
format!("(&{}(!(entryuuid=*)))", raw_filter)
};
+ */
Ok(FixupData { basedn, raw_filter })
}
@@ -213,14 +219,20 @@ pub fn entryuuid_fixup_mapfn(e: &EntryRef, _data: &()) -> Result<(), PluginError
/* Supply a modification to the entry. */
let sdn = e.get_sdnref();
- /* Sanity check that entryuuid doesn't already exist */
- if e.contains_attr("entryUUID") {
- log_error!(
- ErrorLevel::Plugin,
- "skipping fixup for -> {}",
- sdn.to_dn_string()
- );
- return Ok(());
+ /* Check that entryuuid doesn't already exist, and is valid */
+ if let Some(valueset) = e.get_attr("entryUUID") {
+ if valueset.iter().all(|v| {
+ let u: Result<Uuid, _> = (&v).try_into();
+ u.is_ok()
+ }) {
+ // All values were valid uuid, move on!
+ log_error!(
+ ErrorLevel::Plugin,
+ "skipping fixup for -> {}",
+ sdn.to_dn_string()
+ );
+ return Ok(());
+ }
}
// Setup the modifications
--
2.31.1

View File

@ -1,780 +0,0 @@
From 63e1ceac74cdfda7cf432537a18670e9562b58df Mon Sep 17 00:00:00 2001
From: progier389 <progier@redhat.com>
Date: Mon, 2 May 2022 18:43:25 +0200
Subject: [PATCH] Issue 5126 - Memory leak in slapi_ldap_get_lderrno (#5153)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Issue 5126 - Memory leak in slapi_ldap_get_lderrno
The problem is that some time ago libldap API replaced LDAP_OPT_ERROR_STRING whose data should not be freed by
LDAP_OPT_DIAGNOSTIC_MESSAGE whose data must be freed.
slapi_ldap_get_lderrno was adapted to use the new option but the callers were not modified to free the value.
The Solution:
Insure that we also need to free slapi_ldap_get_lderrno value if legacy LDAP_OPT_ERROR_STRING is used (by duping the value)
Insure that the callers free the value.
Added test case about replication using SASL/Digest-md5 authentication
Added test case to check this leak
Also updated test case about SASL/GSSAPI to be comapatible with current lib389 framework but marked as skipped because it requires a specific configuration (This path should be tested by IPA tests)
Fixed valgrind lib389 function to run on prefixed installation without needing to be root.
At last I also improved lib389 mapped object to have a better diagnostic when LDAP operation fails (by adding the request within the exception)
issue: 5126 https://github.com/389ds/389-ds-base/issues/5126
Reviewd by: @droideck
(cherry picked from commit 4d89e11494233d8297896540bc752cfdbab2cc69)
---
.../suites/gssapi_repl/gssapi_repl_test.py | 31 ++-
.../tests/suites/replication/sasl_m2_test.py | 185 ++++++++++++++++++
ldap/servers/plugins/chainingdb/cb_search.c | 6 +-
ldap/servers/plugins/passthru/ptbind.c | 2 +
.../plugins/replication/repl5_connection.c | 4 +
.../plugins/replication/windows_connection.c | 3 +
ldap/servers/slapd/ldaputil.c | 6 +
src/lib389/lib389/_mapped_object.py | 76 ++++---
src/lib389/lib389/utils.py | 40 +++-
9 files changed, 311 insertions(+), 42 deletions(-)
create mode 100644 dirsrvtests/tests/suites/replication/sasl_m2_test.py
diff --git a/dirsrvtests/tests/suites/gssapi_repl/gssapi_repl_test.py b/dirsrvtests/tests/suites/gssapi_repl/gssapi_repl_test.py
index 41f323c06..402684aab 100644
--- a/dirsrvtests/tests/suites/gssapi_repl/gssapi_repl_test.py
+++ b/dirsrvtests/tests/suites/gssapi_repl/gssapi_repl_test.py
@@ -9,6 +9,7 @@
import pytest
from lib389.tasks import *
from lib389.utils import *
+from lib389.agreement import *
from lib389.topologies import topology_m2
pytestmark = pytest.mark.tier2
@@ -65,10 +66,27 @@ def _allow_machine_account(inst, name):
# First we need to get the mapping tree dn
mt = inst.mappingtree.list(suffix=DEFAULT_SUFFIX)[0]
inst.modify_s('cn=replica,%s' % mt.dn, [
- (ldap.MOD_REPLACE, 'nsDS5ReplicaBindDN', "uid=%s,ou=Machines,%s" % (name, DEFAULT_SUFFIX))
+ (ldap.MOD_REPLACE, 'nsDS5ReplicaBindDN', f"uid={name},ou=Machines,{DEFAULT_SUFFIX}".encode('utf-8'))
])
-
+def _verify_etc_hosts():
+ #Check if /etc/hosts is compatible with the test
+ NEEDED_HOSTS = ( ('ldapkdc.example.com', '127.0.0.1'),
+ ('ldapkdc1.example.com', '127.0.1.1'),
+ ('ldapkdc2.example.com', '127.0.2.1'))
+ found_hosts = {}
+ with open('/etc/hosts','r') as f:
+ for l in f:
+ s = l.split()
+ if len(s) < 2:
+ continue
+ for nh in NEEDED_HOSTS:
+ if (s[0] == nh[1] and s[1] == nh[0]):
+ found_hosts[s[1]] = True
+ return len(found_hosts) == len(NEEDED_HOSTS)
+
+@pytest.mark.skipif(not _verify_etc_hosts(), reason="/etc/hosts does not contains the needed hosts.")
+@pytest.mark.skipif(True, reason="Test disabled because it requires specific kerberos requirement (server principal, keytab, etc ...")
def test_gssapi_repl(topology_m2):
"""Test gssapi authenticated replication agreement of two suppliers using KDC
@@ -94,8 +112,6 @@ def test_gssapi_repl(topology_m2):
6. Test User should be created on M1 and M2 both
7. Test User should be created on M1 and M2 both
"""
-
- return
supplier1 = topology_m2.ms["supplier1"]
supplier2 = topology_m2.ms["supplier2"]
@@ -121,6 +137,7 @@ def test_gssapi_repl(topology_m2):
properties = {RA_NAME: r'meTo_$host:$port',
RA_METHOD: 'SASL/GSSAPI',
RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+ supplier1.agreement.delete(suffix=SUFFIX, consumer_host=supplier2.host, consumer_port=supplier2.port)
m1_m2_agmt = supplier1.agreement.create(suffix=SUFFIX, host=supplier2.host, port=supplier2.port, properties=properties)
if not m1_m2_agmt:
log.fatal("Fail to create a supplier -> supplier replica agreement")
@@ -133,6 +150,7 @@ def test_gssapi_repl(topology_m2):
properties = {RA_NAME: r'meTo_$host:$port',
RA_METHOD: 'SASL/GSSAPI',
RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+ supplier2.agreement.delete(suffix=SUFFIX, consumer_host=supplier1.host, consumer_port=supplier1.port)
m2_m1_agmt = supplier2.agreement.create(suffix=SUFFIX, host=supplier1.host, port=supplier1.port, properties=properties)
if not m2_m1_agmt:
log.fatal("Fail to create a supplier -> supplier replica agreement")
@@ -145,8 +163,9 @@ def test_gssapi_repl(topology_m2):
#
# Initialize all the agreements
#
- supplier1.agreement.init(SUFFIX, HOST_SUPPLIER_2, PORT_SUPPLIER_2)
- supplier1.waitForReplInit(m1_m2_agmt)
+ agmt = Agreement(supplier1, m1_m2_agmt)
+ agmt.begin_reinit()
+ agmt.wait_reinit()
# Check replication is working...
if supplier1.testReplication(DEFAULT_SUFFIX, supplier2):
diff --git a/dirsrvtests/tests/suites/replication/sasl_m2_test.py b/dirsrvtests/tests/suites/replication/sasl_m2_test.py
new file mode 100644
index 000000000..d7406ac7e
--- /dev/null
+++ b/dirsrvtests/tests/suites/replication/sasl_m2_test.py
@@ -0,0 +1,185 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2022 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import logging
+import os
+import pytest
+import ldap
+import uuid
+from lib389.utils import ds_is_older, valgrind_enable, valgrind_disable, valgrind_get_results_file, valgrind_check_file
+
+from lib389.idm.services import ServiceAccounts
+from lib389.idm.group import Groups
+from lib389.config import CertmapLegacy, Config
+from lib389._constants import DEFAULT_SUFFIX
+from lib389.agreement import Agreements
+from lib389._mapped_object import DSLdapObject
+from lib389.replica import ReplicationManager, Replicas, BootstrapReplicationManager
+from lib389.topologies import topology_m2 as topo_m2
+
+pytestmark = pytest.mark.tier1
+
+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__)
+
+def set_sasl_md5_client_auth(inst, to):
+ # Create the certmap before we restart
+ cm = CertmapLegacy(to)
+ certmaps = cm.list()
+ certmaps['default']['nsSaslMapRegexString'] = '^dn:\\(.*\\)'
+ certmaps['default']['nsSaslMapBaseDNTemplate'] = 'cn=config'
+ certmaps['default']['nsSaslMapFilterTemplate'] = '(objectclass=*)'
+ cm.set(certmaps)
+
+ Config(to).replace("passwordStorageScheme", 'CLEAR')
+
+ # Create a repl manager on the replica
+ replication_manager_pwd = 'secret12'
+ brm = BootstrapReplicationManager(to)
+ try:
+ brm.delete()
+ except ldap.NO_SUCH_OBJECT:
+ pass
+ brm.create(properties={
+ 'cn': brm.common_name,
+ 'userPassword': replication_manager_pwd
+ })
+ replication_manager_dn = brm.dn
+
+ replica = Replicas(inst).get(DEFAULT_SUFFIX)
+ replica.set('nsDS5ReplicaBindDN', brm.dn)
+ replica.remove_all('nsDS5ReplicaBindDNgroup')
+ agmt = replica.get_agreements().list()[0]
+ agmt.replace_many(
+ ('nsDS5ReplicaBindMethod', 'SASL/DIGEST-MD5'),
+ ('nsDS5ReplicaTransportInfo', 'LDAP'),
+ ('nsDS5ReplicaPort', str(to.port)),
+ ('nsDS5ReplicaBindDN', replication_manager_dn),
+ ('nsDS5ReplicaCredentials', replication_manager_pwd),
+ )
+
+
+def gen_valgrind_wrapper(dir):
+ name=f"{dir}/VALGRIND"
+ with open(name, 'w') as f:
+ f.write('#!/bin/sh\n')
+ f.write('export SASL_PATH=foo\n')
+ f.write(f'valgrind -q --tool=memcheck --leak-check=yes --leak-resolution=high --num-callers=50 --log-file=/var/tmp/slapd.vg.$$ {dir}/ns-slapd.original "$@"\n')
+ os.chmod(name, 0o755)
+ return name
+
+@pytest.fixture
+def use_valgrind(topo_m2, request):
+ """Adds entries to the supplier1"""
+
+ log.info("Enable valgrind")
+ m1 = topo_m2.ms['supplier1']
+ m2 = topo_m2.ms['supplier2']
+ if m1.has_asan():
+ pytest.skip('Tescase using valgring cannot run on asan enabled build')
+ return
+ set_sasl_md5_client_auth(m1, m2)
+ set_sasl_md5_client_auth(m2, m1)
+ m1.stop()
+ m2.stop()
+ m1.systemd_override = False
+ m2.systemd_override = False
+ valgrind_enable(m1.ds_paths.sbin_dir, gen_valgrind_wrapper(m1.ds_paths.sbin_dir))
+
+ def fin():
+ log.info("Disable valgrind")
+ valgrind_disable(m1.ds_paths.sbin_dir)
+
+ request.addfinalizer(fin)
+
+
+def test_repl_sasl_md5_auth(topo_m2):
+ """Test replication with SASL digest-md5 authentication
+
+ :id: 922d16f8-662a-4915-a39e-0aecd7c8e6e2
+ :setup: Two supplier replication
+ :steps:
+ 1. Set sasl digest/md4 on both suppliers
+ 2. Restart the instance
+ 3. Check that replication works
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 3. Replication works
+ """
+
+ m1 = topo_m2.ms['supplier1']
+ m2 = topo_m2.ms['supplier2']
+
+ set_sasl_md5_client_auth(m1, m2)
+ set_sasl_md5_client_auth(m2, m1)
+
+ m1.restart()
+ m2.restart()
+
+ repl = ReplicationManager(DEFAULT_SUFFIX)
+ repl.test_replication_topology(topo_m2)
+
+
+@pytest.mark.skipif(not os.path.exists('/usr/bin/valgrind'), reason="valgrind is not installed.")
+def test_repl_sasl_leak(topo_m2, use_valgrind):
+ """Test replication with SASL digest-md5 authentication
+
+ :id: 180e088e-841c-11ec-af4f-482ae39447e5
+ :setup: Two supplier replication, valgrind
+ :steps:
+ 1. Set sasl digest/md4 on both suppliers
+ 2. Break sasl by setting invalid PATH
+ 3. Restart the instances
+ 4. Perform a change
+ 5. Poke replication 100 times
+ 6. Stop server
+ 7. Check presence of "SASL(-4): no mechanism available: No worthy mechs found" message in error log
+ 8 Check that there is no leak about slapi_ldap_get_lderrno
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 2. Success
+ 4. Success
+ 5. Success
+ 6. Success
+ 7. Success
+ 8. Success
+ """
+
+ m1 = topo_m2.ms['supplier1']
+ m2 = topo_m2.ms['supplier2']
+
+ os.environ["SASL_PATH"] = 'foo'
+
+ m1.start()
+ m2.start()
+
+ resfile=valgrind_get_results_file(m1)
+
+ # Perform a change
+ from_groups = Groups(m1, basedn=DEFAULT_SUFFIX, rdn=None)
+ from_group = from_groups.get('replication_managers')
+ change = str(uuid.uuid4())
+ from_group.replace('description', change)
+
+ # Poke replication to trigger thev leak
+ replica = Replicas(m1).get(DEFAULT_SUFFIX)
+ agmt = Agreements(m1, replica.dn).list()[0]
+ for i in range(0, 100):
+ agmt.pause()
+ agmt.resume()
+
+ m1.stop()
+ assert m1.searchErrorsLog("worthy")
+ assert not valgrind_check_file(resfile, 'slapi_ldap_get_lderrno');
+
diff --git a/ldap/servers/plugins/chainingdb/cb_search.c b/ldap/servers/plugins/chainingdb/cb_search.c
index ffc8f56f8..d6f30b357 100644
--- a/ldap/servers/plugins/chainingdb/cb_search.c
+++ b/ldap/servers/plugins/chainingdb/cb_search.c
@@ -348,10 +348,9 @@ chainingdb_build_candidate_list(Slapi_PBlock *pb)
warned_rc = 1;
}
cb_send_ldap_result(pb, rc, NULL, ENDUSERMSG, 0, NULL);
- /* BEWARE: matched_msg and error_msg points */
+ /* BEWARE: matched_msg points */
/* to ld fields. */
matched_msg = NULL;
- error_msg = NULL;
rc = -1;
}
@@ -695,10 +694,9 @@ chainingdb_next_search_entry(Slapi_PBlock *pb)
}
cb_send_ldap_result(pb, rc, matched_msg, ENDUSERMSG, 0, NULL);
- /* BEWARE: Don't free matched_msg && error_msg */
+ /* BEWARE: Don't free matched_msg */
/* Points to the ld fields */
matched_msg = NULL;
- error_msg = NULL;
retcode = -1;
} else {
/* Add control response sent by the farm server */
diff --git a/ldap/servers/plugins/passthru/ptbind.c b/ldap/servers/plugins/passthru/ptbind.c
index 705ab2c3a..3e79b47f6 100644
--- a/ldap/servers/plugins/passthru/ptbind.c
+++ b/ldap/servers/plugins/passthru/ptbind.c
@@ -33,6 +33,8 @@ passthru_simple_bind_once_s(PassThruServer *srvr, const char *dn, struct berval
* are only interested in recovering silently when the remote server is up
* but decided to close our connection, we retry without pausing between
* attempts.
+ *
+ * Note that errmsgp must be freed by the caller.
*/
int
passthru_simple_bind_s(Slapi_PBlock *pb, PassThruServer *srvr, int tries, const char *dn, struct berval *creds, LDAPControl **reqctrls, int *lderrnop, char **matcheddnp, char **errmsgp, struct berval ***refurlsp, LDAPControl ***resctrlsp)
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index 2dd74f9e7..b6bc21c46 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -244,6 +244,7 @@ conn_delete_internal(Repl_Connection *conn)
PR_ASSERT(NULL != conn);
close_connection_internal(conn);
/* slapi_ch_free accepts NULL pointer */
+ slapi_ch_free_string(&conn->last_ldap_errmsg);
slapi_ch_free((void **)&conn->hostname);
slapi_ch_free((void **)&conn->binddn);
slapi_ch_free((void **)&conn->plain);
@@ -450,6 +451,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retda
char *s = NULL;
rc = slapi_ldap_get_lderrno(conn->ld, NULL, &s);
+ slapi_ch_free_string(&conn->last_ldap_errmsg);
conn->last_ldap_errmsg = s;
conn->last_ldap_error = rc;
/* some errors will require a disconnect and retry the connection
@@ -1937,6 +1939,7 @@ bind_and_check_pwp(Repl_Connection *conn, char *binddn, char *password)
agmt_get_long_name(conn->agmt),
mech ? mech : "SIMPLE", rc,
ldap_err2string(rc), errmsg ? errmsg : "");
+ slapi_ch_free_string(&errmsg);
} else {
char *errmsg = NULL;
/* errmsg is a pointer directly into the ld structure - do not free */
@@ -1946,6 +1949,7 @@ bind_and_check_pwp(Repl_Connection *conn, char *binddn, char *password)
agmt_get_long_name(conn->agmt),
mech ? mech : "SIMPLE", rc,
ldap_err2string(rc), errmsg ? errmsg : "");
+ slapi_ch_free_string(&errmsg);
}
return (CONN_OPERATION_FAILED);
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
index 5eca5fad1..d3f6a4e93 100644
--- a/ldap/servers/plugins/replication/windows_connection.c
+++ b/ldap/servers/plugins/replication/windows_connection.c
@@ -331,6 +331,7 @@ windows_perform_operation(Repl_Connection *conn, int optype, const char *dn, LDA
"windows_perform_operation - %s: Received error %d: %s for %s operation\n",
agmt_get_long_name(conn->agmt),
rc, s ? s : "NULL", op_string);
+ slapi_ch_free_string(&s);
conn->last_ldap_error = rc;
/* some errors will require a disconnect and retry the connection
later */
@@ -1709,6 +1710,7 @@ bind_and_check_pwp(Repl_Connection *conn, char *binddn, char *password)
agmt_get_long_name(conn->agmt),
mech ? mech : "SIMPLE", rc,
ldap_err2string(rc), errmsg);
+ slapi_ch_free_string(&errmsg);
} else {
char *errmsg = NULL;
/* errmsg is a pointer directly into the ld structure - do not free */
@@ -1718,6 +1720,7 @@ bind_and_check_pwp(Repl_Connection *conn, char *binddn, char *password)
agmt_get_long_name(conn->agmt),
mech ? mech : "SIMPLE", rc,
ldap_err2string(rc), errmsg);
+ slapi_ch_free_string(&errmsg);
}
slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= bind_and_check_pwp - CONN_OPERATION_FAILED\n");
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
index 336ca3912..db3300e30 100644
--- a/ldap/servers/slapd/ldaputil.c
+++ b/ldap/servers/slapd/ldaputil.c
@@ -375,6 +375,8 @@ slapi_ldap_url_parse(const char *url, LDAPURLDesc **ludpp, int require_dn, int *
#include <sasl/sasl.h>
+
+/* Warning: caller must free s (if not NULL) */
int
slapi_ldap_get_lderrno(LDAP *ld, char **m, char **s)
{
@@ -389,6 +391,9 @@ slapi_ldap_get_lderrno(LDAP *ld, char **m, char **s)
ldap_get_option(ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, s);
#else
ldap_get_option(ld, LDAP_OPT_ERROR_STRING, s);
+ if (*s) {
+ *s = slapi_ch_strdup(*s);
+ }
#endif
}
return rc;
@@ -1517,6 +1522,7 @@ slapd_ldap_sasl_interactive_bind(
mech ? mech : "SIMPLE",
rc, ldap_err2string(rc), errmsg,
errno, slapd_system_strerror(errno));
+ slapi_ch_free_string(&errmsg);
if (can_retry_bind(ld, mech, bindid, creds, rc, errmsg)) {
; /* pass through to retry one time */
} else {
diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
index 48d3879a3..1c314322b 100644
--- a/src/lib389/lib389/_mapped_object.py
+++ b/src/lib389/lib389/_mapped_object.py
@@ -67,6 +67,34 @@ def _gen_filter(attrtypes, values, extra=None):
return filt
+# Define wrappers around the ldap operation to have a clear diagnostic
+def _ldap_op_s(inst, f, fname, *args, **kwargs):
+ # f.__name__ says 'inner' so the wanted name is provided as argument
+ try:
+ return f(*args, **kwargs)
+ except ldap.LDAPError as e:
+ new_desc = f"{fname}({args},{kwargs}) on instance {inst.serverid}";
+ if len(e.args) >= 1:
+ e.args[0]['ldap_request'] = new_desc
+ logging.getLogger().error(f"args={e.args}")
+ raise
+
+def _add_ext_s(inst, *args, **kwargs):
+ return _ldap_op_s(inst, inst.add_ext_s, 'add_ext_s', *args, **kwargs)
+
+def _modify_ext_s(inst, *args, **kwargs):
+ return _ldap_op_s(inst, inst.modify_ext_s, 'modify_ext_s', *args, **kwargs)
+
+def _delete_ext_s(inst, *args, **kwargs):
+ return _ldap_op_s(inst, inst.delete_ext_s, 'delete_ext_s', *args, **kwargs)
+
+def _search_ext_s(inst, *args, **kwargs):
+ return _ldap_op_s(inst, inst.search_ext_s, 'search_ext_s', *args, **kwargs)
+
+def _search_s(inst, *args, **kwargs):
+ return _ldap_op_s(inst, inst.search_s, 'search_s', *args, **kwargs)
+
+
class DSLogging(object):
"""The benefit of this is automatic name detection, and correct application
of level and verbosity to the object.
@@ -129,7 +157,7 @@ class DSLdapObject(DSLogging, DSLint):
:returns: Entry object
"""
- return self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=["*"],
+ return _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=["*"],
serverctrls=self._server_controls, clientctrls=self._client_controls,
escapehatch='i am sure')[0]
@@ -140,7 +168,7 @@ class DSLdapObject(DSLogging, DSLint):
"""
try:
- self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter, attrsonly=1,
+ _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter, attrsonly=1,
serverctrls=self._server_controls, clientctrls=self._client_controls,
escapehatch='i am sure')
except ldap.NO_SUCH_OBJECT:
@@ -156,7 +184,7 @@ class DSLdapObject(DSLogging, DSLint):
search_scope = ldap.SCOPE_ONE
elif scope == 'subtree':
search_scope = ldap.SCOPE_SUBTREE
- return self._instance.search_ext_s(self._dn, search_scope, filter,
+ return _search_ext_s(self._instance,self._dn, search_scope, filter,
serverctrls=self._server_controls,
clientctrls=self._client_controls,
escapehatch='i am sure')
@@ -166,7 +194,7 @@ class DSLdapObject(DSLogging, DSLint):
:returns: LDIF formatted string
"""
- e = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=attrlist,
+ e = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=attrlist,
serverctrls=self._server_controls, clientctrls=self._client_controls,
escapehatch='i am sure')[0]
return e.__repr__()
@@ -258,7 +286,7 @@ class DSLdapObject(DSLogging, DSLint):
raise ValueError("Invalid state. Cannot get presence on instance that is not ONLINE")
self._log.debug("%s present(%r) %s" % (self._dn, attr, value))
- self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=[attr, ],
+ _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=[attr, ],
serverctrls=self._server_controls, clientctrls=self._client_controls,
escapehatch='i am sure')[0]
values = self.get_attr_vals_bytes(attr)
@@ -313,7 +341,7 @@ class DSLdapObject(DSLogging, DSLint):
else:
value = [ensure_bytes(arg[1])]
mods.append((ldap.MOD_REPLACE, ensure_str(arg[0]), value))
- return self._instance.modify_ext_s(self._dn, mods, serverctrls=self._server_controls,
+ return _modify_ext_s(self._instance,self._dn, mods, serverctrls=self._server_controls,
clientctrls=self._client_controls, escapehatch='i am sure')
# This needs to work on key + val, and key
@@ -457,7 +485,7 @@ class DSLdapObject(DSLogging, DSLint):
elif value is not None:
value = [ensure_bytes(value)]
- return self._instance.modify_ext_s(self._dn, [(action, key, value)],
+ return _modify_ext_s(self._instance,self._dn, [(action, key, value)],
serverctrls=self._server_controls, clientctrls=self._client_controls,
escapehatch='i am sure')
@@ -497,7 +525,7 @@ class DSLdapObject(DSLogging, DSLint):
else:
# Error too many items
raise ValueError('Too many arguments in the mod op')
- return self._instance.modify_ext_s(self._dn, mod_list, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
+ return _modify_ext_s(self._instance,self._dn, mod_list, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
def _unsafe_compare_attribute(self, other):
"""Compare two attributes from two objects. This is currently marked unsafe as it's
@@ -593,7 +621,7 @@ class DSLdapObject(DSLogging, DSLint):
raise ValueError("Invalid state. Cannot get properties on instance that is not ONLINE")
else:
# retrieving real(*) and operational attributes(+)
- attrs_entry = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter,
+ attrs_entry = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter,
attrlist=["*", "+"], serverctrls=self._server_controls,
clientctrls=self._client_controls, escapehatch='i am sure')[0]
# getting dict from 'entry' object
@@ -613,7 +641,7 @@ class DSLdapObject(DSLogging, DSLint):
raise ValueError("Invalid state. Cannot get properties on instance that is not ONLINE")
else:
# retrieving real(*) and operational attributes(+)
- attrs_entry = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter,
+ attrs_entry = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter,
attrlist=["*", "+"], serverctrls=self._server_controls,
clientctrls=self._client_controls, escapehatch='i am sure')[0]
# getting dict from 'entry' object
@@ -627,7 +655,7 @@ class DSLdapObject(DSLogging, DSLint):
if self._instance.state != DIRSRV_STATE_ONLINE:
raise ValueError("Invalid state. Cannot get properties on instance that is not ONLINE")
else:
- entry = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter,
+ entry = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter,
attrlist=keys, serverctrls=self._server_controls,
clientctrls=self._client_controls, escapehatch='i am sure')[0]
return entry.getValuesSet(keys)
@@ -636,7 +664,7 @@ class DSLdapObject(DSLogging, DSLint):
self._log.debug("%s get_attrs_vals_utf8(%r)" % (self._dn, keys))
if self._instance.state != DIRSRV_STATE_ONLINE:
raise ValueError("Invalid state. Cannot get properties on instance that is not ONLINE")
- entry = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=keys,
+ entry = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter, attrlist=keys,
serverctrls=self._server_controls, clientctrls=self._client_controls,
escapehatch='i am sure')[0]
vset = entry.getValuesSet(keys)
@@ -655,7 +683,7 @@ class DSLdapObject(DSLogging, DSLint):
else:
# It would be good to prevent the entry code intercepting this ....
# We have to do this in this method, because else we ignore the scope base.
- entry = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter,
+ entry = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter,
attrlist=[key], serverctrls=self._server_controls,
clientctrls=self._client_controls, escapehatch='i am sure')[0]
vals = entry.getValues(key)
@@ -675,7 +703,7 @@ class DSLdapObject(DSLogging, DSLint):
# In the future, I plan to add a mode where if local == true, we
# can use get on dse.ldif to get values offline.
else:
- entry = self._instance.search_ext_s(self._dn, ldap.SCOPE_BASE, self._object_filter,
+ entry = _search_ext_s(self._instance,self._dn, ldap.SCOPE_BASE, self._object_filter,
attrlist=[key], serverctrls=self._server_controls,
clientctrls=self._client_controls, escapehatch='i am sure')[0]
return entry.getValue(key)
@@ -831,11 +859,11 @@ class DSLdapObject(DSLogging, DSLint):
# Is there a way to mark this as offline and kill it
if recursive:
filterstr = "(|(objectclass=*)(objectclass=ldapsubentry))"
- ents = self._instance.search_s(self._dn, ldap.SCOPE_SUBTREE, filterstr, escapehatch='i am sure')
+ ents = _search_s(self._instance, self._dn, ldap.SCOPE_SUBTREE, filterstr, escapehatch='i am sure')
for ent in sorted(ents, key=lambda e: len(e.dn), reverse=True):
- self._instance.delete_ext_s(ent.dn, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
+ _delete_ext_s(self._instance, ent.dn, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
else:
- self._instance.delete_ext_s(self._dn, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
+ _delete_ext_s(self._instance, self._dn, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
def _validate(self, rdn, properties, basedn):
"""Used to validate a create request.
@@ -933,7 +961,7 @@ class DSLdapObject(DSLogging, DSLint):
# If we are running in stateful ensure mode, we need to check if the object exists, and
# we can see the state that it is in.
try:
- self._instance.search_ext_s(dn, ldap.SCOPE_BASE, self._object_filter, attrsonly=1, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
+ _search_ext_s(self._instance,dn, ldap.SCOPE_BASE, self._object_filter, attrsonly=1, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
exists = True
except ldap.NO_SUCH_OBJECT:
pass
@@ -946,7 +974,7 @@ class DSLdapObject(DSLogging, DSLint):
mods = []
for k, v in list(valid_props.items()):
mods.append((ldap.MOD_REPLACE, k, v))
- self._instance.modify_ext_s(self._dn, mods, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
+ _modify_ext_s(self._instance,self._dn, mods, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
elif not exists:
# This case is reached in two cases. One is we are in ensure mode, and we KNOW the entry
# doesn't exist.
@@ -957,7 +985,7 @@ class DSLdapObject(DSLogging, DSLint):
e.update({'objectclass': ensure_list_bytes(self._create_objectclasses)})
e.update(valid_props)
# We rely on exceptions here to indicate failure to the parent.
- self._instance.add_ext_s(e, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
+ _add_ext_s(self._instance, e, serverctrls=self._server_controls, clientctrls=self._client_controls, escapehatch='i am sure')
self._log.debug('Created entry %s : %s' % (dn, display_log_data(e.data)))
# If it worked, we need to fix our instance dn for the object's self reference. Because
# we may not have a self reference yet (just created), it may have changed (someone
@@ -1104,7 +1132,7 @@ class DSLdapObjects(DSLogging, DSLints):
else:
# If not paged
try:
- results = self._instance.search_ext_s(
+ results = _search_ext_s(self._instance,
base=self._basedn,
scope=self._scope,
filterstr=filterstr,
@@ -1172,7 +1200,7 @@ class DSLdapObjects(DSLogging, DSLints):
filterstr = self._get_objectclass_filter()
self._log.debug('_gen_dn filter = %s' % filterstr)
self._log.debug('_gen_dn dn = %s' % dn)
- return self._instance.search_ext_s(
+ return _search_ext_s(self._instance,
base=dn,
scope=ldap.SCOPE_BASE,
filterstr=filterstr,
@@ -1187,7 +1215,7 @@ class DSLdapObjects(DSLogging, DSLints):
# This will yield and & filter for objectClass with as many terms as needed.
filterstr = self._get_selector_filter(selector)
self._log.debug('_gen_selector filter = %s' % filterstr)
- return self._instance.search_ext_s(
+ return _search_ext_s(self._instance,
base=self._basedn,
scope=self._scope,
filterstr=filterstr,
@@ -1261,7 +1289,7 @@ class DSLdapObjects(DSLogging, DSLints):
self._list_attrlist = attrlist
self._log.debug(f'list filter = {search_filter} with scope {scope} and attribute list {attrlist}')
try:
- results = self._instance.search_ext_s(
+ results = _search_ext_s(self._instance,
base=self._basedn,
scope=scope,
filterstr=search_filter,
diff --git a/src/lib389/lib389/utils.py b/src/lib389/lib389/utils.py
index 6eba2d7b9..da966ed97 100644
--- a/src/lib389/lib389/utils.py
+++ b/src/lib389/lib389/utils.py
@@ -52,7 +52,7 @@ from ldapurl import LDAPUrl
from contextlib import closing
import lib389
-from lib389.paths import Paths
+from lib389.paths import ( Paths, DEFAULTS_PATH )
from lib389.dseldif import DSEldif
from lib389._constants import (
DEFAULT_USER, VALGRIND_WRAPPER, DN_CONFIG, CFGSUFFIX, LOCALHOST,
@@ -495,8 +495,10 @@ def valgrind_enable(sbin_dir, wrapper=None):
:raise EnvironmentError: If script is not run as 'root'
'''
- if os.geteuid() != 0:
- log.error('This script must be run as root to use valgrind')
+ if not os.access(sbin_dir, os.W_OK):
+ # Note: valgrind has no limitation but ns-slapd must be replaced
+ # This check allows non root user to use custom install prefix
+ log.error('This script must be run as root to use valgrind (Should at least be able to write in {sbin_dir})')
raise EnvironmentError
if not wrapper:
@@ -542,7 +544,20 @@ def valgrind_enable(sbin_dir, wrapper=None):
e.strerror)
# Disable selinux
- os.system('setenforce 0')
+ if os.geteuid() == 0:
+ os.system('setenforce 0')
+
+ # Disable systemd by turning off with_system in .inf file
+ old_path = Paths()._get_defaults_loc(DEFAULTS_PATH)
+ new_path = f'{old_path}.orig'
+ os.rename(old_path, new_path)
+ with open(new_path, 'rt') as fin:
+ with open(old_path, 'wt') as fout:
+ for line in fin:
+ if line.startswith('with_systemd'):
+ fout.write('with_systemd = 0\n')
+ else:
+ fout.write(line)
log.info('Valgrind is now enabled.')
@@ -559,8 +574,10 @@ def valgrind_disable(sbin_dir):
:raise EnvironmentError: If script is not run as 'root'
'''
- if os.geteuid() != 0:
- log.error('This script must be run as root to use valgrind')
+ if not os.access(sbin_dir, os.W_OK):
+ # Note: valgrind has no limitation but ns-slapd must be replaced
+ # This check allows non root user to use custom install prefix
+ log.error('This script must be run as root to use valgrind (Should at least be able to write in {sbin_dir})')
raise EnvironmentError
nsslapd_orig = '%s/ns-slapd' % sbin_dir
@@ -584,7 +601,14 @@ def valgrind_disable(sbin_dir):
e.strerror)
# Enable selinux
- os.system('setenforce 1')
+ if os.geteuid() == 0:
+ os.system('setenforce 1')
+
+ # Restore .inf file (for systemd)
+ new_path = Paths()._get_defaults_loc(DEFAULTS_PATH)
+ old_path = f'{new_path}.orig'
+ if os.path.exists(old_path):
+ os.replace(old_path, new_path)
log.info('Valgrind is now disabled.')
@@ -610,7 +634,7 @@ def valgrind_get_results_file(dirsrv_inst):
# Run the command and grab the output
p = os.popen(cmd)
- results_file = p.readline()
+ results_file = p.readline().strip()
p.close()
return results_file
--
2.31.1

View File

@ -1,34 +0,0 @@
From 16536e5d306727761ffd10403f4762956f177147 Mon Sep 17 00:00:00 2001
From: progier389 <progier@redhat.com>
Date: Wed, 5 Jan 2022 12:09:27 +0100
Subject: [PATCH] Issue 5085 - Race condition about snmp collator at startup
(#5086)
---
ldap/servers/slapd/snmp_collator.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
index 10a99475d..ed34d2ac4 100644
--- a/ldap/servers/slapd/snmp_collator.c
+++ b/ldap/servers/slapd/snmp_collator.c
@@ -201,7 +201,7 @@ set_snmp_interaction_row(char *host, int port, int error)
/* The interactions table is using the default (first) snmp_vars*/
snmp_vars = g_get_first_thread_snmp_vars(&cookie);
- if (snmp_vars == NULL)
+ if (snmp_vars == NULL || interaction_table_mutex == NULL)
return;
/* stevross: our servers don't have a concept of dsName as a distinguished name
@@ -856,7 +856,6 @@ snmp_update_cache_stats(void)
if (search_result == 0) {
int cookie;
- uint64_t total;
struct snmp_vars_t *snmp_vars;
slapi_pblock_get(search_result_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
&search_entries);
--
2.31.1

View File

@ -1,41 +0,0 @@
From 2ee8d9d2ce8bf252287089d18e15b519f15e9538 Mon Sep 17 00:00:00 2001
From: Firstyear <william@blackhats.net.au>
Date: Thu, 6 Jan 2022 09:49:30 +1000
Subject: [PATCH 1/5] Issue 5079 - BUG - multiple ways to specific primary
(#5087)
Bug Description: In a winsync environment, we can only sync
changes to a primary replica. There are however, multiple
ways to specify which server is a primary for a replication
agreement, and I only accounted for one of them.
Fix Description: Improve the check to account for the
other primary replica flags.
fixes: https://github.com/389ds/389-ds-base/issues/5079
Author: William Brown <william@blackhats.net.au>
Review by: @droideck
---
ldap/servers/plugins/replication/repl5_agmt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 82efdcd15..a71343dec 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -482,7 +482,9 @@ agmt_new_from_entry(Slapi_Entry *e)
/* DBDB: review this code */
if (slapi_entry_attr_hasvalue(e, "objectclass", "nsDSWindowsReplicationAgreement")) {
- if (replica && replica_get_type(replica) == REPLICA_TYPE_PRIMARY) {
+ if (replica_get_type(replica) == REPLICA_TYPE_PRIMARY
+ || (replica_get_type(replica) == REPLICA_TYPE_UPDATABLE && replica_is_flag_set(replica, REPLICA_LOG_CHANGES))
+ ) {
ra->agreement_type = REPLICA_TYPE_WINDOWS;
windows_init_agreement_from_entry(ra, e);
} else {
--
2.37.1

View File

@ -1,873 +0,0 @@
From e65d6225398901c3319e72a460bc58e5d50df67c Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Wed, 3 Aug 2022 16:27:15 -0400
Subject: [PATCH 2/5] Issue 3903 - Supplier should do periodic updates
Description:
On suppliers update the keep alive entry periodically to keep the RUV up
to date in case a replica is neglected for along time. This prevents
very long changelog scans when finally processing updates.
relates: https://github.com/389ds/389-ds-base/issues/3903
Reviewed by: firstyear & tbordaz(Thanks!)
---
.../suites/replication/regression_m2_test.py | 96 +++++--------
.../suites/replication/replica_config_test.py | 6 +-
ldap/schema/01core389.ldif | 3 +-
ldap/servers/plugins/replication/repl5.h | 11 +-
.../plugins/replication/repl5_inc_protocol.c | 44 +-----
.../plugins/replication/repl5_replica.c | 127 +++++++++++++-----
.../replication/repl5_replica_config.c | 12 ++
.../plugins/replication/repl5_tot_protocol.c | 4 +-
ldap/servers/plugins/replication/repl_extop.c | 2 +-
.../plugins/replication/repl_globals.c | 1 +
.../src/lib/replication/replConfig.jsx | 32 ++++-
src/cockpit/389-console/src/replication.jsx | 6 +
src/lib389/lib389/cli_conf/replication.py | 6 +-
13 files changed, 202 insertions(+), 148 deletions(-)
diff --git a/dirsrvtests/tests/suites/replication/regression_m2_test.py b/dirsrvtests/tests/suites/replication/regression_m2_test.py
index 466e3c2c0..7dd0f2984 100644
--- a/dirsrvtests/tests/suites/replication/regression_m2_test.py
+++ b/dirsrvtests/tests/suites/replication/regression_m2_test.py
@@ -14,6 +14,7 @@ import ldif
import ldap
import pytest
import subprocess
+import time
from lib389.idm.user import TEST_USER_PROPERTIES, UserAccounts
from lib389.pwpolicy import PwPolicyManager
from lib389.utils import *
@@ -204,12 +205,12 @@ def rename_entry(server, idx, ou_name, new_parent):
def add_ldapsubentry(server, parent):
pwp = PwPolicyManager(server)
policy_props = {'passwordStorageScheme': 'ssha',
- 'passwordCheckSyntax': 'on',
- 'passwordInHistory': '6',
- 'passwordChange': 'on',
- 'passwordMinAge': '0',
- 'passwordExp': 'off',
- 'passwordMustChange': 'off',}
+ 'passwordCheckSyntax': 'on',
+ 'passwordInHistory': '6',
+ 'passwordChange': 'on',
+ 'passwordMinAge': '0',
+ 'passwordExp': 'off',
+ 'passwordMustChange': 'off',}
log.info('Create password policy for subtree {}'.format(parent))
pwp.create_subtree_policy(parent, policy_props)
@@ -742,7 +743,7 @@ def get_keepalive_entries(instance, replica):
try:
entries = instance.search_s(replica.get_suffix(), ldap.SCOPE_ONELEVEL,
"(&(objectclass=ldapsubentry)(cn=repl keep alive*))",
- ['cn', 'nsUniqueId', 'modifierTimestamp'])
+ ['cn', 'keepalivetimestamp', 'nsUniqueId', 'modifierTimestamp'])
except ldap.LDAPError as e:
log.fatal('Failed to retrieve keepalive entry (%s) on instance %s: error %s' % (dn, instance, str(e)))
assert False
@@ -761,6 +762,7 @@ def verify_keepalive_entries(topo, expected):
# (for example after: db2ldif / demote a supplier / ldif2db / init other suppliers)
# ==> if the function is somehow pushed in lib389, a check better than simply counting the entries
# should be done.
+ entries = []
for supplierId in topo.ms:
supplier = topo.ms[supplierId]
for replica in Replicas(supplier).list():
@@ -771,6 +773,7 @@ def verify_keepalive_entries(topo, expected):
keepaliveEntries = get_keepalive_entries(supplier, replica);
expectedCount = len(topo.ms) if expected else 0
foundCount = len(keepaliveEntries)
+ entries += keepaliveEntries
if (foundCount == expectedCount):
log.debug(f'Found {foundCount} keepalive entries as expected on {replica_info}.')
else:
@@ -778,70 +781,45 @@ def verify_keepalive_entries(topo, expected):
f'while {expectedCount} were expected on {replica_info}.')
assert False
+ return entries
+
-def test_online_init_should_create_keepalive_entries(topo_m2):
- """Check that keep alive entries are created when initializinf a supplier from another one
+def test_keepalive_entries(topo_m2):
+ """Check that keep alive entries are created
:id: d5940e71-d18a-4b71-aaf7-b9185361fffe
:setup: Two suppliers replication setup
:steps:
- 1. Generate ldif without replication data
- 2 Init both suppliers from that ldif
- 3 Check that keep alive entries does not exists
- 4 Perform on line init of supplier2 from supplier1
- 5 Check that keep alive entries exists
+ 1. Keep alives entries are present
+ 2. Keep alive entries are updated every 60 seconds
:expectedresults:
- 1. No error while generating ldif
- 2. No error while importing the ldif file
- 3. No keepalive entrie should exists on any suppliers
- 4. No error while initializing supplier2
- 5. All keepalive entries should exist on every suppliers
+ 1. Success
+ 2. Success
"""
- repl = ReplicationManager(DEFAULT_SUFFIX)
- m1 = topo_m2.ms["supplier1"]
- m2 = topo_m2.ms["supplier2"]
- # Step 1: Generate ldif without replication data
- m1.stop()
- m2.stop()
- ldif_file = '%s/norepl.ldif' % m1.get_ldif_dir()
- m1.db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX],
- excludeSuffixes=None, repl_data=False,
- outputfile=ldif_file, encrypt=False)
- # Remove replication metadata that are still in the ldif
- _remove_replication_data(ldif_file)
-
- # Step 2: Init both suppliers from that ldif
- m1.ldif2db(DEFAULT_BENAME, None, None, None, ldif_file)
- m2.ldif2db(DEFAULT_BENAME, None, None, None, ldif_file)
- m1.start()
- m2.start()
-
- """ Replica state is now as if CLI setup has been done using:
- dsconf supplier1 replication enable --suffix "${SUFFIX}" --role supplier
- dsconf supplier2 replication enable --suffix "${SUFFIX}" --role supplier
- dsconf supplier1 replication create-manager --name "${REPLICATION_MANAGER_NAME}" --passwd "${REPLICATION_MANAGER_PASSWORD}"
- dsconf supplier2 replication create-manager --name "${REPLICATION_MANAGER_NAME}" --passwd "${REPLICATION_MANAGER_PASSWORD}"
- dsconf supplier1 repl-agmt create --suffix "${SUFFIX}"
- dsconf supplier2 repl-agmt create --suffix "${SUFFIX}"
- """
+ # default interval is 1 hour, too long for test, set it to the minimum of
+ # 60 seconds
+ for supplierId in topo_m2.ms:
+ supplier = topo_m2.ms[supplierId]
+ replica = Replicas(supplier).get(DEFAULT_SUFFIX)
+ replica.replace('nsds5ReplicaKeepAliveUpdateInterval', '60')
+ supplier.restart()
- # Step 3: No keepalive entrie should exists on any suppliers
- verify_keepalive_entries(topo_m2, False)
+ # verify entries exist
+ entries = verify_keepalive_entries(topo_m2, True);
- # Step 4: Perform on line init of supplier2 from supplier1
- agmt = Agreements(m1).list()[0]
- agmt.begin_reinit()
- (done, error) = agmt.wait_reinit()
- assert done is True
- assert error is False
+ # Get current time from keep alive entry
+ keep_alive_s1 = str(entries[0].data['keepalivetimestamp'])
+ keep_alive_s2 = str(entries[1].data['keepalivetimestamp'])
+
+ # Wait for event interval (60 secs) to pass
+ time.sleep(61)
- # Step 5: All keepalive entries should exists on every suppliers
- # Verify the keep alive entry once replication is in sync
- # (that is the step that fails when bug is not fixed)
- repl.wait_for_ruv(m2,m1)
- verify_keepalive_entries(topo_m2, True);
+ # Check keep alives entries have been updated
+ entries = verify_keepalive_entries(topo_m2, True);
+ assert keep_alive_s1 != str(entries[0].data['keepalivetimestamp'])
+ assert keep_alive_s2 != str(entries[1].data['keepalivetimestamp'])
@pytest.mark.ds49915
diff --git a/dirsrvtests/tests/suites/replication/replica_config_test.py b/dirsrvtests/tests/suites/replication/replica_config_test.py
index c2140a2ac..06ae5afcf 100644
--- a/dirsrvtests/tests/suites/replication/replica_config_test.py
+++ b/dirsrvtests/tests/suites/replication/replica_config_test.py
@@ -50,7 +50,8 @@ repl_add_attrs = [('nsDS5ReplicaType', '-1', '4', overflow, notnum, '1'),
('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '1'),
('nsds5ReplicaReleaseTimeout', '-1', too_big, overflow, notnum, '1'),
('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'),
- ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')]
+ ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6'),
+ ('nsds5ReplicaKeepAliveUpdateInterval', '59', too_big, overflow, notnum, '60'),]
repl_mod_attrs = [('nsDS5Flags', '-1', '2', overflow, notnum, '1'),
('nsds5ReplicaPurgeDelay', '-2', too_big, overflow, notnum, '1'),
@@ -59,7 +60,8 @@ repl_mod_attrs = [('nsDS5Flags', '-1', '2', overflow, notnum, '1'),
('nsds5ReplicaProtocolTimeout', '-1', too_big, overflow, notnum, '1'),
('nsds5ReplicaReleaseTimeout', '-1', too_big, overflow, notnum, '1'),
('nsds5ReplicaBackoffMin', '0', too_big, overflow, notnum, '3'),
- ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6')]
+ ('nsds5ReplicaBackoffMax', '0', too_big, overflow, notnum, '6'),
+ ('nsds5ReplicaKeepAliveUpdateInterval', '59', too_big, overflow, notnum, '60'),]
agmt_attrs = [
('nsds5ReplicaPort', '0', '65535', overflow, notnum, '389'),
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index 0c73e5114..7a9598730 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -327,6 +327,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2371 NAME 'nsDS5ReplicaBootstrapBindDN'
attributeTypes: ( 2.16.840.1.113730.3.1.2372 NAME 'nsDS5ReplicaBootstrapCredentials' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2373 NAME 'nsDS5ReplicaBootstrapBindMethod' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2374 NAME 'nsDS5ReplicaBootstrapTransportInfo' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2390 NAME 'nsds5ReplicaKeepAliveUpdateInterval' DESC '389 defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
#
# objectclasses
#
@@ -336,7 +337,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.44 NAME 'nsIndex' DESC 'Netscape defined
objectClasses: ( 2.16.840.1.113730.3.2.109 NAME 'nsBackendInstance' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.110 NAME 'nsMappingTree' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.104 NAME 'nsContainer' DESC 'Netscape defined objectclass' SUP top MUST ( CN ) X-ORIGIN 'Netscape Directory Server' )
-objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Replication configuration objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsDS5ReplicaBindDNGroup $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax $ nsds5ReplicaReleaseTimeout $ nsDS5ReplicaBindDnGroupCheckInterval ) X-ORIGIN 'Netscape Directory Server' )
+objectClasses: ( 2.16.840.1.113730.3.2.108 NAME 'nsDS5Replica' DESC 'Replication configuration objectclass' SUP top MUST ( nsDS5ReplicaRoot $ nsDS5ReplicaId ) MAY (cn $ nsds5ReplicaPreciseTombstonePurging $ nsds5ReplicaCleanRUV $ nsds5ReplicaAbortCleanRUV $ nsDS5ReplicaType $ nsDS5ReplicaBindDN $ nsDS5ReplicaBindDNGroup $ nsState $ nsDS5ReplicaName $ nsDS5Flags $ nsDS5Task $ nsDS5ReplicaReferral $ nsDS5ReplicaAutoReferral $ nsds5ReplicaPurgeDelay $ nsds5ReplicaTombstonePurgeInterval $ nsds5ReplicaChangeCount $ nsds5ReplicaLegacyConsumer $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaBackoffMin $ nsds5ReplicaBackoffMax $ nsds5ReplicaReleaseTimeout $ nsDS5ReplicaBindDnGroupCheckInterval $ nsds5ReplicaKeepAliveUpdateInterval ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.113 NAME 'nsTombstone' DESC 'Netscape defined objectclass' SUP top MAY ( nstombstonecsn $ nsParentUniqueId $ nscpEntryDN ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsds5ReplicaCleanRUVNotified $ nsDS5ReplicaHost $ nsDS5ReplicaPort $ nsDS5ReplicaTransportInfo $ nsDS5ReplicaBindDN $ nsDS5ReplicaCredentials $ nsDS5ReplicaBindMethod $ nsDS5ReplicaRoot $ nsDS5ReplicatedAttributeList $ nsDS5ReplicatedAttributeListTotal $ nsDS5ReplicaUpdateSchedule $ nsds5BeginReplicaRefresh $ description $ nsds50ruv $ nsruvReplicaLastModified $ nsds5ReplicaTimeout $ nsds5replicaChangesSentSinceStartup $ nsds5replicaLastUpdateEnd $ nsds5replicaLastUpdateStart $ nsds5replicaLastUpdateStatus $ nsds5replicaUpdateInProgress $ nsds5replicaLastInitEnd $ nsds5ReplicaEnabled $ nsds5replicaLastInitStart $ nsds5replicaLastInitStatus $ nsds5debugreplicatimeout $ nsds5replicaBusyWaitTime $ nsds5ReplicaStripAttrs $ nsds5replicaSessionPauseTime $ nsds5ReplicaProtocolTimeout $ nsds5ReplicaFlowControlWindow $ nsds5ReplicaFlowControlPause $ nsDS5ReplicaWaitForAsyncResults $ nsds5ReplicaIgnoreMissingChange $ nsDS5ReplicaBootstrapBindDN $ nsDS5ReplicaBootstrapCredentials $ nsDS5ReplicaBootstrapBindMethod $ nsDS5ReplicaBootstrapTransportInfo ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' )
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
index 06e747811..c2fbff8c0 100644
--- a/ldap/servers/plugins/replication/repl5.h
+++ b/ldap/servers/plugins/replication/repl5.h
@@ -1,6 +1,6 @@
/** BEGIN COPYRIGHT BLOCK
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2020 Red Hat, Inc.
+ * Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
*
@@ -120,6 +120,8 @@
#define PROTOCOL_STATUS_TOTAL_SENDING_DATA 711
#define DEFAULT_PROTOCOL_TIMEOUT 120
+#define DEFAULT_REPLICA_KEEPALIVE_UPDATE_INTERVAL 3600
+#define REPLICA_KEEPALIVE_UPDATE_INTERVAL_MIN 60
/* To Allow Consumer Initialization when adding an agreement - */
#define STATE_PERFORMING_TOTAL_UPDATE 501
@@ -162,6 +164,7 @@ extern const char *type_nsds5ReplicaBootstrapBindDN;
extern const char *type_nsds5ReplicaBootstrapCredentials;
extern const char *type_nsds5ReplicaBootstrapBindMethod;
extern const char *type_nsds5ReplicaBootstrapTransportInfo;
+extern const char *type_replicaKeepAliveUpdateInterval;
/* Attribute names for windows replication agreements */
extern const char *type_nsds7WindowsReplicaArea;
@@ -677,8 +680,8 @@ Replica *windows_replica_new(const Slapi_DN *root);
during addition of the replica over LDAP */
int replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation, Replica **r);
void replica_destroy(void **arg);
-int replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid);
-int replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid);
+void replica_subentry_update(time_t when, void *arg);
+int replica_subentry_check(const char *repl_root, ReplicaId rid);
PRBool replica_get_exclusive_access(Replica *r, PRBool *isInc, uint64_t connid, int opid, const char *locking_purl, char **current_purl);
void replica_relinquish_exclusive_access(Replica *r, uint64_t connid, int opid);
PRBool replica_get_tombstone_reap_active(const Replica *r);
@@ -739,6 +742,8 @@ void consumer5_set_mapping_tree_state_for_replica(const Replica *r, RUV *supplie
Replica *replica_get_for_backend(const char *be_name);
void replica_set_purge_delay(Replica *r, uint32_t purge_delay);
void replica_set_tombstone_reap_interval(Replica *r, long interval);
+void replica_set_keepalive_update_interval(Replica *r, int64_t interval);
+int64_t replica_get_keepalive_update_interval(Replica *r);
void replica_update_ruv_consumer(Replica *r, RUV *supplier_ruv);
Slapi_Entry *get_in_memory_ruv(Slapi_DN *suffix_sdn);
int replica_write_ruv(Replica *r);
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 4bb384882..846951b9e 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -1,6 +1,6 @@
/** BEGIN COPYRIGHT BLOCK
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2020 Red Hat, Inc.
+ * Copyright (C) 2022 Red Hat, Inc.
* All rights reserved.
*
* License: GPL (version 3 or any later version).
@@ -1677,13 +1677,9 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
} else {
ConnResult replay_crc;
Replica *replica = prp->replica;
- PRBool subentry_update_needed = PR_FALSE;
PRUint64 release_timeout = replica_get_release_timeout(replica);
char csn_str[CSN_STRSIZE];
- int skipped_updates = 0;
- int fractional_repl;
int finished = 0;
-#define FRACTIONAL_SKIPPED_THRESHOLD 100
/* Start the results reading thread */
rd = repl5_inc_rd_new(prp);
@@ -1700,7 +1696,6 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
memset((void *)&op, 0, sizeof(op));
entry.op = &op;
- fractional_repl = agmt_is_fractional(prp->agmt);
do {
cl5_operation_parameters_done(entry.op);
memset((void *)entry.op, 0, sizeof(op));
@@ -1781,14 +1776,6 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
replica_id = csn_get_replicaid(entry.op->csn);
uniqueid = entry.op->target_address.uniqueid;
- if (fractional_repl && message_id) {
- /* This update was sent no need to update the subentry
- * and restart counting the skipped updates
- */
- subentry_update_needed = PR_FALSE;
- skipped_updates = 0;
- }
-
if (prp->repl50consumer && message_id) {
int operation, error = 0;
@@ -1816,15 +1803,6 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
agmt_get_long_name(prp->agmt),
entry.op->target_address.uniqueid, csn_str);
agmt_inc_last_update_changecount(prp->agmt, csn_get_replicaid(entry.op->csn), 1 /*skipped*/);
- if (fractional_repl) {
- skipped_updates++;
- if (skipped_updates > FRACTIONAL_SKIPPED_THRESHOLD) {
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "send_updates - %s: skipped updates is too high (%d) if no other update is sent we will update the subentry\n",
- agmt_get_long_name(prp->agmt), skipped_updates);
- subentry_update_needed = PR_TRUE;
- }
- }
}
}
break;
@@ -1906,26 +1884,6 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
PR_Unlock(rd->lock);
} while (!finished);
- if (fractional_repl && subentry_update_needed) {
- ReplicaId rid = -1; /* Used to create the replica keep alive subentry */
- Slapi_DN *replarea_sdn = NULL;
-
- if (replica) {
- rid = replica_get_rid(replica);
- }
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "send_updates - %s: skipped updates was definitely too high (%d) update the subentry now\n",
- agmt_get_long_name(prp->agmt), skipped_updates);
- replarea_sdn = agmt_get_replarea(prp->agmt);
- if (!replarea_sdn) {
- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
- "send_updates - Unknown replication area due to agreement not found.");
- agmt_set_last_update_status(prp->agmt, 0, -1, "Agreement is corrupted: missing suffix");
- return_value = UPDATE_FATAL_ERROR;
- } else {
- replica_subentry_update(replarea_sdn, rid);
- }
- }
/* Terminate the results reading thread */
if (!prp->repl50consumer) {
/* We need to ensure that we wait until all the responses have been received from our operations */
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index 3bd57647f..ded4cf754 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -1,6 +1,6 @@
/** BEGIN COPYRIGHT BLOCK
* Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
* All rights reserved.
*
@@ -22,7 +22,6 @@
#include "slap.h"
#define RUV_SAVE_INTERVAL (30 * 1000) /* 30 seconds */
-
#define REPLICA_RDN "cn=replica"
/*
@@ -48,6 +47,7 @@ struct replica
PRMonitor *repl_lock; /* protects entire structure */
Slapi_Eq_Context repl_eqcxt_rs; /* context to cancel event that saves ruv */
Slapi_Eq_Context repl_eqcxt_tr; /* context to cancel event that reaps tombstones */
+ Slapi_Eq_Context repl_eqcxt_ka_update; /* keep-alive entry update event */
Object *repl_csngen; /* CSN generator for this replica */
PRBool repl_csn_assigned; /* Flag set when new csn is assigned. */
int64_t repl_purge_delay; /* When purgeable, CSNs are held on to for this many extra seconds */
@@ -66,6 +66,7 @@ struct replica
uint64_t agmt_count; /* Number of agmts */
Slapi_Counter *release_timeout; /* The amount of time to wait before releasing active replica */
uint64_t abort_session; /* Abort the current replica session */
+ int64_t keepalive_update_interval; /* interval to do dummy update to keep RUV fresh */)
};
@@ -133,8 +134,8 @@ replica_new(const Slapi_DN *root)
&r);
if (NULL == r) {
- slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_new - "
- "Unable to configure replica %s: %s\n",
+ slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
+ "replica_new - Unable to configure replica %s: %s\n",
slapi_sdn_get_dn(root), errorbuf);
}
slapi_entry_free(e);
@@ -232,7 +233,15 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation,
In that case the updated would fail but nothing bad would happen. The next
scheduled update would save the state */
r->repl_eqcxt_rs = slapi_eq_repeat_rel(replica_update_state, r->repl_name,
- slapi_current_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
+ slapi_current_rel_time_t() + START_UPDATE_DELAY,
+ RUV_SAVE_INTERVAL);
+
+ /* create supplier update event */
+ if (r->repl_eqcxt_ka_update == NULL && replica_get_type(r) == REPLICA_TYPE_UPDATABLE) {
+ r->repl_eqcxt_ka_update = slapi_eq_repeat_rel(replica_subentry_update, r,
+ slapi_current_rel_time_t() + START_UPDATE_DELAY,
+ replica_get_keepalive_update_interval(r));
+ }
if (r->tombstone_reap_interval > 0) {
/*
@@ -302,6 +311,11 @@ replica_destroy(void **arg)
* and ruv updates.
*/
+ if (r->repl_eqcxt_ka_update) {
+ slapi_eq_cancel_rel(r->repl_eqcxt_ka_update);
+ r->repl_eqcxt_ka_update = NULL;
+ }
+
if (r->repl_eqcxt_rs) {
slapi_eq_cancel_rel(r->repl_eqcxt_rs);
r->repl_eqcxt_rs = NULL;
@@ -393,7 +407,7 @@ replica_destroy(void **arg)
static int
-replica_subentry_create(Slapi_DN *repl_root, ReplicaId rid)
+replica_subentry_create(const char *repl_root, ReplicaId rid)
{
char *entry_string = NULL;
Slapi_Entry *e = NULL;
@@ -402,7 +416,7 @@ replica_subentry_create(Slapi_DN *repl_root, ReplicaId rid)
int rc = 0;
entry_string = slapi_ch_smprintf("dn: cn=%s %d,%s\nobjectclass: top\nobjectclass: ldapsubentry\nobjectclass: extensibleObject\ncn: %s %d",
- KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root), KEEP_ALIVE_ENTRY, rid);
+ KEEP_ALIVE_ENTRY, rid, repl_root, KEEP_ALIVE_ENTRY, rid);
if (entry_string == NULL) {
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
"replica_subentry_create - Failed in slapi_ch_smprintf\n");
@@ -441,7 +455,7 @@ done:
}
int
-replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid)
+replica_subentry_check(const char *repl_root, ReplicaId rid)
{
Slapi_PBlock *pb;
char *filter = NULL;
@@ -451,7 +465,7 @@ replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid)
pb = slapi_pblock_new();
filter = slapi_ch_smprintf("(&(objectclass=ldapsubentry)(cn=%s %d))", KEEP_ALIVE_ENTRY, rid);
- slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(repl_root), LDAP_SCOPE_ONELEVEL,
+ slapi_search_internal_set_pb(pb, repl_root, LDAP_SCOPE_ONELEVEL,
filter, NULL, 0, NULL, NULL,
repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
slapi_search_internal_pb(pb);
@@ -460,17 +474,19 @@ replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid)
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
if (entries && (entries[0] == NULL)) {
slapi_log_err(SLAPI_LOG_NOTICE, repl_plugin_name,
- "replica_subentry_check - Need to create replication keep alive entry <cn=%s %d,%s>\n", KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root));
+ "replica_subentry_check - Need to create replication keep alive entry <cn=%s %d,%s>\n",
+ KEEP_ALIVE_ENTRY, rid, repl_root);
rc = replica_subentry_create(repl_root, rid);
} else {
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "replica_subentry_check - replication keep alive entry <cn=%s %d,%s> already exists\n", KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root));
+ "replica_subentry_check - replication keep alive entry <cn=%s %d,%s> already exists\n",
+ KEEP_ALIVE_ENTRY, rid, repl_root);
rc = 0;
}
} else {
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
"replica_subentry_check - Error accessing replication keep alive entry <cn=%s %d,%s> res=%d\n",
- KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root), res);
+ KEEP_ALIVE_ENTRY, rid, repl_root, res);
/* The status of the entry is not clear, do not attempt to create it */
rc = 1;
}
@@ -481,60 +497,59 @@ replica_subentry_check(Slapi_DN *repl_root, ReplicaId rid)
return rc;
}
-int
-replica_subentry_update(Slapi_DN *repl_root, ReplicaId rid)
+void
+replica_subentry_update(time_t when __attribute__((unused)), void *arg)
{
- int ldrc;
- int rc = LDAP_SUCCESS; /* Optimistic default */
+ Slapi_PBlock *modpb = NULL;
+ Replica *replica = (Replica *)arg;
+ ReplicaId rid;
LDAPMod *mods[2];
LDAPMod mod;
struct berval *vals[2];
- char buf[SLAPI_TIMESTAMP_BUFSIZE];
struct berval val;
- Slapi_PBlock *modpb = NULL;
- char *dn;
+ const char *repl_root = NULL;
+ char buf[SLAPI_TIMESTAMP_BUFSIZE];
+ char *dn = NULL;
+ int ldrc = 0;
+ rid = replica_get_rid(replica);
+ repl_root = slapi_ch_strdup(slapi_sdn_get_dn(replica_get_root(replica)));
replica_subentry_check(repl_root, rid);
slapi_timestamp_utc_hr(buf, SLAPI_TIMESTAMP_BUFSIZE);
-
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "subentry_update called at %s\n", buf);
-
-
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "replica_subentry_update called at %s\n", buf);
val.bv_val = buf;
val.bv_len = strlen(val.bv_val);
-
vals[0] = &val;
vals[1] = NULL;
mod.mod_op = LDAP_MOD_REPLACE | LDAP_MOD_BVALUES;
mod.mod_type = KEEP_ALIVE_ATTR;
mod.mod_bvalues = vals;
-
mods[0] = &mod;
mods[1] = NULL;
modpb = slapi_pblock_new();
- dn = slapi_ch_smprintf(KEEP_ALIVE_DN_FORMAT, KEEP_ALIVE_ENTRY, rid, slapi_sdn_get_dn(repl_root));
-
+ dn = slapi_ch_smprintf(KEEP_ALIVE_DN_FORMAT, KEEP_ALIVE_ENTRY, rid, repl_root);
slapi_modify_internal_set_pb(modpb, dn, mods, NULL, NULL,
repl_get_plugin_identity(PLUGIN_MULTIMASTER_REPLICATION), 0);
slapi_modify_internal_pb(modpb);
-
slapi_pblock_get(modpb, SLAPI_PLUGIN_INTOP_RESULT, &ldrc);
-
if (ldrc != LDAP_SUCCESS) {
slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
- "Failure (%d) to update replication keep alive entry \"%s: %s\"\n", ldrc, KEEP_ALIVE_ATTR, buf);
- rc = ldrc;
+ "replica_subentry_update - "
+ "Failure (%d) to update replication keep alive entry \"%s: %s\"\n",
+ ldrc, KEEP_ALIVE_ATTR, buf);
} else {
slapi_log_err(SLAPI_LOG_PLUGIN, repl_plugin_name,
- "Successful update of replication keep alive entry \"%s: %s\"\n", KEEP_ALIVE_ATTR, buf);
+ "replica_subentry_update - "
+ "Successful update of replication keep alive entry \"%s: %s\"\n",
+ KEEP_ALIVE_ATTR, buf);
}
slapi_pblock_destroy(modpb);
+ slapi_ch_free_string((char **)&repl_root);
slapi_ch_free_string(&dn);
- return rc;
}
/*
* Attempt to obtain exclusive access to replica (advisory only)
@@ -1512,7 +1527,15 @@ replica_set_enabled(Replica *r, PRBool enable)
if (r->repl_eqcxt_rs == NULL) /* event is not already registered */
{
r->repl_eqcxt_rs = slapi_eq_repeat_rel(replica_update_state, r->repl_name,
- slapi_current_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
+ slapi_current_rel_time_t() + START_UPDATE_DELAY,
+ RUV_SAVE_INTERVAL);
+
+ }
+ /* create supplier update event */
+ if (r->repl_eqcxt_ka_update == NULL && replica_get_type(r) == REPLICA_TYPE_UPDATABLE) {
+ r->repl_eqcxt_ka_update = slapi_eq_repeat_rel(replica_subentry_update, r,
+ slapi_current_rel_time_t() + START_UPDATE_DELAY,
+ replica_get_keepalive_update_interval(r));
}
} else /* disable */
{
@@ -1521,6 +1544,11 @@ replica_set_enabled(Replica *r, PRBool enable)
slapi_eq_cancel_rel(r->repl_eqcxt_rs);
r->repl_eqcxt_rs = NULL;
}
+ /* Remove supplier update event */
+ if (replica_get_type(r) == REPLICA_TYPE_PRIMARY) {
+ slapi_eq_cancel_rel(r->repl_eqcxt_ka_update);
+ r->repl_eqcxt_ka_update = NULL;
+ }
}
replica_unlock(r->repl_lock);
@@ -2119,6 +2147,17 @@ _replica_init_from_config(Replica *r, Slapi_Entry *e, char *errortext)
r->tombstone_reap_interval = 3600 * 24; /* One week, in seconds */
}
+ if ((val = (char*)slapi_entry_attr_get_ref(e, type_replicaKeepAliveUpdateInterval))) {
+ if (repl_config_valid_num(type_replicaKeepAliveUpdateInterval, val, REPLICA_KEEPALIVE_UPDATE_INTERVAL_MIN,
+ INT_MAX, &rc, errormsg, &interval) != 0)
+ {
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+ r->keepalive_update_interval = interval;
+ } else {
+ r->keepalive_update_interval = DEFAULT_REPLICA_KEEPALIVE_UPDATE_INTERVAL;
+ }
+
r->tombstone_reap_stop = r->tombstone_reap_active = PR_FALSE;
/* No supplier holding the replica */
@@ -3646,6 +3685,26 @@ replica_set_tombstone_reap_interval(Replica *r, long interval)
replica_unlock(r->repl_lock);
}
+void
+replica_set_keepalive_update_interval(Replica *r, int64_t interval)
+{
+ replica_lock(r->repl_lock);
+ r->keepalive_update_interval = interval;
+ replica_unlock(r->repl_lock);
+}
+
+int64_t
+replica_get_keepalive_update_interval(Replica *r)
+{
+ int64_t interval = DEFAULT_REPLICA_KEEPALIVE_UPDATE_INTERVAL;
+
+ replica_lock(r->repl_lock);
+ interval = r->keepalive_update_interval;
+ replica_unlock(r->repl_lock);
+
+ return interval;
+}
+
static void
replica_strip_cleaned_rids(Replica *r)
{
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
index 2c6d74b13..aea2cf506 100644
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
@@ -438,6 +438,9 @@ replica_config_modify(Slapi_PBlock *pb,
} else if (strcasecmp(config_attr, type_replicaBackoffMax) == 0) {
if (apply_mods)
replica_set_backoff_max(r, PROTOCOL_BACKOFF_MAXIMUM);
+ } else if (strcasecmp(config_attr, type_replicaKeepAliveUpdateInterval) == 0) {
+ if (apply_mods)
+ replica_set_keepalive_update_interval(r, DEFAULT_REPLICA_KEEPALIVE_UPDATE_INTERVAL);
} else if (strcasecmp(config_attr, type_replicaPrecisePurge) == 0) {
if (apply_mods)
replica_set_precise_purging(r, 0);
@@ -472,6 +475,15 @@ replica_config_modify(Slapi_PBlock *pb,
} else {
break;
}
+ } else if (strcasecmp(config_attr, type_replicaKeepAliveUpdateInterval) == 0) {
+ int64_t interval = DEFAULT_REPLICA_KEEPALIVE_UPDATE_INTERVAL;
+ if (repl_config_valid_num(config_attr, config_attr_value, REPLICA_KEEPALIVE_UPDATE_INTERVAL_MIN,
+ INT_MAX, returncode, errortext, &interval) == 0)
+ {
+ replica_set_keepalive_update_interval(r, interval);
+ } else {
+ break;
+ }
} else if (strcasecmp(config_attr, attr_replicaType) == 0) {
int64_t rtype;
slapi_ch_free_string(&new_repl_type);
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
index f67263c3e..4b2064912 100644
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
@@ -510,7 +510,7 @@ retry:
if (prp->replica) {
rid = replica_get_rid(prp->replica);
}
- replica_subentry_check(area_sdn, rid);
+ replica_subentry_check(slapi_sdn_get_dn(area_sdn), rid);
/* Send the subtree of the suffix in the order of parentid index plus ldapsubentry and nstombstone. */
check_suffix_entryID(be, suffix);
@@ -531,7 +531,7 @@ retry:
if (prp->replica) {
rid = replica_get_rid(prp->replica);
}
- replica_subentry_check(area_sdn, rid);
+ replica_subentry_check(slapi_sdn_get_dn(area_sdn), rid);
slapi_search_internal_set_pb(pb, slapi_sdn_get_dn(area_sdn),
LDAP_SCOPE_SUBTREE, "(|(objectclass=ldapsubentry)(objectclass=nstombstone)(nsuniqueid=*))", NULL, 0, ctrls, NULL,
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index ef2025dd9..8b178610b 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -1176,7 +1176,7 @@ multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb)
/* now that the changelog is open and started, we can alos cretae the
* keep alive entry without risk that db and cl will not match
*/
- replica_subentry_check((Slapi_DN *)replica_get_root(r), replica_get_rid(r));
+ replica_subentry_check(slapi_sdn_get_dn(replica_get_root(r)), replica_get_rid(r));
}
/* ONREPL code that dealt with new RUV, etc was moved into the code
diff --git a/ldap/servers/plugins/replication/repl_globals.c b/ldap/servers/plugins/replication/repl_globals.c
index 000777fdd..797ca957f 100644
--- a/ldap/servers/plugins/replication/repl_globals.c
+++ b/ldap/servers/plugins/replication/repl_globals.c
@@ -89,6 +89,7 @@ const char *type_replicaReleaseTimeout = "nsds5ReplicaReleaseTimeout";
const char *type_replicaBackoffMin = "nsds5ReplicaBackoffMin";
const char *type_replicaBackoffMax = "nsds5ReplicaBackoffMax";
const char *type_replicaPrecisePurge = "nsds5ReplicaPreciseTombstonePurging";
+const char *type_replicaKeepAliveUpdateInterval = "nsds5ReplicaKeepAliveUpdateInterval";
/* Attribute names for replication agreement attributes */
const char *type_nsds5ReplicaHost = "nsds5ReplicaHost";
diff --git a/src/cockpit/389-console/src/lib/replication/replConfig.jsx b/src/cockpit/389-console/src/lib/replication/replConfig.jsx
index 1f0dc3ec5..3dffb8f1a 100644
--- a/src/cockpit/389-console/src/lib/replication/replConfig.jsx
+++ b/src/cockpit/389-console/src/lib/replication/replConfig.jsx
@@ -48,6 +48,7 @@ export class ReplConfig extends React.Component {
nsds5replicaprotocoltimeout: Number(this.props.data.nsds5replicaprotocoltimeout) == 0 ? 120 : Number(this.props.data.nsds5replicaprotocoltimeout),
nsds5replicabackoffmin: Number(this.props.data.nsds5replicabackoffmin) == 0 ? 3 : Number(this.props.data.nsds5replicabackoffmin),
nsds5replicabackoffmax: Number(this.props.data.nsds5replicabackoffmax) == 0 ? 300 : Number(this.props.data.nsds5replicabackoffmax),
+ nsds5replicakeepaliveupdateinterval: Number(this.props.data.nsds5replicakeepaliveupdateinterval) == 0 ? 3600 : Number(this.props.data.nsds5replicakeepaliveupdateinterval),
// Original settings
_nsds5replicabinddn: this.props.data.nsds5replicabinddn,
_nsds5replicabinddngroup: this.props.data.nsds5replicabinddngroup,
@@ -59,6 +60,7 @@ export class ReplConfig extends React.Component {
_nsds5replicaprotocoltimeout: Number(this.props.data.nsds5replicaprotocoltimeout) == 0 ? 120 : Number(this.props.data.nsds5replicaprotocoltimeout),
_nsds5replicabackoffmin: Number(this.props.data.nsds5replicabackoffmin) == 0 ? 3 : Number(this.props.data.nsds5replicabackoffmin),
_nsds5replicabackoffmax: Number(this.props.data.nsds5replicabackoffmax) == 0 ? 300 : Number(this.props.data.nsds5replicabackoffmax),
+ _nsds5replicakeepaliveupdateinterval: Number(this.props.data.nsds5replicakeepaliveupdateinterval) == 0 ? 3600 : Number(this.props.data.nsds5replicakeepaliveupdateinterval),
};
this.onToggle = (isExpanded) => {
@@ -275,7 +277,7 @@ export class ReplConfig extends React.Component {
'nsds5replicapurgedelay', 'nsds5replicatombstonepurgeinterval',
'nsds5replicareleasetimeout', 'nsds5replicaprotocoltimeout',
'nsds5replicabackoffmin', 'nsds5replicabackoffmax',
- 'nsds5replicaprecisetombstonepurging'
+ 'nsds5replicaprecisetombstonepurging', 'nsds5replicakeepaliveupdateinterval',
];
// Check if a setting was changed, if so enable the save button
for (const config_attr of config_attrs) {
@@ -301,7 +303,7 @@ export class ReplConfig extends React.Component {
'nsds5replicapurgedelay', 'nsds5replicatombstonepurgeinterval',
'nsds5replicareleasetimeout', 'nsds5replicaprotocoltimeout',
'nsds5replicabackoffmin', 'nsds5replicabackoffmax',
- 'nsds5replicaprecisetombstonepurging'
+ 'nsds5replicaprecisetombstonepurging', 'nsds5replicakeepaliveupdateinterval',
];
// Check if a setting was changed, if so enable the save button
for (const config_attr of config_attrs) {
@@ -451,6 +453,9 @@ export class ReplConfig extends React.Component {
if (this.state.nsds5replicabinddngroupcheckinterval != this.state._nsds5replicabinddngroupcheckinterval) {
cmd.push("--repl-bind-group-interval=" + this.state.nsds5replicabinddngroupcheckinterval);
}
+ if (this.state.nsds5replicakeepaliveupdateinterval != this.state._nsds5replicakeepaliveupdateinterval) {
+ cmd.push("--repl-keepalive-update-interval=" + this.state.nsds5replicakeepaliveupdateinterval);
+ }
if (this.state.nsds5replicareleasetimeout != this.state._nsds5replicareleasetimeout) {
cmd.push("--repl-release-timeout=" + this.state.nsds5replicareleasetimeout);
}
@@ -786,6 +791,29 @@ export class ReplConfig extends React.Component {
/>
</GridItem>
</Grid>
+ <Grid
+ title="The interval in seconds that the server will apply an internal update to get the RUV from getting stale. (nsds5replicakeepaliveupdateinterval)."
+ className="ds-margin-top"
+ >
+ <GridItem className="ds-label" span={3}>
+ Refresh RUV Interval
+ </GridItem>
+ <GridItem span={9}>
+ <NumberInput
+ value={this.state.nsds5replicakeepaliveupdateinterval}
+ min={60}
+ max={this.maxValue}
+ onMinus={() => { this.onMinusConfig("nsds5replicakeepaliveupdateinterval") }}
+ onChange={(e) => { this.onConfigChange(e, "nsds5replicakeepaliveupdateinterval", 60) }}
+ onPlus={() => { this.onPlusConfig("nsds5replicakeepaliveupdateinterval") }}
+ inputName="input"
+ inputAriaLabel="number input"
+ minusBtnAriaLabel="minus"
+ plusBtnAriaLabel="plus"
+ widthChars={8}
+ />
+ </GridItem>
+ </Grid>
<Grid
title="Enables faster tombstone purging (nsds5replicaprecisetombstonepurging)."
className="ds-margin-top"
diff --git a/src/cockpit/389-console/src/replication.jsx b/src/cockpit/389-console/src/replication.jsx
index 28364156a..db9d030db 100644
--- a/src/cockpit/389-console/src/replication.jsx
+++ b/src/cockpit/389-console/src/replication.jsx
@@ -553,6 +553,7 @@ export class Replication extends React.Component {
nsds5replicaprotocoltimeout: 'nsds5replicaprotocoltimeout' in config.attrs ? config.attrs.nsds5replicaprotocoltimeout[0] : "",
nsds5replicabackoffmin: 'nsds5replicabackoffmin' in config.attrs ? config.attrs.nsds5replicabackoffmin[0] : "",
nsds5replicabackoffmax: 'nsds5replicabackoffmax' in config.attrs ? config.attrs.nsds5replicabackoffmax[0] : "",
+ nsds5replicakeepaliveupdateinterval: 'nsds5replicakeepaliveupdateinterval' in config.attrs ? config.attrs.nsds5replicakeepaliveupdateinterval[0] : "3600",
},
suffixSpinning: false,
disabled: false,
@@ -695,6 +696,11 @@ export class Replication extends React.Component {
nsds5replicaprotocoltimeout: 'nsds5replicaprotocoltimeout' in config.attrs ? config.attrs.nsds5replicaprotocoltimeout[0] : "",
nsds5replicabackoffmin: 'nsds5replicabackoffmin' in config.attrs ? config.attrs.nsds5replicabackoffmin[0] : "",
nsds5replicabackoffmax: 'nsds5replicabackoffmax' in config.attrs ? config.attrs.nsds5replicabackoffmax[0] : "",
+ nsds5replicakeepaliveupdateinterval: 'nsds5replicakeepaliveupdateinterval' in config.attrs ? config.attrs.nsds5replicakeepaliveupdateinterval[0] : "3600",
+ clMaxEntries: "",
+ clMaxAge: "",
+ clTrimInt: "",
+ clEncrypt: false,
}
}, this.loadLDIFs);
diff --git a/src/lib389/lib389/cli_conf/replication.py b/src/lib389/lib389/cli_conf/replication.py
index 0048cd09b..450246b3d 100644
--- a/src/lib389/lib389/cli_conf/replication.py
+++ b/src/lib389/lib389/cli_conf/replication.py
@@ -33,6 +33,7 @@ arg_to_attr = {
'repl_backoff_min': 'nsds5replicabackoffmin',
'repl_backoff_max': 'nsds5replicabackoffmax',
'repl_release_timeout': 'nsds5replicareleasetimeout',
+ 'repl_keepalive_update_interval': 'nsds5replicakeepaliveupdateinterval',
# Changelog
'cl_dir': 'nsslapd-changelogdir',
'max_entries': 'nsslapd-changelogmaxentries',
@@ -1278,6 +1279,9 @@ def create_parser(subparsers):
"while waiting to acquire the consumer. Default is 3 seconds")
repl_set_parser.add_argument('--repl-release-timeout', help="A timeout in seconds a replication supplier should send "
"updates before it yields its replication session")
+ repl_set_parser.add_argument('--repl-keepalive-update-interval', help="Interval in seconds for how often the server will apply "
+ "an internal update to keep the RUV from getting stale. "
+ "The default is 1 hour (3600 seconds)")
repl_monitor_parser = repl_subcommands.add_parser('monitor', help='Display the full replication topology report')
repl_monitor_parser.set_defaults(func=get_repl_monitor_info)
@@ -1289,7 +1293,7 @@ def create_parser(subparsers):
repl_monitor_parser.add_argument('-a', '--aliases', nargs="*",
help="Enables displaying an alias instead of host:port, if an alias is "
"assigned to a host:port combination. The format: alias=host:port")
-#
+
############################################
# Replication Agmts
############################################
--
2.37.1

View File

@ -1,79 +0,0 @@
From 108dd02791da19915beb29c872516c52a74fc637 Mon Sep 17 00:00:00 2001
From: Simon Pichugin <spichugi@redhat.com>
Date: Fri, 5 Aug 2022 10:08:45 -0700
Subject: [PATCH 3/5] Issue 5399 - UI - LDAP Editor is not updated when we
switch instances (#5400)
Description: We don't refresh LDAP Editor when we switch instances.
It may lead to unpleasant errors.
Add componentDidUpdate function with the appropriate processing and
properties.
Fixes: https://github.com/389ds/389-ds-base/issues/5399
Reviewed by: @mreynolds389 (Thanks!)
---
src/cockpit/389-console/src/LDAPEditor.jsx | 19 +++++++++++++++++++
src/cockpit/389-console/src/ds.jsx | 1 +
2 files changed, 20 insertions(+)
diff --git a/src/cockpit/389-console/src/LDAPEditor.jsx b/src/cockpit/389-console/src/LDAPEditor.jsx
index 70324be39..04fc97d41 100644
--- a/src/cockpit/389-console/src/LDAPEditor.jsx
+++ b/src/cockpit/389-console/src/LDAPEditor.jsx
@@ -60,6 +60,7 @@ export class LDAPEditor extends React.Component {
this.state = {
activeTabKey: 0,
+ firstLoad: true,
keyIndex: 0,
suffixList: [],
changeLayout: false,
@@ -249,6 +250,12 @@ export class LDAPEditor extends React.Component {
baseDn: this.state.baseDN
};
+ if (this.state.firstLoad) {
+ this.setState({
+ firstLoad: false
+ });
+ }
+
this.setState({
searching: true,
loading: refresh
@@ -361,6 +368,18 @@ export class LDAPEditor extends React.Component {
});
}
+ componentDidUpdate(prevProps) {
+ if (this.props.wasActiveList.includes(7)) {
+ if (this.state.firstLoad) {
+ this.handleReload(true);
+ } else {
+ if (this.props.serverId !== prevProps.serverId) {
+ this.handleReload(true);
+ }
+ }
+ }
+ }
+
getPageData (page, perPage) {
if (page === 1) {
const pagedRows = this.state.rows.slice(0, 2 * perPage); // Each parent has a single child.
diff --git a/src/cockpit/389-console/src/ds.jsx b/src/cockpit/389-console/src/ds.jsx
index e88915e41..de4385292 100644
--- a/src/cockpit/389-console/src/ds.jsx
+++ b/src/cockpit/389-console/src/ds.jsx
@@ -764,6 +764,7 @@ export class DSInstance extends React.Component {
key="ldap-editor"
addNotification={this.addNotification}
serverId={this.state.serverId}
+ wasActiveList={this.state.wasActiveList}
setPageSectionVariant={this.setPageSectionVariant}
/>
</Tab>
--
2.37.1

View File

@ -1,49 +0,0 @@
From 877df07df2e41988a797778b132935b7d8acfd87 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Fri, 5 Aug 2022 14:07:18 -0400
Subject: [PATCH 4/5] Issue 5397 - Fix various memory leaks
Description:
Fixed memory leaks in:
- Filter optimizer introduced sr_norm_filter_intent which dupped a filter
but never freed it.
- Replication connections would leak the replication manager's
credentials.
relates: https://github.com/389ds/389-ds-base/issues/5397
Reviewed by: progier & jchapman (Thanks!!)
---
ldap/servers/plugins/replication/repl5_connection.c | 1 +
ldap/servers/slapd/back-ldbm/ldbm_search.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index b6bc21c46..be8bba08e 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -247,6 +247,7 @@ conn_delete_internal(Repl_Connection *conn)
slapi_ch_free_string(&conn->last_ldap_errmsg);
slapi_ch_free((void **)&conn->hostname);
slapi_ch_free((void **)&conn->binddn);
+ slapi_ch_free((void **)&conn->creds);
slapi_ch_free((void **)&conn->plain);
}
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index d0f52b6f7..771c35a33 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -1930,6 +1930,7 @@ delete_search_result_set(Slapi_PBlock *pb, back_search_result_set **sr)
rc, filt_errs);
}
slapi_filter_free((*sr)->sr_norm_filter, 1);
+ slapi_filter_free((*sr)->sr_norm_filter_intent, 1);
memset(*sr, 0, sizeof(back_search_result_set));
slapi_ch_free((void **)sr);
return;
--
2.37.1

View File

@ -1,60 +0,0 @@
From 27f0c60a54514773e3ffaa09cfbb71c350f44143 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Sat, 6 Aug 2022 14:03:16 -0400
Subject: [PATCH 5/5] Issue 3903 - keep alive update event starts too soon
Description: THe keep alive update needs a little more time to start to
allow changelog, and other replication protocols to startup
relates: https://github.com/389ds/389-ds-base/issues/3903
Reviewed by: tbordaz (Thanks!)
---
dirsrvtests/tests/suites/replication/regression_m2_test.py | 5 +++++
ldap/servers/plugins/replication/repl5_replica.c | 7 ++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/dirsrvtests/tests/suites/replication/regression_m2_test.py b/dirsrvtests/tests/suites/replication/regression_m2_test.py
index 7dd0f2984..bbf9c8486 100644
--- a/dirsrvtests/tests/suites/replication/regression_m2_test.py
+++ b/dirsrvtests/tests/suites/replication/regression_m2_test.py
@@ -821,6 +821,11 @@ def test_keepalive_entries(topo_m2):
assert keep_alive_s1 != str(entries[0].data['keepalivetimestamp'])
assert keep_alive_s2 != str(entries[1].data['keepalivetimestamp'])
+ # Test replication
+ supplier = topo_m2.ms['supplier1']
+ replica = Replicas(supplier).get(DEFAULT_SUFFIX)
+ assert replica.test_replication([topo_m2.ms['supplier2']])
+
@pytest.mark.ds49915
@pytest.mark.bz1626375
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index ded4cf754..fa6419262 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -239,7 +239,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation,
/* create supplier update event */
if (r->repl_eqcxt_ka_update == NULL && replica_get_type(r) == REPLICA_TYPE_UPDATABLE) {
r->repl_eqcxt_ka_update = slapi_eq_repeat_rel(replica_subentry_update, r,
- slapi_current_rel_time_t() + START_UPDATE_DELAY,
+ slapi_current_rel_time_t() + 30,
replica_get_keepalive_update_interval(r));
}
@@ -415,8 +415,9 @@ replica_subentry_create(const char *repl_root, ReplicaId rid)
int return_value;
int rc = 0;
- entry_string = slapi_ch_smprintf("dn: cn=%s %d,%s\nobjectclass: top\nobjectclass: ldapsubentry\nobjectclass: extensibleObject\ncn: %s %d",
- KEEP_ALIVE_ENTRY, rid, repl_root, KEEP_ALIVE_ENTRY, rid);
+ entry_string = slapi_ch_smprintf("dn: cn=%s %d,%s\nobjectclass: top\nobjectclass: ldapsubentry\n"
+ "objectclass: extensibleObject\n%s: 0\ncn: %s %d",
+ KEEP_ALIVE_ENTRY, rid, repl_root, KEEP_ALIVE_ATTR, KEEP_ALIVE_ENTRY, rid);
if (entry_string == NULL) {
slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name,
"replica_subentry_create - Failed in slapi_ch_smprintf\n");
--
2.37.1

View File

@ -1,28 +0,0 @@
From 1b2cc62c0802af650f80eebcc716b5d5db87030e Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Aug 2022 13:56:49 -0400
Subject: [PATCH] Issue 5397 - Fix check pick error
Description:
Original commit included a free for a new filter, but that filter was
not implemented in 1.4.3
---
ldap/servers/slapd/back-ldbm/ldbm_search.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_search.c b/ldap/servers/slapd/back-ldbm/ldbm_search.c
index 771c35a33..d0f52b6f7 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_search.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_search.c
@@ -1930,7 +1930,6 @@ delete_search_result_set(Slapi_PBlock *pb, back_search_result_set **sr)
rc, filt_errs);
}
slapi_filter_free((*sr)->sr_norm_filter, 1);
- slapi_filter_free((*sr)->sr_norm_filter_intent, 1);
memset(*sr, 0, sizeof(back_search_result_set));
slapi_ch_free((void **)sr);
return;
--
2.37.1

View File

@ -1,28 +0,0 @@
From 1203808f59614f3bace1631cc713dcaa89026dde Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Aug 2022 14:19:36 -0400
Subject: [PATCH] Issue 5397 - Fix check pick error #2
Description:
Original commit included a free for repl conn creds which does not exist
in 1.4.3
---
ldap/servers/plugins/replication/repl5_connection.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
index be8bba08e..b6bc21c46 100644
--- a/ldap/servers/plugins/replication/repl5_connection.c
+++ b/ldap/servers/plugins/replication/repl5_connection.c
@@ -247,7 +247,6 @@ conn_delete_internal(Repl_Connection *conn)
slapi_ch_free_string(&conn->last_ldap_errmsg);
slapi_ch_free((void **)&conn->hostname);
slapi_ch_free((void **)&conn->binddn);
- slapi_ch_free((void **)&conn->creds);
slapi_ch_free((void **)&conn->plain);
}
--
2.37.1

View File

@ -1,27 +0,0 @@
From 4e712bcb7ce7bd972515d996b5659fc607e09e2f Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Mon, 8 Aug 2022 14:41:47 -0400
Subject: [PATCH] Issue 3903 - Fix another cherry-pick error
Description: erroneous ")" was added to the replica struct which broke
the build
---
ldap/servers/plugins/replication/repl5_replica.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index fa6419262..5dab57de4 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -66,7 +66,7 @@ struct replica
uint64_t agmt_count; /* Number of agmts */
Slapi_Counter *release_timeout; /* The amount of time to wait before releasing active replica */
uint64_t abort_session; /* Abort the current replica session */
- int64_t keepalive_update_interval; /* interval to do dummy update to keep RUV fresh */)
+ int64_t keepalive_update_interval; /* interval to do dummy update to keep RUV fresh */
};
--
2.37.1

View File

@ -1,508 +0,0 @@
From 508a6dd02986024b03eeef62d135f7e16b0c85e9 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Thu, 2 Jun 2022 16:57:07 -0400
Subject: [PATCH 1/4] Issue 5329 - Improve replication extended op logging
Description:
We need logging around parsing extended op payload, right now when it
fails we have no idea why.
relates: https://github.com/389ds/389-ds-base/issues/5329
Reviewed by: progier, firstyear, and spichugi(Thanks!!!)
---
ldap/servers/plugins/replication/repl_extop.c | 207 +++++++++++++++++-
ldap/servers/slapd/slapi2runtime.c | 1 -
2 files changed, 197 insertions(+), 11 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
index 8b178610b..70c45ec50 100644
--- a/ldap/servers/plugins/replication/repl_extop.c
+++ b/ldap/servers/plugins/replication/repl_extop.c
@@ -73,6 +73,18 @@ done:
return rc;
}
+static void
+ruv_dump_to_log(const RUV *ruv, char *log_name)
+{
+ if (!ruv) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "%s: RUV: None\n", log_name);
+ } else {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "%s: RUV:\n", log_name);
+ ruv_dump(ruv, log_name, NULL);
+ }
+}
+
+
/* The data_guid and data parameters should only be set if we
* are talking with a 9.0 replica. */
static struct berval *
@@ -95,33 +107,60 @@ create_ReplicationExtopPayload(const char *protocol_oid,
PR_ASSERT(protocol_oid != NULL || send_end);
PR_ASSERT(repl_root != NULL);
- /* Create the request data */
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "encoding '%s' payload...\n",
+ send_end ? "End Replication" : "Start Replication");
+ }
+ /* Create the request data */
if ((tmp_bere = der_alloc()) == NULL) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: der_alloc failed\n");
rc = LDAP_ENCODING_ERROR;
goto loser;
}
if (!send_end) {
if (ber_printf(tmp_bere, "{ss", protocol_oid, repl_root) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_printf failed - protocol_oid (%s) repl_root (%s)\n",
+ protocol_oid, repl_root);
rc = LDAP_ENCODING_ERROR;
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "encoding protocol_oid: %s\n", protocol_oid);
+ }
} else {
if (ber_printf(tmp_bere, "{s", repl_root) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_printf failed - repl_root (%s)\n",
+ repl_root);
rc = LDAP_ENCODING_ERROR;
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "encoding repl_root: %s\n", repl_root);
+ }
}
sdn = slapi_sdn_new_dn_byref(repl_root);
repl = replica_get_replica_from_dn(sdn);
if (repl == NULL) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: failed to get replica from dn (%s)\n",
+ slapi_sdn_get_dn(sdn));
rc = LDAP_OPERATIONS_ERROR;
goto loser;
}
ruv_obj = replica_get_ruv(repl);
if (ruv_obj == NULL) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: failed to get ruv from replica suffix (%s)\n",
+ slapi_sdn_get_dn(sdn));
rc = LDAP_OPERATIONS_ERROR;
goto loser;
}
@@ -134,8 +173,14 @@ create_ReplicationExtopPayload(const char *protocol_oid,
/* We need to encode and send each time the local ruv in case we have changed it */
rc = encode_ruv(tmp_bere, ruv);
if (rc != 0) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: encode_ruv failed for replica suffix (%s)\n",
+ slapi_sdn_get_dn(sdn));
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ ruv_dump_to_log(ruv, "create_ReplicationExtopPayload");
+ }
if (!send_end) {
char s[CSN_STRSIZE];
@@ -157,36 +202,67 @@ create_ReplicationExtopPayload(const char *protocol_oid,
charray_merge(&referrals_to_send, local_replica_referral, 0);
if (NULL != referrals_to_send) {
if (ber_printf(tmp_bere, "[v]", referrals_to_send) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_printf (referrals_to_send)\n");
rc = LDAP_ENCODING_ERROR;
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ for (size_t i = 0; referrals_to_send[i]; i++) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "encoding ref: %s\n", referrals_to_send[i]);
+ }
+ }
slapi_ch_free((void **)&referrals_to_send);
}
/* Add the CSN */
PR_ASSERT(NULL != csn);
if (ber_printf(tmp_bere, "s", csn_as_string(csn, PR_FALSE, s)) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_printf (csnstr)\n");
rc = LDAP_ENCODING_ERROR;
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "encoding csn: %s\n", csn_as_string(csn, PR_FALSE, s));
+ }
}
/* If we have data to send to a 9.0 style replica, set it here. */
if (data_guid && data) {
if (ber_printf(tmp_bere, "sO", data_guid, data) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_printf (data_guid, data)\n");
rc = LDAP_ENCODING_ERROR;
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "encoding data_guid (%s) data (%s:%ld)\n",
+ data_guid, data->bv_val, data->bv_len);
+ }
}
+
if (ber_printf(tmp_bere, "}") == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_printf\n");
rc = LDAP_ENCODING_ERROR;
goto loser;
}
if (ber_flatten(tmp_bere, &req_data) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "create_ReplicationExtopPayload",
+ "encoding failed: ber_flatten failed\n");
rc = LDAP_LOCAL_ERROR;
goto loser;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "create_ReplicationExtopPayload - "
+ "Encoding finished\n");
+ }
+
/* Success */
goto done;
@@ -293,8 +369,14 @@ decode_startrepl_extop(Slapi_PBlock *pb, char **protocol_oid, char **repl_root,
if ((NULL == extop_oid) ||
((strcmp(extop_oid, REPL_START_NSDS50_REPLICATION_REQUEST_OID) != 0) &&
(strcmp(extop_oid, REPL_START_NSDS90_REPLICATION_REQUEST_OID) != 0)) ||
- !BV_HAS_DATA(extop_value)) {
+ !BV_HAS_DATA(extop_value))
+ {
/* bogus */
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: extop_oid (%s) (%s) extop_value (%s)\n",
+ NULL == extop_oid ? "NULL" : "Ok",
+ extop_oid ? extop_oid : "",
+ extop_value ? !BV_HAS_DATA(extop_value) ? "No data" : "Ok" : "No data");
rc = -1;
goto free_and_return;
}
@@ -307,25 +389,36 @@ decode_startrepl_extop(Slapi_PBlock *pb, char **protocol_oid, char **repl_root,
}
if ((tmp_bere = ber_init(extop_value)) == NULL) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_init for extop_value (%s:%lu)\n",
+ extop_value->bv_val, extop_value->bv_len);
rc = -1;
goto free_and_return;
}
if (ber_scanf(tmp_bere, "{") == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_scanf 1\n");
rc = -1;
goto free_and_return;
}
/* Get the required protocol OID and root of replicated subtree */
if (ber_get_stringa(tmp_bere, protocol_oid) == LBER_DEFAULT) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_get_stringa (protocol_oid)\n");
rc = -1;
goto free_and_return;
}
if (ber_get_stringa(tmp_bere, repl_root) == LBER_DEFAULT) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_get_stringa (repl_root)\n");
rc = -1;
goto free_and_return;
}
/* get supplier's ruv */
if (decode_ruv(tmp_bere, supplier_ruv) == -1) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: decode_ruv (supplier_ruv)\n");
rc = -1;
goto free_and_return;
}
@@ -333,33 +426,45 @@ decode_startrepl_extop(Slapi_PBlock *pb, char **protocol_oid, char **repl_root,
/* Get the optional set of referral URLs */
if (ber_peek_tag(tmp_bere, &len) == LBER_SET) {
if (ber_scanf(tmp_bere, "[v]", extra_referrals) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_scanf (extra_referrals)\n");
rc = -1;
goto free_and_return;
}
}
/* Get the CSN */
if (ber_get_stringa(tmp_bere, csnstr) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_get_stringa (csnstr)\n");
rc = -1;
goto free_and_return;
}
/* Get the optional replication session callback data. */
if (ber_peek_tag(tmp_bere, &len) == LBER_OCTETSTRING) {
if (ber_get_stringa(tmp_bere, data_guid) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_get_stringa (data_guid)\n");
rc = -1;
goto free_and_return;
}
/* If a data_guid was specified, data must be specified as well. */
if (ber_peek_tag(tmp_bere, &len) == LBER_OCTETSTRING) {
if (ber_get_stringal(tmp_bere, data) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_get_stringal (data)\n");
rc = -1;
goto free_and_return;
}
} else {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_peek_tag\n");
rc = -1;
goto free_and_return;
}
}
if (ber_scanf(tmp_bere, "}") == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_startrepl_extop",
+ "decoding failed: ber_scanf 2\n");
rc = -1;
goto free_and_return;
}
@@ -378,6 +483,22 @@ free_and_return:
if (*supplier_ruv) {
ruv_destroy(supplier_ruv);
}
+ } else if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "decode_startrepl_extop - decoding payload...\n");
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "decode_startrepl_extop - decoded protocol_oid: %s\n", *protocol_oid);
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "decode_startrepl_extop - decoded repl_root: %s\n", *repl_root);
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "decode_startrepl_extop - decoded csn: %s\n", *csnstr);
+ ruv_dump_to_log(*supplier_ruv, "decode_startrepl_extop");
+ for (size_t i = 0; *extra_referrals && *extra_referrals[i]; i++) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "decode_startrepl_extop - "
+ "decoded referral: %s\n", *extra_referrals[i]);
+ }
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "decode_startrepl_extop - Finshed decoding payload.\n");
}
if (NULL != tmp_bere) {
ber_free(tmp_bere, 1);
@@ -406,30 +527,54 @@ decode_endrepl_extop(Slapi_PBlock *pb, char **repl_root)
if ((NULL == extop_oid) ||
(strcmp(extop_oid, REPL_END_NSDS50_REPLICATION_REQUEST_OID) != 0) ||
- !BV_HAS_DATA(extop_value)) {
+ !BV_HAS_DATA(extop_value))
+ {
/* bogus */
+ slapi_log_err(SLAPI_LOG_ERR, "decode_endrepl_extop",
+ "decoding failed: extop_oid (%s) correct oid (%s) extop_value data (%s)\n",
+ extop_oid ? extop_oid : "NULL",
+ extop_oid ? strcmp(extop_oid, REPL_END_NSDS50_REPLICATION_REQUEST_OID) != 0 ? "wrong oid" : "correct oid" : "NULL",
+ !BV_HAS_DATA(extop_value) ? "No data" : "Has data");
rc = -1;
goto free_and_return;
}
if ((tmp_bere = ber_init(extop_value)) == NULL) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_endrepl_extop",
+ "decoding failed: ber_init failed: extop_value (%s:%lu)\n",
+ extop_value->bv_val, extop_value->bv_len);
rc = -1;
goto free_and_return;
}
if (ber_scanf(tmp_bere, "{") == LBER_DEFAULT) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_endrepl_extop",
+ "decoding failed: ber_scanf failed1\n");
rc = -1;
goto free_and_return;
}
/* Get the required root of replicated subtree */
if (ber_get_stringa(tmp_bere, repl_root) == LBER_DEFAULT) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_endrepl_extop",
+ "decoding failed: ber_get_stringa failed\n");
rc = -1;
goto free_and_return;
}
if (ber_scanf(tmp_bere, "}") == LBER_DEFAULT) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_endrepl_extop",
+ "decoding failed: ber_scanf2 failed\n");
rc = -1;
goto free_and_return;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, "decode_endrepl_extop",
+ "Decoding payload...\n");
+ slapi_log_err(SLAPI_LOG_REPL, "decode_endrepl_extop",
+ "Decoded repl_root: %s\n", *repl_root);
+ slapi_log_err(SLAPI_LOG_REPL, "decode_endrepl_extop",
+ "Finished decoding payload.\n");
+ }
+
free_and_return:
if (NULL != tmp_bere) {
ber_free(tmp_bere, 1);
@@ -461,27 +606,46 @@ decode_repl_ext_response(struct berval *bvdata, int *response_code, struct berva
PR_ASSERT(NULL != ruv_bervals);
if ((NULL == response_code) || (NULL == ruv_bervals) ||
- (NULL == data_guid) || (NULL == data) || !BV_HAS_DATA(bvdata)) {
+ (NULL == data_guid) || (NULL == data) || !BV_HAS_DATA(bvdata))
+ {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_repl_ext_response",
+ "decoding failed: response_code (%s) ruv_bervals (%s) data_guid (%s) data (%s) bvdata (%s)\n",
+ NULL == response_code ? "NULL" : "Ok",
+ NULL == ruv_bervals ? "NULL" : "Ok",
+ NULL == data_guid ? "NULL" : "Ok",
+ NULL == data ? "NULL" : "Ok",
+ !BV_HAS_DATA(bvdata) ? "No data" : "Ok");
return_value = -1;
} else {
ber_len_t len;
ber_int_t temp_response_code = 0;
*ruv_bervals = NULL;
if ((tmp_bere = ber_init(bvdata)) == NULL) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_repl_ext_response",
+ "decoding failed: ber_init failed from bvdata (%s:%lu)\n",
+ bvdata->bv_val, bvdata->bv_len);
return_value = -1;
} else if (ber_scanf(tmp_bere, "{e", &temp_response_code) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_repl_ext_response",
+ "decoding failed: ber_scanf failed\n");
return_value = -1;
} else if (ber_peek_tag(tmp_bere, &len) == LBER_SEQUENCE) {
if (ber_scanf(tmp_bere, "{V}", ruv_bervals) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_repl_ext_response",
+ "decoding failed: ber_scanf2 failed from ruv_bervals\n");
return_value = -1;
}
}
/* Check for optional data from replication session callback */
if (ber_peek_tag(tmp_bere, &len) == LBER_OCTETSTRING) {
if (ber_scanf(tmp_bere, "aO}", data_guid, data) == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_repl_ext_response",
+ "decoding failed: ber_scanf3 failed from data_guid & data\n");
return_value = -1;
}
} else if (ber_scanf(tmp_bere, "}") == LBER_ERROR) {
+ slapi_log_err(SLAPI_LOG_ERR, "decode_repl_ext_response",
+ "decoding failed: ber_scanf4 failed\n");
return_value = -1;
}
@@ -934,17 +1098,36 @@ send_response:
/* ONREPL - not sure what we suppose to do here */
}
ber_printf(resp_bere, "{e", response);
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "multisupplier_extop_StartNSDS50ReplicationRequest - encoded response: %d\n",
+ response);
+ }
if (NULL != ruv_bervals) {
ber_printf(resp_bere, "{V}", ruv_bervals);
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ ruv_dump_to_log(ruv, "multisupplier_extop_StartNSDS50ReplicationRequest");
+ }
}
+
/* Add extra data from replication session callback if necessary */
if (is90 && data_guid && data) {
ber_printf(resp_bere, "sO", data_guid, data);
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "multisupplier_extop_StartNSDS50ReplicationRequest - encoded data_guid (%s) data (%s:%ld)\n",
+ data_guid, data->bv_val, data->bv_len);
+ }
}
ber_printf(resp_bere, "}");
ber_flatten(resp_bere, &resp_bval);
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
+ "multisupplier_extop_StartNSDS50ReplicationRequest - Finished encoding payload\n");
+ }
+
if (is90) {
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_OID, REPL_NSDS90_REPLICATION_RESPONSE_OID);
} else {
@@ -1005,8 +1188,8 @@ send_response:
* sending this request).
* The situation is confused
*/
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
- "already acquired replica: replica not ready (%d) (replica=%s)\n",
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multisupplier_extop_StartNSDS50ReplicationRequest - "
+ "already acquired replica: replica not ready (%d) (replica=%s)\n",
response, replica_get_name(r) ? replica_get_name(r) : "no name");
/*
@@ -1016,8 +1199,8 @@ send_response:
if (r) {
r_locking_conn = replica_get_locking_conn(r);
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
- "already acquired replica: locking_conn=%" PRIu64 ", current connid=%" PRIu64 "\n",
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multisupplier_extop_StartNSDS50ReplicationRequest - "
+ "already acquired replica: locking_conn=%" PRIu64 ", current connid=%" PRIu64 "\n",
r_locking_conn, connid);
if ((r_locking_conn != ULONG_MAX) && (r_locking_conn == connid)) {
@@ -1032,8 +1215,8 @@ send_response:
* On the supplier, we need to close the connection so
* that the RA will restart a new session in a clear state
*/
- slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multimaster_extop_StartNSDS50ReplicationRequest - "
- "already acquired replica: disconnect conn=%" PRIu64 "\n",
+ slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "multisupplier_extop_StartNSDS50ReplicationRequest - "
+ "already acquired replica: disconnect conn=%" PRIu64 "\n",
connid);
slapi_disconnect_server(conn);
}
@@ -1210,6 +1393,10 @@ send_response:
if ((resp_bere = der_alloc()) == NULL) {
goto free_and_return;
}
+ if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+ slapi_log_err(SLAPI_LOG_REPL, "multisupplier_extop_EndNSDS50ReplicationRequest",
+ "encoded response: %d\n", response);
+ }
ber_printf(resp_bere, "{e}", response);
ber_flatten(resp_bere, &resp_bval);
slapi_pblock_set(pb, SLAPI_EXT_OP_RET_OID, REPL_NSDS50_REPLICATION_RESPONSE_OID);
diff --git a/ldap/servers/slapd/slapi2runtime.c b/ldap/servers/slapd/slapi2runtime.c
index 53927934a..e622f1b65 100644
--- a/ldap/servers/slapd/slapi2runtime.c
+++ b/ldap/servers/slapd/slapi2runtime.c
@@ -88,7 +88,6 @@ slapi_lock_mutex(Slapi_Mutex *mutex)
inline int __attribute__((always_inline))
slapi_unlock_mutex(Slapi_Mutex *mutex)
{
- PR_ASSERT(mutex != NULL);
if (mutex == NULL || pthread_mutex_unlock((pthread_mutex_t *)mutex) != 0) {
return (0);
} else {
--
2.37.1

View File

@ -1,88 +0,0 @@
From 6fd4fd082424838f7d06e0de8683d28f04ec0d43 Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Wed, 10 Aug 2022 08:59:15 -0400
Subject: [PATCH 2/4] Issue 5412 - lib389 - do not set backend name to
lowercase
Description:
There is no reason to set a new suffix to lowercase. The server
will correctly handle the case, and some customers, especially
with migrations, want to have the base suffix a certain case.
relates: https://github.com/389ds/389-ds-base/issues/5412
Reviewed by: spichugi(Thanks!)
---
dirsrvtests/tests/suites/basic/basic_test.py | 33 ++++++++++++++++++--
src/lib389/lib389/backend.py | 3 +-
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
index 003cd8f28..6fa4dea25 100644
--- a/dirsrvtests/tests/suites/basic/basic_test.py
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
@@ -22,6 +22,8 @@ from lib389.idm.directorymanager import DirectoryManager
from lib389.config import LDBMConfig
from lib389.dseldif import DSEldif
from lib389.rootdse import RootDSE
+from lib389.backend import Backends
+from lib389.idm.domain import Domain
pytestmark = pytest.mark.tier0
@@ -1410,8 +1412,35 @@ def test_ldbm_modification_audit_log(topology_st):
assert conn.searchAuditLog('%s: %s' % (attr, VALUE))
-@pytest.mark.skipif(not get_user_is_root() or ds_is_older('1.4.0.0'),
- reason="This test is only required if perl is enabled, and requires root.")
+def test_suffix_case(topology_st):
+ """Test that the suffix case is preserved when creating a new backend
+
+ :id: 4eff15be-6cde-4312-b492-c88941876bda
+ :setup: Standalone Instance
+ :steps:
+ 1. Create backend with uppercase characters
+ 2. Create root node entry
+ 3. Search should return suffix with upper case characters
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 3. Success
+ """
+
+ # Start with a clean slate
+ topology_st.standalone.restart()
+
+ TEST_SUFFIX = 'dc=UPPER_CASE'
+
+ backends = Backends(topology_st.standalone)
+ backends.create(properties={'nsslapd-suffix': TEST_SUFFIX,
+ 'name': 'upperCaseRoot',
+ 'sample_entries': '001004002'})
+
+ domain = Domain(topology_st.standalone, TEST_SUFFIX)
+ assert domain.dn == TEST_SUFFIX
+
+
def test_dscreate(request):
"""Test that dscreate works, we need this for now until setup-ds.pl is
fully discontinued.
diff --git a/src/lib389/lib389/backend.py b/src/lib389/lib389/backend.py
index cbd2810e9..24613655d 100644
--- a/src/lib389/lib389/backend.py
+++ b/src/lib389/lib389/backend.py
@@ -608,8 +608,7 @@ class Backend(DSLdapObject):
dn = ",".join(dn_comps)
if properties is not None:
- suffix_dn = properties['nsslapd-suffix'].lower()
- dn_comps = ldap.dn.explode_dn(suffix_dn)
+ dn_comps = ldap.dn.explode_dn(properties['nsslapd-suffix'])
ndn = ",".join(dn_comps)
properties['nsslapd-suffix'] = ndn
sample_entries = properties.pop(BACKEND_SAMPLE_ENTRIES, False)
--
2.37.1

View File

@ -1,110 +0,0 @@
From 48ef747b731b5debfefc20757f3b3775828504c2 Mon Sep 17 00:00:00 2001
From: tbordaz <tbordaz@redhat.com>
Date: Thu, 18 Aug 2022 11:17:30 +0200
Subject: [PATCH 3/4] Issue 5418 - Sync_repl may crash while managing invalid
cookie (#5420)
Bug description:
If the servers receives an invalid cookie without separator '#',
it parses it into an empty cookie (Sync_Cookie) instead of a NULL
cookie (failure).
Later it sigsegv when using the empty cookie.
Fix description:
If the parsing fails return NULL
relates: #5418
Reviewed by: Viktor Ashirov, Mark Reynolds, William Brown, Simon
Pichugin (thanks !)
---
.../suites/syncrepl_plugin/basic_test.py | 76 +++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
index 533460e8f..375517693 100644
--- a/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
+++ b/dirsrvtests/tests/suites/syncrepl_plugin/basic_test.py
@@ -594,3 +594,79 @@ def test_sync_repl_cenotaph(topo_m2, request):
pass
request.addfinalizer(fin)
+
+def test_sync_repl_invalid_cookie(topology, request):
+ """Test sync_repl with invalid cookie
+
+ :id: 8fa4a8f8-acf4-42a5-90f1-6ba1d8080e46
+ :setup: install a standalone instance
+ :steps:
+ 1. reset instance to standard (no retroCL, no sync_repl, no dynamic plugin)
+ 2. Enable retroCL/content_sync
+ 3. Establish a sync_repl connection
+ 4. Tests servers results to search with invalid cookie
+ 5. Add/delete an user entry to check the server is up and running
+ :expectedresults:
+ 1. Should succeeds
+ 2. Should succeeds
+ 3. Should succeeds
+ 4. Should succeeds
+ 5. Should succeeds
+ """
+
+ # Reset the instance in a default config
+ # Disable content sync plugin
+ topology.standalone.restart()
+ topology.standalone.plugins.disable(name=PLUGIN_REPL_SYNC)
+
+ # Disable retro changelog
+ topology.standalone.plugins.disable(name=PLUGIN_RETRO_CHANGELOG)
+
+ # Disable dynamic plugins
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', b'off')])
+ topology.standalone.restart()
+
+ # Enable retro changelog
+ topology.standalone.plugins.enable(name=PLUGIN_RETRO_CHANGELOG)
+
+ # Enbale content sync plugin
+ topology.standalone.plugins.enable(name=PLUGIN_REPL_SYNC)
+ topology.standalone.restart()
+
+ # Setup the syncer
+ sync = ISyncRepl(topology.standalone)
+
+ # Test invalid cookies
+ cookies = ('#', '##', 'a#a#a', 'a#a#1', 'foo')
+ for invalid_cookie in cookies:
+ log.info('Testing cookie: %s' % invalid_cookie)
+ try:
+ ldap_search = sync.syncrepl_search(base=DEFAULT_SUFFIX,
+ scope=ldap.SCOPE_SUBTREE,
+ attrlist=['objectclass', 'cn', 'homedirectory', 'sn','uid'],
+ filterstr='(|(objectClass=groupofnames)(objectClass=person))',
+ mode='refreshOnly',
+ cookie=invalid_cookie)
+ poll_result = sync.syncrepl_poll(all=1)
+
+ log.fatal('Invalid cookie accepted!')
+ assert False
+ except Exception as e:
+ log.info('Invalid cookie correctly rejected: {}'.format(e.args[0]['info']))
+ pass
+
+ # check that the server is still up and running
+ users = UserAccounts(topology.standalone, DEFAULT_SUFFIX)
+ user = users.create_test_user(uid=1000)
+
+ # Success
+ log.info('Test complete')
+
+ def fin():
+ topology.standalone.restart()
+ try:
+ user.delete()
+ except:
+ pass
+
+ request.addfinalizer(fin)
--
2.37.1

537
SOURCES/Cargo.lock generated
View File

@ -2,6 +2,17 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
@ -30,9 +41,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "base64"
version = "0.13.0"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bitflags"
@ -65,9 +76,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.0.73"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
dependencies = [
"jobserver",
]
@ -93,6 +104,90 @@ dependencies = [
"vec_map",
]
[[package]]
name = "concread"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcc9816f5ac93ebd51c37f7f9a6bf2b40dfcd42978ad2aea5d542016e9244cf6"
dependencies = [
"ahash",
"crossbeam",
"crossbeam-epoch",
"crossbeam-utils",
"lru",
"parking_lot",
"rand",
"smallvec",
"tokio",
]
[[package]]
name = "crossbeam"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c"
dependencies = [
"cfg-if",
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-epoch",
"crossbeam-queue",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
dependencies = [
"cfg-if",
]
[[package]]
name = "entryuuid"
version = "0.1.0"
@ -116,10 +211,31 @@ dependencies = [
]
[[package]]
name = "fastrand"
version = "1.7.0"
name = "errno"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
dependencies = [
"errno-dragonfly",
"libc",
"winapi",
]
[[package]]
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "fastrand"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
dependencies = [
"instant",
]
@ -154,15 +270,24 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "getrandom"
version = "0.2.6"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
dependencies = [
"ahash",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -182,31 +307,35 @@ dependencies = [
]
[[package]]
name = "itoa"
version = "1.0.1"
name = "io-lifetimes"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3"
dependencies = [
"libc",
"windows-sys 0.45.0",
]
[[package]]
name = "itoa"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "jobserver"
version = "0.1.24"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.125"
version = "0.2.140"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c"
[[package]]
name = "librnsslapd"
@ -222,10 +351,27 @@ name = "librslapd"
version = "0.1.0"
dependencies = [
"cbindgen",
"concread",
"libc",
"slapd",
]
[[package]]
name = "linux-raw-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
[[package]]
name = "lock_api"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.17"
@ -236,16 +382,34 @@ dependencies = [
]
[[package]]
name = "once_cell"
version = "1.10.0"
name = "lru"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a"
dependencies = [
"hashbrown",
]
[[package]]
name = "memoffset"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "openssl"
version = "0.10.40"
version = "0.10.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e"
checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1"
dependencies = [
"bitflags",
"cfg-if",
@ -269,9 +433,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.73"
version = "0.9.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5fd19fb3e0a8191c1e34935718976a3e70c112ab9a24af6d7cadccd9d90bc0"
checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7"
dependencies = [
"autocfg",
"cc",
@ -280,6 +444,31 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "parking_lot"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
dependencies = [
"cfg-if",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "paste"
version = "0.1.18"
@ -300,51 +489,97 @@ dependencies = [
]
[[package]]
name = "pkg-config"
version = "0.3.25"
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "pkg-config"
version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
version = "0.5.20+deprecated"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]]
name = "proc-macro2"
version = "1.0.38"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
checksum = "1d0e1ae9e836cc3beddd63db0df682593d7e2d3d891ae8c9083d2113e1744224"
dependencies = [
"unicode-xid",
"unicode-ident",
]
[[package]]
name = "pwdchan"
version = "0.1.0"
dependencies = [
"base64",
"cc",
"libc",
"openssl",
"paste",
"slapi_r_plugin",
"uuid",
]
[[package]]
name = "quote"
version = "1.0.18"
version = "1.0.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.2.13"
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"bitflags",
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "remove_dir_all"
version = "0.5.3"
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"winapi",
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "redox_syscall"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
dependencies = [
"bitflags",
]
[[package]]
@ -352,25 +587,45 @@ name = "rsds"
version = "0.1.0"
[[package]]
name = "ryu"
version = "1.0.9"
name = "rustix"
version = "0.36.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc"
dependencies = [
"bitflags",
"errno",
"io-lifetimes",
"libc",
"linux-raw-sys",
"windows-sys 0.45.0",
]
[[package]]
name = "ryu"
version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "serde"
version = "1.0.137"
version = "1.0.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
checksum = "71f2b4817415c6d4210bfe1c7bfcf4801b2d904cb4d0e1a8fdb651013c9e86b8"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.137"
version = "1.0.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
checksum = "d071a94a3fac4aff69d023a7f411e33f40f3483f8c5190b1953822b6b76d7630"
dependencies = [
"proc-macro2",
"quote",
@ -379,9 +634,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.81"
version = "1.0.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
dependencies = [
"itoa",
"ryu",
@ -399,12 +654,17 @@ dependencies = [
name = "slapi_r_plugin"
version = "0.1.0"
dependencies = [
"lazy_static",
"libc",
"paste",
"uuid",
]
[[package]]
name = "smallvec"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
[[package]]
name = "strsim"
version = "0.8.0"
@ -413,13 +673,13 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "syn"
version = "1.0.94"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a07e33e919ebcd69113d5be0e4d70c5707004ff45188910106854f38b960df4a"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
"unicode-ident",
]
[[package]]
@ -436,16 +696,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.3.0"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
dependencies = [
"cfg-if",
"fastrand",
"libc",
"redox_syscall",
"remove_dir_all",
"winapi",
"rustix",
"windows-sys 0.42.0",
]
[[package]]
@ -458,25 +717,54 @@ dependencies = [
]
[[package]]
name = "toml"
version = "0.5.9"
name = "tokio"
version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64"
dependencies = [
"autocfg",
"pin-project-lite",
"tokio-macros",
"windows-sys 0.45.0",
]
[[package]]
name = "tokio-macros"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "toml"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234"
dependencies = [
"serde",
]
[[package]]
name = "unicode-width"
version = "0.1.9"
name = "unicode-ident"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "unicode-xid"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "uuid"
@ -500,10 +788,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
@ -528,19 +822,100 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "zeroize"
version = "1.5.5"
name = "windows-sys"
version = "0.42.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07"
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "zeroize"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f"
dependencies = [
"zeroize_derive",
]
[[package]]
name = "zeroize_derive"
version = "1.3.2"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c"
dependencies = [
"proc-macro2",
"quote",

View File

@ -47,9 +47,9 @@ ExcludeArch: i686
Summary: 389 Directory Server (base)
Name: 389-ds-base
Version: 1.4.3.30
Release: %{?relprefix}6%{?prerel}%{?dist}
License: GPLv3+ and MIT and (ASL 2.0 or MIT) and (ASL 2.0 or Boost) and MPLv2.0 and ASL 2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and (Unlicense or MIT)
Version: 1.4.3.34
Release: %{?relprefix}1%{?prerel}%{?dist}
License: GPLv3+ and (ASL 2.0 or MIT) and MIT and (Unlicense or MIT) and MPLv2.0 and BSD and (ASL 2.0 with exceptions or ASL 2.0 or MIT) and ASL 2.0 and (ASL 2.0 or Boost) and ((MIT or ASL 2.0) and Unicode-DFS-2016)
URL: https://www.port389.org
Group: System Environment/Daemons
Conflicts: selinux-policy-base < 3.9.8
@ -58,68 +58,107 @@ Obsoletes: %{name} <= 1.4.0.9
Provides: ldif2ldbm >= 0
##### Bundled cargo crates list - START #####
Provides: bundled(crate(ahash)) = 0.7.6
Provides: bundled(crate(ansi_term)) = 0.12.1
Provides: bundled(crate(atty)) = 0.2.14
Provides: bundled(crate(autocfg)) = 1.1.0
Provides: bundled(crate(base64)) = 0.13.0
Provides: bundled(crate(base64)) = 0.13.1
Provides: bundled(crate(bitflags)) = 1.3.2
Provides: bundled(crate(byteorder)) = 1.4.3
Provides: bundled(crate(cbindgen)) = 0.9.1
Provides: bundled(crate(cc)) = 1.0.73
Provides: bundled(crate(cc)) = 1.0.79
Provides: bundled(crate(cfg-if)) = 1.0.0
Provides: bundled(crate(clap)) = 2.34.0
Provides: bundled(crate(concread)) = 0.2.21
Provides: bundled(crate(crossbeam)) = 0.8.2
Provides: bundled(crate(crossbeam-channel)) = 0.5.7
Provides: bundled(crate(crossbeam-deque)) = 0.8.3
Provides: bundled(crate(crossbeam-epoch)) = 0.9.14
Provides: bundled(crate(crossbeam-queue)) = 0.3.8
Provides: bundled(crate(crossbeam-utils)) = 0.8.15
Provides: bundled(crate(entryuuid)) = 0.1.0
Provides: bundled(crate(entryuuid_syntax)) = 0.1.0
Provides: bundled(crate(fastrand)) = 1.7.0
Provides: bundled(crate(errno)) = 0.2.8
Provides: bundled(crate(errno-dragonfly)) = 0.1.2
Provides: bundled(crate(fastrand)) = 1.9.0
Provides: bundled(crate(fernet)) = 0.1.4
Provides: bundled(crate(foreign-types)) = 0.3.2
Provides: bundled(crate(foreign-types-shared)) = 0.1.1
Provides: bundled(crate(getrandom)) = 0.2.6
Provides: bundled(crate(getrandom)) = 0.2.8
Provides: bundled(crate(hashbrown)) = 0.12.3
Provides: bundled(crate(hermit-abi)) = 0.1.19
Provides: bundled(crate(instant)) = 0.1.12
Provides: bundled(crate(itoa)) = 1.0.1
Provides: bundled(crate(jobserver)) = 0.1.24
Provides: bundled(crate(lazy_static)) = 1.4.0
Provides: bundled(crate(libc)) = 0.2.125
Provides: bundled(crate(io-lifetimes)) = 1.0.6
Provides: bundled(crate(itoa)) = 1.0.6
Provides: bundled(crate(jobserver)) = 0.1.26
Provides: bundled(crate(libc)) = 0.2.140
Provides: bundled(crate(librnsslapd)) = 0.1.0
Provides: bundled(crate(librslapd)) = 0.1.0
Provides: bundled(crate(linux-raw-sys)) = 0.1.4
Provides: bundled(crate(lock_api)) = 0.4.9
Provides: bundled(crate(log)) = 0.4.17
Provides: bundled(crate(once_cell)) = 1.10.0
Provides: bundled(crate(openssl)) = 0.10.40
Provides: bundled(crate(lru)) = 0.7.8
Provides: bundled(crate(memoffset)) = 0.8.0
Provides: bundled(crate(once_cell)) = 1.17.1
Provides: bundled(crate(openssl)) = 0.10.45
Provides: bundled(crate(openssl-macros)) = 0.1.0
Provides: bundled(crate(openssl-sys)) = 0.9.73
Provides: bundled(crate(openssl-sys)) = 0.9.80
Provides: bundled(crate(parking_lot)) = 0.11.2
Provides: bundled(crate(parking_lot_core)) = 0.8.6
Provides: bundled(crate(paste)) = 0.1.18
Provides: bundled(crate(paste-impl)) = 0.1.18
Provides: bundled(crate(pkg-config)) = 0.3.25
Provides: bundled(crate(proc-macro-hack)) = 0.5.19
Provides: bundled(crate(proc-macro2)) = 1.0.38
Provides: bundled(crate(quote)) = 1.0.18
Provides: bundled(crate(redox_syscall)) = 0.2.13
Provides: bundled(crate(remove_dir_all)) = 0.5.3
Provides: bundled(crate(pin-project-lite)) = 0.2.9
Provides: bundled(crate(pkg-config)) = 0.3.26
Provides: bundled(crate(ppv-lite86)) = 0.2.17
Provides: bundled(crate(proc-macro-hack)) = 0.5.20+deprecated
Provides: bundled(crate(proc-macro2)) = 1.0.52
Provides: bundled(crate(pwdchan)) = 0.1.0
Provides: bundled(crate(quote)) = 1.0.26
Provides: bundled(crate(rand)) = 0.8.5
Provides: bundled(crate(rand_chacha)) = 0.3.1
Provides: bundled(crate(rand_core)) = 0.6.4
Provides: bundled(crate(redox_syscall)) = 0.2.16
Provides: bundled(crate(rsds)) = 0.1.0
Provides: bundled(crate(ryu)) = 1.0.9
Provides: bundled(crate(serde)) = 1.0.137
Provides: bundled(crate(serde_derive)) = 1.0.137
Provides: bundled(crate(serde_json)) = 1.0.81
Provides: bundled(crate(rustix)) = 0.36.9
Provides: bundled(crate(ryu)) = 1.0.13
Provides: bundled(crate(scopeguard)) = 1.1.0
Provides: bundled(crate(serde)) = 1.0.155
Provides: bundled(crate(serde_derive)) = 1.0.155
Provides: bundled(crate(serde_json)) = 1.0.94
Provides: bundled(crate(slapd)) = 0.1.0
Provides: bundled(crate(slapi_r_plugin)) = 0.1.0
Provides: bundled(crate(smallvec)) = 1.10.0
Provides: bundled(crate(strsim)) = 0.8.0
Provides: bundled(crate(syn)) = 1.0.94
Provides: bundled(crate(syn)) = 1.0.109
Provides: bundled(crate(synstructure)) = 0.12.6
Provides: bundled(crate(tempfile)) = 3.3.0
Provides: bundled(crate(tempfile)) = 3.4.0
Provides: bundled(crate(textwrap)) = 0.11.0
Provides: bundled(crate(toml)) = 0.5.9
Provides: bundled(crate(unicode-width)) = 0.1.9
Provides: bundled(crate(unicode-xid)) = 0.2.3
Provides: bundled(crate(tokio)) = 1.26.0
Provides: bundled(crate(tokio-macros)) = 1.8.2
Provides: bundled(crate(toml)) = 0.5.11
Provides: bundled(crate(unicode-ident)) = 1.0.8
Provides: bundled(crate(unicode-width)) = 0.1.10
Provides: bundled(crate(unicode-xid)) = 0.2.4
Provides: bundled(crate(uuid)) = 0.8.2
Provides: bundled(crate(vcpkg)) = 0.2.15
Provides: bundled(crate(vec_map)) = 0.8.2
Provides: bundled(crate(wasi)) = 0.10.2+wasi_snapshot_preview1
Provides: bundled(crate(version_check)) = 0.9.4
Provides: bundled(crate(wasi)) = 0.11.0+wasi_snapshot_preview1
Provides: bundled(crate(winapi)) = 0.3.9
Provides: bundled(crate(winapi-i686-pc-windows-gnu)) = 0.4.0
Provides: bundled(crate(winapi-x86_64-pc-windows-gnu)) = 0.4.0
Provides: bundled(crate(zeroize)) = 1.5.5
Provides: bundled(crate(zeroize_derive)) = 1.3.2
Provides: bundled(crate(windows-sys)) = 0.42.0
Provides: bundled(crate(windows-sys)) = 0.45.0
Provides: bundled(crate(windows-targets)) = 0.42.2
Provides: bundled(crate(windows_aarch64_gnullvm)) = 0.42.2
Provides: bundled(crate(windows_aarch64_msvc)) = 0.42.2
Provides: bundled(crate(windows_i686_gnu)) = 0.42.2
Provides: bundled(crate(windows_i686_msvc)) = 0.42.2
Provides: bundled(crate(windows_x86_64_gnu)) = 0.42.2
Provides: bundled(crate(windows_x86_64_gnullvm)) = 0.42.2
Provides: bundled(crate(windows_x86_64_msvc)) = 0.42.2
Provides: bundled(crate(zeroize)) = 1.5.7
Provides: bundled(crate(zeroize_derive)) = 1.3.3
##### Bundled cargo crates list - END #####
BuildRequires: nspr-devel >= 4.32
@ -183,6 +222,7 @@ BuildRequires: python%{python3_pkgversion}-argcomplete
BuildRequires: python%{python3_pkgversion}-argparse-manpage
BuildRequires: python%{python3_pkgversion}-policycoreutils
BuildRequires: python%{python3_pkgversion}-libselinux
BuildRequires: python%{python3_pkgversion}-cryptography
# For cockpit
BuildRequires: rsync
@ -244,28 +284,10 @@ Source2: %{name}-devel.README
Source3: https://github.com/jemalloc/%{jemalloc_name}/releases/download/%{jemalloc_ver}/%{jemalloc_name}-%{jemalloc_ver}.tar.bz2
%endif
%if %{use_rust}
Source4: vendor-%{version}-1.tar.gz
Source4: vendor-%{version}-2.tar.gz
Source5: Cargo.lock
%endif
Patch01: 0001-Revert-4866-cl-trimming-not-applicable-in-1.4.3.patch
Patch02: 0002-Issue-4877-RFE-EntryUUID-to-validate-UUIDs-on-fixup-.patch
Patch03: 0003-Issue-5126-Memory-leak-in-slapi_ldap_get_lderrno-515.patch
Patch04: 0004-Issue-5085-Race-condition-about-snmp-collator-at-sta.patch
Patch05: 0005-Issue-5079-BUG-multiple-ways-to-specific-primary-508.patch
Patch06: 0006-Issue-3903-Supplier-should-do-periodic-updates.patch
Patch07: 0007-Issue-5399-UI-LDAP-Editor-is-not-updated-when-we-swi.patch
Patch08: 0008-Issue-5397-Fix-various-memory-leaks.patch
Patch09: 0009-Issue-3903-keep-alive-update-event-starts-too-soon.patch
Patch10: 0010-Issue-5397-Fix-check-pick-error.patch
Patch11: 0011-Issue-5397-Fix-check-pick-error-2.patch
Patch12: 0012-Issue-3903-Fix-another-cherry-pick-error.patch
Patch13: 0013-Issue-5329-Improve-replication-extended-op-logging.patch
Patch14: 0014-Issue-5412-lib389-do-not-set-backend-name-to-lowerca.patch
Patch15: 0015-Issue-5418-Sync_repl-may-crash-while-managing-invali.patch
Patch16: 0016-Issue-3903-fix-repl-keep-alive-event-interval.patch
%description
389 Directory Server is an LDAPv3 compliant server. The base package includes
the LDAP server and command line utilities for server administration.
@ -375,6 +397,7 @@ Requires: python%{python3_pkgversion}-libselinux
Requires: python%{python3_pkgversion}-setuptools
Requires: python%{python3_pkgversion}-distro
%{?python_provide:%python_provide python%{python3_pkgversion}-lib389}
Requires: python%{python3_pkgversion}-cryptography
%description -n python%{python3_pkgversion}-lib389
This module contains tools and libraries for accessing, testing,
@ -885,7 +908,11 @@ exit 0
%doc README.md
%changelog
* Thu Aug 18 2022 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.20-6
* Mon Mar 13 2023 Mark Reynolds <mreynolds@rehdat.com> - 1.4.3.34-1
- Bump version to 1.4.3.34-1
- Resolves: Bug 2177234 - pam mutex lock causing high etimes, affecting red hat internal sso
* Thu Aug 18 2022 Mark Reynolds <mreynolds@redhat.com> - 1.4.3.30-6
- Bump version to 1.4.3.30-6
- Resolves: Bug 2113002 - ipa-replica-manage --connect --winsync fails with traceback
- Resolves: Bug 2118763 - SIGSEGV in sync_repl