Resolves: CVE-2026-9064

This commit is contained in:
Viktor Ashirov
2026-06-05 10:11:20 +02:00
parent c875824408
commit b69019f5ff
2 changed files with 441 additions and 1 deletions
+2 -1
View File
@@ -545,6 +545,7 @@ Patch: 0025-Issue-7223-Remove-integerOrderingMatch-requirement-f.patc
Patch: 0026-Security-fix-for-CVE-2025-14905.patch
Patch: 0027-Issue-7302-dblib-bdb2mdb-fails-on-F43-F43-upgrade-73.patch
Patch: 0028-Issue-7267-MDB_BAD_VALSIZE-error-when-updating-index.patch
Patch: 0029-Issue-7503-CVE-2026-9064-Add-a-limit-to-the-number-c.patch
%description
389 Directory Server is an LDAPv3 compliant server. The base package includes
@@ -558,7 +559,7 @@ Please see http://seclists.org/oss-sec/2016/q1/363 for more information.
%if %{with libbdb_ro}
%package robdb-libs
Summary: Read-only Berkeley Database Library
License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib
License: GPL-3.0-or-later WITH GPL-3.0-389-ds-base-exception AND (Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND (Apache-2.0 OR LGPL-2.1-or-later OR MIT) AND (Apache-2.0 OR MIT) AND (CC-BY-4.0 AND MIT) AND (MIT OR Apache-2.0) AND Unicode-3.0 AND (MIT OR CC0-1.0) AND (MIT OR Unlicense) AND 0BSD AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND MIT AND MIT AND ISC AND MPL-2.0 AND PSF-2.0 AND Zlib
%description robdb-libs
The %{name}-robdb-lib package contains a library derived from rpm
@@ -0,0 +1,439 @@
From 7e9647f5bb5c47602f4cdf0022cf6bd22872d3ef Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Thu, 21 May 2026 09:17:39 -0400
Subject: [PATCH] Issue 7503 - CVE-2026-9064 - Add a limit to the number
controls per operation
Description:
Security fix for CVE-2026-9064
To prevent resource starvation limit the number of controls the server will
process per operation. Reject the operation if number of controls exceeds
the limit
relates: https://github.com/389ds/389-ds-base/issues/7503
References:
- https://access.redhat.com/security/cve/cve-2026-9064
- https://bugzilla.redhat.com/show_bug.cgi?id=2480093
CI test assisted by: Cursor
Reviewed by: jchapman & tbordaz (Thanks!!)
---
.../suites/features/ldap_controls_test.py | 76 ++++++++++++++++++-
ldap/schema/01core389.ldif | 3 +-
ldap/servers/slapd/control.c | 14 +++-
ldap/servers/slapd/libglobs.c | 52 +++++++++++++
ldap/servers/slapd/proto-slap.h | 2 +
ldap/servers/slapd/slap.h | 4 +
.../389-console/src/lib/server/tuning.jsx | 52 ++++++++++++-
7 files changed, 197 insertions(+), 6 deletions(-)
diff --git a/dirsrvtests/tests/suites/features/ldap_controls_test.py b/dirsrvtests/tests/suites/features/ldap_controls_test.py
index 0f8aa08be..59a58b21d 100644
--- a/dirsrvtests/tests/suites/features/ldap_controls_test.py
+++ b/dirsrvtests/tests/suites/features/ldap_controls_test.py
@@ -9,15 +9,18 @@
import logging
import pytest
import ldap
+from ldap.controls import RequestControl
from ldap.controls.readentry import PostReadControl
from lib389.idm.user import UserAccounts, UserAccount
-from lib389.topologies import topology_st
-from lib389._constants import DEFAULT_SUFFIX
+from test389.topologies import topology_st
+from lib389._constants import DEFAULT_SUFFIX, DN_DM, PASSWORD
pytestmark = pytest.mark.tier1
log = logging.getLogger(__name__)
+MANAGE_DSAIT_OID = "2.16.840.1.113730.3.4.2"
+MAX_CONTROLS_PER_OP_ATTR = "nsslapd-maxcontrolsperop"
def test_postread_ctrl_modify(topology_st):
"""Test PostReadControl with LDAP modify operations.
@@ -79,6 +82,75 @@ def test_postread_ctrl_modify(topology_st):
user.delete()
+def _make_request_controls(count):
+ return [
+ RequestControl(controlType=MANAGE_DSAIT_OID, criticality=False)
+ for _ in range(count)
+ ]
+
+
+def test_bind_excessive_controls(topology_st):
+ """Bind request control count is limited by nsslapd-maxcontrolsperop
+
+ :id: c3888f02-2107-4682-a50a-2189d1436233
+ :setup: Standalone instance
+ :steps:
+ 1. Read nsslapd-maxcontrolsperop from cn=config (default 10)
+ 2. Bind with one fewer control than the limit
+ 3. Bind with one more control than the limit
+ 4. Set nsslapd-maxcontrolsperop to 5
+ 5. Bind with 4 controls (new limit minus one)
+ 6. Bind with 6 controls (over new limit)
+ 7. Restore nsslapd-maxcontrolsperop and re-bind as Directory Manager
+ :expectedresults:
+ 1. Config value is 10
+ 2. Bind succeeds
+ 3. Bind fails with ldap.UNWILLING_TO_PERFORM
+ 4. Success
+ 5. Bind succeeds
+ 6. Bind fails with ldap.UNWILLING_TO_PERFORM
+ 7. Success
+ """
+ inst = topology_st.standalone
+ original_max = inst.config.get_attr_val_utf8(MAX_CONTROLS_PER_OP_ATTR)
+
+ try:
+ max_controls = int(inst.config.get_attr_val_utf8(MAX_CONTROLS_PER_OP_ATTR))
+ assert max_controls == 10
+
+ log.info("Bind with %d controls (limit %d, limit minus one)",
+ max_controls - 1, max_controls)
+ inst.simple_bind_s(DN_DM, PASSWORD,
+ serverctrls=_make_request_controls(max_controls - 1))
+
+ log.info("Bind with %d controls (limit %d plus one)",
+ max_controls + 1, max_controls)
+ with pytest.raises(ldap.UNWILLING_TO_PERFORM):
+ inst.simple_bind_s(DN_DM, PASSWORD,
+ serverctrls=_make_request_controls(max_controls + 1))
+ inst.simple_bind_s(DN_DM, PASSWORD)
+
+ lowered_max = 5
+ log.info("Set %s to %d", MAX_CONTROLS_PER_OP_ATTR, lowered_max)
+ inst.config.set(MAX_CONTROLS_PER_OP_ATTR, str(lowered_max))
+ assert int(inst.config.get_attr_val_utf8(MAX_CONTROLS_PER_OP_ATTR)) == lowered_max
+
+ log.info("Bind with %d controls (lowered limit %d, limit minus one)",
+ lowered_max - 1, lowered_max)
+ inst.simple_bind_s(DN_DM, PASSWORD,
+ serverctrls=_make_request_controls(lowered_max - 1))
+
+ log.info("Bind with %d controls (lowered limit %d plus one)",
+ lowered_max + 1, lowered_max)
+ with pytest.raises(ldap.UNWILLING_TO_PERFORM):
+ inst.simple_bind_s(DN_DM, PASSWORD,
+ serverctrls=_make_request_controls(lowered_max + 1))
+ finally:
+ log.info("Restore %s to %s", MAX_CONTROLS_PER_OP_ATTR, original_max)
+ inst.config.set(MAX_CONTROLS_PER_OP_ATTR, original_max)
+ inst.simple_bind_s(DN_DM, PASSWORD)
+
+
if __name__ == '__main__':
CURRENT_FILE = __file__
pytest.main(["-s", "-v", CURRENT_FILE])
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index bfe8259f8..7e2d1ac44 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -5,7 +5,7 @@
# All rights reserved.
#
# License: GPL (version 3 or any later version).
-# See LICENSE for details.
+# See LICENSE for details.
# END COPYRIGHT BLOCK
#
#
@@ -333,6 +333,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2392 NAME 'nsslapd-return-original-entry
attributeTypes: ( 2.16.840.1.113730.3.1.2393 NAME 'nsslapd-auditlog-display-attrs' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2398 NAME 'nsslapd-haproxy-trusted-ip' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN '389 Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2400 NAME 'nsslapd-pwdPBKDF2NumIterations' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2402 NAME 'nsslapd-maxcontrolsperop' DESC '389 Directory Server defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN '389 Directory Server' )
#
# objectclasses
#
diff --git a/ldap/servers/slapd/control.c b/ldap/servers/slapd/control.c
index d661dc6e1..9373c9f70 100644
--- a/ldap/servers/slapd/control.c
+++ b/ldap/servers/slapd/control.c
@@ -302,7 +302,7 @@ get_ldapmessage_controls_ext(
ber_tag_t tag;
/* ber_len_t is uint, cannot be -1 */
ber_len_t len = LBER_ERROR;
- int rc, maxcontrols, curcontrols;
+ int rc, maxcontrols, curcontrols, maxcontrols_per_op;
char *last;
int managedsait, pwpolicy_ctrl;
Connection *pb_conn = NULL;
@@ -379,11 +379,21 @@ get_ldapmessage_controls_ext(
return (LDAP_PROTOCOL_ERROR);
}
+ maxcontrols_per_op = config_get_maxcontrolsperop();
maxcontrols = curcontrols = 0;
for (tag = ber_first_element(ber, &len, &last);
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
- tag = ber_next_element(ber, &len, last)) {
+ tag = ber_next_element(ber, &len, last))
+ {
len = -1; /* reset */
+ if (curcontrols >= maxcontrols_per_op) {
+ slapi_log_err(SLAPI_LOG_ERR, "get_ldapmessage_controls_ext",
+ "Too many controls in LDAP request (max %d)\n",
+ maxcontrols_per_op);
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ goto free_and_return;
+ }
+
if (curcontrols >= maxcontrols - 1) {
#define CONTROL_GRABSIZE 6
maxcontrols += CONTROL_GRABSIZE;
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 887ae9a9d..ecf736ef6 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -1466,6 +1466,11 @@ static struct config_get_and_set
NULL, 0,
(void **)&global_slapdFrontendConfig.return_orig_dn,
CONFIG_ON_OFF, (ConfigGetFunc)config_get_return_orig_dn, &init_return_orig_dn, NULL},
+ {CONFIG_MAXCONTROLS_PER_OP_ATTRIBUTE, config_set_maxcontrolsperop,
+ NULL, 0,
+ (void **)&global_slapdFrontendConfig.maxcontrols_per_op,
+ CONFIG_INT, (ConfigGetFunc)config_get_maxcontrolsperop,
+ SLAPD_DEFAULT_MAXCONTROLS_PER_OP_STR, NULL},
/* End config */
};
@@ -2041,6 +2046,7 @@ FrontendConfig_init(void)
init_cn_uses_dn_syntax_in_dns = cfg->cn_uses_dn_syntax_in_dns = LDAP_OFF;
init_global_backend_local = LDAP_OFF;
cfg->maxsimplepaged_per_conn = SLAPD_DEFAULT_MAXSIMPLEPAGED_PER_CONN;
+ cfg->maxcontrols_per_op = SLAPD_DEFAULT_MAXCONTROLS_PER_OP;
cfg->maxbersize = SLAPD_DEFAULT_MAXBERSIZE;
cfg->logging_backend = slapi_ch_strdup(SLAPD_INIT_LOGGING_BACKEND_INTERNAL);
cfg->rootdn = slapi_ch_strdup(SLAPD_DEFAULT_DIRECTORY_MANAGER);
@@ -10105,6 +10111,52 @@ config_get_maxsimplepaged_per_conn()
return retVal;
}
+int
+config_set_maxcontrolsperop(const char *attrname, char *value, char *errorbuf, int apply)
+{
+ int retVal = LDAP_SUCCESS;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ long size;
+ char *endp;
+
+ if (config_value_is_null(attrname, value, errorbuf, 0)) {
+ return LDAP_OPERATIONS_ERROR;
+ }
+
+ errno = 0;
+ size = strtol(value, &endp, 10);
+ if (*endp != '\0' || errno == ERANGE || size < 1 || size > 1000) {
+ slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
+ "(%s) value (%s) is invalid, must be at least 1 and less than 1000\n",
+ attrname, value);
+ return LDAP_OPERATIONS_ERROR;
+ }
+
+ if (!apply) {
+ return retVal;
+ }
+
+ CFG_LOCK_WRITE(slapdFrontendConfig);
+
+ slapdFrontendConfig->maxcontrols_per_op = size;
+
+ CFG_UNLOCK_WRITE(slapdFrontendConfig);
+ return retVal;
+}
+
+int
+config_get_maxcontrolsperop()
+{
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ retVal = slapdFrontendConfig->maxcontrols_per_op;
+ if (retVal == 0) {
+ retVal = SLAPD_DEFAULT_MAXCONTROLS_PER_OP;
+ }
+ return retVal;
+}
+
int32_t
config_set_extract_pem(const char *attrname, char *value, char *errorbuf, int apply)
{
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 8a2f74836..c6482414f 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -426,6 +426,7 @@ int32_t config_set_maxdescriptors(const char *attrname, char *value, char *error
int config_set_localuser(const char *attrname, char *value, char *errorbuf, int apply);
int config_set_maxsimplepaged_per_conn(const char *attrname, char *value, char *errorbuf, int apply);
+int config_set_maxcontrolsperop(const char *attrname, char *value, char *errorbuf, int apply);
int log_external_libs_debug_set_log_fn(void);
int log_set_backend(const char *attrname, char *value, int logtype, char *errorbuf, int apply);
@@ -631,6 +632,7 @@ int config_get_malloc_mmap_threshold(void);
#endif
int config_get_maxsimplepaged_per_conn(void);
+int config_get_maxcontrolsperop(void);
int config_get_extract_pem(void);
int32_t config_get_enable_upgrade_hash(void);
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 1e5ad84bf..5b1d8850e 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -301,6 +301,8 @@ typedef void (*VFPV)(); /* takes undefined arguments */
#define SLAPD_DEFAULT_MAXBERSIZE_STR "2097152"
#define SLAPD_DEFAULT_MAXSIMPLEPAGED_PER_CONN (-1)
#define SLAPD_DEFAULT_MAXSIMPLEPAGED_PER_CONN_STR "-1"
+#define SLAPD_DEFAULT_MAXCONTROLS_PER_OP 10
+#define SLAPD_DEFAULT_MAXCONTROLS_PER_OP_STR "10"
#define SLAPD_DEFAULT_LDAPSSOTOKEN_TTL 3600
#define SLAPD_DEFAULT_LDAPSSOTOKEN_TTL_STR "3600"
@@ -2417,6 +2419,7 @@ typedef struct _slapdEntryPoints
#define CONFIG_CN_USES_DN_SYNTAX_IN_DNS "nsslapd-cn-uses-dn-syntax-in-dns"
#define CONFIG_MAXSIMPLEPAGED_PER_CONN_ATTRIBUTE "nsslapd-maxsimplepaged-per-conn"
+#define CONFIG_MAXCONTROLS_PER_OP_ATTRIBUTE "nsslapd-maxcontrolsperop"
#define CONFIG_LOGGING_BACKEND "nsslapd-logging-backend"
#define CONFIG_EXTRACT_PEM "nsslapd-extract-pemfiles"
@@ -2749,6 +2752,7 @@ typedef struct _slapdFrontendConfig
slapi_onoff_t cn_uses_dn_syntax_in_dns; /* indicates the cn value in dns has dn syntax */
slapi_onoff_t global_backend_lock;
slapi_int_t maxsimplepaged_per_conn; /* max simple paged results reqs handled per connection */
+ slapi_int_t maxcontrols_per_op; /* max LDAP controls allowed per operation */
slapi_onoff_t enable_nunc_stans; /* Despite the removal of NS, we have to leave the value in
* case someone was setting it.
*/
diff --git a/src/cockpit/389-console/src/lib/server/tuning.jsx b/src/cockpit/389-console/src/lib/server/tuning.jsx
index 5f56ff858..fe0ed9d2e 100644
--- a/src/cockpit/389-console/src/lib/server/tuning.jsx
+++ b/src/cockpit/389-console/src/lib/server/tuning.jsx
@@ -23,6 +23,7 @@ const tuning_attrs = [
'nsslapd-connection-nocanon',
'nsslapd-enable-turbo-mode',
'nsslapd-threadnumber',
+ 'nsslapd-maxthreadsperconn',
'nsslapd-maxdescriptors',
'nsslapd-timelimit',
'nsslapd-sizelimit',
@@ -34,6 +35,7 @@ const tuning_attrs = [
'nsslapd-maxsasliosize',
'nsslapd-listen-backlog-size',
'nsslapd-max-filter-nest-level',
+ 'nsslapd-maxcontrolsperop',
'nsslapd-ndn-cache-max-size',
];
@@ -161,6 +163,7 @@ export class ServerTuning extends React.Component {
'nsslapd-connection-nocanon': connNoCannon,
'nsslapd-enable-turbo-mode': turboMode,
'nsslapd-threadnumber': attrs['nsslapd-threadnumber'][0],
+ 'nsslapd-maxthreadsperconn': attrs['nsslapd-maxthreadsperconn'][0],
'nsslapd-maxdescriptors': attrs['nsslapd-maxdescriptors'][0],
'nsslapd-timelimit': attrs['nsslapd-timelimit'][0],
'nsslapd-sizelimit': attrs['nsslapd-sizelimit'][0],
@@ -172,6 +175,7 @@ export class ServerTuning extends React.Component {
'nsslapd-maxsasliosize': attrs['nsslapd-maxsasliosize'][0],
'nsslapd-listen-backlog-size': attrs['nsslapd-listen-backlog-size'][0],
'nsslapd-max-filter-nest-level': attrs['nsslapd-max-filter-nest-level'][0],
+ 'nsslapd-maxcontrolsperop': attrs['nsslapd-maxcontrolsperop'][0],
'nsslapd-ndn-cache-max-size': attrs['nsslapd-ndn-cache-max-size'][0],
// Record original values
'_nsslapd-ndn-cache-enabled': ndnEnabled,
@@ -179,6 +183,7 @@ export class ServerTuning extends React.Component {
'_nsslapd-connection-nocanon': connNoCannon,
'_nsslapd-enable-turbo-mode': turboMode,
'_nsslapd-threadnumber': attrs['nsslapd-threadnumber'][0],
+ '_nsslapd-maxthreadsperconn': attrs['nsslapd-maxthreadsperconn'][0],
'_nsslapd-maxdescriptors': attrs['nsslapd-maxdescriptors'][0],
'_nsslapd-timelimit': attrs['nsslapd-timelimit'][0],
'_nsslapd-sizelimit': attrs['nsslapd-sizelimit'][0],
@@ -190,6 +195,7 @@ export class ServerTuning extends React.Component {
'_nsslapd-maxsasliosize': attrs['nsslapd-maxsasliosize'][0],
'_nsslapd-listen-backlog-size': attrs['nsslapd-listen-backlog-size'][0],
'_nsslapd-max-filter-nest-level': attrs['nsslapd-max-filter-nest-level'][0],
+ '_nsslapd-maxcontrolsperop': attrs['nsslapd-maxcontrolsperop'][0],
'_nsslapd-ndn-cache-max-size': attrs['nsslapd-ndn-cache-max-size'][0],
}, this.props.enableTree());
})
@@ -275,7 +281,7 @@ export class ServerTuning extends React.Component {
<TextContent>
<Text component={TextVariants.h3}>
{_("Tuning & Limits")}
- <Button
+ <Button
variant="plain"
aria-label={_("Refresh settings")}
onClick={() => {
@@ -312,6 +318,28 @@ export class ServerTuning extends React.Component {
/>
</GridItem>
</Grid>
+ <Grid
+ title={_("The maximum number of threads that can handle requests for a single connection (nsslapd-maxthreadsperconn).")}
+ >
+ <GridItem className="ds-label" span={3}>
+ {_("Max Threads Per Connection")}
+ </GridItem>
+ <GridItem span={9}>
+ <NumberInput
+ value={this.state['nsslapd-maxthreadsperconn']}
+ min={1}
+ max={65535}
+ onMinus={() => { this.onMinusConfig("nsslapd-maxthreadsperconn") }}
+ onChange={(e) => { this.onConfigChange(e, "nsslapd-maxthreadsperconn", 1, 65535) }}
+ onPlus={() => { this.onPlusConfig("nsslapd-maxthreadsperconn") }}
+ inputName="input"
+ inputAriaLabel="number input"
+ minusBtnAriaLabel="minus"
+ plusBtnAriaLabel="plus"
+ widthChars={8}
+ />
+ </GridItem>
+ </Grid>
<Grid
title={_("The maximum number of seconds allocated for a search request. Set to '-1' to disable the time limit (nsslapd-timelimit).")}
>
@@ -542,6 +570,28 @@ export class ServerTuning extends React.Component {
/>
</GridItem>
</Grid>
+ <Grid
+ title={_("The maximum number of LDAP controls allowed per operation (nsslapd-maxcontrolsperop).")}
+ >
+ <GridItem className="ds-label" span={3}>
+ {_("Maximum Controls Per Operation")}
+ </GridItem>
+ <GridItem span={9}>
+ <NumberInput
+ value={this.state['nsslapd-maxcontrolsperop']}
+ min={1}
+ max={1000}
+ onMinus={() => { this.onMinusConfig("nsslapd-maxcontrolsperop") }}
+ onChange={(e) => { this.onConfigChange(e, "nsslapd-maxcontrolsperop", 1, 0) }}
+ onPlus={() => { this.onPlusConfig("nsslapd-maxcontrolsperop") }}
+ inputName="input"
+ inputAriaLabel="number input"
+ minusBtnAriaLabel="minus"
+ plusBtnAriaLabel="plus"
+ widthChars={8}
+ />
+ </GridItem>
+ </Grid>
<Grid
title={_("Disable DNS reverse entries for outgoing connections (nsslapd-connection-nocanon).")}
>
--
2.54.0