Compare commits

...
Sign in to create a new pull request.

8 commits

Author SHA1 Message Date
Viktor Ashirov
dcbf6ba789 Update to 3.0.6-2
- Resolves: Issue 6544 - logconv.py: python3-magic conflicts with python3-file-magic
- Resolves: Issue 6374 - nsslapd-mdb-max-dbs autotuning doesn't work properly
- Resolves: Issue 6090 - Fix dbscan options and man pages
- Resolves: Issue 6489 - After log rotation refresh the FD pointer
- Resolves: Issue 6436 - MOD on a large group slow if substring index is present
- Resolves: Issue 6566 - RI plugin failure to handle a modrdn for rename of member of multiple groups
- Resolves: Issue 6229 - After an initial failure, subsequent online backups fail
- Resolves: Issue 6554 - During import of entries without nsUniqueId, a supplier generates duplicate nsUniqueId (LMDB only)
2025-02-14 13:58:03 +01:00
Viktor Ashirov
13f1ad3a14 Update to 3.0.6 2025-01-24 09:27:51 +01:00
Viktor Ashirov
67eabb81a4 Update information about bundled npm and cargo packages 2024-12-16 18:49:48 +01:00
Viktor Ashirov
b68bcd7b25 Update to 3.0.5 2024-12-16 18:38:13 +01:00
Viktor Ashirov
26c233b7c5 Resolves: VLV errors in Fedora 40 with RSNv3 and pruning enabled (rhbz#2317851) 2024-10-15 17:44:15 +02:00
Viktor Ashirov
f0da45153f Replace lmdb with lmdb-libs in Requires 2024-07-30 13:52:47 +02:00
Viktor Ashirov
502e0cf5cb Update to 3.0.4
...
- Resolves: CVE-2024-1062 (rhbz#2261884)
- Resolves: CVE-2024-2199 (rhbz#2283632)
- Resolves: CVE-2024-3657 (rhbz#2283631)
- Resolves: CVE-2024-5953 (rhbz#2292109)
2024-07-30 13:08:01 +02:00
Viktor Ashirov
c68077aecb Convert to %autorelease and %autochangelog
[skip changelog]
2024-07-30 12:44:17 +02:00
19 changed files with 2569 additions and 1087 deletions

1
.fmf/version Normal file
View file

@ -0,0 +1 @@
1

231
.gitignore vendored
View file

@ -1,229 +1,4 @@
*~
/389-ds-base-1.2.7.2.tar.bz2
/389-ds-base-1.2.7.3.tar.bz2
/389-ds-base-1.2.7.4.tar.bz2
/389-ds-base-1.2.7.5.tar.bz2
/389-ds-base-1.2.8.a1.tar.bz2
/389-ds-base-1.2.8.a2.tar.bz2
/389-ds-base-1.2.8.a3.tar.bz2
/389-ds-base-1.2.8.rc1.tar.bz2
/389-ds-base-1.2.8.rc2.tar.bz2
/389-ds-base-1.2.8.rc4.tar.bz2
/389-ds-base-1.2.8.rc5.tar.bz2
/389-ds-base-1.2.8.0.tar.bz2
/389-ds-base-1.2.8.1.tar.bz2
/389-ds-base-1.2.8.2.tar.bz2
/389-ds-base-1.2.8.3.tar.bz2
/389-ds-base-1.2.9.a1.tar.bz2
/389-ds-base-1.2.9.a2.tar.bz2
/389-ds-base-1.2.9.0.tar.bz2
/389-ds-base-1.2.9.1.tar.bz2
/389-ds-base-1.2.9.2.tar.bz2
/389-ds-base-1.2.9.3.tar.bz2
/389-ds-base-1.2.9.4.tar.bz2
/389-ds-base-1.2.9.5.tar.bz2
/389-ds-base-1.2.9.6.tar.bz2
/389-ds-base-1.2.9.7.tar.bz2
/389-ds-base-1.2.9.8.tar.bz2
/389-ds-base-1.2.9.9.tar.bz2
/389-ds-base-1.2.9.10.tar.bz2
/389-ds-base-1.2.10.a1.tar.bz2
/389-ds-base-1.2.10.a2.tar.bz2
/389-ds-base-1.2.10.a3.tar.bz2
/389-ds-base-1.2.10.a4.tar.bz2
/389-ds-base-1.2.10.a5.tar.bz2
/389-ds-base-1.2.10.a6.tar.bz2
/389-ds-base-1.2.10.a7.tar.bz2
/389-ds-base-1.2.10.a8.tar.bz2
/389-ds-base-1.2.10.rc1.tar.bz2
/389-ds-base-1.2.10.0.tar.bz2
/389-ds-base-1.2.10.1.tar.bz2
/389-ds-base-1.2.10.2.tar.bz2
/389-ds-base-1.2.10.3.tar.bz2
/389-ds-base-1.2.10.4.tar.bz2
/389-ds-base-1.2.11.a1.tar.bz2
/389-ds-base-1.2.11.1.tar.bz2
/389-ds-base-1.2.11.2.tar.bz2
/389-ds-base-1.2.11.3.tar.bz2
/389-ds-base-1.2.11.4.tar.bz2
/389-ds-base-1.2.11.5.tar.bz2
/389-ds-base-1.2.11.6.tar.bz2
/389-ds-base-1.2.11.7.tar.bz2
/389-ds-base-1.2.11.8.tar.bz2
/389-ds-base-1.2.11.9.tar.bz2
/389-ds-base-1.2.11.10.tar.bz2
/389-ds-base-1.2.11.11.tar.bz2
/389-ds-base-1.2.11.12.tar.bz2
/389-ds-base-1.2.11.13.tar.bz2
/389-ds-base-1.2.11.14.tar.bz2
/389-ds-base-1.2.11.15.tar.bz2
/389-ds-base-1.3.0.a1.tar.bz2
/389-ds-base-1.3.0.rc1.tar.bz2
/389-ds-base-1.3.0.rc2.tar.bz2
/389-ds-base-1.3.0.rc3.tar.bz2
/389-ds-base-1.3.0.0.tar.bz2
/389-ds-base-1.3.0.1.tar.bz2
/389-ds-base-1.3.0.2.tar.bz2
/389-ds-base-1.3.0.3.tar.bz2
/389-ds-base-1.3.0.4.tar.bz2
/389-ds-base-1.3.0.5.tar.bz2
/389-ds-base-1.3.1.0.tar.bz2
/389-ds-base-1.3.1.1.tar.bz2
/389-ds-base-1.3.1.2.tar.bz2
/389-ds-base-1.3.1.3.tar.bz2
/389-ds-base-1.3.1.4.tar.bz2
/389-ds-base-1.3.1.5.tar.bz2
/389-ds-base-1.3.1.6.tar.bz2
/389-ds-base-1.3.1.7.tar.bz2
/389-ds-base-1.3.1.8.tar.bz2
/389-ds-base-1.3.1.9.tar.bz2
/389-ds-base-1.3.1.10.tar.bz2
/389-ds-base-1.3.1.11.tar.bz2
/389-ds-base-1.3.2.0.tar.bz2
/389-ds-base-1.3.2.1.tar.bz2
/389-ds-base-1.3.2.2.tar.bz2
/389-ds-base-1.3.2.3.tar.bz2
/389-ds-base-1.3.2.4.tar.bz2
/389-ds-base-1.3.2.5.tar.bz2
/389-ds-base-1.3.2.6.tar.bz2
/389-ds-base-1.3.2.7.tar.bz2
/389-ds-base-1.3.2.8.tar.bz2
/389-ds-base-1.3.2.9.tar.bz2
/389-ds-base-1.3.2.10.tar.bz2
/389-ds-base-1.3.2.11.tar.bz2
/389-ds-base-1.3.2.12.tar.bz2
/389-ds-base-1.3.2.13.tar.bz2
/389-ds-base-1.3.2.14.tar.bz2
/389-ds-base-1.3.2.15.tar.bz2
/389-ds-base-1.3.2.16.tar.bz2
/389-ds-base-1.3.2.17.tar.bz2
/389-ds-base-1.3.2.18.tar.bz2
/389-ds-base-1.3.2.19.tar.bz2
/389-ds-base-1.3.2.20.tar.bz2
/389-ds-base-1.3.2.21.tar.bz2
/389-ds-base-1.3.2.22.tar.bz2
/389-ds-base-1.3.2.23.tar.bz2
/389-ds-base-1.3.3.0.tar.bz2
/389-ds-base-1.3.3.2.tar.bz2
/389-ds-base-1.3.3.3.tar.bz2
/389-ds-base-1.3.3.4.tar.bz2
/389-ds-base-1.3.3.5.tar.bz2
/389-ds-base-1.3.3.6.tar.bz2
/389-ds-base-1.3.3.7.tar.bz2
/389-ds-base-1.3.3.8.tar.bz2
/389-ds-base-1.3.3.9.tar.bz2
/389-ds-base-1.3.3.10.tar.bz2
/389-ds-base-1.3.3.11.tar.bz2
/389-ds-base-1.3.3.12.tar.bz2
/389-ds-base-1.3.4.0.tar.bz2
/nunc-stans-0.1.3.tar.bz2
/nunc-stans-0.1.4.tar.bz2
/389-ds-base-1.3.4.1.tar.bz2
/nunc-stans-0.1.5.tar.bz2
/389-ds-base-1.3.4.2.tar.bz2
/389-ds-base-1.3.4.3.tar.bz2
/389-ds-base-1.3.4.4.tar.bz2
/389-ds-base-1.3.4.5.tar.bz2
/389-ds-base-1.3.4.6.tar.bz2
/389-ds-base-1.3.4.7.tar.bz2
/389-ds-base-1.3.4.8.tar.bz2
/389-ds-base-1.3.5.0.tar.bz2
/nunc-stans-0.1.8.tar.bz2
/389-ds-base-1.3.5.1.tar.bz2
/389-ds-base-1.3.5.3.tar.bz2
/389-ds-base-1.3.5.4.tar.bz2
/389-ds-base-1.3.5.5.tar.bz2
/389-ds-base-1.3.5.6.tar.bz2
/389-ds-base-1.3.5.10.tar.bz2
/389-ds-base-1.3.5.11.tar.bz2
/389-ds-base-1.3.5.12.tar.bz2
/389-ds-base-1.3.5.13.tar.bz2
/389-ds-base-1.3.5.14.tar.bz2
/nunc-stans-0.2.0.tar.bz2
/389-ds-base-1.3.6.1.tar.bz2
/389-ds-base-1.3.6.2.tar.bz2
/389-ds-base-1.3.6.3.tar.bz2
/389-ds-base-1.3.6.4.tar.bz2
/389-ds-base-1.3.6.5.tar.bz2
/389-ds-base-1.3.6.6.tar.bz2
/389-ds-base-1.3.7.1.tar.bz2
/389-ds-base-1.3.7.2.tar.bz2
/389-ds-base-1.3.7.3.tar.bz2
/389-ds-base-1.3.7.4.tar.bz2
/389-ds-base-1.4.0.0.tar.bz2
/389-ds-base-1.4.0.1.tar.bz2
/389-ds-base-1.4.0.2.tar.bz2
/389-ds-base-1.4.0.3.tar.bz2
/389-ds-base-1.4.0.4.tar.bz2
/389-ds-base-1.4.0.5.tar.bz2
/389-ds-base-1.4.0.6.tar.bz2
/389-ds-base-1.4.0.7.tar.bz2
/389-ds-base-1.4.0.8.tar.bz2
/389-ds-base-1.4.0.9.tar.bz2
/389-ds-base-1.4.0.10.tar.bz2
/jemalloc-5.0.1.tar.bz2
/389-ds-base-1.4.0.11.tar.bz2
/jemalloc-5.1.0.tar.bz2
/389-ds-base-1.4.0.12.tar.bz2
/389-ds-base-1.4.0.13.tar.bz2
/389-ds-base-1.4.0.14.tar.bz2
/389-ds-base-1.4.0.15.tar.bz2
/389-ds-base-1.4.0.16.tar.bz2
/389-ds-base-1.4.0.17.tar.bz2
/389-ds-base-1.4.0.18.tar.bz2
/389-ds-base-1.4.0.19.tar.bz2
/389-ds-base-1.4.0.20.tar.bz2
/389-ds-base-1.4.1.1.tar.bz2
/389-ds-base-1.4.1.2.tar.bz2
/389-ds-base-1.4.1.3.tar.bz2
/389-ds-base-1.4.1.4.tar.bz2
/389-ds-base-1.4.1.5.tar.bz2
/jemalloc-5.2.0.tar.bz2
/389-ds-base-1.4.1.6.tar.bz2
/389-ds-base-1.4.2.1.tar.bz2
/389-ds-base-1.4.2.2.tar.bz2
/389-ds-base-1.4.2.3.tar.bz2
/389-ds-base-1.4.2.4.tar.bz2
/389-ds-base-1.4.2.5.tar.bz2
/389-ds-base-1.4.3.1.tar.bz2
/jemalloc-5.2.1.tar.bz2
/389-ds-base-1.4.3.2.tar.bz2
/389-ds-base-1.4.3.3.tar.bz2
/389-ds-base-1.4.3.4.tar.bz2
/389-ds-base-1.4.3.5.tar.bz2
/389-ds-base-1.4.4.0.tar.bz2
/389-ds-base-1.4.4.1.tar.bz2
/389-ds-base-1.4.4.2.tar.bz2
/389-ds-base-1.4.4.3.tar.bz2
/389-ds-base-1.4.4.4.tar.bz2
/389-ds-base-1.4.4.6.tar.bz2
/389-ds-base-1.4.5.0.tar.bz2
/389-ds-base-2.0.1.tar.bz2
/389-ds-base-2.0.2.tar.bz2
/389-ds-base-2.0.3.tar.bz2
/389-ds-base-2.0.4.tar.bz2
/389-ds-base-2.0.4.3.tar.bz2
/389-ds-base-2.0.5.tar.bz2
/389-ds-base-2.0.6.tar.bz2
/389-ds-base-2.0.7.tar.bz2
/389-ds-base-2.0.10.tar.bz2
/389-ds-base-2.0.11.tar.bz2
/389-ds-base-2.0.12.tar.bz2
/389-ds-base-2.0.13.tar.bz2
/389-ds-base-2.1.0.tar.bz2
/389-ds-base-2.2.0.tar.bz2
/389-ds-base-2.1.1.tar.bz2
/jemalloc-5.3.0.tar.bz2
/389-ds-base-2.2.1.tar.bz2
/389-ds-base-2.2.2.tar.bz2
/389-ds-base-2.3.0.tar.bz2
/389-ds-base-2.3.1.tar.bz2
/389-ds-base-2.3.2.tar.bz2
/389-ds-base-2.4.0.tar.bz2
/389-ds-base-2.4.1.tar.bz2
/389-ds-base-2.4.2.tar.bz2
/389-ds-base-2.4.3.tar.bz2
/389-ds-base-2.4.4.tar.bz2
/389-ds-base-2.4.5.tar.bz2
/389-ds-base-3.0.1.tar.bz2
/389-ds-base-3.0.2.tar.bz2
/389-ds-base-*.tar.bz2
/jemalloc-*.tar.bz2
/libdb-5.3.28-59.tar.bz2

View file

@ -0,0 +1,53 @@
From fc7f5aa01e245c7c2e35b01d171dbd5a6dc75db4 Mon Sep 17 00:00:00 2001
From: Viktor Ashirov <vashirov@redhat.com>
Date: Sat, 25 Jan 2025 13:54:33 +0100
Subject: [PATCH] Issue 6544 - logconv.py: python3-magic conflicts with
python3-file-magic
Bug Description:
python3-magic and python3-file-magic can't be installed simultaneously,
python3-magic is not packaged for EL10.
Fix Description:
Use python3-file-magic instead.
Issue identified and fix suggested by Adam Williamson.
Fixes: https://github.com/389ds/389-ds-base/issues/6544
Reviewed by: @mreynolds389 (Thanks!)
---
ldap/admin/src/logconv.py | 3 +--
rpm/389-ds-base.spec.in | 2 +-
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/ldap/admin/src/logconv.py b/ldap/admin/src/logconv.py
index 566f9af38..2fb5bb8c1 100755
--- a/ldap/admin/src/logconv.py
+++ b/ldap/admin/src/logconv.py
@@ -1798,8 +1798,7 @@ class logAnalyser:
return None
try:
- mime = magic.Magic(mime=True)
- filetype = mime.from_file(filepath)
+ filetype = magic.detect_from_filename(filepath).mime_type
# List of supported compression types
compressed_mime_types = [
diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in
index 3146b9186..3c6e95938 100644
--- a/rpm/389-ds-base.spec.in
+++ b/rpm/389-ds-base.spec.in
@@ -298,7 +298,7 @@ Requires: json-c
# Log compression
Requires: zlib-devel
# logconv.py, MIME type
-Requires: python-magic
+Requires: python3-file-magic
# Picks up our systemd deps.
%{?systemd_requires}
--
2.48.0

View file

@ -0,0 +1,311 @@
From 1aabba9b17f99eb1a460be3305aad4b7099b9fe6 Mon Sep 17 00:00:00 2001
From: progier389 <progier@redhat.com>
Date: Wed, 13 Nov 2024 15:31:35 +0100
Subject: [PATCH] Issue 6374 - nsslapd-mdb-max-dbs autotuning doesn't work
properly (#6400)
* Issue 6374 - nsslapd-mdb-max-dbs autotuning doesn't work properly
Several issues:
After restarting the server nsslapd-mdb-max-dbs may not be high enough to add a new backend
because the value computation is wrong.
dbscan fails to open the database if nsslapd-mdb-max-dbs has been increased.
dbscan crashes when closing the database (typically when using -S)
When starting the instance the nsslapd-mdb-max-dbs parameter is increased to ensure that a new backend may be added.
When dse.ldif path is not specified, the db environment is now open using the INFO.mdb data instead of using the default values.
synchronization between thread closure and database context destruction is hardened
Issue: #6374
Reviewed by: @tbordaz , @vashirov (Thanks!)
(cherry picked from commit 56cd3389da608a3f6eeee58d20dffbcd286a8033)
---
.../tests/suites/config/config_test.py | 86 +++++++++++++++++++
ldap/servers/slapd/back-ldbm/back-ldbm.h | 2 +
.../slapd/back-ldbm/db-mdb/mdb_config.c | 17 ++--
.../back-ldbm/db-mdb/mdb_import_threads.c | 9 +-
.../slapd/back-ldbm/db-mdb/mdb_instance.c | 8 ++
ldap/servers/slapd/back-ldbm/dbimpl.c | 2 +-
ldap/servers/slapd/back-ldbm/import.c | 14 ++-
7 files changed, 128 insertions(+), 10 deletions(-)
diff --git a/dirsrvtests/tests/suites/config/config_test.py b/dirsrvtests/tests/suites/config/config_test.py
index c3e26eed4..08544594f 100644
--- a/dirsrvtests/tests/suites/config/config_test.py
+++ b/dirsrvtests/tests/suites/config/config_test.py
@@ -17,6 +17,7 @@ from lib389.topologies import topology_m2, topology_st as topo
from lib389.utils import *
from lib389._constants import DN_CONFIG, DEFAULT_SUFFIX, DEFAULT_BENAME
from lib389._mapped_object import DSLdapObjects
+from lib389.agreement import Agreements
from lib389.cli_base import FakeArgs
from lib389.cli_conf.backend import db_config_set
from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
@@ -27,6 +28,8 @@ from lib389.cos import CosPointerDefinitions, CosTemplates
from lib389.backend import Backends, DatabaseConfig
from lib389.monitor import MonitorLDBM, Monitor
from lib389.plugins import ReferentialIntegrityPlugin
+from lib389.replica import BootstrapReplicationManager, Replicas
+from lib389.passwd import password_generate
pytestmark = pytest.mark.tier0
@@ -36,6 +39,8 @@ PSTACK_CMD = '/usr/bin/pstack'
logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+
@pytest.fixture(scope="module")
def big_file():
TEMP_BIG_FILE = ''
@@ -813,6 +818,87 @@ def test_numlisteners_limit(topo):
assert numlisteners[0] == '4'
+def bootstrap_replication(inst_from, inst_to, creds):
+ manager = BootstrapReplicationManager(inst_to)
+ rdn_val = 'replication manager'
+ if manager.exists():
+ manager.delete()
+ manager.create(properties={
+ 'cn': rdn_val,
+ 'uid': rdn_val,
+ 'userPassword': creds
+ })
+ for replica in Replicas(inst_to).list():
+ replica.remove_all('nsDS5ReplicaBindDNGroup')
+ replica.replace('nsDS5ReplicaBindDN', manager.dn)
+ for agmt in Agreements(inst_from).list():
+ agmt.replace('nsDS5ReplicaBindDN', manager.dn)
+ agmt.replace('nsDS5ReplicaCredentials', creds)
+
+
+@pytest.mark.skipif(get_default_db_lib() != "mdb", reason="This test requires lmdb")
+def test_lmdb_autotuned_maxdbs(topology_m2, request):
+ """Verify that after restart, nsslapd-mdb-max-dbs is large enough to add a new backend.
+
+ :id: 0272d432-9080-11ef-8f40-482ae39447e5
+ :setup: Two suppliers configuration
+ :steps:
+ 1. loop 20 times
+ 3. In 1 loop: restart instance
+ 3. In 1 loop: add a new backend
+ 4. In 1 loop: check that instance is still alive
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 3. Success
+ 4. Success
+ """
+
+ s1 = topology_m2.ms["supplier1"]
+ s2 = topology_m2.ms["supplier2"]
+
+ backends = Backends(s1)
+ db_config = DatabaseConfig(s1)
+ # Generate the teardown finalizer
+ belist = []
+ creds=password_generate()
+ bootstrap_replication(s2, s1, creds)
+ bootstrap_replication(s1, s2, creds)
+
+ def fin():
+ s1.start()
+ for be in belist:
+ be.delete()
+
+ if not DEBUGGING:
+ request.addfinalizer(fin)
+
+ # 1. Set autotuning (off-line to be able to decrease the value)
+ s1.stop()
+ dse_ldif = DSEldif(s1)
+ dse_ldif.replace(db_config.dn, 'nsslapd-mdb-max-dbs', '0')
+ os.remove(f'{s1.dbdir}/data.mdb')
+ s1.start()
+
+ # 2. Reinitialize the db:
+ log.info("Bulk import...")
+ agmt = Agreements(s2).list()[0]
+ agmt.begin_reinit()
+ (done, error) = agmt.wait_reinit()
+ log.info(f'Bulk importresult is ({done}, {error})')
+ assert done is True
+ assert error is False
+
+ # 3. loop 20 times
+ for idx in range(20):
+ s1.restart()
+ log.info(f'Adding backend test{idx}')
+ belist.append(backends.create(properties={'cn': f'test{idx}',
+ 'nsslapd-suffix': f'dc=test{idx}'}))
+ assert s1.status()
+
+
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h
index 8fea63e35..35d0ece04 100644
--- a/ldap/servers/slapd/back-ldbm/back-ldbm.h
+++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h
@@ -896,4 +896,6 @@ typedef struct _back_search_result_set
((L)->size == (R)->size && !memcmp((L)->data, (R)->data, (L)->size))
typedef int backend_implement_init_fn(struct ldbminfo *li, config_info *config_array);
+
+pthread_mutex_t *get_import_ctx_mutex();
#endif /* _back_ldbm_h_ */
diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c
index 351f54037..1f7b71442 100644
--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c
+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_config.c
@@ -83,7 +83,7 @@ dbmdb_compute_limits(struct ldbminfo *li)
uint64_t total_space = 0;
uint64_t avail_space = 0;
uint64_t cur_dbsize = 0;
- int nbchangelogs = 0;
+ int nbvlvs = 0;
int nbsuffixes = 0;
int nbindexes = 0;
int nbagmt = 0;
@@ -99,8 +99,8 @@ dbmdb_compute_limits(struct ldbminfo *li)
* But some tunable may be autotuned.
*/
if (dbmdb_count_config_entries("(objectClass=nsMappingTree)", &nbsuffixes) ||
- dbmdb_count_config_entries("(objectClass=nsIndex)", &nbsuffixes) ||
- dbmdb_count_config_entries("(&(objectClass=nsds5Replica)(nsDS5Flags=1))", &nbchangelogs) ||
+ dbmdb_count_config_entries("(objectClass=nsIndex)", &nbindexes) ||
+ dbmdb_count_config_entries("(objectClass=vlvIndex)", &nbvlvs) ||
dbmdb_count_config_entries("(objectClass=nsds5replicationagreement)", &nbagmt)) {
/* error message is already logged */
return 1;
@@ -120,8 +120,15 @@ dbmdb_compute_limits(struct ldbminfo *li)
info->pagesize = sysconf(_SC_PAGE_SIZE);
limits->min_readers = config_get_threadnumber() + nbagmt + DBMDB_READERS_MARGIN;
- /* Default indexes are counted in "nbindexes" so we should always have enough resource to add 1 new suffix */
- limits->min_dbs = nbsuffixes + nbindexes + nbchangelogs + DBMDB_DBS_MARGIN;
+ /*
+ * For each suffix there are 4 databases instances:
+ * long-entryrdn, replication_changelog, id2entry and ancestorid
+ * then the indexes and the vlv and vlv cache
+ *
+ * Default indexes are counted in "nbindexes" so we should always have enough
+ * resource to add 1 new suffix
+ */
+ limits->min_dbs = 4*nbsuffixes + nbindexes + 2*nbvlvs + DBMDB_DBS_MARGIN;
total_space = ((uint64_t)(buf.f_blocks)) * ((uint64_t)(buf.f_bsize));
avail_space = ((uint64_t)(buf.f_bavail)) * ((uint64_t)(buf.f_bsize));
diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
index 8c879da31..707a110c5 100644
--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
@@ -4312,9 +4312,12 @@ dbmdb_import_init_writer(ImportJob *job, ImportRole_t role)
void
dbmdb_free_import_ctx(ImportJob *job)
{
- if (job->writer_ctx) {
- ImportCtx_t *ctx = job->writer_ctx;
- job->writer_ctx = NULL;
+ ImportCtx_t *ctx = NULL;
+ pthread_mutex_lock(get_import_ctx_mutex());
+ ctx = job->writer_ctx;
+ job->writer_ctx = NULL;
+ pthread_mutex_unlock(get_import_ctx_mutex());
+ if (ctx) {
pthread_mutex_destroy(&ctx->workerq.mutex);
pthread_cond_destroy(&ctx->workerq.cv);
slapi_ch_free((void**)&ctx->workerq.slots);
diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_instance.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_instance.c
index 6386ecf06..05f1e348d 100644
--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_instance.c
+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_instance.c
@@ -287,6 +287,13 @@ int add_dbi(dbi_open_ctx_t *octx, backend *be, const char *fname, int flags)
slapi_ch_free((void**)&treekey.dbname);
return octx->rc;
}
+ if (treekey.dbi >= ctx->dsecfg.max_dbs) {
+ octx->rc = MDB_DBS_FULL;
+ slapi_log_err(SLAPI_LOG_ERR, "add_dbi", "Failed to open database instance %s slots: %d/%d. Error is %d: %s.\n",
+ treekey.dbname, treekey.dbi, ctx->dsecfg.max_dbs, octx->rc, mdb_strerror(octx->rc));
+ slapi_ch_free((void**)&treekey.dbname);
+ return octx->rc;
+ }
if (octx->ai && octx->ai->ai_key_cmp_fn) {
octx->rc = dbmdb_update_dbi_cmp_fn(ctx, &treekey, octx->ai->ai_key_cmp_fn, octx->txn);
if (octx->rc) {
@@ -689,6 +696,7 @@ int dbmdb_make_env(dbmdb_ctx_t *ctx, int readOnly, mdb_mode_t mode)
rc = dbmdb_write_infofile(ctx);
} else {
/* No Config ==> read it from info file */
+ ctx->dsecfg = ctx->startcfg;
}
if (rc) {
return rc;
diff --git a/ldap/servers/slapd/back-ldbm/dbimpl.c b/ldap/servers/slapd/back-ldbm/dbimpl.c
index 86df986bd..f3bf68a9f 100644
--- a/ldap/servers/slapd/back-ldbm/dbimpl.c
+++ b/ldap/servers/slapd/back-ldbm/dbimpl.c
@@ -505,7 +505,7 @@ int dblayer_show_statistics(const char *dbimpl_name, const char *dbhome, FILE *f
li->li_plugin = be->be_database;
li->li_plugin->plg_name = (char*) "back-ldbm-dbimpl";
li->li_plugin->plg_libpath = (char*) "libback-ldbm";
- li->li_directory = (char*)dbhome;
+ li->li_directory = get_li_directory(dbhome);
/* Initialize database plugin */
rc = dbimpl_setup(li, dbimpl_name);
diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c
index 2bb8cb581..30ec462fa 100644
--- a/ldap/servers/slapd/back-ldbm/import.c
+++ b/ldap/servers/slapd/back-ldbm/import.c
@@ -27,6 +27,9 @@
#define NEED_DN_NORM_SP -25
#define NEED_DN_NORM_BT -26
+/* Protect against import context destruction */
+static pthread_mutex_t import_ctx_mutex = PTHREAD_MUTEX_INITIALIZER;
+
/********** routines to manipulate the entry fifo **********/
@@ -143,6 +146,14 @@ ldbm_back_wire_import(Slapi_PBlock *pb)
/* Threads management */
+/* Return the mutex that protects against import context destruction */
+pthread_mutex_t *
+get_import_ctx_mutex()
+{
+ return &import_ctx_mutex;
+}
+
+
/* tell all the threads to abort */
void
import_abort_all(ImportJob *job, int wait_for_them)
@@ -151,7 +162,7 @@ import_abort_all(ImportJob *job, int wait_for_them)
/* tell all the worker threads to abort */
job->flags |= FLAG_ABORT;
-
+ pthread_mutex_lock(&import_ctx_mutex);
for (worker = job->worker_list; worker; worker = worker->next)
worker->command = ABORT;
@@ -167,6 +178,7 @@ import_abort_all(ImportJob *job, int wait_for_them)
}
}
}
+ pthread_mutex_unlock(&import_ctx_mutex);
}
--
2.48.0

View file

@ -0,0 +1,72 @@
From 6b80ba631161219093267e8e4c885bfc392d3d61 Mon Sep 17 00:00:00 2001
From: progier389 <progier@redhat.com>
Date: Fri, 6 Sep 2024 14:45:06 +0200
Subject: [PATCH] Issue 6090 - Fix dbscan options and man pages (#6315)
* Issue 6090 - Fix dbscan options and man pages
dbscan -d option is dangerously confusing as it removes a database instance while in db_stat it identify the database
(cf issue #5609 ).
This fix implements long options in dbscan, rename -d in --remove, and requires a new --do-it option for action that change the database content.
The fix should also align both the usage and the dbscan man page with the new set of options
Issue: #6090
Reviewed by: @tbordaz, @droideck (Thanks!)
(cherry picked from commit 25e1d16887ebd299dfe0088080b9ee0deec1e41f)
---
ldap/servers/slapd/back-ldbm/dbimpl.c | 5 ++++-
src/lib389/lib389/cli_ctl/dblib.py | 13 ++++++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/ldap/servers/slapd/back-ldbm/dbimpl.c b/ldap/servers/slapd/back-ldbm/dbimpl.c
index f3bf68a9f..83662df8c 100644
--- a/ldap/servers/slapd/back-ldbm/dbimpl.c
+++ b/ldap/servers/slapd/back-ldbm/dbimpl.c
@@ -481,7 +481,10 @@ int dblayer_private_close(Slapi_Backend **be, dbi_env_t **env, dbi_db_t **db)
slapi_ch_free_string(&li->li_directory);
slapi_ch_free((void**)&li->li_dblayer_private);
slapi_ch_free((void**)&li->li_dblayer_config);
- ldbm_config_destroy(li);
+ if (dblayer_is_lmdb(*be)) {
+ /* Generate use after free and double free in bdb case */
+ ldbm_config_destroy(li);
+ }
slapi_ch_free((void**)&(*be)->be_database);
slapi_ch_free((void**)&(*be)->be_instance_info);
slapi_ch_free((void**)be);
diff --git a/src/lib389/lib389/cli_ctl/dblib.py b/src/lib389/lib389/cli_ctl/dblib.py
index 053a72d61..318ae5ae9 100644
--- a/src/lib389/lib389/cli_ctl/dblib.py
+++ b/src/lib389/lib389/cli_ctl/dblib.py
@@ -199,6 +199,14 @@ def run_dbscan(args):
return output
+def does_dbscan_need_do_it():
+ prefix = os.environ.get('PREFIX', "")
+ prog = f'{prefix}/bin/dbscan'
+ args = [ prog, '-h' ]
+ output = subprocess.run(args, encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ return '--do-it' in output.stdout
+
+
def export_changelog(be, dblib):
# Export backend changelog
if not be['has_changelog']:
@@ -217,7 +225,10 @@ def import_changelog(be, dblib):
try:
cl5dbname = be['eccl5dbname'] if dblib == "bdb" else be['cl5dbname']
_log.info(f"Importing changelog {cl5dbname} from {be['cl5name']}")
- run_dbscan(['-D', dblib, '-f', cl5dbname, '--import', be['cl5name'], '--do-it'])
+ if does_dbscan_need_do_it():
+ run_dbscan(['-D', dblib, '-f', cl5dbname, '-I', be['cl5name'], '--do-it'])
+ else:
+ run_dbscan(['-D', dblib, '-f', cl5dbname, '-I', be['cl5name']])
return True
except subprocess.CalledProcessError as e:
return False
--
2.48.0

View file

@ -0,0 +1,146 @@
From dc8032856d51c382e266eea72f66284e70a0e40c Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Fri, 31 Jan 2025 08:54:27 -0500
Subject: [PATCH] Issue 6489 - After log rotation refresh the FD pointer
Description:
When flushing a log buffer we get a FD for log prior to checking if the
log should be rotated. If the log is rotated that FD reference is now
invalid, and it needs to be refrehed before proceeding
Relates: https://github.com/389ds/389-ds-base/issues/6489
Reviewed by: tbordaz(Thanks!)
---
.../suites/logging/log_flush_rotation_test.py | 81 +++++++++++++++++++
ldap/servers/slapd/log.c | 18 +++++
2 files changed, 99 insertions(+)
create mode 100644 dirsrvtests/tests/suites/logging/log_flush_rotation_test.py
diff --git a/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py b/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py
new file mode 100644
index 000000000..b33a622e1
--- /dev/null
+++ b/dirsrvtests/tests/suites/logging/log_flush_rotation_test.py
@@ -0,0 +1,81 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2025 Red Hat, Inc.
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import os
+import logging
+import time
+import pytest
+from lib389._constants import DEFAULT_SUFFIX, PW_DM
+from lib389.tasks import ImportTask
+from lib389.idm.user import UserAccounts
+from lib389.topologies import topology_st as topo
+
+
+log = logging.getLogger(__name__)
+
+
+def test_log_flush_and_rotation_crash(topo):
+ """Make sure server does not crash whening flushing a buffer and rotating
+ the log at the same time
+
+ :id: d4b0af2f-48b2-45f5-ae8b-f06f692c3133
+ :setup: Standalone Instance
+ :steps:
+ 1. Enable all logs
+ 2. Enable log buffering for all logs
+ 3. Set rotation time unit to 1 minute
+ 4. Make sure server is still running after 1 minute
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 3. Success
+ 4. Success
+ """
+
+ inst = topo.standalone
+
+ # Enable logging and buffering
+ inst.config.set("nsslapd-auditlog-logging-enabled", "on")
+ inst.config.set("nsslapd-accesslog-logbuffering", "on")
+ inst.config.set("nsslapd-auditlog-logbuffering", "on")
+ inst.config.set("nsslapd-errorlog-logbuffering", "on")
+ inst.config.set("nsslapd-securitylog-logbuffering", "on")
+
+ # Set rotation policy to trigger rotation asap
+ inst.config.set("nsslapd-accesslog-logrotationtimeunit", "minute")
+ inst.config.set("nsslapd-auditlog-logrotationtimeunit", "minute")
+ inst.config.set("nsslapd-errorlog-logrotationtimeunit", "minute")
+ inst.config.set("nsslapd-securitylog-logrotationtimeunit", "minute")
+
+ #
+ # Performs ops to populate all the logs
+ #
+ # Access & audit log
+ users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
+ user = users.create_test_user()
+ user.set("userPassword", PW_DM)
+ # Security log
+ user.bind(PW_DM)
+ # Error log
+ import_task = ImportTask(inst)
+ import_task.import_suffix_from_ldif(ldiffile="/not/here",
+ suffix=DEFAULT_SUFFIX)
+
+ # Wait a minute and make sure the server did not crash
+ log.info("Sleep until logs are flushed and rotated")
+ time.sleep(61)
+
+ assert inst.status()
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main(["-s", CURRENT_FILE])
+
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
index 76f2b6768..7e2c980a4 100644
--- a/ldap/servers/slapd/log.c
+++ b/ldap/servers/slapd/log.c
@@ -6746,6 +6746,23 @@ log_refresh_state(int32_t log_type)
return 0;
}
}
+static LOGFD
+log_refresh_fd(int32_t log_type)
+{
+ switch (log_type) {
+ case SLAPD_ACCESS_LOG:
+ return loginfo.log_access_fdes;
+ case SLAPD_SECURITY_LOG:
+ return loginfo.log_security_fdes;
+ case SLAPD_AUDIT_LOG:
+ return loginfo.log_audit_fdes;
+ case SLAPD_AUDITFAIL_LOG:
+ return loginfo.log_auditfail_fdes;
+ case SLAPD_ERROR_LOG:
+ return loginfo.log_error_fdes;
+ }
+ return NULL;
+}
/* this function assumes the lock is already acquired */
/* if sync_now is non-zero, data is flushed to physical storage */
@@ -6857,6 +6874,7 @@ log_flush_buffer(LogBufferInfo *lbi, int log_type, int sync_now, int locked)
rotationtime_secs);
}
log_state = log_refresh_state(log_type);
+ fd = log_refresh_fd(log_type);
}
if (log_state & LOGGING_NEED_TITLE) {
--
2.48.0

View file

@ -0,0 +1,236 @@
From 90460bfa66fb77118967927963572f69e097c4eb Mon Sep 17 00:00:00 2001
From: James Chapman <jachapma@redhat.com>
Date: Wed, 29 Jan 2025 17:41:55 +0000
Subject: [PATCH] Issue 6436 - MOD on a large group slow if substring index is
present (#6437)
Bug Description: If the substring index is configured for the group
membership attribute ( member or uniqueMember ), the removal of a
member from a large static group is pretty slow.
Fix Description: A solution to this issue would be to introduce
a new index to track a membership atttribute index. In the interm,
we add a check to healthcheck to inform the user of the implications
of this configuration.
Fixes: https://github.com/389ds/389-ds-base/issues/6436
Reviewed by: @Firstyear, @tbordaz, @droideck (Thanks)
---
.../suites/healthcheck/health_config_test.py | 89 ++++++++++++++++++-
src/lib389/lib389/lint.py | 15 ++++
src/lib389/lib389/plugins.py | 37 +++++++-
3 files changed, 137 insertions(+), 4 deletions(-)
diff --git a/dirsrvtests/tests/suites/healthcheck/health_config_test.py b/dirsrvtests/tests/suites/healthcheck/health_config_test.py
index e1e5398ab..f09bc8bb8 100644
--- a/dirsrvtests/tests/suites/healthcheck/health_config_test.py
+++ b/dirsrvtests/tests/suites/healthcheck/health_config_test.py
@@ -167,6 +167,7 @@ def test_healthcheck_RI_plugin_missing_indexes(topology_st):
MEMBER_DN = 'cn=member,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config'
standalone = topology_st.standalone
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
log.info('Enable RI plugin')
plugin = ReferentialIntegrityPlugin(standalone)
@@ -188,7 +189,7 @@ def test_healthcheck_RI_plugin_missing_indexes(topology_st):
def test_healthcheck_MO_plugin_missing_indexes(topology_st):
- """Check if HealthCheck returns DSMOLE0002 code
+ """Check if HealthCheck returns DSMOLE0001 code
:id: 236b0ec2-13da-48fb-b65a-db7406d56d5d
:setup: Standalone instance
@@ -203,8 +204,8 @@ def test_healthcheck_MO_plugin_missing_indexes(topology_st):
:expectedresults:
1. Success
2. Success
- 3. Healthcheck reports DSMOLE0002 code and related details
- 4. Healthcheck reports DSMOLE0002 code and related details
+ 3. Healthcheck reports DSMOLE0001 code and related details
+ 4. Healthcheck reports DSMOLE0001 code and related details
5. Success
6. Healthcheck reports no issue found
7. Healthcheck reports no issue found
@@ -214,6 +215,7 @@ def test_healthcheck_MO_plugin_missing_indexes(topology_st):
MO_GROUP_ATTR = 'creatorsname'
standalone = topology_st.standalone
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
log.info('Enable MO plugin')
plugin = MemberOfPlugin(standalone)
@@ -236,6 +238,87 @@ def test_healthcheck_MO_plugin_missing_indexes(topology_st):
standalone.restart()
+def test_healthcheck_MO_plugin_substring_index(topology_st):
+ """Check if HealthCheck returns DSMOLE0002 code when the
+ member, uniquemember attribute contains a substring index type
+
+ :id: 10954811-24ac-4886-8183-e30892f8e02d
+ :setup: Standalone instance
+ :steps:
+ 1. Create DS instance
+ 2. Configure the instance with MO Plugin
+ 3. Change index type to substring for member attribute
+ 4. Use HealthCheck without --json option
+ 5. Use HealthCheck with --json option
+ 6. Change index type back to equality for member attribute
+ 7. Use HealthCheck without --json option
+ 8. Use HealthCheck with --json option
+ 9. Change index type to substring for uniquemember attribute
+ 10. Use HealthCheck without --json option
+ 11. Use HealthCheck with --json option
+ 12. Change index type back to equality for uniquemember attribute
+ 13. Use HealthCheck without --json option
+ 14. Use HealthCheck with --json option
+
+ :expectedresults:
+ 1. Success
+ 2. Success
+ 3. Success
+ 4. Healthcheck reports DSMOLE0002 code and related details
+ 5. Healthcheck reports DSMOLE0002 code and related details
+ 6. Success
+ 7. Healthcheck reports no issue found
+ 8. Healthcheck reports no issue found
+ 9. Success
+ 10. Healthcheck reports DSMOLE0002 code and related details
+ 11. Healthcheck reports DSMOLE0002 code and related details
+ 12. Success
+ 13. Healthcheck reports no issue found
+ 14. Healthcheck reports no issue found
+ """
+
+ RET_CODE = 'DSMOLE0002'
+ MEMBER_DN = 'cn=member,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config'
+ UNIQUE_MEMBER_DN = 'cn=uniquemember,cn=index,cn=userroot,cn=ldbm database,cn=plugins,cn=config'
+
+ standalone = topology_st.standalone
+ standalone.config.set("nsslapd-accesslog-logbuffering", "on")
+
+ log.info('Enable MO plugin')
+ plugin = MemberOfPlugin(standalone)
+ plugin.disable()
+ plugin.enable()
+
+ log.info('Change the index type of the member attribute index to substring')
+ index = Index(topology_st.standalone, MEMBER_DN)
+ index.replace('nsIndexType', 'sub')
+
+ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=RET_CODE)
+ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=RET_CODE)
+
+ log.info('Set the index type of the member attribute index back to eq')
+ index.replace('nsIndexType', 'eq')
+
+ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=CMD_OUTPUT)
+ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=JSON_OUTPUT)
+
+ log.info('Change the index type of the uniquemember attribute index to substring')
+ index = Index(topology_st.standalone, UNIQUE_MEMBER_DN)
+ index.replace('nsIndexType', 'sub')
+
+ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=RET_CODE)
+ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=RET_CODE)
+
+ log.info('Set the index type of the uniquemember attribute index back to eq')
+ index.replace('nsIndexType', 'eq')
+
+ run_healthcheck_and_flush_log(topology_st, standalone, json=False, searched_code=CMD_OUTPUT)
+ run_healthcheck_and_flush_log(topology_st, standalone, json=True, searched_code=JSON_OUTPUT)
+
+ # Restart the instance after changing the plugin to avoid breaking the other tests
+ standalone.restart()
+
+
@pytest.mark.xfail(ds_is_older("1.4.1"), reason="Not implemented")
def test_healthcheck_virtual_attr_incorrectly_indexed(topology_st):
"""Check if HealthCheck returns DSVIRTLE0001 code
diff --git a/src/lib389/lib389/lint.py b/src/lib389/lib389/lint.py
index d0747f0f4..460bf64fc 100644
--- a/src/lib389/lib389/lint.py
+++ b/src/lib389/lib389/lint.py
@@ -270,6 +270,21 @@ database after adding the missing index type. Here is an example using dsconf:
"""
}
+DSMOLE0002 = {
+ 'dsle': 'DSMOLE0002',
+ 'severity': 'LOW',
+ 'description': 'Removal of a member can be slow ',
+ 'items': ['cn=memberof plugin,cn=plugins,cn=config', ],
+ 'detail': """If the substring index is configured for a membership attribute. The removal of a member
+from the large group can be slow.
+
+""",
+ 'fix': """If not required, you can remove the substring index type using dsconf:
+
+ # dsconf slapd-YOUR_INSTANCE backend index set --attr=ATTR BACKEND --del-type=sub
+"""
+}
+
# Disk Space check. Note - PARTITION is replaced by the calling function
DSDSLE0001 = {
'dsle': 'DSDSLE0001',
diff --git a/src/lib389/lib389/plugins.py b/src/lib389/lib389/plugins.py
index 67af93a14..31bbfa502 100644
--- a/src/lib389/lib389/plugins.py
+++ b/src/lib389/lib389/plugins.py
@@ -12,7 +12,7 @@ import copy
import os.path
from lib389 import tasks
from lib389._mapped_object import DSLdapObjects, DSLdapObject
-from lib389.lint import DSRILE0001, DSRILE0002, DSMOLE0001
+from lib389.lint import DSRILE0001, DSRILE0002, DSMOLE0001, DSMOLE0002
from lib389.utils import ensure_str, ensure_list_bytes
from lib389.schema import Schema
from lib389._constants import (
@@ -827,6 +827,41 @@ class MemberOfPlugin(Plugin):
report['check'] = f'memberof:attr_indexes'
yield report
+ def _lint_member_substring_index(self):
+ if self.status():
+ from lib389.backend import Backends
+ backends = Backends(self._instance).list()
+ membership_attrs = ['member', 'uniquemember']
+ container = self.get_attr_val_utf8_l("nsslapd-plugincontainerscope")
+ for backend in backends:
+ suffix = backend.get_attr_val_utf8_l('nsslapd-suffix')
+ if suffix == "cn=changelog":
+ # Always skip retro changelog
+ continue
+ if container is not None:
+ # Check if this backend is in the scope
+ if not container.endswith(suffix):
+ # skip this backend that is not in the scope
+ continue
+ indexes = backend.get_indexes()
+ for attr in membership_attrs:
+ report = copy.deepcopy(DSMOLE0002)
+ try:
+ index = indexes.get(attr)
+ types = index.get_attr_vals_utf8_l("nsIndexType")
+ if "sub" in types:
+ report['detail'] = report['detail'].replace('ATTR', attr)
+ report['detail'] = report['detail'].replace('BACKEND', suffix)
+ report['fix'] = report['fix'].replace('ATTR', attr)
+ report['fix'] = report['fix'].replace('BACKEND', suffix)
+ report['fix'] = report['fix'].replace('YOUR_INSTANCE', self._instance.serverid)
+ report['items'].append(suffix)
+ report['items'].append(attr)
+ report['check'] = f'attr:substring_index'
+ yield report
+ except KeyError:
+ continue
+
def get_attr(self):
"""Get memberofattr attribute"""
--
2.48.0

View file

@ -0,0 +1,70 @@
From dcb6298db5bfef4b2541f7c52682d153b424bfa7 Mon Sep 17 00:00:00 2001
From: James Chapman <jachapma@redhat.com>
Date: Tue, 4 Feb 2025 15:40:16 +0000
Subject: [PATCH] Issue 6566 - RI plugin failure to handle a modrdn for rename
of member of multiple groups (#6567)
Bug description:
With AM and RI plugins enabled, the rename of a user that is part of multiple groups
fails with a "value exists" error.
Fix description:
For a modrdn the RI plugin creates a new DN, before a modify is attempted check
if the new DN already exists in the attr being updated.
Fixes: https://github.com/389ds/389-ds-base/issues/6566
Reviewed by: @progier389 , @tbordaz (Thank you)
---
ldap/servers/plugins/referint/referint.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
index 468fdc239..218863ea5 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -924,6 +924,7 @@ _update_all_per_mod(Slapi_DN *entrySDN, /* DN of the searched entry */
{
Slapi_Mods *smods = NULL;
char *newDN = NULL;
+ struct berval bv = {0};
char **dnParts = NULL;
char *sval = NULL;
char *newvalue = NULL;
@@ -1026,22 +1027,30 @@ _update_all_per_mod(Slapi_DN *entrySDN, /* DN of the searched entry */
}
/* else: normalize_rc < 0) Ignore the DN normalization error for now. */
+ bv.bv_val = newDN;
+ bv.bv_len = strlen(newDN);
p = PL_strstr(sval, slapi_sdn_get_ndn(origDN));
if (p == sval) {
/* (case 1) */
slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
- slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newDN);
-
+ /* Add only if the attr value does not exist */
+ if (VALUE_PRESENT != attr_value_find_wsi(attr, &bv, &v)) {
+ slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newDN);
+ }
} else if (p) {
/* (case 2) */
slapi_mods_add_string(smods, LDAP_MOD_DELETE, attrName, sval);
*p = '\0';
newvalue = slapi_ch_smprintf("%s%s", sval, newDN);
- slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newvalue);
+ /* Add only if the attr value does not exist */
+ if (VALUE_PRESENT != attr_value_find_wsi(attr, &bv, &v)) {
+ slapi_mods_add_string(smods, LDAP_MOD_ADD, attrName, newvalue);
+ }
slapi_ch_free_string(&newvalue);
}
/* else: value does not include the modified DN. Ignore it. */
slapi_ch_free_string(&sval);
+ bv = (struct berval){0};
}
rc = _do_modify(mod_pb, entrySDN, slapi_mods_get_ldapmods_byref(smods));
if (rc) {
--
2.48.0

View file

@ -0,0 +1,566 @@
From 8e3a484f88fc9f9a3fcdfdd685d4ad2ed3cbe5d9 Mon Sep 17 00:00:00 2001
From: progier389 <progier@redhat.com>
Date: Fri, 28 Jun 2024 18:56:49 +0200
Subject: [PATCH] Issue 6229 - After an initial failure, subsequent online
backups fail (#6230)
* Issue 6229 - After an initial failure, subsequent online backups will not work
Several issues related to backup task error handling:
Backends stay busy after the failure
Exit code is 0 in some cases
Crash if failing to open the backup directory
And a more general one:
lib389 Task DN collision
Solutions:
Always reset the busy flags that have been set
Ensure that 0 is not returned in error case
Avoid closing NULL directory descriptor
Use a timestamp having milliseconds precision to create the task DN
Issue: #6229
Reviewed by: @droideck (Thanks!)
(cherry picked from commit 04a0b6ac776a1d588ec2e10ff651e5015078ad21)
---
ldap/servers/slapd/back-ldbm/archive.c | 45 +++++-----
.../slapd/back-ldbm/db-mdb/mdb_layer.c | 3 +
src/lib389/lib389/__init__.py | 10 +--
src/lib389/lib389/tasks.py | 82 +++++++++----------
4 files changed, 70 insertions(+), 70 deletions(-)
diff --git a/ldap/servers/slapd/back-ldbm/archive.c b/ldap/servers/slapd/back-ldbm/archive.c
index 0460a42f6..6658cc80a 100644
--- a/ldap/servers/slapd/back-ldbm/archive.c
+++ b/ldap/servers/slapd/back-ldbm/archive.c
@@ -16,6 +16,8 @@
#include "back-ldbm.h"
#include "dblayer.h"
+#define NO_OBJECT ((Object*)-1)
+
int
ldbm_temporary_close_all_instances(Slapi_PBlock *pb)
{
@@ -270,6 +272,7 @@ ldbm_back_ldbm2archive(Slapi_PBlock *pb)
int run_from_cmdline = 0;
Slapi_Task *task;
struct stat sbuf;
+ Object *last_busy_inst_obj = NO_OBJECT;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &li);
slapi_pblock_get(pb, SLAPI_SEQ_VAL, &rawdirectory);
@@ -380,13 +383,12 @@ ldbm_back_ldbm2archive(Slapi_PBlock *pb)
/* to avoid conflict w/ import, do this check for commandline, as well */
{
- Object *inst_obj, *inst_obj2;
ldbm_instance *inst = NULL;
/* server is up -- mark all backends busy */
- for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
- inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
- inst = (ldbm_instance *)object_get_data(inst_obj);
+ for (last_busy_inst_obj = objset_first_obj(li->li_instance_set); last_busy_inst_obj;
+ last_busy_inst_obj = objset_next_obj(li->li_instance_set, last_busy_inst_obj)) {
+ inst = (ldbm_instance *)object_get_data(last_busy_inst_obj);
/* check if an import/restore is already ongoing... */
if (instance_set_busy(inst) != 0 || dblayer_in_import(inst) != 0) {
@@ -400,20 +402,6 @@ ldbm_back_ldbm2archive(Slapi_PBlock *pb)
"another task and cannot be disturbed.",
inst->inst_name);
}
-
- /* painfully, we have to clear the BUSY flags on the
- * backends we'd already marked...
- */
- for (inst_obj2 = objset_first_obj(li->li_instance_set);
- inst_obj2 && (inst_obj2 != inst_obj);
- inst_obj2 = objset_next_obj(li->li_instance_set,
- inst_obj2)) {
- inst = (ldbm_instance *)object_get_data(inst_obj2);
- instance_set_not_busy(inst);
- }
- if (inst_obj2 && inst_obj2 != inst_obj)
- object_release(inst_obj2);
- object_release(inst_obj);
goto err;
}
}
@@ -427,18 +415,26 @@ ldbm_back_ldbm2archive(Slapi_PBlock *pb)
goto err;
}
- if (!run_from_cmdline) {
+err:
+ /* Clear all BUSY flags that have been previously set */
+ if (last_busy_inst_obj != NO_OBJECT) {
ldbm_instance *inst;
Object *inst_obj;
- /* none of these backends are busy anymore */
- for (inst_obj = objset_first_obj(li->li_instance_set); inst_obj;
+ for (inst_obj = objset_first_obj(li->li_instance_set);
+ inst_obj && (inst_obj != last_busy_inst_obj);
inst_obj = objset_next_obj(li->li_instance_set, inst_obj)) {
inst = (ldbm_instance *)object_get_data(inst_obj);
instance_set_not_busy(inst);
}
+ if (last_busy_inst_obj != NULL) {
+ /* release last seen object for aborted objset_next_obj iterations */
+ if (inst_obj != NULL) {
+ object_release(inst_obj);
+ }
+ object_release(last_busy_inst_obj);
+ }
}
-err:
if (return_value) {
if (dir_bak) {
slapi_log_err(SLAPI_LOG_ERR,
@@ -727,7 +723,10 @@ ldbm_archive_config(char *bakdir, Slapi_Task *task)
}
error:
- PR_CloseDir(dirhandle);
+ if (NULL != dirhandle) {
+ PR_CloseDir(dirhandle);
+ dirhandle = NULL;
+ }
dse_backup_unlock();
slapi_ch_free_string(&backup_config_dir);
slapi_ch_free_string(&dse_file);
diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c
index 4a7beedeb..3ecc47170 100644
--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c
+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_layer.c
@@ -983,6 +983,9 @@ dbmdb_backup(struct ldbminfo *li, char *dest_dir, Slapi_Task *task)
if (ldbm_archive_config(dest_dir, task) != 0) {
slapi_log_err(SLAPI_LOG_ERR, "dbmdb_backup",
"Backup of config files failed or is incomplete\n");
+ if (0 == return_value) {
+ return_value = -1;
+ }
}
goto bail;
diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py
index 368741a66..cb372c138 100644
--- a/src/lib389/lib389/__init__.py
+++ b/src/lib389/lib389/__init__.py
@@ -69,7 +69,7 @@ from lib389.utils import (
get_user_is_root)
from lib389.paths import Paths
from lib389.nss_ssl import NssSsl
-from lib389.tasks import BackupTask, RestoreTask
+from lib389.tasks import BackupTask, RestoreTask, Task
from lib389.dseldif import DSEldif
# mixin
@@ -1424,7 +1424,7 @@ class DirSrv(SimpleLDAPObject, object):
name, self.ds_paths.prefix)
# create the archive
- name = "backup_%s_%s.tar.gz" % (self.serverid, time.strftime("%m%d%Y_%H%M%S"))
+ name = "backup_%s_%s.tar.gz" % (self.serverid, Task.get_timestamp())
backup_file = os.path.join(backup_dir, name)
tar = tarfile.open(backup_file, "w:gz")
tar.extraction_filter = (lambda member, path: member)
@@ -2810,7 +2810,7 @@ class DirSrv(SimpleLDAPObject, object):
else:
# No output file specified. Use the default ldif location/name
cmd.append('-a')
- tnow = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
+ tnow = Task.get_timestamp()
if bename:
ldifname = os.path.join(self.ds_paths.ldif_dir, "%s-%s-%s.ldif" % (self.serverid, bename, tnow))
else:
@@ -2881,7 +2881,7 @@ class DirSrv(SimpleLDAPObject, object):
if archive_dir is None:
# Use the instance name and date/time as the default backup name
- tnow = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
+ tnow = Task.get_timestamp()
archive_dir = os.path.join(self.ds_paths.backup_dir, "%s-%s" % (self.serverid, tnow))
elif not archive_dir.startswith("/"):
# Relative path, append it to the bak directory
@@ -3506,7 +3506,7 @@ class DirSrv(SimpleLDAPObject, object):
if archive is None:
# Use the instance name and date/time as the default backup name
- tnow = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
+ tnow = Task.get_timestamp()
if self.serverid is not None:
backup_dir_name = "%s-%s" % (self.serverid, tnow)
else:
diff --git a/src/lib389/lib389/tasks.py b/src/lib389/lib389/tasks.py
index 6c2adb5b2..6bf302862 100644
--- a/src/lib389/lib389/tasks.py
+++ b/src/lib389/lib389/tasks.py
@@ -118,7 +118,7 @@ class Task(DSLdapObject):
return super(Task, self).create(rdn, properties, basedn)
@staticmethod
- def _get_task_date():
+ def get_timestamp():
"""Return a timestamp to use in naming new task entries."""
return datetime.now().isoformat()
@@ -132,7 +132,7 @@ class AutomemberRebuildMembershipTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'automember_rebuild_' + Task._get_task_date()
+ self.cn = 'automember_rebuild_' + Task.get_timestamp()
dn = "cn=" + self.cn + "," + DN_AUTOMEMBER_REBUILD_TASK
super(AutomemberRebuildMembershipTask, self).__init__(instance, dn)
@@ -147,7 +147,7 @@ class AutomemberAbortRebuildTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'automember_abort_' + Task._get_task_date()
+ self.cn = 'automember_abort_' + Task.get_timestamp()
dn = "cn=" + self.cn + "," + DN_AUTOMEMBER_ABORT_REBUILD_TASK
super(AutomemberAbortRebuildTask, self).__init__(instance, dn)
@@ -161,7 +161,7 @@ class FixupLinkedAttributesTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'fixup_linked_attrs_' + Task._get_task_date()
+ self.cn = 'fixup_linked_attrs_' + Task.get_timestamp()
dn = "cn=" + self.cn + "," + DN_FIXUP_LINKED_ATTIBUTES
super(FixupLinkedAttributesTask, self).__init__(instance, dn)
@@ -175,7 +175,7 @@ class MemberUidFixupTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'memberUid_fixup_' + Task._get_task_date()
+ self.cn = 'memberUid_fixup_' + Task.get_timestamp()
dn = f"cn={self.cn},cn=memberuid task,cn=tasks,cn=config"
super(MemberUidFixupTask, self).__init__(instance, dn)
@@ -190,7 +190,7 @@ class MemberOfFixupTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'memberOf_fixup_' + Task._get_task_date()
+ self.cn = 'memberOf_fixup_' + Task.get_timestamp()
dn = "cn=" + self.cn + "," + DN_MBO_TASK
super(MemberOfFixupTask, self).__init__(instance, dn)
@@ -205,7 +205,7 @@ class USNTombstoneCleanupTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'usn_cleanup_' + Task._get_task_date()
+ self.cn = 'usn_cleanup_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=USN tombstone cleanup task," + DN_TASKS
super(USNTombstoneCleanupTask, self).__init__(instance, dn)
@@ -225,7 +225,7 @@ class csngenTestTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'csngenTest_' + Task._get_task_date()
+ self.cn = 'csngenTest_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=csngen_test," + DN_TASKS
super(csngenTestTask, self).__init__(instance, dn)
@@ -238,7 +238,7 @@ class EntryUUIDFixupTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'entryuuid_fixup_' + Task._get_task_date()
+ self.cn = 'entryuuid_fixup_' + Task.get_timestamp()
dn = "cn=" + self.cn + "," + DN_EUUID_TASK
super(EntryUUIDFixupTask, self).__init__(instance, dn)
self._must_attributes.extend(['basedn'])
@@ -252,7 +252,7 @@ class DBCompactTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'compact_db_' + Task._get_task_date()
+ self.cn = 'compact_db_' + Task.get_timestamp()
dn = "cn=" + self.cn + "," + DN_COMPACTDB_TASK
super(DBCompactTask, self).__init__(instance, dn)
@@ -265,7 +265,7 @@ class SchemaReloadTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'schema_reload_' + Task._get_task_date()
+ self.cn = 'schema_reload_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=schema reload task," + DN_TASKS
super(SchemaReloadTask, self).__init__(instance, dn)
@@ -278,7 +278,7 @@ class SyntaxValidateTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'syntax_validate_' + Task._get_task_date()
+ self.cn = 'syntax_validate_' + Task.get_timestamp()
dn = f"cn={self.cn},cn=syntax validate,cn=tasks,cn=config"
super(SyntaxValidateTask, self).__init__(instance, dn)
@@ -295,7 +295,7 @@ class AbortCleanAllRUVTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'abortcleanallruv_' + Task._get_task_date()
+ self.cn = 'abortcleanallruv_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=abort cleanallruv," + DN_TASKS
super(AbortCleanAllRUVTask, self).__init__(instance, dn)
@@ -312,7 +312,7 @@ class CleanAllRUVTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'cleanallruv_' + Task._get_task_date()
+ self.cn = 'cleanallruv_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=cleanallruv," + DN_TASKS
self._properties = None
@@ -359,7 +359,7 @@ class ImportTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'import_' + Task._get_task_date()
+ self.cn = 'import_' + Task.get_timestamp()
dn = "cn=%s,%s" % (self.cn, DN_IMPORT_TASK)
self._properties = None
@@ -388,7 +388,7 @@ class ExportTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'export_' + Task._get_task_date()
+ self.cn = 'export_' + Task.get_timestamp()
dn = "cn=%s,%s" % (self.cn, DN_EXPORT_TASK)
self._properties = None
@@ -411,7 +411,7 @@ class BackupTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'backup_' + Task._get_task_date()
+ self.cn = 'backup_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=backup," + DN_TASKS
self._properties = None
@@ -426,7 +426,7 @@ class RestoreTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'restore_' + Task._get_task_date()
+ self.cn = 'restore_' + Task.get_timestamp()
dn = "cn=" + self.cn + ",cn=restore," + DN_TASKS
self._properties = None
@@ -513,7 +513,7 @@ class Tasks(object):
raise ValueError("Import file (%s) does not exist" % input_file)
# Prepare the task entry
- cn = "import_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = "import_" + Task.get_timestamp()
dn = "cn=%s,%s" % (cn, DN_IMPORT_TASK)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -581,7 +581,7 @@ class Tasks(object):
raise ValueError("output_file is mandatory")
# Prepare the task entry
- cn = "export_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = "export_" + Task.get_timestamp()
dn = "cn=%s,%s" % (cn, DN_EXPORT_TASK)
entry = Entry(dn)
entry.update({
@@ -637,7 +637,7 @@ class Tasks(object):
raise ValueError("You must specify a backup directory.")
# build the task entry
- cn = "backup_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = "backup_" + Task.get_timestamp()
dn = "cn=%s,%s" % (cn, DN_BACKUP_TASK)
entry = Entry(dn)
entry.update({
@@ -694,7 +694,7 @@ class Tasks(object):
raise ValueError("Backup file (%s) does not exist" % backup_dir)
# build the task entry
- cn = "restore_" + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = "restore_" + Task.get_timestamp()
dn = "cn=%s,%s" % (cn, DN_RESTORE_TASK)
entry = Entry(dn)
entry.update({
@@ -789,7 +789,7 @@ class Tasks(object):
attrs.append(attr)
else:
attrs.append(attrname)
- cn = "index_vlv_%s" % (time.strftime("%m%d%Y_%H%M%S", time.localtime()))
+ cn = "index_vlv_%s" % (Task.get_timestamp())
dn = "cn=%s,%s" % (cn, DN_INDEX_TASK)
entry = Entry(dn)
entry.update({
@@ -803,7 +803,7 @@ class Tasks(object):
#
# Reindex all attributes - gather them first...
#
- cn = "index_all_%s" % (time.strftime("%m%d%Y_%H%M%S", time.localtime()))
+ cn = "index_all_%s" % (Task.get_timestamp())
dn = ('cn=%s,cn=ldbm database,cn=plugins,cn=config' % backend)
try:
indexes = self.conn.search_s(dn, ldap.SCOPE_SUBTREE, '(objectclass=nsIndex)')
@@ -815,7 +815,7 @@ class Tasks(object):
#
# Reindex specific attributes
#
- cn = "index_attrs_%s" % (time.strftime("%m%d%Y_%H%M%S", time.localtime()))
+ cn = "index_attrs_%s" % (Task.get_timestamp())
if isinstance(attrname, (tuple, list)):
# Need to guarantee this is a list (and not a tuple)
for attr in attrname:
@@ -903,8 +903,7 @@ class Tasks(object):
suffix = ents[0].getValue(attr)
- cn = "fixupmemberof_" + time.strftime("%m%d%Y_%H%M%S",
- time.localtime())
+ cn = "fixupmemberof_" + Task.get_timestamp()
dn = "cn=%s,%s" % (cn, DN_MBO_TASK)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -965,8 +964,7 @@ class Tasks(object):
if len(ents) != 1:
raise ValueError("invalid backend name: %s" % bename)
- cn = "fixupTombstone_" + time.strftime("%m%d%Y_%H%M%S",
- time.localtime())
+ cn = "fixupTombstone_" + Task.get_timestamp()
dn = "cn=%s,%s" % (cn, DN_TOMB_FIXUP_TASK)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1019,7 +1017,7 @@ class Tasks(object):
@return exit code
'''
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=automember rebuild membership,cn=tasks,cn=config' % cn)
entry = Entry(dn)
@@ -1077,7 +1075,7 @@ class Tasks(object):
if not ldif_out:
raise ValueError("Missing ldif_out")
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=automember export updates,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1129,7 +1127,7 @@ class Tasks(object):
if not ldif_out or not ldif_in:
raise ValueError("Missing ldif_out and/or ldif_in")
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=automember map updates,cn=tasks,cn=config' % cn)
entry = Entry(dn)
@@ -1175,7 +1173,7 @@ class Tasks(object):
@return exit code
'''
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=fixup linked attributes,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1219,7 +1217,7 @@ class Tasks(object):
@return exit code
'''
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=schema reload task,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1264,7 +1262,7 @@ class Tasks(object):
@return exit code
'''
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=memberuid task,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1311,7 +1309,7 @@ class Tasks(object):
@return exit code
'''
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=syntax validate,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1358,7 +1356,7 @@ class Tasks(object):
@return exit code
'''
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=USN tombstone cleanup task,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1413,7 +1411,7 @@ class Tasks(object):
if not configfile:
raise ValueError("Missing required paramter: configfile")
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=sysconfig reload,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1464,7 +1462,7 @@ class Tasks(object):
if not suffix:
raise ValueError("Missing required paramter: suffix")
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=cleanallruv,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1516,7 +1514,7 @@ class Tasks(object):
if not suffix:
raise ValueError("Missing required paramter: suffix")
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=abort cleanallruv,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1571,7 +1569,7 @@ class Tasks(object):
if not nsArchiveDir:
raise ValueError("Missing required paramter: nsArchiveDir")
- cn = 'task-' + time.strftime("%m%d%Y_%H%M%S", time.localtime())
+ cn = 'task-' + Task.get_timestamp()
dn = ('cn=%s,cn=upgradedb,cn=tasks,cn=config' % cn)
entry = Entry(dn)
entry.setValues('objectclass', 'top', 'extensibleObject')
@@ -1616,6 +1614,6 @@ class LDAPIMappingReloadTask(Task):
"""
def __init__(self, instance, dn=None):
- self.cn = 'reload-' + Task._get_task_date()
+ self.cn = 'reload-' + Task.get_timestamp()
dn = f'cn={self.cn},cn=reload ldapi mappings,cn=tasks,cn=config'
super(LDAPIMappingReloadTask, self).__init__(instance, dn)
--
2.48.0

View file

@ -0,0 +1,165 @@
From 2b1b2db90c9d337166fa28e313f60828cd43de09 Mon Sep 17 00:00:00 2001
From: tbordaz <tbordaz@redhat.com>
Date: Thu, 6 Feb 2025 18:25:36 +0100
Subject: [PATCH] Issue 6554 - During import of entries without nsUniqueId, a
supplier generates duplicate nsUniqueId (LMDB only) (#6582)
Bug description:
During an import the entry is prepared (schema, operational
attributes, password encryption,...) before starting the
update of the database and indexes.
A step of the preparation is to assign a value to 'nsuniqueid'
operational attribute. 'nsuniqueid' must be unique.
In LMDB the preparation is done by multiple threads (workers).
In such case the 'nsuniqueid' are generated in parallel and
as it is time based several values can be duplicated.
Fix description:
To prevent that the routine dbmdb_import_generate_uniqueid
should make sure to synchronize the workers.
fixes: #6554
Reviewed by: Pierre Rogier
---
.../tests/suites/import/import_test.py | 79 ++++++++++++++++++-
.../back-ldbm/db-mdb/mdb_import_threads.c | 11 +++
2 files changed, 89 insertions(+), 1 deletion(-)
diff --git a/dirsrvtests/tests/suites/import/import_test.py b/dirsrvtests/tests/suites/import/import_test.py
index dbd921924..54d304753 100644
--- a/dirsrvtests/tests/suites/import/import_test.py
+++ b/dirsrvtests/tests/suites/import/import_test.py
@@ -14,11 +14,13 @@ import os
import pytest
import time
import glob
+import re
import logging
import subprocess
from datetime import datetime
from lib389.topologies import topology_st as topo
-from lib389._constants import DEFAULT_SUFFIX, TaskWarning
+from lib389.topologies import topology_m2 as topo_m2
+from lib389._constants import DEFAULT_BENAME, DEFAULT_SUFFIX, TaskWarning
from lib389.dbgen import dbgen_users
from lib389.tasks import ImportTask
from lib389.index import Indexes
@@ -688,6 +690,81 @@ def test_online_import_under_load(topo):
assert import_task.get_exit_code() == 0
+def test_duplicate_nsuniqueid(topo_m2, request):
+ """Test that after an offline import all
+ nsuniqueid are different
+
+ :id: a2541677-a288-4633-bacf-4050cc56016d
+ :setup: MMR with 2 suppliers
+ :steps:
+ 1. stop the instance to do offline operations
+ 2. Generate a 5K users LDIF file
+ 3. Check that no uniqueid are present in the generated file
+ 4. import the generated LDIF
+ 5. export the database
+ 6. Check that that exported LDIF contains more than 5K nsuniqueid
+ 7. Check that there is no duplicate nsuniqued in exported LDIF
+ :expectedresults:
+ 1. Should succeeds
+ 2. Should succeeds
+ 3. Should succeeds
+ 4. Should succeeds
+ 5. Should succeeds
+ 6. Should succeeds
+ 7. Should succeeds
+ """
+ m1 = topo_m2.ms["supplier1"]
+
+ # Stop the instance
+ m1.stop()
+
+ # Generate a test ldif (5k entries)
+ log.info("Generating LDIF...")
+ ldif_dir = m1.get_ldif_dir()
+ import_ldif = ldif_dir + '/5k_users_import.ldif'
+ dbgen_users(m1, 5000, import_ldif, DEFAULT_SUFFIX)
+
+ # Check that the generated LDIF does not contain nsuniqueid
+ all_nsuniqueid = []
+ with open(import_ldif, 'r') as file:
+ for line in file:
+ if line.lower().startswith("nsuniqueid: "):
+ all_nsuniqueid.append(line.split(': ')[1])
+ log.info("import file contains " + str(len(all_nsuniqueid)) + " nsuniqueid")
+ assert len(all_nsuniqueid) == 0
+
+ # Import the "nsuniquied free" LDIF file
+ if not m1.ldif2db('userRoot', None, None, None, import_ldif):
+ assert False
+
+ # Export the DB that now should contain nsuniqueid
+ export_ldif = ldif_dir + '/5k_user_export.ldif'
+ log.info("export to file " + export_ldif)
+ m1.db2ldif(bename=DEFAULT_BENAME, suffixes=[DEFAULT_SUFFIX],
+ excludeSuffixes=None, repl_data=False,
+ outputfile=export_ldif, encrypt=False)
+
+ # Check that the export LDIF contain nsuniqueid
+ all_nsuniqueid = []
+ with open(export_ldif, 'r') as file:
+ for line in file:
+ if line.lower().startswith("nsuniqueid: "):
+ all_nsuniqueid.append(line.split(': ')[1])
+ log.info("export file " + export_ldif + " contains " + str(len(all_nsuniqueid)) + " nsuniqueid")
+ assert len(all_nsuniqueid) >= 5000
+
+ # Check that the nsuniqueid are unique
+ assert len(set(all_nsuniqueid)) == len(all_nsuniqueid)
+
+ def fin():
+ if os.path.exists(import_ldif):
+ os.remove(import_ldif)
+ if os.path.exists(export_ldif):
+ os.remove(export_ldif)
+ m1.start
+
+ request.addfinalizer(fin)
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
index 707a110c5..0f445bb56 100644
--- a/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
+++ b/ldap/servers/slapd/back-ldbm/db-mdb/mdb_import_threads.c
@@ -610,10 +610,20 @@ dbmdb_import_generate_uniqueid(ImportJob *job, Slapi_Entry *e)
{
const char *uniqueid = slapi_entry_get_uniqueid(e);
int rc = UID_SUCCESS;
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if (!uniqueid && (job->uuid_gen_type != SLAPI_UNIQUEID_GENERATE_NONE)) {
char *newuniqueid;
+ /* With 'mdb' we have several workers generating nsuniqueid
+ * we need to serialize them to prevent generating duplicate value
+ * From performance pov it only impacts import
+ * The default value is SLAPI_UNIQUEID_GENERATE_TIME_BASED so
+ * the only syscall is clock_gettime and then string formating
+ * that should limit contention
+ */
+ pthread_mutex_lock(&mutex);
+
/* generate id based on dn */
if (job->uuid_gen_type == SLAPI_UNIQUEID_GENERATE_NAME_BASED) {
char *dn = slapi_entry_get_dn(e);
@@ -624,6 +634,7 @@ dbmdb_import_generate_uniqueid(ImportJob *job, Slapi_Entry *e)
/* time based */
rc = slapi_uniqueIDGenerateString(&newuniqueid);
}
+ pthread_mutex_unlock(&mutex);
if (rc == UID_SUCCESS) {
slapi_entry_set_uniqueid(e, newuniqueid);
--
2.48.0

View file

@ -1,23 +0,0 @@
#!/bin/bash
DATE=`date +%Y%m%d`
# use a real tag name here
VERSION=1.3.5.14
PKGNAME=389-ds-base
TAG=${TAG:-$PKGNAME-$VERSION}
#SRCNAME=$PKGNAME-$VERSION-$DATE
SRCNAME=$PKGNAME-$VERSION
test -d .git || {
echo you must be in the ds git repo to use this
echo bye
exit 1
}
if [ -z "$1" ] ; then
dir=.
else
dir="$1"
fi
git archive --prefix=$SRCNAME/ $TAG | bzip2 > $dir/$SRCNAME.tar.bz2

View file

@ -1,16 +0,0 @@
#!/bin/bash
DATE=`date +%Y%m%d`
# use a real tag name here
VERSION=1.3.5.14
PKGNAME=389-ds-base
TAG=${TAG:-$PKGNAME-$VERSION}
URL="https://git.fedorahosted.org/git/?p=389/ds.git;a=snapshot;h=$TAG;sf=tgz"
SRCNAME=$PKGNAME-$VERSION
wget -O $SRCNAME.tar.gz "$URL"
echo convert tgz format to tar.bz2 format
gunzip $PKGNAME-$VERSION.tar.gz
bzip2 $PKGNAME-$VERSION.tar

File diff suppressed because it is too large Load diff

498
changelog Normal file
View file

@ -0,0 +1,498 @@
* Mon Apr 15 2024 James Chapman <jachapma@redhat.com> - 3.0.2-1
- Bump version to 3.0.2
- Issue 6082 - Remove explicit dependencies toward libdb - revert default (#6145)
- Issue 6142 - [RFE] Add LMDB configuration related checks into Healthcheck tool (#6143)
- Issue 6141 - freeipa test_topology_TestCASpecificRUVs is failing (#6144)
- Issue 6136 - failure in freeipa tests (#6137)
- Issue 6119 - Synchronise accept_thread with slapd_daemon (#6120)
- Issue 6105 - lmdb - Cannot create entries with long rdn (#6130)
- Issue 6082 - Remove explicit dependencies toward libdb (#6083)
- Issue i6057 - Fix3 - Fix covscan issues (#6127)
- Issue 6057 - vlv search may result wrong result with lmdb - Fix 2 (#6121)
- Issue 6057 - vlv search may result wrong result with lmdb (#6091)
- Issue 6092 - passwordHistory is not updated with a pre-hashed password (#6093)
- Issue 6133 - Move slapi_pblock_set_flag_operation_notes() to slapi-plugin.h
- Issue 6125 - dscreate interactive fails when chosing mdb backend (#6126)
- Issue 6110 - Typo in Account Policy plugin message
- Issue 6080 - ns-slapd crash in referint_get_config (#6081)
- Issue 6117 - Fix the UTC offset print (#6118)
- Issue 5305 - OpenLDAP version autodetection doesn't work
- Issue 6112 - RFE - add new operation note for MFA authentications
- Issue 5842 - Add log buffering to audit log
- Issue 3527 - Support HAProxy and Instance on the same machine configuration (#6107)
- Issue 6103 - New connection timeout error breaks errormap (#6104)
- Issue 6096 - Improve connection timeout error logging (#6097)
- Issue 6067 - Improve dsidm CLI No Such Entry handling (#6079)
- Issue 6067 - Add hidden -v and -j options to each CLI subcommand (#6088)
- Issue 6061 - Certificate lifetime displayed as NaN
* Wed Jan 31 2024 Pete Walter <pwalter@fedoraproject.org> - 3.0.1-2
- Rebuild for ICU 74
* Tue Jan 30 2024 Simon Pichugin <spichugi@redhat.com> - 3.0.1-1
- Bump version to 3.0.1
- Issue 6043, 6044 - Enhance Rust and JS bundling and add SPDX licenses for both (#6045)
- Issue 3555 - Remove audit-ci from dependencies (#6056)
- Issue 6052 - Paged results test sets hostname to `localhost` on test collection
- Issue 6051 - Drop unused pytest markers
- Issue 6049 - lmdb - changelog is wrongly recreated by reindex task (#6050)
- Issue 6047 - Add a check for tagged commits
- Issue 6041 - dscreate ds-root - accepts relative path (#6042)
- Switch default backend to lmdb and bump version to 3.0 (#6013)
- Issue 6032 - Replication broken after backup restore (#6035)
- Issue 6037 - Server crash at startup in vlvIndex_delete (#6038)
- Issue 6034 - Change replica_id from str to int
- Issue 6028 - vlv index keys inconsistencies (#6031)
- Issue 5989 - RFE support of inChain Matching Rule (#5990)
- Issue 6022 - lmdb inconsistency between vlv index and vlv cache names (#6026)
- Issue 6015 - Fix typo remeber (#6014)
- Issue 6016 - Pin upload/download artifacts action to v3
- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007)
- Issue 4673 - Update Rust crates
- Issue 6004 - idletimeout may be ignored (#6005)
- Issue 5954 - Disable Transparent Huge Pages
- Issue 5997 - test_inactivty_and_expiration CI testcase is wrong (#5999)
- Issue 5993 - Fix several race condition around CI tests (#5996)
- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994)
- Bump openssl from 0.10.55 to 0.10.60 in /src (#5995)
- Issue 5980 - Improve instance startup failure handling (#5991)
- Issue 5976 - Fix freeipa install regression with lmdb (#5977)
- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987)
- Issue 5984 - Crash when paged result search are abandoned (#5985)
- Issue 5947 - CI test_vlv_recreation_reindex fails on LMDB (#5979)
* Mon Jan 29 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.5-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Mon Jan 22 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.5-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Fri Jan 19 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.5-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Jan 18 2024 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.5-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
* Thu Jan 18 2024 Viktor Ashirov <vashirov@redhat.com> - 2.4.5-1
- Bump version to 2.4.5
- Issue 5989 - RFE support of inChain Matching Rule (#5990)
- Issue 5939 - During an update, if the target entry is reverted in the entry cache, the server should not retry to lock it (#6007)
- Issue 5944 - Reversion of the entry cache should be limited to BETXN plugin failures (#5994)
- Issue 5954 - Disable Transparent Huge Pages
- Issue 5984 - Crash when paged result search are abandoned - fix2 (#5987)
- Issue 5984 - Crash when paged result search are abandoned (#5985)
* Wed Nov 15 2023 James Chapman <jachapma@redhat.com> - 2.4.4
- Bump version to 2.4.4
- Issue 5971 - CLI - Fix password prompt for repl status (#5972)
- Issue 5973 - Fix fedora cop RawHide builds (#5974)
- Revert "Issue 5761 - Worker thread dynamic management (#5796)" (#5970)
- Issue 5966 - CLI - Custom schema object is removed on a failed edit (#5967)
- Issue 5786 - Update permissions for Release workflow
- Issue 5960 - Subpackages should have more strict interdependencies
- Issue 3555 - UI - Fix audit issue with npm - babel/traverse (#5959)
- Issue 4843 - Fix dscreate create-template issue (#5950)
- bugfix for --passwd-file not working on latest version (#5934)
- Issue 5843 - dsconf / dscreate should be able to handle lmdb parameters (#5943)
- Bump postcss from 8.4.24 to 8.4.31 in /src/cockpit/389-console (#5945)
- Issue 5938 - Attribute Names changed to lowercase after adding the Attributes (#5940)
- issue 5924 - ASAN server build crash when looping opening/closing connections (#5926)
- Issue 1925 - Add a CI test (#5936)
- Issue 5732 - Localizing Cockpit's 389ds Plugin using CockpitPoPlugin (#5764)
- Issue 1870 - Add a CI test (#5929)
- Issue 843 - Add a warning to slapi_valueset_add_value_ext (#5925)
- Issue 5761 - Worker thread dynamic management (#5796)
- Issue 1802 - Improve ldclt man page (#5928)
- Issue 1456 - Add a CI test that verifies there is no issue (#5927)
- Issue 1317 - Add a CI test (#5923)
- Issue 1081 - CI - Add more tests for overwriting x-origin issue (#5815)
- Issue 1115 - Add a CI test (#5913)
- Issue 5848 - Fix condition and add a CI test (#5916)
- Issue 5848 - Fix condition and add a CI test (#5916)
- Issue 5914 - UI - server settings page validation improvements and db index fixes
- Issue 5909 - Multi listener hang with 20k connections (#5917)
- Issue 5902 - Fix previous commit regression (#5919)
- pass instance correctly to ds_is_older (#5903)
- Issue 5909 - Multi listener hang with 20k connections (#5910)
- Issue 5722 - improve testcase (#5904)
- Issue 5203 - outdated version in provided metadata for lib389
- Bug Description:
- issue 5890 part 2 - Need a tester for testing multiple listening thread feature (#5897)
- Issue i5846 - Crash when lmdb import is aborted (#5881)
- Issue 5894 - lmdb import error fails with Could not store the entry (#5895)
- Issue 5890 - Need a tester for testing multiple listening thread feature (#5891)
- Issue 5082 - slugify: ModuleNotFoundError when running test cases
- Issue 4551 - Part 2 - Fix build warning of previous PR (#5888)
- Issue 5834 - AccountPolicyPlugin erroring for some users (#5866)
- Issue 5872 - part 2 - fix is_dbi regression (#5887)
- Issue 4758 - Add tests for WebUI
- Issue 5848 - dsconf should prevent setting the replicaID for hub and consumer roles (#5849)
- Issue 5883 - Remove connection mutex contention risk on autobind (#5886)
- Issue 5872 - `dbscan()` in lib389 can return bytes
* Thu Aug 3 2023 Mark Reynolds<mreynolds@redhat.com> - 2.4.3-1
- Bump version to 2.4.3-1
- Issue 5729 - Memory leak in factory_create_extension (#5814)
- Issue 5870 - ns-slapd crashes at startup if a backend has no suffix (#5871)
- Issue 5876 - CI Test random failure - Import (#5879)
- Issue 5877 - test_basic_ldapagent breaks test_setup_ds_as_non_root* tests
- Issue 5867 - lib389 should use filter for tarfile as recommended by PEP 706 (#5868)
- Issue 5853 - Update Cargo.lock and fix minor warning (#5854)
- Issue 5785 - CLI - arg completion is broken
- Issue 5864 - Server fails to start after reboot because it's unable to access nsslapd-rundir
- Issue 5856 - SyntaxWarning: invalid escape sequence '\,'
- Issue 5859 - dbscan fails with AttributeError: 'list' object has no attribute 'extends'
- Issue 3527 - UI - Add nsslapd-haproxy-trusted-ip to server setting (#5839)
- Issue 4551 - Paged search impacts performance (#5838)
- Issue 4758 - Add tests for WebUI
- Issue 4169 - UI - Fix retrochangelog and schema Typeaheads (#5837)
- issue 5833 - dsconf monitor backend fails on lmdb (#5835)
- Issue 3555 - UI - Fix audit issue with npm - stylelint (#5836)
* Mon Jul 24 2023 Mark Reynolds <mreynolds@redhat.com> - 2.4.2-5
- Bump version to 2.4.2-5
- Add the bash completion scripts to the appropriate files section
* Wed Jul 19 2023 Fedora Release Engineering <releng@fedoraproject.org> - 2.4.2-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
* Tue Jul 11 2023 František Zatloukal <fzatlouk@redhat.com> - 2.4.2-3
- Rebuilt for ICU 73.2
* Mon Jul 10 2023 Mark Reynolds <mreynolds@redhat.com> - 2.4.2-2
- Bump version to 2.4.2-2
- Issue 5752 - RFE - Provide a history for LastLoginTime (#5807)
= Issue 4719 - CI - Add dsconf add a PTA URL test
* Fri Jul 7 2023 Mark Reynolds <mreynolds@redhat.com> - 2.4.2-1
- Bump version to 2.4.2
- Issue 5793 - UI - fix suffix selection in export modal
- Issue 5793 - UI - Fix minor crashes (#5827)
- Issue 5825 - healthcheck - password storage scheme warning needs more info
- Issue 5822 - Allow empty export path for db2ldif
- Issue 5755 - Massive memory leaking on update operations (#5824)
- Issue 5701 - CI - Add more tests for referral mode fix (#5810)
- Issue 5551 - Almost empty and not loaded ns-slapd high cpu load
- Issue 5755 - The Massive memory leaking on update operations (#5803)
- Issue 2375 - CLI - Healthcheck - revise and add new checks
- Bump openssl from 0.10.52 to 0.10.55 in /src
- Issue 5793 - UI - movce from webpack to esbuild bundler
- Issue 5752 - CI - Add more tests for lastLoginHistorySize RFE (#5802)
- Issue 3527 - Fix HAProxy x390x compatibility and compiler warnings (#5801)
- Issue 5798 - CLI - Add multi-valued support to dsconf config (#5799)
- Issue 5781 - Bug handling return code of pre-extended operation plugin.
- Issue 5785 - move bash completion to post section of specfile
- Issue 5156 - (cont) RFE slapi_memberof reusing memberof values (#5744)
- Issue 4758 - Add tests for WebUI
- Issue 3527 - Add PROXY protocol support (#5762)
- Issue 5789 - Improve ds-replcheck error handling
- Issue 5786 - CLI - registers tools for bash completion
- Issue 5786 - Set minimal permissions on GitHub Workflows (#5787)
- Issue 5646 - Various memory leaks (#5725)
- Issue 5778 - UI - Remove error message if .dsrc is missing
- Issue 5751 - Cleanallruv task crashes on consumer (#5775)
* Wed Jun 28 2023 Python Maint <python-maint@redhat.com> - 2.4.1-2
- Rebuilt for Python 3.12
* Thu May 18 2023 Mark Reynolds <mreynolds@redhat.com> - 2.4.1-1
- Bump version to 2.4.1
- Issue 5770 - RFE - Extend Password Adminstrators to allow skipping password info updates
- Issue 5768 - CLI/UI - cert checks are too strict, and other issues
- Issue 5722 - fix compilation warnings (#5771)
- Issue 5765 - Improve installer selinux handling
- Issue 152 - RFE - Add support for LDAP alias entries
- Issue 5052 - BUG - Custom filters prevented entry deletion (#5060)
- Issue 5752 - RFE - Provide a history for LastLoginTime (#5753)
- Issue 5722 - RFE When a filter contains 'nsrole', improve response time by rewriting the filter (#5723)
- Issue 5704 - crash in sync_refresh_initial_content (#5720)
- Issue 5738 - RFE - UI - Read/write replication monitor info to .dsrc file
- Issue 5156 - build warnings (#5758)
- Issue 5749 - RFE - Allow Account Policy Plugin to handle inactivity and expiration at the same time
- Issue 5743 - Disabling replica crashes the server (#5746)
- Issue 2562 - Copy config files into backup directory
- Issue 5156 - fix build breakage from slapi-memberof commit
- Issue 4758 - Add tests for WebUI
* Tue Apr 25 2023 Mark Reynolds <mreynolds@redhat.com> - 2.4.0-1
- Bump version to 2.4.0
- Issue 5156 - RFE that implement slapi_memberof (#5694)
- Issue 5734 - RFE - Exclude pwdFailureTime and ContextCSN (#5735)
- Issue 5726 - ns-slapd crashing in ldbm_back_upgradednformat (#5727)
- Issue 4758 - Add tests for WebUI
- Issue 5718 - Memory leak in connection table (#5719)
- Issue 5705 - Add config parameter to close client conns on failed bind (#5712)
- Issue 4758 - Add tests for WebUI
- Issue 5643 - Memory leak in entryrdn during delete (#5717)
- Issue 5714 - UI - fix typo, db settings, log settings, and LDAP editor paginations
- Issue 5701 - CLI - Fix referral mode setting (#5708)
- Bump openssl from 0.10.45 to 0.10.48 in /src (#5709)
- Issue 5710 - subtree search statistics for index lookup does not report ancestorid/entryrdn lookups (#5711)
- Issue 5697 - Obsolete nsslapd-ldapimaprootdn attribute (#5698)
- Issue 1081 - Stop schema replication from overwriting x-origin
- Issue 4812 - Listener thread does not scale with a high num of established connections (#5706)
- Issue 4812 - Listener thread does not scale with a high num of established connections (#5681)
- Bump webpack from 5.75.0 to 5.76.0 in /src/cockpit/389-console (#5699)
- Issue 5598 - (3rd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5692)
- Issue 5598 - (2nd) In 2.x, SRCH throughput drops by 10% because of handling of referral (#5691)
- Issue 5687 - UI - sensitive information disclosure
- Issue 5661 - LMDB hangs while Rebuilding the replication changelog RUV (#5676)
- Issue 5554 - Add more tests to security_basic_test suite
- Issue 4583 - Update specfile to skip checks of ASAN builds
- Issue 4758 - Add tests for WebUI
- Issue 3604 - UI - Add support for Subject Alternative Names in CSR
- Issue 5600 - buffer overflow when enabling sync repl plugin when dynamic plugins is enabled
- Issue 5640 - Update logconv for new logging format
- Issue 5162 - CI - fix error message for invalid pem file
- Issue 5598 - In 2.x, SRCH throughput drops by 10% because of handling of referral (#5604)
- Issue 5671 - covscan - clang warning (#5672)
- Issue 5267 - CI - Fix issues with nsslapd-return-original-entrydn
- Issue 5666 - CLI - Add timeout parameter for tasks
- Issue 5567 - CLI - make ldifgen use the same default ldif name for all options
- Issue 5647 - Fix unused variable warning from previous commit (#5670)
- Issue 5162 - Lib389 - verify certificate type before adding
- Issue 5642 - Build fails against setuptools 67.0.0
- Issue 5630 - CLI - need to add logging filter for stdout
- Issue 5646 - CLI/UI - do not hardcode password storage schemes
- Issue 5640 - Update logconv for new logging format
- issue 5647 - covscan: memory leak in audit log when adding entries (#5650)
- Issue 5658 - CLI - unable to add attribute with matching rule
- Issue 5653 - covscan - fix invalid dereference
- Issue 5652 - Libasan crash in replication/cascading_test (#5659)
- Issue 5628 - Handle graceful timeout in CI tests (#5657)
- Issue 5648 - Covscan - Compiler warnings (#5651)
- Issue 5630 - CLI - error messages should goto stderr
- Issue 2435 - RFE - Raise IDL Scan Limit to INT_MAX (#5639)
- Issue 5632 - CLI - improve error handling with db2ldif
- Issue 5517 - Replication conflict CI test sometime fails (#5518)
- Issue 5634 - Deprecated warning related to github action workflow code (#5635)
- Issue 5637 - Covscan - fix Buffer Overflows (#5638)
- Issue 5624 - RFE - UI - export certificates, and import text base64 encoded certificates
- Bump tokio from 1.24.1 to 1.25.0 in /src (#5629)
- Issue 4577 - Add LMDB pytest github action (#5627)
- Issue 4293 - RFE - CLI - add dsrc options for setting user and group subtrees
- Remove stale libevent(-devel) dependency
- Issue 5578 - dscreate ds-root does not normaile paths (#5613)
- Issue 5497 - boolean attributes should be case insensitive
* Fri Mar 31 2023 Viktor Ashirov <vashirov@redhat.com> - 2.3.2-3
- Fix build issue against setuptools 67.0.0 (#2183375)
* Tue Feb 28 2023 Simon Pichugin <spichugi@redhat.com> - 2.3.2-2
- Use systemd-sysusers for dirsrv user and group (#2173834)
* Mon Jan 23 2023 Mark Reynolds <mreynolds@redhat.com> - 2.3.2-1
- Bump version to 2.3.2
- Issue 5547 - automember plugin improvements
- Issue 5607, 5351, 5611 - UI/CLI - fix various issues
- Issue 5610 - Build failure on Debian
- Issue 5608 - UI - need to replace some "const" with "let"
- Issue 5560 - dscreate run by non superuser set defaults requiring superuser privilege (#5579)
- Issue 3604 - Create a private key/CSR with dsconf/Cockpit (#5584)
- Issue 5605 - Adding a slapi_log_backtrace function in libslapd (#5606)
- Issue 5602 - UI - browser crash when trying to modify read-only variable
- Issue 5581 - UI - Support cockpit dark theme
- Issue 5593 - CLI - dsidm account subtree-status fails with TypeError
- Issue 5591 - BUG - Segfault in cl5configtrim with invalid confi (#5592)
- Fix latest npm audit failures
- Issue 5599 - CI - webui tests randomly fail
- Issue 5348 - RFE - CLI - add functionality to do bulk updates to entries
- Issue 5588 - Fix CI tests
- Issue 5585 - lib389 password policy DN handling is incorrect (#5587)
- Issue 5521 - UI - Update plugins for new split PAM and LDAP pass thru auth
- Bump json5 from 2.2.1 to 2.2.3 in /src/cockpit/389-console
- Issue 5236 - UI add specialized group edit modal
- Issue 5550 - dsconf monitor crashes with Error math domain error (#5553)
- Issue 5278 - CLI - dsidm asks for the old password on password reset
- Issue 5531 - CI - use universal_lines in capture_output
- Issue 5425 - CLI - add confirmation arg when deleting backend
- Issue 5558 - non-root instance fails to start on creation (#5559)
- Issue 5545 - A random crash in import over lmdb (#5546)
- Issue 3615 - CLI - prevent virtual attribute indexing
- Update specfile and rust crates
- Issue 5413 - Allow mutliple MemberOf fixup tasks with different bases/filters
- Issue 5554 - Add more tests to security_basic_test suite (#5555)
- Issue 5561 - Nightly tests are failing
- Issue 5521 - RFE - split pass through auth cli
- Issue 5521 - BUG - Pam PTA multiple issues
- Issue 5544 - Increase default task TTL
- Issue 5526 - RFE - Improve saslauthd migration options (#5528)
- Issue 5539 - Make logger's parameter name unified (#5540)
- Issue 5541 - Fix typo in `lib389.cli_conf.backend._get_backend` (#5542)
- Issue 3729 - (cont) RFE Extend log of operations statistics in access log (#5538)
- Issue 5534 - Fix a rebase typo (#5537)
- Issue 5534 - Add copyright text to the repository files
* Wed Jan 18 2023 Fedora Release Engineering <releng@fedoraproject.org> - 2.3.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
* Sat Dec 31 2022 Pete Walter <pwalter@fedoraproject.org> - 2.3.1-2
- Rebuild for ICU 72
* Fri Nov 18 2022 Mark Reynolds <mreynolds@redhat.com> - 2.3.1-1
- Bump version to 2.3.1
- Issue 5532 - Make db compaction TOD day more robust.
- Issue 3729 - RFE Extend log of operations statistics in access log (#5508)
- Issue 5529 - UI - Fix npm vulnerability in loader-utils
- Issue 5490 - tombstone in entryrdn index with lmdb but not with bdb (#5498)
- Issue 5162 - Fix dsctl tls ca-certfiicate add-cert arg requirement
- Issue 5510 - remove twalk_r dependency to build on RHEL8 (#5516)
- Issue 5162 - RFE - CLI allow adding CA certificate bundles
- Issue 5440 - memberof is slow on update/fixup if there are several 'groupattr' (#5455)
- Issue 5512 - BUG - skip pwdPolicyChecker OC in migration (#5513)
- Issue 3555 - UI - fix audit issue with npm loader-utils (#5514)
- Issue 5505 - Fix compiler warning (#5506)
- Issue 5469 - Increase the default value of nsslapd-conntablesize (#5472)
- Issue 5408 - lmdb import is slow (#5481)
- Issue 5429 - healthcheck - add checks for MemberOf group attrs being indexed
- Issue 5502 - RFE - Add option to display entry attributes in audit log
- Issue 5495 - BUG - Minor fix to dds skip, inconsistent attrs caused errors (#5501)
- Issue 5367 - RFE - store full DN in database record
- Issue 5495 - RFE - skip dds during migration. (#5496)
- Issue 5491 - UI - Add rework and finish jpegPhoto functionality (#5492)
- Issue 5368 - Retro Changelog trimming does not work (#5486)
- Issue 5487 - Fix various issues with logconv.pl
- Issue 5476 - RFE - add memberUid read aci by default (#5477)
- Issue 5482 - lib389 - Can not enable replication with a mixed case suffix
- Issue 5478 - Random crash in connection code during server shutdown (#5479)
- Issue 3061 - RFE - Add password policy debug log level
- Issue 5302 - Release tarballs don't contain cockpit webapp
- Issue 5262 - high contention in find_entry_internal_dn on mixed load (#5264)
- Issue 4324 - Revert recursive pthread mutex change (#5463)
- Issue 5462 - RFE - add missing default indexes (#5464)
- Issue 5465 - Fix dbscan linking (#5466)
- Issue 5271 - Serialization of pam_passthrough causing high etimes (#5272)
- Issue 5453 - UI/CLI - Changing Root DN breaks UI
- Issue 5446 - Fix some covscan issues (#5451)
- Issue 4308 - checking if an entry is a referral is expensive
- Issue 5447 - UI - add NDN max cache size to UI
- Issue 5443 - UI - disable save button while saving
- Issue 5413 - Allow only one MemberOf fixup task at a time
- Issue 4592 - dscreate error with custom dir_path (#5434)
- Issue 5158 - entryuuid fixup tasks fails in replicated topology (#5439)
* Tue Sep 20 2022 Mark Reynolds <mreynolds@redhat.com> - 2.3.0-2
- Bump version to 2.3.0-2
- Update old pcre-devel requirement to pcre2-devel
* Thu Sep 1 2022 Mark Reynolds <mreynolds@redhat.com> - 2.3.0-1
- Bump version to 2.3.0
- Issue 5012 - Migrate pcre to pcre2 - remove match limit
- Issue 5356 - Make Rust non-optional and update default password storage scheme
- Issue 5012 - Migrate pcre to pcre2
- Issue 5428 - Fix regression with nscpEntryWsi computation
- Fix missing 'not' in description (closes #5423) (#5424)
- Issue 5421 - CI - makes replication/acceptance_test.py::test_modify_entry more robust (#5422)
- Issue 3903 - fix repl keep alive event interval
- Issue 5418 - Sync_repl may crash while managing invalid cookie (#5420)
- Issue 5415 - Hostname when set to localhost causing failures in other tests
- Issue 5412 - lib389 - do not set backend name to lowercase
- Issue 5407 - sync_repl crashes if enabled while dynamic plugin is enabled (#5411)
- Issue 5385 - LMDB - import crash in rdncache_add_elem (#5406)
- Issue 5403 - Memory leak in conntection table mulit list (#5404)
- Issue 3903 - keep alive update event starts too soon
- Issue 5397 - Fix various memory leaks
- Issue 5399 - UI - LDAP Editor is not updated when we switch instances (#5400)
- Issue 3903 - Supplier should do periodic updates
- Issue 5377 - Code cleanup: Fix Covscan invalid reference (#5393)
- Issue 5394 - configure doesn't check for lmdb and json-c
- Issue 5392 - dscreate fails when using alternative ports in the SELinux hi_reserved_port_t label range
- Issue 5386 - BUG - Update sudoers schema to correctly support UTF-8 (#5387)
- Issue 5388 - fix use-after-free and deadcode
- Issue 5383 - UI - Various fixes and RFE's for UI
- Issue 4656 - Remove problematic language from source code
- Issue 5380 - Separate cleanAllRUV code into new file
- Issue 5322 - optime & wtime on rejected connections is not properly set
- Issue 5335 - RFE - Add Security Audit Log
- Issue 5375 - CI - disable TLS hostname checking
- Issue 981 - Managed Entries betxnpreoperation - transaction not aborted on managed entry failure (#5369)
- Issue 5373 - dsidm user get_dn fails with search_ext() argument 1 must be str, not function
- Issue 5371 - Update npm and cargo packages
- Issue 3069 - Support ECDSA private keys for TLS (#5365)
- Issue 5290 - Importing certificate chain files via "import-server-key-cert" no longer works (#5293)
* Mon Aug 01 2022 Frantisek Zatloukal <fzatlouk@redhat.com> - 2.2.2-3
- Rebuilt for ICU 71.1
* Wed Jul 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
* Tue Jul 5 2022 Mark Reynolds <mreynolds@redhat.com> - 2.2.2-1
- Bump version to 2.2.2
- Issue 5221 - fix covscan (#5359)
- Issue 5294 - Report Portal 5 is not processing an XML file with (#5358)
- Issue 5353 - CLI - dsconf backend export breaks with multiple backends
- Issue 5346 - New connection table fails with ASAN failures (#5350)
- Issue 5345 - BUG - openldap migration fails when ppolicy is active (#5347)
- Issue 5323 - BUG - improve skipping of monitor db (#5340)
- Issue 5329 - Improve replication extended op logging
- Issue 5343 - Various improvements to winsync
- Issue 4932 - CLI - add parser aliases to long arg names
- Issue 5332 - BUG - normalise filter as intended
- Issue 5327 - Validate test metadata
- Issue 4812 - Scalability with high number of connections (#5090)
- Issue 4348 - Add tests for dsidm
- Issue 5333 - 389-ds-base fails to build with Python 3.11
* Thu Jun 16 2022 Python Maint <python-maint@redhat.com> - 2.2.1-4
- Rebuilt for Python 3.11
* Wed Jun 15 2022 Mark Reynolds <mreynolds@redhat.com> - 2.2.1-3
- Bump version to 2.2.1-3
- Issue 5332 - BUG - normalise filter as intended
- Issue 5327 - Validate test metadata
- Issue 4348 - Add tests for dsidm
- Bump crossbeam-utils from 0.8.6 to 0.8.8 in /src
- Issue 5333 - 389-ds-base fails to build with Python 3.11
* Mon Jun 13 2022 Python Maint <python-maint@redhat.com> - 2.2.1-2
- Rebuilt for Python 3.11
* Fri Jun 3 2022 Mark Reynolds <mreynolds@redhat.com> - 2.2.1-1
- Bump version to 2.2.1
- Issue 5323 - BUG - Fix issue in mdb tests with monitor (#5326)
- Issue 5170 - BUG - incorrect behaviour of filter test (#5315)
- Issue 5324 - plugin acceptance test needs hardening
- Issue 5319 - dsctl_tls_test.py fails with openssl-3.x
- Issue 5323 - BUG - migrating database for monitoring interface lead to crash (#5321)
- Issue 5304 - Need a compatibility option about sub suffix handling (#5310)
- Issue 5313 - dbgen test uses deprecated -h HOST and -p PORT options for ldapmodify
- Issue 5311 - Missing Requires for acl in the spec file
- Issue 5305 - OpenLDAP version autodetection doesn't work
- Issue 5307 - VERSION_PREREL is not set correctly in CI builds
- Issue 5302 - Release tarballs don't contain cockpit webapp
- Issue 5170 - RFE - improve filter logging to assist debugging (#5301)
- Issue 5299 - jemalloc 5.3 released
- Issue 5175 - Remove stale zlib-devel dependency declaration (#5173)
- Issue 5294 - Report Portal 5 is not processing test results XML file
- Issue 5170 - BUG - ldapsubentries were incorrectly returned (#5285)
- Issue 5291 - Harden ReplicationManager.wait_for_replication (#5292)
- Issue 379 - RFE - Compress rotated logs (fix linker)
- Issue 379 - RFE - Compress rotated logs
- Issue 5281 - HIGH - basic test does not run
- Issue 5284 - Replication broken after password change (#5286)
- Issue 5279 - dscontainer: TypeError: unsupported operand type(s) for /: 'str' and 'int'
- Issue 5170 - RFE - Filter optimiser (#5171)
- Issue 5276 - CLI - improve task handling
- Issue 5126 - Memory leak in slapi_ldap_get_lderrno (#5153)
- Issue 3 - ansible-ds - Prefix handling fix (#5275)
- Issue 5273 - CLI - add arg completer for instance name
- Issue 2893 - CLI - dscreate - add options for setting up replication
- Issue 4866 - CLI - when enabling replication set changelog trimming by default
- Issue 5241 - UI - Add account locking missing functionality (#5251)
- Issue 5180 - snmp_collator tries to unlock NULL mutex (#5266)
- Issue 4904 - Fix various small issues
- lib389 prerequisite for ansible-ds (#5253)
- Issue 5260 - BUG - OpenLDAP allows multiple names of memberof overlay (#5261)
- Issue 5252 - During DEL, vlv search can erroneously return NULL candidate (#5256)
- Issue 5254 - dscreate create-template regression due to 5a3bdc336 (#5255)
- Issue 5210 - Python undefined names in lib389
- Issue 5065 - Crash in suite plugins - test_dna_max_value (#5108)
- Issue 5247 - BUG - Missing attributes in samba schema (#5248)
- Issue 5242- Craft message may crash the server (#5243)
- Issue 4775 -plugin entryuuid failing (#5229)
- Issue 5239 - Nightly copr builds are broken
- Issue 5237 - audit-ci: Cannot convert undefined or null to object
- Issue 5234 - UI - rename Users and Groups tab
- Issue 5227 - UI - No way to move back to Get Started step (#5233)
- Issue 5217 - Simplify instance creation and administration by non root user (#5224)

File diff suppressed because one or more lines are too long

15
gating.yaml Normal file
View file

@ -0,0 +1,15 @@
--- !Policy
product_versions:
- fedora-*
decision_contexts: [bodhi_update_push_testing]
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}
--- !Policy
product_versions:
- fedora-*
decision_contexts: [bodhi_update_push_stable]
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional}

17
main.fmf Normal file
View file

@ -0,0 +1,17 @@
/plan:
summary: Basic test suite
discover:
how: fmf
execute:
how: tmt
prepare:
- name: install required packages
how: install
package: [389-ds-base, git, pytest]
- name: clone repo
how: shell
script: git clone https://github.com/389ds/389-ds-base /root/ds
/test:
/upstream_basic:
test: pytest -v /root/ds/dirsrvtests/tests/suites/basic/basic_test.py
duration: 30m

View file

@ -1,2 +1,3 @@
SHA512 (389-ds-base-3.0.6.tar.bz2) = 9091da9229f20446357fd713f4177a885faa3fb4f83fc7806bdd0590f959dd02e6ebb8bb4e573b19537efeb3cef96f43eedab565b98b2d155055ea579f09b474
SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1
SHA512 (389-ds-base-3.0.2.tar.bz2) = e17ebc39a256848b6f7e601be3df7dafa38b1148f9b4112824f242839ad6bd9f0472dfb5518b1868ceb3b24a48f232ab3099f3176d31713281ec1f926bdacf88
SHA512 (libdb-5.3.28-59.tar.bz2) = 731a434fa2e6487ebb05c458b0437456eb9f7991284beb08cb3e21931e23bdeddddbc95bfabe3a2f9f029fe69cd33a2d4f0f5ce6a9811e9c3b940cb6fde4bf79

View file

@ -1,26 +0,0 @@
---
- hosts: localhost
remote_user: root
vars:
ds_repo_url: https://github.com/389ds/389-ds-base.git
ds_repo_dir: ds
ds_tests: "{{ ds_repo_dir }}/dirsrvtests/tests"
pytest: py.test-3
pytest_args: "-v --continue-on-collection-errors"
pytest_tests: "suites/basic"
artifacts: ./artifacts
roles:
- role: standard-test-basic
tags:
- classic
repositories:
- repo: "{{ ds_repo_url }}"
dest: "{{ ds_repo_dir }}"
tests:
- basic:
dir: "{{ ds_tests }}"
run: "{{ pytest }} {{ pytest_args }} {{ pytest_tests }}"
required_packages:
- python3-pytest
- 389-ds-base
- 389-ds-base-snmp